def test__do_trace_request(self): from qubit.opencensus.trace import asyncio_context sanic_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' span_id = '6e0c63257de34c92' sanic_trace_id = '{}/{}'.format(trace_id, span_id) app = mock.Mock(config={}) sanic_middleware.SanicMiddleware(app=app) context = app.test_request_context( path='/', headers={sanic_trace_header: sanic_trace_id}) with context: app.preprocess_request() tracer = asyncio_context.get_opencensus_tracer() self.assertIsNotNone(tracer) span = tracer.current_span() expected_attributes = { '/http/url': u'http://localhost/', '/http/method': 'GET', } self.assertEqual(span.attributes, expected_attributes) self.assertEqual(span.parent_span.span_id, span_id) span_context = tracer.span_context self.assertEqual(span_context.trace_id, trace_id)
def test_header_encoding(self): # The test is for detecting the encoding compatibility issue in # Python2 and Python3 and what sanic does for encoding the headers. # This test case is expected to fail at the check_trace_id method # in SpanContext because it cannot match the pattern for trace_id, # And a new trace_id will generate for the context. sanic_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = "你好" span_id = '6e0c63257de34c92' sanic_trace_id = '{}/{}'.format(trace_id, span_id) app = self.create_app() sanic_middleware.SanicMiddleware(app=app) context = app.test_request_context( path='/', headers={sanic_trace_header: sanic_trace_id}) with context: app.preprocess_request() tracer = asyncio_context.get_opencensus_tracer() self.assertIsNotNone(tracer) span = tracer.current_span() expected_attributes = { '/http/url': u'http://localhost/', '/http/method': 'GET', } self.assertEqual(span.attributes, expected_attributes) assert isinstance(span.parent_span, base.NullContextManager) span_context = tracer.span_context self.assertNotEqual(span_context.trace_id, trace_id)
def test_init_app(self): app = mock.Mock() middleware = sanic_middleware.SanicMiddleware() middleware.init_app(app) self.assertIs(middleware.app, app)
def test_init_app_config_jaeger_exporter(self): app = mock.Mock() app.config = { 'OPENCENSUS_TRACE': { 'SAMPLER': ProbabilitySampler, 'EXPORTER': jaeger_exporter.JaegerExporter, 'PROPAGATOR': jaeger_format.JaegerFormatPropagator, }, 'OPENCENSUS_TRACE_PARAMS': { 'BLACKLIST_PATHS': ['/_ah/health'], 'GCP_EXPORTER_PROJECT': None, 'SAMPLING_RATE': 0.5, 'ZIPKIN_EXPORTER_SERVICE_NAME': 'my_service', 'ZIPKIN_EXPORTER_HOST_NAME': 'localhost', 'ZIPKIN_EXPORTER_PORT': 9411, }, } class JaegerExporter(object): def __init__(self, *args, **kwargs): pass middleware = sanic_middleware.SanicMiddleware(exporter=JaegerExporter) middleware.init_app(app) self.assertIs(middleware.app, app)
def test_constructor_default(self): app = mock.Mock(config={}) middleware = sanic_middleware.SanicMiddleware(app=app) self.assertIs(app, middleware.app) self.assertTrue(app.do_trace_request.called) self.assertTrue(app.do_trace_response.called) assert isinstance(middleware.sampler, always_on.AlwaysOnSampler) assert isinstance(middleware.exporter, print_exporter.PrintExporter) assert isinstance(middleware.propagator, jaeger_format.JaegerFormatPropagator)
def test_teardown_include_exception(self): mock_exporter = mock.MagicMock() app = self.create_app() sanic_middleware.SanicMiddleware(app=app, exporter=mock_exporter) request, response = app.test_client.get('/error') self.assertEqual(response.status, 500) exported_spandata = mock_exporter.export.call_args[0][0][0] self.assertIsInstance(exported_spandata, span_data.SpanData) self.assertIsInstance(exported_spandata.status, status.Status) self.assertEqual(exported_spandata.status.message, 'error')
def test__after_request_sampled(self): sanic_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' span_id = '6e0c63257de34c92' sanic_trace_id = '{}/{}'.format(trace_id, span_id) app = self.create_app() sanic_middleware.SanicMiddleware(app=app) request, response = app.test_client.get( '/', headers={sanic_trace_header: sanic_trace_id}) self.assertEqual(response.status, 200)
def test_constructor_explicit(self): app = mock.Mock(config={}) sampler = mock.Mock() exporter = mock.Mock() propagator = mock.Mock() middleware = sanic_middleware.SanicMiddleware(app=app, sampler=sampler, exporter=exporter, propagator=propagator) self.assertIs(middleware.app, app) self.assertIs(middleware.sampler, sampler) self.assertIs(middleware.exporter, exporter) self.assertIs(middleware.propagator, propagator)
def test_teardown_include_exception_and_traceback(self): mock_exporter = mock.MagicMock() app = self.create_app() app.config['TESTING'] = True sanic_middleware.SanicMiddleware(app=app, exporter=mock_exporter) app.test_client.get('/error') exported_spandata = mock_exporter.export.call_args[0][0][0] self.assertIsInstance(exported_spandata, span_data.SpanData) self.assertIsInstance(exported_spandata.status, status.Status) self.assertEqual(exported_spandata.status.message, 'error') self.assertIsInstance(exported_spandata.stack_trace, stack_trace.StackTrace) self.assertIsNotNone(exported_spandata.stack_trace.stack_trace_hash_id) self.assertNotEqual(exported_spandata.stack_trace.stack_frames, [])
def test__after_request_blacklist(self): sanic_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' span_id = '6e0c63257de34c92' sanic_trace_id = '{}/{}'.format(trace_id, span_id) app = self.create_app() sanic_middleware.SanicMiddleware(app=app) request, response = app.test_client.get( '/_ah/health', headers={sanic_trace_header: sanic_trace_id}) tracer = asyncio_context.get_opencensus_tracer() self.assertEqual(response.status, 200) assert isinstance(tracer, noop_tracer.NoopTracer)
def test_header_is_none(self): app = self.create_app() sanic_middleware.SanicMiddleware(app=app) context = app.test_request_context(path='/') with context: app.preprocess_request() tracer = asyncio_context.get_opencensus_tracer() self.assertIsNotNone(tracer) span = tracer.current_span() expected_attributes = { '/http/url': u'http://localhost/', '/http/method': 'GET', } self.assertEqual(span.attributes, expected_attributes) assert isinstance(span.parent_span, base.NullContextManager)
def test__before_request_blacklist(self): sanic_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' span_id = '6e0c63257de34c92' sanic_trace_id = '{}/{}'.format(trace_id, span_id) app = self.create_app() sanic_middleware.SanicMiddleware(app=app) context = app.test_request_context( path='/_ah/health', headers={sanic_trace_header: sanic_trace_id}) with context: app.preprocess_request() tracer = asyncio_context.get_opencensus_tracer() assert isinstance(tracer, noop_tracer.NoopTracer) span = tracer.current_span() assert isinstance(span, base.NullContextManager)
def test_init_app_config_zipkin_exporter(self): app = mock.Mock() app.config = { 'OPENCENSUS_TRACE': { 'SAMPLER': ProbabilitySampler, 'EXPORTER': zipkin_exporter.ZipkinExporter, 'PROPAGATOR': jaeger_format.JaegerFormatPropagator, }, 'OPENCENSUS_TRACE_PARAMS': { 'ZIPKIN_EXPORTER_SERVICE_NAME': 'my_service', 'ZIPKIN_EXPORTER_HOST_NAME': 'localhost', 'ZIPKIN_EXPORTER_PORT': 9411, }, } middleware = sanic_middleware.SanicMiddleware() middleware.init_app(app) self.assertIs(middleware.app, app)