Skip to content

Commit 2f44df1

Browse files
author
Emanuele Palazzetti
committed
[aiobotocore] update context manager so it works using async with
1 parent e164347 commit 2f44df1

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

ddtrace/contrib/aiobotocore/patch.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,14 @@ def read(self, *args, **kwargs):
5656
if PYTHON_VERSION >= (3, 5, 0):
5757
@asyncio.coroutine
5858
def __aenter__(self):
59-
return self.__wrapped__.__aenter__()
59+
# call the wrapped method but return the object proxy
60+
yield from self.__wrapped__.__aenter__()
61+
return self
6062

6163
@asyncio.coroutine
6264
def __aexit__(self, *args, **kwargs):
63-
return self.__wrapped__.__aexit__(*args, **kwargs)
65+
response = yield from self.__wrapped__.__aexit__(*args, **kwargs)
66+
return response
6467

6568

6669
def truncate_arg_value(value, max_len=1024):
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from nose.tools import eq_, ok_, assert_raises
2+
from botocore.errorfactory import ClientError
3+
4+
from ddtrace.contrib.aiobotocore.patch import patch, unpatch
5+
6+
from .utils import aiobotocore_client
7+
from ..asyncio.utils import AsyncioTestCase, mark_asyncio
8+
from ...test_tracer import get_dummy_tracer
9+
10+
11+
class AIOBotocoreTest(AsyncioTestCase):
12+
"""Botocore integration testsuite"""
13+
def setUp(self):
14+
super(AIOBotocoreTest, self).setUp()
15+
patch()
16+
self.tracer = get_dummy_tracer()
17+
18+
def tearDown(self):
19+
super(AIOBotocoreTest, self).tearDown()
20+
unpatch()
21+
self.tracer = None
22+
23+
@mark_asyncio
24+
async def test_response_context_manager(self):
25+
# the client should call the wrapped __aenter__ and return the
26+
# object proxy
27+
with aiobotocore_client('s3', self.tracer) as s3:
28+
# prepare S3 and flush traces if any
29+
await s3.create_bucket(Bucket='tracing')
30+
await s3.put_object(Bucket='tracing', Key='apm', Body=b'')
31+
self.tracer.writer.pop_traces()
32+
# `async with` under test
33+
response = await s3.get_object(Bucket='tracing', Key='apm')
34+
async with response['Body'] as stream:
35+
await stream.read()
36+
37+
traces = self.tracer.writer.pop_traces()
38+
eq_(len(traces), 2)
39+
eq_(len(traces[0]), 1)
40+
eq_(len(traces[1]), 1)
41+
42+
span = traces[0][0]
43+
eq_(span.get_tag('aws.operation'), 'GetObject')
44+
eq_(span.get_tag('http.status_code'), '200')
45+
eq_(span.service, 'aws.s3')
46+
eq_(span.resource, 's3.getobject')
47+
48+
read_span = traces[1][0]
49+
eq_(read_span.get_tag('aws.operation'), 'GetObject')
50+
eq_(read_span.get_tag('http.status_code'), '200')
51+
eq_(read_span.service, 'aws.s3')
52+
eq_(read_span.resource, 's3.getobject')
53+
eq_(read_span.name, 's3.command.read')
54+
# enforce parenting
55+
eq_(read_span.parent_id, span.span_id)
56+
eq_(read_span.trace_id, span.trace_id)

tox.ini

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ commands =
210210
{py27}-pylons: nosetests {posargs} tests/contrib/pylons
211211
{py27,py34}-boto: nosetests {posargs} tests/contrib/boto
212212
{py27,py34}-botocore: nosetests {posargs} tests/contrib/botocore
213-
aiobotocore{02,03,04}: nosetests {posargs} tests/contrib/aiobotocore
213+
py{34}-aiobotocore{02,03,04}: nosetests {posargs} --exclude=".*(test_35).*" tests/contrib/aiobotocore
214+
py{35,36}-aiobotocore{02,03,04}: nosetests {posargs} tests/contrib/aiobotocore
214215
bottle{12}: nosetests {posargs} tests/contrib/bottle/test.py
215216
bottle-autopatch{12}: ddtrace-run nosetests {posargs} tests/contrib/bottle/test_autopatch.py
216217
cassandra{35,36,37,38}: nosetests {posargs} tests/contrib/cassandra

0 commit comments

Comments
 (0)