Skip to content

Commit 4d89e06

Browse files
authored
[testing] Ensure consistent use of override_config and override_env (#815)
* [testing] Ensure consistent use of override_config/override_env * fix linting issues * fix usage of override_env * fix override_env logic
1 parent ef0c134 commit 4d89e06

File tree

11 files changed

+72
-106
lines changed

11 files changed

+72
-106
lines changed

tests/base/__init__.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import contextlib
2+
import os
23
import unittest
34

45
import ddtrace
@@ -23,6 +24,25 @@ def test_case(self):
2324
pass
2425
"""
2526

27+
@contextlib.contextmanager
28+
def override_env(self, env):
29+
"""
30+
Temporarily override ``os.environ`` with provided values
31+
>>> with self.override_env(dict(DATADOG_TRACE_DEBUG=True)):
32+
# Your test
33+
"""
34+
# Copy the full original environment
35+
original = dict(os.environ)
36+
37+
# Update based on the passed in arguments
38+
os.environ.update(env)
39+
try:
40+
yield
41+
finally:
42+
# Full clear the environment out and reset back to the original
43+
os.environ.clear()
44+
os.environ.update(original)
45+
2646
@contextlib.contextmanager
2747
def override_config(self, integration, values):
2848
"""

tests/contrib/celery/base.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from celery import Celery
22

3-
from ddtrace import Pin, config
3+
from ddtrace import Pin
44
from ddtrace.compat import PY2
55
from ddtrace.contrib.celery import patch, unpatch
66

@@ -21,8 +21,6 @@ class CeleryBaseTestCase(BaseTracerTestCase):
2121
def setUp(self):
2222
super(CeleryBaseTestCase, self).setUp()
2323

24-
# keep track of original config
25-
self._config = dict(config.celery)
2624
# instrument Celery and create an app with Broker and Result backends
2725
patch()
2826
self.pin = Pin(service='celery-unittest', tracer=self.tracer)
@@ -34,9 +32,6 @@ def tearDown(self):
3432
# remove instrumentation from Celery
3533
unpatch()
3634
self.app = None
37-
# restore the global configuration
38-
config.celery.update(self._config)
39-
self._config = None
4035

4136
super(CeleryBaseTestCase, self).tearDown()
4237

tests/contrib/celery/test_integration.py

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
from nose.tools import eq_, ok_
55

6-
from ddtrace import config
76
from ddtrace.contrib.celery import patch, unpatch
87

98
from .base import CeleryBaseTestCase
@@ -306,41 +305,39 @@ def add(x, y):
306305
eq_(span.get_tag('celery.state'), 'SUCCESS')
307306

308307
def test_worker_service_name(self):
309-
# Ensure worker service name can be changed via
310-
# configuration object
311-
config.celery['worker_service_name'] = 'worker-notify'
312-
313308
@self.app.task
314309
def fn_task():
315310
return 42
316311

317-
t = fn_task.apply()
318-
ok_(t.successful())
319-
eq_(42, t.result)
312+
# Ensure worker service name can be changed via
313+
# configuration object
314+
with self.override_config('celery', dict(worker_service_name='worker-notify')):
315+
t = fn_task.apply()
316+
self.assertTrue(t.successful())
317+
self.assertEqual(42, t.result)
320318

321-
traces = self.tracer.writer.pop_traces()
322-
eq_(1, len(traces))
323-
eq_(1, len(traces[0]))
324-
span = traces[0][0]
325-
eq_(span.service, 'worker-notify')
319+
traces = self.tracer.writer.pop_traces()
320+
self.assertEqual(1, len(traces))
321+
self.assertEqual(1, len(traces[0]))
322+
span = traces[0][0]
323+
self.assertEqual(span.service, 'worker-notify')
326324

327325
def test_producer_service_name(self):
328-
# Ensure producer service name can be changed via
329-
# configuration object
330-
config.celery['producer_service_name'] = 'task-queue'
331-
332326
@self.app.task
333327
def fn_task():
334328
return 42
335329

336-
t = fn_task.delay()
337-
eq_('PENDING', t.status)
338-
339-
traces = self.tracer.writer.pop_traces()
340-
eq_(1, len(traces))
341-
eq_(1, len(traces[0]))
342-
span = traces[0][0]
343-
eq_(span.service, 'task-queue')
330+
# Ensure producer service name can be changed via
331+
# configuration object
332+
with self.override_config('celery', dict(producer_service_name='task-queue')):
333+
t = fn_task.delay()
334+
self.assertEqual('PENDING', t.status)
335+
336+
traces = self.tracer.writer.pop_traces()
337+
self.assertEqual(1, len(traces))
338+
self.assertEqual(1, len(traces[0]))
339+
span = traces[0][0]
340+
self.assertEqual(span.service, 'task-queue')
344341

345342
def test_fn_task_apply_async_ot(self):
346343
"""OpenTracing version of test_fn_task_apply_async."""

tests/contrib/django/test_instrumentation.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
# testing
88
from .utils import DjangoTraceTestCase
9-
from ...util import set_env
109

1110

1211
class DjangoInstrumentationTest(DjangoTraceTestCase):
@@ -23,17 +22,17 @@ def test_tracer_flags(self):
2322
def test_environment_vars(self):
2423
# Django defaults can be overridden by env vars, ensuring that
2524
# environment strings are properly converted
26-
with set_env(
25+
with self.override_env(dict(
2726
DATADOG_TRACE_AGENT_HOSTNAME='agent.consul.local',
2827
DATADOG_TRACE_AGENT_PORT='58126'
29-
):
28+
)):
3029
settings = DatadogSettings()
3130
eq_(settings.AGENT_HOSTNAME, 'agent.consul.local')
3231
eq_(settings.AGENT_PORT, 58126)
3332

3433
def test_environment_var_wrong_port(self):
3534
# ensures that a wrong Agent Port doesn't crash the system
3635
# and defaults to 8126
37-
with set_env(DATADOG_TRACE_AGENT_PORT='something'):
36+
with self.override_env(dict(DATADOG_TRACE_AGENT_PORT='something')):
3837
settings = DatadogSettings()
3938
eq_(settings.AGENT_PORT, 8126)

tests/contrib/falcon/test_suite.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from ddtrace.ext import errors as errx, http as httpx
66

77
from tests.opentracer.utils import init_tracer
8-
from ...util import override_config
98

109

1110
class FalconTestCase(object):
@@ -193,7 +192,7 @@ def on_falcon_request(span, request, response):
193192
eq_(span.get_tag('my.custom'), 'tag')
194193

195194
def test_http_header_tracing(self):
196-
with override_config('falcon', {}):
195+
with self.override_config('falcon', {}):
197196
config.falcon.http.trace_headers(['my-header', 'my-response-header'])
198197
self.simulate_get('/200', headers={'my-header': 'my_value'})
199198
traces = self.tracer.writer.pop_traces()

tests/contrib/flask/test_request.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from ddtrace.propagation.http import HTTP_HEADER_TRACE_ID, HTTP_HEADER_PARENT_ID
66
from flask import abort
77

8-
from ...util import override_config
98
from . import BaseFlaskTestCase
109

1110

@@ -117,7 +116,7 @@ def index():
117116
return 'Hello Flask', 200
118117

119118
# Enable distributed tracing
120-
with override_config('flask', dict(distributed_tracing_enabled=True)):
119+
with self.override_config('flask', dict(distributed_tracing_enabled=True)):
121120
res = self.client.get('/', headers={
122121
HTTP_HEADER_PARENT_ID: '12345',
123122
HTTP_HEADER_TRACE_ID: '678910',
@@ -131,7 +130,7 @@ def index():
131130
self.assertEqual(span.parent_id, 12345)
132131

133132
# With distributed tracing disabled
134-
with override_config('flask', dict(distributed_tracing_enabled=False)):
133+
with self.override_config('flask', dict(distributed_tracing_enabled=False)):
135134
res = self.client.get('/', headers={
136135
HTTP_HEADER_PARENT_ID: '12345',
137136
HTTP_HEADER_TRACE_ID: '678910',

tests/contrib/httplib/test_httplib.py

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Standard library
22
import contextlib
33
import sys
4-
import unittest
54

65
# Third party
76
import wrapt
@@ -15,8 +14,8 @@
1514

1615
from tests.opentracer.utils import init_tracer
1716

18-
from ...test_tracer import get_dummy_tracer
19-
from ...util import assert_dict_issuperset, override_global_tracer, override_config
17+
from ...base import BaseTracerTestCase
18+
from ...util import assert_dict_issuperset, override_global_tracer
2019

2120
if PY2:
2221
from urllib2 import urlopen, build_opener, Request
@@ -39,16 +38,19 @@ def to_str(self, value):
3938
return value.decode('utf-8')
4039

4140
def setUp(self):
41+
super(HTTPLibBaseMixin, self).setUp()
42+
4243
patch()
43-
self.tracer = get_dummy_tracer()
4444
Pin.override(httplib, tracer=self.tracer)
4545

4646
def tearDown(self):
4747
unpatch()
4848

49+
super(HTTPLibBaseMixin, self).tearDown()
50+
4951

5052
# Main test cases for httplib/http.client and urllib2/urllib.request
51-
class HTTPLibTestCase(HTTPLibBaseMixin, unittest.TestCase):
53+
class HTTPLibTestCase(HTTPLibBaseMixin, BaseTracerTestCase):
5254
SPAN_NAME = 'httplib.request' if PY2 else 'http.client.request'
5355

5456
def to_str(self, value):
@@ -65,13 +67,6 @@ def get_https_connection(self, *args, **kwargs):
6567
Pin.override(conn, tracer=self.tracer)
6668
return conn
6769

68-
def setUp(self):
69-
patch()
70-
self.tracer = get_dummy_tracer()
71-
72-
def tearDown(self):
73-
unpatch()
74-
7570
def test_patch(self):
7671
"""
7772
When patching httplib
@@ -354,7 +349,7 @@ def test_httplib_request_and_response_headers(self):
354349
self.assertEqual(s.get_tag('http.response.headers.access_control_allow_origin'), None)
355350

356351
# Enabled when configured
357-
with override_config('hhtplib', {}):
352+
with self.override_config('hhtplib', {}):
358353
integration_config = config.httplib # type: IntegrationConfig
359354
integration_config.http.trace_headers(['my-header', 'access-control-allow-origin'])
360355
conn = self.get_http_connection(SOCKET)
@@ -502,7 +497,7 @@ def test_httplib_request_get_request_ot(self):
502497
if PY2:
503498
import urllib
504499

505-
class HTTPLibPython2Test(HTTPLibBaseMixin, unittest.TestCase):
500+
class HTTPLibPython2Test(HTTPLibBaseMixin, BaseTracerTestCase):
506501
def test_urllib_request(self):
507502
"""
508503
When making a request via urllib.urlopen

tests/contrib/molten/test_molten.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from ddtrace.contrib.molten.patch import MOLTEN_VERSION
1212

1313
from ...base import BaseTracerTestCase
14-
from ...util import override_config
1514

1615

1716
# NOTE: Type annotations required by molten otherwise parameters cannot be coerced
@@ -158,7 +157,7 @@ def test_resources(self):
158157

159158
def test_distributed_tracing(self):
160159
""" Tests whether span IDs are propogated when distributed tracing is on """
161-
with override_config('molten', dict(distributed_tracing=True)):
160+
with self.override_config('molten', dict(distributed_tracing=True)):
162161
response = molten_client(headers={
163162
HTTP_HEADER_TRACE_ID: '100',
164163
HTTP_HEADER_PARENT_ID: '42',
@@ -173,7 +172,7 @@ def test_distributed_tracing(self):
173172
self.assertEqual(span.parent_id, 42)
174173

175174
# Now without tracing on
176-
with override_config('molten', dict(distributed_tracing=False)):
175+
with self.override_config('molten', dict(distributed_tracing=False)):
177176
response = molten_client(headers={
178177
HTTP_HEADER_TRACE_ID: '100',
179178
HTTP_HEADER_PARENT_ID: '42',

tests/contrib/requests/test_requests.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import unittest
2-
31
import requests
42
from requests import Session
53
from requests.exceptions import MissingSchema
@@ -11,30 +9,33 @@
119

1210
from tests.opentracer.utils import init_tracer
1311

14-
from ...test_tracer import get_dummy_tracer
15-
from ...util import override_global_tracer, override_config
12+
from ...base import BaseTracerTestCase
13+
from ...util import override_global_tracer
1614

1715
# socket name comes from https://english.stackexchange.com/a/44048
1816
SOCKET = 'httpbin.org'
1917
URL_200 = 'http://{}/status/200'.format(SOCKET)
2018
URL_500 = 'http://{}/status/500'.format(SOCKET)
2119

2220

23-
class BaseRequestTestCase(unittest.TestCase):
21+
class BaseRequestTestCase(object):
2422
"""Create a traced Session, patching during the setUp and
2523
unpatching after the tearDown
2624
"""
2725
def setUp(self):
26+
super(BaseRequestTestCase, self).setUp()
27+
2828
patch()
29-
self.tracer = get_dummy_tracer()
3029
self.session = Session()
3130
setattr(self.session, 'datadog_tracer', self.tracer)
3231

3332
def tearDown(self):
3433
unpatch()
3534

35+
super(BaseRequestTestCase, self).tearDown()
36+
3637

37-
class TestRequests(BaseRequestTestCase):
38+
class TestRequests(BaseRequestTestCase, BaseTracerTestCase):
3839
def test_resource_path(self):
3940
out = self.session.get(URL_200)
4041
eq_(out.status_code, 200)
@@ -375,7 +376,7 @@ def test_request_and_response_headers(self):
375376
eq_(s.get_tag('http.response.headers.access-control-allow-origin'), None)
376377

377378
# Enabled when explicitly configured
378-
with override_config('requests', {}):
379+
with self.override_config('requests', {}):
379380
config.requests.http.trace_headers(['my-header', 'access-control-allow-origin'])
380381
self.session.get(URL_200, headers={'my-header': 'my_value'})
381382
spans = self.tracer.writer.pop()

tests/contrib/requests/test_requests_distributed.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33

44
from ddtrace import config
55

6+
from ...base import BaseTracerTestCase
67
from .test_requests import BaseRequestTestCase
78

89

9-
class TestRequestsDistributed(BaseRequestTestCase):
10+
class TestRequestsDistributed(BaseRequestTestCase, BaseTracerTestCase):
1011
def headers_here(self, tracer, request, root_span):
1112
# Use an additional matcher to query the request headers.
1213
# This is because the parent_id can only been known within such a callback,

0 commit comments

Comments
 (0)