def test_cache_add_without_arguments(self): # initialize the dummy writer writer = DummyWriter() tracer = Tracer() tracer.writer = writer # create the TracedCache instance for a Flask app Cache = get_traced_cache(tracer, service=self.SERVICE) app = Flask(__name__) cache = Cache(app, config={'CACHE_TYPE': 'simple'}) # make a wrong call with pytest.raises(TypeError) as ex: cache.add() # ensure that the error is not caused by our tracer assert 'add()' in ex.value.args[0] assert 'argument' in ex.value.args[0] spans = writer.pop() # an error trace must be sent assert len(spans) == 1 span = spans[0] assert span.service == self.SERVICE assert span.resource == 'add' assert span.name == 'flask_cache.cmd' assert span.span_type == 'cache' assert span.error == 1
def test_memcached_cache_tracing_with_a_wrong_connection(self): # initialize the dummy writer writer = DummyWriter() tracer = Tracer() tracer.writer = writer # create the TracedCache instance for a Flask app Cache = get_traced_cache(tracer, service=self.SERVICE) app = Flask(__name__) config = { 'CACHE_TYPE': 'memcached', 'CACHE_MEMCACHED_SERVERS': ['localhost:2230'], } cache = Cache(app, config=config) # use a wrong memcached connection try: cache.get(u'á_complex_operation') except Exception: pass # ensure that the error is not caused by our tracer spans = writer.pop() assert len(spans) == 1 span = spans[0] assert span.service == self.SERVICE assert span.resource == 'get' assert span.name == 'flask_cache.cmd' assert span.span_type == 'cache' assert span.meta[CACHE_BACKEND] == 'memcached' assert span.meta[net.TARGET_HOST] == 'localhost' assert span.meta[net.TARGET_PORT] == '2230'
def test_redis_cache_tracing_with_a_wrong_connection(self): # initialize the dummy writer writer = DummyWriter() tracer = Tracer() tracer.writer = writer # create the TracedCache instance for a Flask app Cache = get_traced_cache(tracer, service=self.SERVICE) app = Flask(__name__) config = { 'CACHE_TYPE': 'redis', 'CACHE_REDIS_PORT': 2230, 'CACHE_REDIS_HOST': '127.0.0.1' } cache = Cache(app, config=config) # use a wrong redis connection with pytest.raises(ConnectionError) as ex: cache.get(u'á_complex_operation') # ensure that the error is not caused by our tracer assert '127.0.0.1:2230. Connection refused.' in ex.value.args[0] spans = writer.pop() # an error trace must be sent assert len(spans) == 1 span = spans[0] assert span.service == self.SERVICE assert span.resource == 'get' assert span.name == 'flask_cache.cmd' assert span.span_type == 'cache' assert span.meta[CACHE_BACKEND] == 'redis' assert span.meta[net.TARGET_HOST] == '127.0.0.1' assert span.meta[net.TARGET_PORT] == '2230' assert span.error == 1
def setUp(self): """ Create a tracer with running workers, while spying the ``_put()`` method to keep trace of triggered API calls. """ self.exporter = InMemorySpanExporter() api = APIOtel(exporter=self.exporter) # create a new tracer self.tracer = Tracer() self.tracer.configure(api=api) # spy the send() method self.api = self.tracer.writer.api
def test_resource_from_cache_without_prefix(self): # create the TracedCache instance for a Flask app tracer = Tracer() Cache = get_traced_cache(tracer, service=self.SERVICE) app = Flask(__name__) traced_cache = Cache(app, config={'CACHE_TYPE': 'redis'}) # expect only the resource name expected_resource = 'get' resource = _resource_from_cache_prefix('GET', traced_cache.config) assert resource == expected_resource
def setUp(self): # backup previous conf self.backupEnabled = settings.ENABLED self.backupTracer = settings.TRACER # Use a new tracer to be sure that a new service # would be sent to the the writer self.tracer = Tracer() self.tracer.writer = DummyWriter() # Restart app with tracing disabled settings.ENABLED = False self.app = apps.get_app_config('opentelemetry_django') self.app.ready()
def test_resource_from_cache_with_prefix(self): # create the TracedCache instance for a Flask app tracer = Tracer() Cache = get_traced_cache(tracer, service=self.SERVICE) app = Flask(__name__) config = { 'CACHE_TYPE': 'redis', 'CACHE_REDIS_PORT': REDIS_CONFIG['port'], 'CACHE_KEY_PREFIX': 'users', } traced_cache = Cache(app, config=config) # expect a resource with a prefix expected_resource = 'get users' resource = _resource_from_cache_prefix('GET', traced_cache.cache) assert resource == expected_resource
def test_extract_redis_connection_metadata(self): # create the TracedCache instance for a Flask app tracer = Tracer() Cache = get_traced_cache(tracer, service=self.SERVICE) app = Flask(__name__) config = { 'CACHE_TYPE': 'redis', 'CACHE_REDIS_PORT': REDIS_CONFIG['port'], } traced_cache = Cache(app, config=config) # extract client data meta = _extract_conn_tags(traced_cache.cache._client) expected_meta = { 'out.host': 'localhost', 'out.port': REDIS_CONFIG['port'], 'out.redis_db': 0 } assert meta == expected_meta
def test_extract_memcached_connection_metadata(self): # create the TracedCache instance for a Flask app tracer = Tracer() Cache = get_traced_cache(tracer, service=self.SERVICE) app = Flask(__name__) config = { 'CACHE_TYPE': 'memcached', 'CACHE_MEMCACHED_SERVERS': ['127.0.0.1:{}'.format(MEMCACHED_CONFIG['port'])], } traced_cache = Cache(app, config=config) # extract client data meta = _extract_conn_tags(traced_cache.cache._client) expected_meta = { 'out.host': '127.0.0.1', 'out.port': MEMCACHED_CONFIG['port'] } assert meta == expected_meta
class TestWorkers(TestCase): """ Ensures that a workers interacts correctly with the main thread. These are part of integration tests so real calls are triggered. """ def setUp(self): """ Create a tracer with running workers, while spying the ``_put()`` method to keep trace of triggered API calls. """ self.exporter = InMemorySpanExporter() api = APIOtel(exporter=self.exporter) # create a new tracer self.tracer = Tracer() self.tracer.configure(api=api) # spy the send() method self.api = self.tracer.writer.api def tearDown(self): """ Stop running worker """ self._wait_thread_flush() def _wait_thread_flush(self): """ Helper that waits for the thread flush """ self.tracer.writer.stop() self.tracer.writer.join(None) def test_worker_single_trace(self): # create a trace block and send it using the transport system tracer = self.tracer tracer.trace('client.testing').finish() # one send is expected self._wait_thread_flush() spans = self.exporter.get_finished_spans() self.assertEqual(len(spans), 1) self.assertEqual(spans[0].name, 'client.testing') def test_worker_single_trace_multiple_spans(self): # make a single send() if a single trace with multiple spans is created before the flush tracer = self.tracer parent = tracer.trace('client.testing.parent') tracer.trace('client.testing.child').finish() parent.finish() # one send is expected self._wait_thread_flush() spans = self.exporter.get_finished_spans() self.assertEqual(len(spans), 2) self.assertEqual(spans[0].name, 'client.testing.parent') self.assertEqual(spans[1].name, 'client.testing.child') def test_worker_filter_request(self): self.tracer.configure( settings={FILTERS_KEY: [FilterRequestsOnUrl(r'http://example\.com/health')]}, api=self.api, ) span = self.tracer.trace('testing.filteredurl') span.set_tag(http.URL, 'http://example.com/health') span.finish() span = self.tracer.trace('testing.nonfilteredurl') span.set_tag(http.URL, 'http://example.com/api/resource') span.finish() self._wait_thread_flush() spans = self.exporter.get_finished_spans() self.assertEqual(len(spans), 1) self.assertEqual(spans[0].name, 'testing.nonfilteredurl')
# project from oteltrace.tracer import Tracer from oteltrace.contrib.django.conf import settings from oteltrace.contrib.django.db import patch_db, unpatch_db from oteltrace.contrib.django.cache import unpatch_cache from oteltrace.contrib.django.templates import unpatch_template from oteltrace.contrib.django.middleware import remove_exception_middleware, remove_trace_middleware # testing from ...base import BaseTestCase from ...test_tracer import DummyWriter # testing tracer tracer = Tracer() tracer.writer = DummyWriter() class DjangoTraceTestCase(BaseTestCase, TestCase): """ Base class that provides an internal tracer according to given OpenTelemetry settings. This class ensures that the tracer spans are properly reset after each run. The tracer is available in the ``self.tracer`` attribute. """ def setUp(self): # assign the default tracer self.tracer = settings.TRACER # empty the tracer spans from previous operations # such as database creation queries