diff --git a/src/instana/__init__.py b/src/instana/__init__.py index bb4d53b9..ded022fa 100644 --- a/src/instana/__init__.py +++ b/src/instana/__init__.py @@ -197,10 +197,10 @@ def boot_agent(): # pubsub, # noqa: F401 # storage, # noqa: F401 # ) - # from instana.instrumentation.tornado import ( - # client, # noqa: F401 - # server, # noqa: F401 - # ) + from instana.instrumentation.tornado import ( + client, # noqa: F401 + server, # noqa: F401 + ) # Hooks # from instana.hooks import hook_uwsgi # noqa: F401 diff --git a/src/instana/instrumentation/tornado/client.py b/src/instana/instrumentation/tornado/client.py index 24e37809..e937db68 100644 --- a/src/instana/instrumentation/tornado/client.py +++ b/src/instana/instrumentation/tornado/client.py @@ -1,34 +1,27 @@ # (c) Copyright IBM Corp. 2021 # (c) Copyright Instana Inc. 2019 - -import opentracing -import wrapt -import functools - -from ...log import logger -from ...singletons import agent, setup_tornado_tracer, tornado_tracer -from ...util.secrets import strip_secrets_from_query - try: import tornado - # Tornado >=6.0 switched to contextvars for context management. This requires changes to the opentracing - # scope managers which we will tackle soon. - # Limit Tornado version for the time being. - if not (hasattr(tornado, 'version') and tornado.version[0] < '6'): - logger.debug('Instana supports Tornado package versions < 6.0. Skipping.') - raise ImportError + import wrapt + import functools - setup_tornado_tracer() + from opentelemetry.semconv.trace import SpanAttributes + + from instana.log import logger + from instana.singletons import agent, tracer + from instana.util.secrets import strip_secrets_from_query + from instana.propagators.format import Format + from instana.span.span import get_current_span @wrapt.patch_function_wrapper('tornado.httpclient', 'AsyncHTTPClient.fetch') def fetch_with_instana(wrapped, instance, argv, kwargs): try: - parent_span = tornado_tracer.active_span + parent_span = get_current_span() # If we're not tracing, just return - if (parent_span is None) or (parent_span.operation_name == "tornado-client"): + if (not parent_span.is_recording()) or (parent_span.name == "tornado-client"): return wrapped(*argv, **kwargs) request = argv[0] @@ -45,41 +38,43 @@ def fetch_with_instana(wrapped, instance, argv, kwargs): new_kwargs[param] = kwargs.pop(param) kwargs = new_kwargs - scope = tornado_tracer.start_active_span('tornado-client', child_of=parent_span) - tornado_tracer.inject(scope.span.context, opentracing.Format.HTTP_HEADERS, request.headers) + parent_context = parent_span.get_span_context() if parent_span else None + + span = tracer.start_span("tornado-client", span_context=parent_context) + tracer.inject(span.context, Format.HTTP_HEADERS, request.headers) # Query param scrubbing parts = request.url.split('?') if len(parts) > 1: cleaned_qp = strip_secrets_from_query(parts[1], agent.options.secrets_matcher, agent.options.secrets_list) - scope.span.set_tag("http.params", cleaned_qp) + span.set_attribute("http.params", cleaned_qp) - scope.span.set_tag("http.url", parts[0]) - scope.span.set_tag("http.method", request.method) + span.set_attribute(SpanAttributes.HTTP_URL, parts[0]) + span.set_attribute(SpanAttributes.HTTP_METHOD, request.method) future = wrapped(request, **kwargs) if future is not None: - cb = functools.partial(finish_tracing, scope=scope) + cb = functools.partial(finish_tracing, span=span) future.add_done_callback(cb) return future except Exception: - logger.debug("tornado fetch", exc_info=True) - raise + logger.debug("Tornado fetch_with_instana: ", exc_info=True) - def finish_tracing(future, scope): + def finish_tracing(future, span): try: response = future.result() - scope.span.set_tag("http.status_code", response.code) + span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, response.code) except tornado.httpclient.HTTPClientError as e: - scope.span.set_tag("http.status_code", e.code) - scope.span.log_exception(e) - raise + span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, e.code) + span.record_exception(e) + logger.debug("Tornado finish_tracing HTTPClientError: ", exc_info=True) finally: - scope.close() + if span.is_recording(): + span.end() logger.debug("Instrumenting tornado client") diff --git a/src/instana/instrumentation/tornado/server.py b/src/instana/instrumentation/tornado/server.py index 8fe8822c..7c928500 100644 --- a/src/instana/instrumentation/tornado/server.py +++ b/src/instana/instrumentation/tornado/server.py @@ -2,26 +2,17 @@ # (c) Copyright Instana Inc. 2019 -import opentracing -import wrapt - -from ...log import logger -from ...singletons import agent, setup_tornado_tracer, tornado_tracer -from ...util.secrets import strip_secrets_from_query - try: import tornado - # Tornado >=6.0 switched to contextvars for context management. This requires changes to the opentracing - # scope managers which we will tackle soon. - # Limit Tornado version for the time being. - if not (hasattr(tornado, 'version') and tornado.version[0] < '6'): - logger.debug('Instana supports Tornado package versions < 6.0. Skipping.') - raise ImportError + import wrapt - from opentracing.scope_managers.tornado import tracer_stack_context + from opentelemetry.semconv.trace import SpanAttributes - setup_tornado_tracer() + from instana.log import logger + from instana.singletons import agent, tracer + from instana.util.secrets import strip_secrets_from_query + from instana.propagators.format import Format def extract_custom_headers(span, headers): if not agent.options.extra_http_headers or not headers: @@ -29,7 +20,7 @@ def extract_custom_headers(span, headers): try: for custom_header in agent.options.extra_http_headers: if custom_header in headers: - span.set_tag("http.header.%s" % custom_header, headers[custom_header]) + span.set_attribute("http.header.%s" % custom_header, headers[custom_header]) except Exception: logger.debug("extract_custom_headers: ", exc_info=True) @@ -38,36 +29,36 @@ def extract_custom_headers(span, headers): @wrapt.patch_function_wrapper('tornado.web', 'RequestHandler._execute') def execute_with_instana(wrapped, instance, argv, kwargs): try: - with tracer_stack_context(): - ctx = None - if hasattr(instance.request.headers, '__dict__') and '_dict' in instance.request.headers.__dict__: - ctx = tornado_tracer.extract(opentracing.Format.HTTP_HEADERS, - instance.request.headers.__dict__['_dict']) - scope = tornado_tracer.start_active_span('tornado-server', child_of=ctx) + span_context = None + if hasattr(instance.request.headers, '__dict__') and '_dict' in instance.request.headers.__dict__: + span_context = tracer.extract(Format.HTTP_HEADERS, + instance.request.headers.__dict__['_dict']) - # Query param scrubbing - if instance.request.query is not None and len(instance.request.query) > 0: - cleaned_qp = strip_secrets_from_query(instance.request.query, agent.options.secrets_matcher, - agent.options.secrets_list) - scope.span.set_tag("http.params", cleaned_qp) + span = tracer.start_span("tornado-server", span_context=span_context) - url = "%s://%s%s" % (instance.request.protocol, instance.request.host, instance.request.path) - scope.span.set_tag("http.url", url) - scope.span.set_tag("http.method", instance.request.method) + # Query param scrubbing + if instance.request.query is not None and len(instance.request.query) > 0: + cleaned_qp = strip_secrets_from_query(instance.request.query, agent.options.secrets_matcher, + agent.options.secrets_list) + span.set_attribute("http.params", cleaned_qp) + + url = f"{instance.request.protocol}://{instance.request.host}{instance.request.path}" + span.set_attribute(SpanAttributes.HTTP_URL, url) + span.set_attribute(SpanAttributes.HTTP_METHOD, instance.request.method) - scope.span.set_tag("handler", instance.__class__.__name__) + span.set_attribute("handler", instance.__class__.__name__) - # Request header tracking support - extract_custom_headers(scope.span, instance.request.headers) + # Request header tracking support + extract_custom_headers(span, instance.request.headers) - setattr(instance.request, "_instana", scope) + setattr(instance.request, "_instana", span) - # Set the context response headers now because tornado doesn't give us a better option to do so - # later for this request. - tornado_tracer.inject(scope.span.context, opentracing.Format.HTTP_HEADERS, instance._headers) - instance.set_header(name='Server-Timing', value="intid;desc=%s" % scope.span.context.trace_id) + # Set the context response headers now because tornado doesn't give us a better option to do so + # later for this request. + tracer.inject(span.context, Format.HTTP_HEADERS, instance._headers) + instance.set_header(name='Server-Timing', value=f"intid;desc={span.context.trace_id}") - return wrapped(*argv, **kwargs) + return wrapped(*argv, **kwargs) except Exception: logger.debug("tornado execute", exc_info=True) @@ -77,9 +68,9 @@ def set_default_headers_with_instana(wrapped, instance, argv, kwargs): if not hasattr(instance.request, '_instana'): return wrapped(*argv, **kwargs) - scope = instance.request._instana - tornado_tracer.inject(scope.span.context, opentracing.Format.HTTP_HEADERS, instance._headers) - instance.set_header(name='Server-Timing', value="intid;desc=%s" % scope.span.context.trace_id) + span = instance.request._instana + tracer.inject(span.context, Format.HTTP_HEADERS, instance._headers) + instance.set_header(name='Server-Timing', value=f"intid;desc={span.context.trace_id}") @wrapt.patch_function_wrapper('tornado.web', 'RequestHandler.on_finish') @@ -88,17 +79,19 @@ def on_finish_with_instana(wrapped, instance, argv, kwargs): if not hasattr(instance.request, '_instana'): return wrapped(*argv, **kwargs) - with instance.request._instana as scope: - # Response header tracking support - extract_custom_headers(scope.span, instance._headers) + span = instance.request._instana + # Response header tracking support + extract_custom_headers(span, instance._headers) - status_code = instance.get_status() + status_code = instance.get_status() - # Mark 500 responses as errored - if 500 <= status_code: - scope.span.mark_as_errored() + # Mark 500 responses as errored + if 500 <= status_code: + span.mark_as_errored() - scope.span.set_tag("http.status_code", status_code) + span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code) + if span.is_recording(): + span.end() return wrapped(*argv, **kwargs) except Exception: @@ -112,8 +105,8 @@ def log_exception_with_instana(wrapped, instance, argv, kwargs): return wrapped(*argv, **kwargs) if not isinstance(argv[1], tornado.web.HTTPError): - scope = instance.request._instana - scope.span.log_exception(argv[0]) + span = instance.request._instana + span.record_exception(argv[0]) return wrapped(*argv, **kwargs) except Exception: diff --git a/tests/apps/tornado_server/app.py b/tests/apps/tornado_server/app.py index 01b8859e..cf71c677 100755 --- a/tests/apps/tornado_server/app.py +++ b/tests/apps/tornado_server/app.py @@ -14,7 +14,7 @@ import asyncio -from ...helpers import testenv +from tests.helpers import testenv class Application(tornado.web.Application): diff --git a/tests/conftest.py b/tests/conftest.py index 6d757672..363cf529 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -34,7 +34,6 @@ collect_ignore_glob.append("*frameworks/test_celery*") collect_ignore_glob.append("*frameworks/test_gevent*") collect_ignore_glob.append("*frameworks/test_grpcio*") -collect_ignore_glob.append("*frameworks/test_tornado*") # # Cassandra and gevent tests are run in dedicated jobs on CircleCI and will # # be run explicitly. (So always exclude them here) @@ -48,14 +47,6 @@ # collect_ignore_glob.append("*test_gevent*") # collect_ignore_glob.append("*test_starlette*") -# Python 3.10 support is incomplete yet -# TODO: Remove this once we start supporting Tornado >= 6.0 -if sys.version_info >= (3, 10): - collect_ignore_glob.append("*test_tornado*") - # Furthermore on Python 3.11 the above TC is skipped: - # tests/opentracing/test_ot_span.py::TestOTSpan::test_stacks - # TODO: Remove that once we find a workaround or DROP opentracing! - if sys.version_info >= (3, 11): if not os.environ.get("GOOGLE_CLOUD_TEST"): collect_ignore_glob.append("*test_google-cloud*") @@ -64,6 +55,7 @@ # TODO: Test Case failures for unknown reason: collect_ignore_glob.append("*test_aiohttp_server*") collect_ignore_glob.append("*test_celery*") + collect_ignore_glob.append("*frameworks/test_tornado_server*") # Currently there is a runtime incompatibility caused by the library: # `undefined symbol: _PyErr_WriteUnraisableMsg` diff --git a/tests/frameworks/test_tornado_client.py b/tests/frameworks/test_tornado_client.py index 244a03b7..24b8dca3 100644 --- a/tests/frameworks/test_tornado_client.py +++ b/tests/frameworks/test_tornado_client.py @@ -3,22 +3,23 @@ import time import asyncio -import unittest +import pytest +from typing import Generator import tornado from tornado.httpclient import AsyncHTTPClient -from instana.singletons import tornado_tracer +from instana.singletons import tracer +from instana.span.span import get_current_span import tests.apps.tornado_server -from ..helpers import testenv +from tests.helpers import testenv, get_first_span_by_name, get_first_span_by_filter -raise unittest.SkipTest("Non deterministic tests TBR") +class TestTornadoClient: -class TestTornadoClient(unittest.TestCase): - - def setUp(self): + @pytest.fixture(autouse=True) + def _resource(self) -> Generator[None, None, None]: """ Clear all spans before a test run """ - self.recorder = tornado_tracer.recorder + self.recorder = tracer.span_processor self.recorder.clear_spans() # New event loop for every test @@ -27,435 +28,434 @@ def setUp(self): asyncio.set_event_loop(self.loop) self.http_client = AsyncHTTPClient() - - def tearDown(self): + yield self.http_client.close() - def test_get(self): + def test_get(self) -> None: async def test(): - with tornado_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): return await self.http_client.fetch(testenv["tornado_server"] + "/") response = tornado.ioloop.IOLoop.current().run_sync(test) - self.assertIsinstance(response, tornado.httpclient.HTTPResponse) + assert isinstance(response, tornado.httpclient.HTTPResponse) time.sleep(0.5) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 - server_span = spans[0] - client_span = spans[1] - test_span = spans[2] + server_span = get_first_span_by_name(spans, "tornado-server") + client_span = get_first_span_by_name(spans, "tornado-client") + test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNone(tornado_tracer.active_span) + assert not get_current_span().is_recording() # Same traceId traceId = test_span.t - self.assertEqual(traceId, client_span.t) - self.assertEqual(traceId, server_span.t) + assert traceId == client_span.t + assert traceId == server_span.t # Parent relationships - self.assertEqual(client_span.p, test_span.s) - self.assertEqual(server_span.p, client_span.s) + assert client_span.p == test_span.s + assert server_span.p == client_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertIsNone(client_span.ec) - self.assertIsNone(server_span.ec) - - self.assertEqual("tornado-server", server_span.n) - self.assertEqual(200, server_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", server_span.data["http"]["url"]) - self.assertIsNone(server_span.data["http"]["params"]) - self.assertEqual("GET", server_span.data["http"]["method"]) - self.assertIsNotNone(server_span.stack) - self.assertTrue(type(server_span.stack) is list) - self.assertTrue(len(server_span.stack) > 1) - - self.assertEqual("tornado-client", client_span.n) - self.assertEqual(200, client_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", client_span.data["http"]["url"]) - self.assertEqual("GET", client_span.data["http"]["method"]) - self.assertIsNotNone(client_span.stack) - self.assertTrue(type(client_span.stack) is list) - self.assertTrue(len(client_span.stack) > 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], server_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_post(self): + assert not test_span.ec + assert not client_span.ec + assert not server_span.ec + + assert server_span.n == "tornado-server" + assert server_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == server_span.data["http"]["url"] + assert not server_span.data["http"]["params"] + assert server_span.data["http"]["method"] == "GET" + # assert server_span.stack + # assert type(server_span.stack) is list + # assert len(server_span.stack) > 1 + + assert client_span.n == "tornado-client" + assert client_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == client_span.data["http"]["url"] + assert client_span.data["http"]["method"] == "GET" + assert client_span.stack + assert type(client_span.stack) is list + assert len(client_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(server_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_post(self) -> None: async def test(): - with tornado_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): return await self.http_client.fetch(testenv["tornado_server"] + "/", method="POST", body='asdf') response = tornado.ioloop.IOLoop.current().run_sync(test) - self.assertIsInstance(response, tornado.httpclient.HTTPResponse) + assert isinstance(response, tornado.httpclient.HTTPResponse) time.sleep(0.5) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 - server_span = spans[0] - client_span = spans[1] - test_span = spans[2] + server_span = get_first_span_by_name(spans, "tornado-server") + client_span = get_first_span_by_name(spans, "tornado-client") + test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNone(tornado_tracer.active_span) + assert not get_current_span().is_recording() # Same traceId traceId = test_span.t - self.assertEqual(traceId, client_span.t) - self.assertEqual(traceId, server_span.t) + assert traceId == client_span.t + assert traceId == server_span.t # Parent relationships - self.assertEqual(client_span.p, test_span.s) - self.assertEqual(server_span.p, client_span.s) + assert client_span.p == test_span.s + assert server_span.p == client_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertIsNone(client_span.ec) - self.assertIsNone(server_span.ec) - - self.assertEqual("tornado-server", server_span.n) - self.assertEqual(200, server_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", server_span.data["http"]["url"]) - self.assertIsNone(server_span.data["http"]["params"]) - self.assertEqual("POST", server_span.data["http"]["method"]) - self.assertIsNotNone(server_span.stack) - self.assertTrue(type(server_span.stack) is list) - self.assertTrue(len(server_span.stack) > 1) - - self.assertEqual("tornado-client", client_span.n) - self.assertEqual(200, client_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", client_span.data["http"]["url"]) - self.assertEqual("POST", client_span.data["http"]["method"]) - self.assertIsNotNone(client_span.stack) - self.assertTrue(type(client_span.stack) is list) - self.assertTrue(len(client_span.stack) > 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], server_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_get_301(self): + assert not test_span.ec + assert not client_span.ec + assert not server_span.ec + + assert server_span.n == "tornado-server" + assert server_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == server_span.data["http"]["url"] + assert not server_span.data["http"]["params"] + assert server_span.data["http"]["method"] == "POST" + + assert client_span.n == "tornado-client" + assert client_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == client_span.data["http"]["url"] + assert client_span.data["http"]["method"] == "POST" + assert client_span.stack + assert type(client_span.stack) is list + assert len(client_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(server_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_get_301(self) -> None: async def test(): - with tornado_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): return await self.http_client.fetch(testenv["tornado_server"] + "/301") response = tornado.ioloop.IOLoop.current().run_sync(test) - self.assertIsInstance(response, tornado.httpclient.HTTPResponse) + assert isinstance(response, tornado.httpclient.HTTPResponse) time.sleep(0.5) spans = self.recorder.queued_spans() - self.assertEqual(4, len(spans)) + assert len(spans) == 5 server301_span = spans[0] server_span = spans[1] client_span = spans[2] - test_span = spans[3] + client301_span = spans[3] + test_span = spans[4] + + filter = lambda span: span.n == "tornado-server" and span.data["http"]["status"] == 301 + server301_span = get_first_span_by_filter(spans, filter) + filter = lambda span: span.n == "tornado-server" and span.data["http"]["status"] == 200 + server_span = get_first_span_by_filter(spans, filter) + filter = lambda span: span.n == "tornado-client" and span.data["http"]["url"] == testenv["tornado_server"] + "/" + client_span = get_first_span_by_filter(spans, filter) + filter = lambda span: span.n == "tornado-client" and span.data["http"]["url"] == testenv["tornado_server"] + "/301" + client301_span = get_first_span_by_filter(spans, filter) + test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNone(tornado_tracer.active_span) + assert not get_current_span().is_recording() # Same traceId traceId = test_span.t - self.assertEqual(traceId, client_span.t) - self.assertEqual(traceId, server301_span.t) - self.assertEqual(traceId, server_span.t) + assert traceId == client_span.t + assert traceId == client301_span.t + assert traceId == server301_span.t + assert traceId == server_span.t # Parent relationships - self.assertEqual(server301_span.p, client_span.s) - self.assertEqual(client_span.p, test_span.s) - self.assertEqual(server_span.p, client_span.s) + assert server301_span.p == client301_span.s + assert client_span.p == test_span.s + assert client301_span.p == test_span.s + assert server_span.p == client_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertIsNone(client_span.ec) - self.assertIsNone(server_span.ec) - - self.assertEqual("tornado-server", server_span.n) - self.assertEqual(200, server_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", server_span.data["http"]["url"]) - self.assertIsNone(server_span.data["http"]["params"]) - self.assertEqual("GET", server_span.data["http"]["method"]) - self.assertIsNotNone(server_span.stack) - self.assertTrue(type(server_span.stack) is list) - self.assertTrue(len(server_span.stack) > 1) - - self.assertEqual("tornado-server", server301_span.n) - self.assertEqual(301, server301_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/301", server301_span.data["http"]["url"]) - self.assertIsNone(server301_span.data["http"]["params"]) - self.assertEqual("GET", server301_span.data["http"]["method"]) - self.assertIsNotNone(server301_span.stack) - self.assertTrue(type(server301_span.stack) is list) - self.assertTrue(len(server301_span.stack) > 1) - - self.assertEqual("tornado-client", client_span.n) - self.assertEqual(200, client_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/301", client_span.data["http"]["url"]) - self.assertEqual("GET", client_span.data["http"]["method"]) - self.assertIsNotNone(client_span.stack) - self.assertTrue(type(client_span.stack) is list) - self.assertTrue(len(client_span.stack) > 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], server_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_get_405(self): + assert not test_span.ec + assert not client_span.ec + assert not server_span.ec + + assert server_span.n == "tornado-server" + assert server_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == server_span.data["http"]["url"] + assert not server_span.data["http"]["params"] + assert server_span.data["http"]["method"] == "GET" + + assert server301_span.n == "tornado-server" + assert server301_span.data["http"]["status"] == 301 + assert testenv["tornado_server"] + "/301" == server301_span.data["http"]["url"] + assert not server301_span.data["http"]["params"] + assert server301_span.data["http"]["method"] == "GET" + + assert client_span.n == "tornado-client" + assert client_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == client_span.data["http"]["url"] + assert client_span.data["http"]["method"] == "GET" + assert client_span.stack + assert type(client_span.stack) is list + assert len(client_span.stack) > 1 + + assert client301_span.n == "tornado-client" + assert client301_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/301" == client301_span.data["http"]["url"] + assert client301_span.data["http"]["method"] == "GET" + assert client301_span.stack + assert type(client301_span.stack) is list + assert len(client301_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(server_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_get_405(self) -> None: async def test(): - with tornado_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): try: return await self.http_client.fetch(testenv["tornado_server"] + "/405") except tornado.httpclient.HTTPClientError as e: return e.response response = tornado.ioloop.IOLoop.current().run_sync(test) - self.assertIsInstance(response, tornado.httpclient.HTTPResponse) + assert isinstance(response, tornado.httpclient.HTTPResponse) time.sleep(0.5) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 - server_span = spans[0] - client_span = spans[1] - test_span = spans[2] + server_span = get_first_span_by_name(spans, "tornado-server") + client_span = get_first_span_by_name(spans, "tornado-client") + test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNone(tornado_tracer.active_span) + assert not get_current_span().is_recording() # Same traceId traceId = test_span.t - self.assertEqual(traceId, client_span.t) - self.assertEqual(traceId, server_span.t) + assert traceId == client_span.t + assert traceId == server_span.t # Parent relationships - self.assertEqual(client_span.p, test_span.s) - self.assertEqual(server_span.p, client_span.s) + assert client_span.p == test_span.s + assert server_span.p == client_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertEqual(client_span.ec, 1) - self.assertIsNone(server_span.ec) - - self.assertEqual("tornado-server", server_span.n) - self.assertEqual(405, server_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/405", server_span.data["http"]["url"]) - self.assertIsNone(server_span.data["http"]["params"]) - self.assertEqual("GET", server_span.data["http"]["method"]) - self.assertIsNotNone(server_span.stack) - self.assertTrue(type(server_span.stack) is list) - self.assertTrue(len(server_span.stack) > 1) - - self.assertEqual("tornado-client", client_span.n) - self.assertEqual(405, client_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/405", client_span.data["http"]["url"]) - self.assertEqual("GET", client_span.data["http"]["method"]) - self.assertIsNotNone(client_span.stack) - self.assertTrue(type(client_span.stack) is list) - self.assertTrue(len(client_span.stack) > 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], server_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_get_500(self): + assert not test_span.ec + assert client_span.ec == 1 + assert not server_span.ec + + assert server_span.n == "tornado-server" + assert server_span.data["http"]["status"] == 405 + assert testenv["tornado_server"] + "/405" == server_span.data["http"]["url"] + assert not server_span.data["http"]["params"] + assert server_span.data["http"]["method"] == "GET" + + assert client_span.n == "tornado-client" + assert client_span.data["http"]["status"] == 405 + assert testenv["tornado_server"] + "/405" == client_span.data["http"]["url"] + assert client_span.data["http"]["method"] == "GET" + assert client_span.stack + assert type(client_span.stack) is list + assert len(client_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(server_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_get_500(self) -> None: async def test(): - with tornado_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): try: return await self.http_client.fetch(testenv["tornado_server"] + "/500") except tornado.httpclient.HTTPClientError as e: return e.response response = tornado.ioloop.IOLoop.current().run_sync(test) - self.assertIsInstance(response, tornado.httpclient.HTTPResponse) + assert isinstance(response, tornado.httpclient.HTTPResponse) time.sleep(0.5) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 - server_span = spans[0] - client_span = spans[1] - test_span = spans[2] + server_span = get_first_span_by_name(spans, "tornado-server") + client_span = get_first_span_by_name(spans, "tornado-client") + test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNone(tornado_tracer.active_span) + assert not get_current_span().is_recording() # Same traceId traceId = test_span.t - self.assertEqual(traceId, client_span.t) - self.assertEqual(traceId, server_span.t) + assert traceId == client_span.t + assert traceId == server_span.t # Parent relationships - self.assertEqual(client_span.p, test_span.s) - self.assertEqual(server_span.p, client_span.s) + assert client_span.p == test_span.s + assert server_span.p == client_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertEqual(client_span.ec, 1) - self.assertEqual(server_span.ec, 1) - - self.assertEqual("tornado-server", server_span.n) - self.assertEqual(500, server_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/500", server_span.data["http"]["url"]) - self.assertIsNone(server_span.data["http"]["params"]) - self.assertEqual("GET", server_span.data["http"]["method"]) - self.assertIsNotNone(server_span.stack) - self.assertTrue(type(server_span.stack) is list) - self.assertTrue(len(server_span.stack) > 1) - - self.assertEqual("tornado-client", client_span.n) - self.assertEqual(500, client_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/500", client_span.data["http"]["url"]) - self.assertEqual("GET", client_span.data["http"]["method"]) - self.assertIsNotNone(client_span.stack) - self.assertTrue(type(client_span.stack) is list) - self.assertTrue(len(client_span.stack) > 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], server_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_get_504(self): + assert not test_span.ec + assert client_span.ec == 1 + assert server_span.ec == 1 + + assert server_span.n == "tornado-server" + assert server_span.data["http"]["status"] == 500 + assert testenv["tornado_server"] + "/500" == server_span.data["http"]["url"] + assert not server_span.data["http"]["params"] + assert server_span.data["http"]["method"] == "GET" + + assert client_span.n == "tornado-client" + assert client_span.data["http"]["status"] == 500 + assert testenv["tornado_server"] + "/500" == client_span.data["http"]["url"] + assert client_span.data["http"]["method"] == "GET" + assert client_span.stack + assert type(client_span.stack) is list + assert len(client_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(server_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_get_504(self) -> None: async def test(): - with tornado_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): try: return await self.http_client.fetch(testenv["tornado_server"] + "/504") except tornado.httpclient.HTTPClientError as e: return e.response response = tornado.ioloop.IOLoop.current().run_sync(test) - self.assertIsInstance(response, tornado.httpclient.HTTPResponse) + assert isinstance(response, tornado.httpclient.HTTPResponse) time.sleep(0.5) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 - server_span = spans[0] - client_span = spans[1] - test_span = spans[2] + server_span = get_first_span_by_name(spans, "tornado-server") + client_span = get_first_span_by_name(spans, "tornado-client") + test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNone(tornado_tracer.active_span) + assert not get_current_span().is_recording() # Same traceId traceId = test_span.t - self.assertEqual(traceId, client_span.t) - self.assertEqual(traceId, server_span.t) + assert traceId == client_span.t + assert traceId == server_span.t # Parent relationships - self.assertEqual(client_span.p, test_span.s) - self.assertEqual(server_span.p, client_span.s) + assert client_span.p == test_span.s + assert server_span.p == client_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertEqual(client_span.ec, 1) - self.assertEqual(server_span.ec, 1) - - self.assertEqual("tornado-server", server_span.n) - self.assertEqual(504, server_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/504", server_span.data["http"]["url"]) - self.assertIsNone(server_span.data["http"]["params"]) - self.assertEqual("GET", server_span.data["http"]["method"]) - self.assertIsNotNone(server_span.stack) - self.assertTrue(type(server_span.stack) is list) - self.assertTrue(len(server_span.stack) > 1) - - self.assertEqual("tornado-client", client_span.n) - self.assertEqual(504, client_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/504", client_span.data["http"]["url"]) - self.assertEqual("GET", client_span.data["http"]["method"]) - self.assertIsNotNone(client_span.stack) - self.assertTrue(type(client_span.stack) is list) - self.assertTrue(len(client_span.stack) > 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], server_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_get_with_params_to_scrub(self): + assert not test_span.ec + assert client_span.ec == 1 + assert server_span.ec == 1 + + assert server_span.n == "tornado-server" + assert server_span.data["http"]["status"] == 504 + assert testenv["tornado_server"] + "/504" == server_span.data["http"]["url"] + assert not server_span.data["http"]["params"] + assert server_span.data["http"]["method"] == "GET" + + assert client_span.n == "tornado-client" + assert client_span.data["http"]["status"] == 504 + assert testenv["tornado_server"] + "/504" == client_span.data["http"]["url"] + assert client_span.data["http"]["method"] == "GET" + assert client_span.stack + assert type(client_span.stack) is list + assert len(client_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(server_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_get_with_params_to_scrub(self) -> None: async def test(): - with tornado_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): return await self.http_client.fetch(testenv["tornado_server"] + "/?secret=yeah") response = tornado.ioloop.IOLoop.current().run_sync(test) - self.assertIsInstance(response, tornado.httpclient.HTTPResponse) + assert isinstance(response, tornado.httpclient.HTTPResponse) time.sleep(0.5) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 - server_span = spans[0] - client_span = spans[1] - test_span = spans[2] + server_span = get_first_span_by_name(spans, "tornado-server") + client_span = get_first_span_by_name(spans, "tornado-client") + test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNone(tornado_tracer.active_span) + assert not get_current_span().is_recording() # Same traceId traceId = test_span.t - self.assertEqual(traceId, client_span.t) - self.assertEqual(traceId, server_span.t) + assert traceId == client_span.t + assert traceId == server_span.t # Parent relationships - self.assertEqual(client_span.p, test_span.s) - self.assertEqual(server_span.p, client_span.s) + assert client_span.p == test_span.s + assert server_span.p == client_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertIsNone(client_span.ec) - self.assertIsNone(server_span.ec) - - self.assertEqual("tornado-server", server_span.n) - self.assertEqual(200, server_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", server_span.data["http"]["url"]) - self.assertEqual('secret=', server_span.data["http"]["params"]) - self.assertEqual("GET", server_span.data["http"]["method"]) - self.assertIsNotNone(server_span.stack) - self.assertTrue(type(server_span.stack) is list) - self.assertTrue(len(server_span.stack) > 1) - - self.assertEqual("tornado-client", client_span.n) - self.assertEqual(200, client_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", client_span.data["http"]["url"]) - self.assertEqual('secret=', client_span.data["http"]["params"]) - self.assertEqual("GET", client_span.data["http"]["method"]) - self.assertIsNotNone(client_span.stack) - self.assertTrue(type(client_span.stack) is list) - self.assertTrue(len(client_span.stack) > 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], server_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) + assert not test_span.ec + assert not client_span.ec + assert not server_span.ec + + assert server_span.n == "tornado-server" + assert server_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == server_span.data["http"]["url"] + assert 'secret=' == server_span.data["http"]["params"] + assert server_span.data["http"]["method"] == "GET" + + assert client_span.n == "tornado-client" + assert client_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == client_span.data["http"]["url"] + assert 'secret=' == client_span.data["http"]["params"] + assert client_span.data["http"]["method"] == "GET" + assert client_span.stack + assert type(client_span.stack) is list + assert len(client_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(server_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId diff --git a/tests/frameworks/test_tornado_server.py b/tests/frameworks/test_tornado_server.py index 9972edf1..b0546a53 100644 --- a/tests/frameworks/test_tornado_server.py +++ b/tests/frameworks/test_tornado_server.py @@ -1,7 +1,8 @@ # (c) Copyright IBM Corp. 2021 # (c) Copyright Instana Inc. 2020 -import unittest +import pytest +from typing import Generator import asyncio import aiohttp @@ -10,11 +11,12 @@ import tests.apps.tornado_server -from instana.singletons import async_tracer, agent -from ..helpers import testenv, get_first_span_by_name, get_first_span_by_filter +from instana.singletons import tracer, agent +from tests.helpers import testenv, get_first_span_by_name, get_first_span_by_filter +from instana.span.span import get_current_span -class TestTornadoServer(unittest.TestCase): +class TestTornadoServer: async def fetch(self, session, url, headers=None, params=None): try: async with session.get(url, headers=headers, params=params) as response: @@ -29,9 +31,10 @@ async def post(self, session, url, headers=None): except aiohttp.web_exceptions.HTTPException: pass - def setUp(self): + @pytest.fixture(autouse=True) + def _resource(self) -> Generator[None, None, None]: """ Clear all spans before a test run """ - self.recorder = async_tracer.recorder + self.recorder = tracer.span_processor self.recorder.clear_spans() # New event loop for every test @@ -40,166 +43,165 @@ def setUp(self): asyncio.set_event_loop(self.loop) self.http_client = AsyncHTTPClient() - - def tearDown(self): + yield self.http_client.close() - def test_get(self): + def test_get(self) -> None: async def test(): - with async_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): async with aiohttp.ClientSession() as session: return await self.fetch(session, testenv["tornado_server"] + "/") response = tornado.ioloop.IOLoop.current().run_sync(test) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 tornado_span = get_first_span_by_name(spans, "tornado-server") aiohttp_span = get_first_span_by_name(spans, "aiohttp-client") test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNotNone(tornado_span) - self.assertIsNotNone(aiohttp_span) - self.assertIsNotNone(test_span) + assert tornado_span + assert aiohttp_span + assert test_span - self.assertIsNone(async_tracer.active_span) + assert not get_current_span().is_recording() # Same traceId traceId = test_span.t - self.assertEqual(traceId, aiohttp_span.t) - self.assertEqual(traceId, tornado_span.t) + assert traceId == aiohttp_span.t + assert traceId == tornado_span.t # Parent relationships - self.assertEqual(aiohttp_span.p, test_span.s) - self.assertEqual(tornado_span.p, aiohttp_span.s) + assert aiohttp_span.p == test_span.s + assert tornado_span.p == aiohttp_span.s # Synthetic - self.assertIsNone(tornado_span.sy) - self.assertIsNone(aiohttp_span.sy) - self.assertIsNone(test_span.sy) + assert not tornado_span.sy + assert not aiohttp_span.sy + assert not test_span.sy # Error logging - self.assertIsNone(test_span.ec) - self.assertIsNone(aiohttp_span.ec) - self.assertIsNone(tornado_span.ec) - - self.assertEqual(200, tornado_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", tornado_span.data["http"]["url"]) - self.assertIsNone(tornado_span.data["http"]["params"]) - self.assertEqual("GET", tornado_span.data["http"]["method"]) - self.assertIsNone(tornado_span.stack) - - self.assertEqual(200, aiohttp_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", aiohttp_span.data["http"]["url"]) - self.assertEqual("GET", aiohttp_span.data["http"]["method"]) - self.assertIsNotNone(aiohttp_span.stack) - self.assertIsInstance(aiohttp_span.stack, list) - self.assertGreater(len(aiohttp_span.stack), 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], tornado_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_post(self): + assert not test_span.ec + assert not aiohttp_span.ec + assert not tornado_span.ec + + assert tornado_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == tornado_span.data["http"]["url"] + assert not tornado_span.data["http"]["params"] + assert tornado_span.data["http"]["method"] == "GET" + assert not tornado_span.stack + + assert aiohttp_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == aiohttp_span.data["http"]["url"] + assert aiohttp_span.data["http"]["method"] == "GET" + assert aiohttp_span.stack + assert isinstance(aiohttp_span.stack, list) + assert len(aiohttp_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(tornado_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_post(self) -> None: async def test(): - with async_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): async with aiohttp.ClientSession() as session: return await self.post(session, testenv["tornado_server"] + "/") response = tornado.ioloop.IOLoop.current().run_sync(test) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 tornado_span = get_first_span_by_name(spans, "tornado-server") aiohttp_span = get_first_span_by_name(spans, "aiohttp-client") test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNotNone(tornado_span) - self.assertIsNotNone(aiohttp_span) - self.assertIsNotNone(test_span) + assert tornado_span + assert aiohttp_span + assert test_span - self.assertIsNone(async_tracer.active_span) + assert not get_current_span().is_recording() - self.assertEqual("tornado-server", tornado_span.n) - self.assertEqual("aiohttp-client", aiohttp_span.n) - self.assertEqual("sdk", test_span.n) + assert tornado_span.n == "tornado-server" + assert aiohttp_span.n == "aiohttp-client" + assert test_span.n == "sdk" # Same traceId traceId = test_span.t - self.assertEqual(traceId, aiohttp_span.t) - self.assertEqual(traceId, tornado_span.t) + assert traceId == aiohttp_span.t + assert traceId == tornado_span.t # Parent relationships - self.assertEqual(aiohttp_span.p, test_span.s) - self.assertEqual(tornado_span.p, aiohttp_span.s) + assert aiohttp_span.p == test_span.s + assert tornado_span.p == aiohttp_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertIsNone(aiohttp_span.ec) - self.assertIsNone(tornado_span.ec) - - self.assertEqual(200, tornado_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", tornado_span.data["http"]["url"]) - self.assertIsNone(tornado_span.data["http"]["params"]) - self.assertEqual("POST", tornado_span.data["http"]["method"]) - self.assertIsNone(tornado_span.stack) - - self.assertEqual(200, aiohttp_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", aiohttp_span.data["http"]["url"]) - self.assertEqual("POST", aiohttp_span.data["http"]["method"]) - self.assertIsNotNone(aiohttp_span.stack) - self.assertIsInstance(aiohttp_span.stack, list) - self.assertGreater(len(aiohttp_span.stack), 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], tornado_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_synthetic_request(self): + assert not test_span.ec + assert not aiohttp_span.ec + assert not tornado_span.ec + + assert tornado_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == tornado_span.data["http"]["url"] + assert not tornado_span.data["http"]["params"] + assert tornado_span.data["http"]["method"] == "POST" + assert not tornado_span.stack + + assert aiohttp_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == aiohttp_span.data["http"]["url"] + assert aiohttp_span.data["http"]["method"] == "POST" + assert aiohttp_span.stack + assert isinstance(aiohttp_span.stack, list) + assert len(aiohttp_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(tornado_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_synthetic_request(self) -> None: async def test(): headers = { 'X-INSTANA-SYNTHETIC': '1' } - with async_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): async with aiohttp.ClientSession() as session: return await self.fetch(session, testenv["tornado_server"] + "/", headers=headers) tornado.ioloop.IOLoop.current().run_sync(test) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 tornado_span = get_first_span_by_name(spans, "tornado-server") aiohttp_span = get_first_span_by_name(spans, "aiohttp-client") test_span = get_first_span_by_name(spans, "sdk") - self.assertTrue(tornado_span.sy) - self.assertIsNone(aiohttp_span.sy) - self.assertIsNone(test_span.sy) + assert tornado_span.sy + assert not aiohttp_span.sy + assert not test_span.sy - def test_get_301(self): + def test_get_301(self) -> None: async def test(): - with async_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): async with aiohttp.ClientSession() as session: return await self.fetch(session, testenv["tornado_server"] + "/301") response = tornado.ioloop.IOLoop.current().run_sync(test) spans = self.recorder.queued_spans() - self.assertEqual(4, len(spans)) + assert len(spans) == 4 filter = lambda span: span.n == "tornado-server" and span.data["http"]["status"] == 301 tornado_301_span = get_first_span_by_filter(spans, filter) @@ -208,312 +210,312 @@ async def test(): aiohttp_span = get_first_span_by_name(spans, "aiohttp-client") test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNotNone(tornado_301_span) - self.assertIsNotNone(tornado_span) - self.assertIsNotNone(aiohttp_span) - self.assertIsNotNone(test_span) + assert tornado_301_span + assert tornado_span + assert aiohttp_span + assert test_span - self.assertIsNone(async_tracer.active_span) + assert not get_current_span().is_recording() - self.assertEqual("tornado-server", tornado_301_span.n) - self.assertEqual("tornado-server", tornado_span.n) - self.assertEqual("aiohttp-client", aiohttp_span.n) - self.assertEqual("sdk", test_span.n) + assert tornado_301_span.n == "tornado-server" + assert tornado_span.n == "tornado-server" + assert aiohttp_span.n == "aiohttp-client" + assert test_span.n == "sdk" # Same traceId traceId = test_span.t - self.assertEqual(traceId, aiohttp_span.t) - self.assertEqual(traceId, tornado_span.t) - self.assertEqual(traceId, tornado_301_span.t) + assert traceId == aiohttp_span.t + assert traceId == tornado_span.t + assert traceId == tornado_301_span.t # Parent relationships - self.assertEqual(aiohttp_span.p, test_span.s) - self.assertEqual(tornado_301_span.p, aiohttp_span.s) - self.assertEqual(tornado_span.p, aiohttp_span.s) + assert aiohttp_span.p == test_span.s + assert tornado_301_span.p == aiohttp_span.s + assert tornado_span.p == aiohttp_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertIsNone(aiohttp_span.ec) - self.assertIsNone(tornado_301_span.ec) - self.assertIsNone(tornado_span.ec) - - self.assertEqual(301, tornado_301_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/301", tornado_301_span.data["http"]["url"]) - self.assertIsNone(tornado_span.data["http"]["params"]) - self.assertEqual("GET", tornado_301_span.data["http"]["method"]) - self.assertIsNone(tornado_301_span.stack) - - self.assertEqual(200, tornado_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", tornado_span.data["http"]["url"]) - self.assertEqual("GET", tornado_span.data["http"]["method"]) - self.assertIsNone(tornado_span.stack) - - self.assertEqual(200, aiohttp_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/301", aiohttp_span.data["http"]["url"]) - self.assertEqual("GET", aiohttp_span.data["http"]["method"]) - self.assertIsNotNone(aiohttp_span.stack) - self.assertIsInstance(aiohttp_span.stack, list) - self.assertGreater(len(aiohttp_span.stack), 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], tornado_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_get_405(self): + assert not test_span.ec + assert not aiohttp_span.ec + assert not tornado_301_span.ec + assert not tornado_span.ec + + assert tornado_301_span.data["http"]["status"] == 301 + assert testenv["tornado_server"] + "/301" == tornado_301_span.data["http"]["url"] + assert not tornado_span.data["http"]["params"] + assert tornado_301_span.data["http"]["method"] == "GET" + assert not tornado_301_span.stack + + assert tornado_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == tornado_span.data["http"]["url"] + assert tornado_span.data["http"]["method"] == "GET" + assert not tornado_span.stack + + assert aiohttp_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/301" == aiohttp_span.data["http"]["url"] + assert aiohttp_span.data["http"]["method"] == "GET" + assert aiohttp_span.stack + assert isinstance(aiohttp_span.stack, list) + assert len(aiohttp_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(tornado_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_get_405(self) -> None: async def test(): - with async_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): async with aiohttp.ClientSession() as session: return await self.fetch(session, testenv["tornado_server"] + "/405") response = tornado.ioloop.IOLoop.current().run_sync(test) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 tornado_span = get_first_span_by_name(spans, "tornado-server") aiohttp_span = get_first_span_by_name(spans, "aiohttp-client") test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNotNone(tornado_span) - self.assertIsNotNone(aiohttp_span) - self.assertIsNotNone(test_span) + assert tornado_span + assert aiohttp_span + assert test_span - self.assertIsNone(async_tracer.active_span) + assert not get_current_span().is_recording() - self.assertEqual("tornado-server", tornado_span.n) - self.assertEqual("aiohttp-client", aiohttp_span.n) - self.assertEqual("sdk", test_span.n) + assert tornado_span.n == "tornado-server" + assert aiohttp_span.n == "aiohttp-client" + assert test_span.n == "sdk" # Same traceId traceId = test_span.t - self.assertEqual(traceId, aiohttp_span.t) - self.assertEqual(traceId, tornado_span.t) + assert traceId == aiohttp_span.t + assert traceId == tornado_span.t # Parent relationships - self.assertEqual(aiohttp_span.p, test_span.s) - self.assertEqual(tornado_span.p, aiohttp_span.s) + assert aiohttp_span.p == test_span.s + assert tornado_span.p == aiohttp_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertIsNone(aiohttp_span.ec) - self.assertIsNone(tornado_span.ec) - - self.assertEqual(405, tornado_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/405", tornado_span.data["http"]["url"]) - self.assertIsNone(tornado_span.data["http"]["params"]) - self.assertEqual("GET", tornado_span.data["http"]["method"]) - self.assertIsNone(tornado_span.stack) - - self.assertEqual(405, aiohttp_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/405", aiohttp_span.data["http"]["url"]) - self.assertEqual("GET", aiohttp_span.data["http"]["method"]) - self.assertIsNotNone(aiohttp_span.stack) - self.assertIsInstance(aiohttp_span.stack, list) - self.assertGreater(len(aiohttp_span.stack), 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], tornado_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_get_500(self): + assert not test_span.ec + assert not aiohttp_span.ec + assert not tornado_span.ec + + assert tornado_span.data["http"]["status"] == 405 + assert testenv["tornado_server"] + "/405" == tornado_span.data["http"]["url"] + assert not tornado_span.data["http"]["params"] + assert tornado_span.data["http"]["method"] == "GET" + assert not tornado_span.stack + + assert aiohttp_span.data["http"]["status"] == 405 + assert testenv["tornado_server"] + "/405" == aiohttp_span.data["http"]["url"] + assert aiohttp_span.data["http"]["method"] == "GET" + assert aiohttp_span.stack + assert isinstance(aiohttp_span.stack, list) + assert len(aiohttp_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(tornado_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_get_500(self) -> None: async def test(): - with async_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): async with aiohttp.ClientSession() as session: return await self.fetch(session, testenv["tornado_server"] + "/500") response = tornado.ioloop.IOLoop.current().run_sync(test) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 tornado_span = get_first_span_by_name(spans, "tornado-server") aiohttp_span = get_first_span_by_name(spans, "aiohttp-client") test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNotNone(tornado_span) - self.assertIsNotNone(aiohttp_span) - self.assertIsNotNone(test_span) + assert tornado_span + assert aiohttp_span + assert test_span - self.assertIsNone(async_tracer.active_span) + assert not get_current_span().is_recording() - self.assertEqual("tornado-server", tornado_span.n) - self.assertEqual("aiohttp-client", aiohttp_span.n) - self.assertEqual("sdk", test_span.n) + assert tornado_span.n == "tornado-server" + assert aiohttp_span.n == "aiohttp-client" + assert test_span.n == "sdk" # Same traceId traceId = test_span.t - self.assertEqual(traceId, aiohttp_span.t) - self.assertEqual(traceId, tornado_span.t) + assert traceId == aiohttp_span.t + assert traceId == tornado_span.t # Parent relationships - self.assertEqual(aiohttp_span.p, test_span.s) - self.assertEqual(tornado_span.p, aiohttp_span.s) + assert aiohttp_span.p == test_span.s + assert tornado_span.p == aiohttp_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertEqual(aiohttp_span.ec, 1) - self.assertEqual(tornado_span.ec, 1) - - self.assertEqual(500, tornado_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/500", tornado_span.data["http"]["url"]) - self.assertIsNone(tornado_span.data["http"]["params"]) - self.assertEqual("GET", tornado_span.data["http"]["method"]) - self.assertIsNone(tornado_span.stack) - - self.assertEqual(500, aiohttp_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/500", aiohttp_span.data["http"]["url"]) - self.assertEqual("GET", aiohttp_span.data["http"]["method"]) - self.assertEqual('Internal Server Error', aiohttp_span.data["http"]["error"]) - self.assertIsNotNone(aiohttp_span.stack) - self.assertIsInstance(aiohttp_span.stack, list) - self.assertGreater(len(aiohttp_span.stack), 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], tornado_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_get_504(self): + assert not test_span.ec + assert aiohttp_span.ec == 1 + assert tornado_span.ec == 1 + + assert tornado_span.data["http"]["status"] == 500 + assert testenv["tornado_server"] + "/500" == tornado_span.data["http"]["url"] + assert not tornado_span.data["http"]["params"] + assert tornado_span.data["http"]["method"] == "GET" + assert not tornado_span.stack + + assert aiohttp_span.data["http"]["status"] == 500 + assert testenv["tornado_server"] + "/500" == aiohttp_span.data["http"]["url"] + assert aiohttp_span.data["http"]["method"] == "GET" + assert 'Internal Server Error' == aiohttp_span.data["http"]["error"] + assert aiohttp_span.stack + assert isinstance(aiohttp_span.stack, list) + assert len(aiohttp_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(tornado_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_get_504(self) -> None: async def test(): - with async_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): async with aiohttp.ClientSession() as session: return await self.fetch(session, testenv["tornado_server"] + "/504") response = tornado.ioloop.IOLoop.current().run_sync(test) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 tornado_span = get_first_span_by_name(spans, "tornado-server") aiohttp_span = get_first_span_by_name(spans, "aiohttp-client") test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNotNone(tornado_span) - self.assertIsNotNone(aiohttp_span) - self.assertIsNotNone(test_span) + assert tornado_span + assert aiohttp_span + assert test_span - self.assertIsNone(async_tracer.active_span) + assert not get_current_span().is_recording() - self.assertEqual("tornado-server", tornado_span.n) - self.assertEqual("aiohttp-client", aiohttp_span.n) - self.assertEqual("sdk", test_span.n) + assert tornado_span.n == "tornado-server" + assert aiohttp_span.n == "aiohttp-client" + assert test_span.n == "sdk" # Same traceId traceId = test_span.t - self.assertEqual(traceId, aiohttp_span.t) - self.assertEqual(traceId, tornado_span.t) + assert traceId == aiohttp_span.t + assert traceId == tornado_span.t # Parent relationships - self.assertEqual(aiohttp_span.p, test_span.s) - self.assertEqual(tornado_span.p, aiohttp_span.s) + assert aiohttp_span.p == test_span.s + assert tornado_span.p == aiohttp_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertEqual(aiohttp_span.ec, 1) - self.assertEqual(tornado_span.ec, 1) - - self.assertEqual(504, tornado_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/504", tornado_span.data["http"]["url"]) - self.assertIsNone(tornado_span.data["http"]["params"]) - self.assertEqual("GET", tornado_span.data["http"]["method"]) - self.assertIsNone(tornado_span.stack) - - self.assertEqual(504, aiohttp_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/504", aiohttp_span.data["http"]["url"]) - self.assertEqual("GET", aiohttp_span.data["http"]["method"]) - self.assertEqual('Gateway Timeout', aiohttp_span.data["http"]["error"]) - self.assertIsNotNone(aiohttp_span.stack) - self.assertIsInstance(aiohttp_span.stack, list) - self.assertGreater(len(aiohttp_span.stack), 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], tornado_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_get_with_params_to_scrub(self): + assert not test_span.ec + assert aiohttp_span.ec == 1 + assert tornado_span.ec == 1 + + assert tornado_span.data["http"]["status"] == 504 + assert testenv["tornado_server"] + "/504" == tornado_span.data["http"]["url"] + assert not tornado_span.data["http"]["params"] + assert tornado_span.data["http"]["method"] == "GET" + assert not tornado_span.stack + + assert aiohttp_span.data["http"]["status"] == 504 + assert testenv["tornado_server"] + "/504" == aiohttp_span.data["http"]["url"] + assert aiohttp_span.data["http"]["method"] == "GET" + assert 'Gateway Timeout' == aiohttp_span.data["http"]["error"] + assert aiohttp_span.stack + assert isinstance(aiohttp_span.stack, list) + assert len(aiohttp_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(tornado_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_get_with_params_to_scrub(self) -> None: async def test(): - with async_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): async with aiohttp.ClientSession() as session: return await self.fetch(session, testenv["tornado_server"], params={"secret": "yeah"}) response = tornado.ioloop.IOLoop.current().run_sync(test) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 - self.assertIsNone(async_tracer.active_span) + assert not get_current_span().is_recording() tornado_span = get_first_span_by_name(spans, "tornado-server") aiohttp_span = get_first_span_by_name(spans, "aiohttp-client") test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNotNone(tornado_span) - self.assertIsNotNone(aiohttp_span) - self.assertIsNotNone(test_span) + assert tornado_span + assert aiohttp_span + assert test_span - self.assertEqual("tornado-server", tornado_span.n) - self.assertEqual("aiohttp-client", aiohttp_span.n) - self.assertEqual("sdk", test_span.n) + assert tornado_span.n == "tornado-server" + assert aiohttp_span.n == "aiohttp-client" + assert test_span.n == "sdk" # Same traceId traceId = test_span.t - self.assertEqual(traceId, aiohttp_span.t) - self.assertEqual(traceId, tornado_span.t) + assert traceId == aiohttp_span.t + assert traceId == tornado_span.t # Parent relationships - self.assertEqual(aiohttp_span.p, test_span.s) - self.assertEqual(tornado_span.p, aiohttp_span.s) + assert aiohttp_span.p == test_span.s + assert tornado_span.p == aiohttp_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertIsNone(aiohttp_span.ec) - self.assertIsNone(tornado_span.ec) - - self.assertEqual(200, tornado_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", tornado_span.data["http"]["url"]) - self.assertEqual("secret=", tornado_span.data["http"]["params"]) - self.assertEqual("GET", tornado_span.data["http"]["method"]) - self.assertIsNone(tornado_span.stack) - - self.assertEqual(200, aiohttp_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", aiohttp_span.data["http"]["url"]) - self.assertEqual("GET", aiohttp_span.data["http"]["method"]) - self.assertEqual("secret=", aiohttp_span.data["http"]["params"]) - self.assertIsNotNone(aiohttp_span.stack) - self.assertIsInstance(aiohttp_span.stack, list) - self.assertGreater(len(aiohttp_span.stack), 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], tornado_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - def test_request_header_capture(self): + assert not test_span.ec + assert not aiohttp_span.ec + assert not tornado_span.ec + + assert tornado_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == tornado_span.data["http"]["url"] + assert tornado_span.data["http"]["params"] == "secret=" + assert tornado_span.data["http"]["method"] == "GET" + assert not tornado_span.stack + + assert aiohttp_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == aiohttp_span.data["http"]["url"] + assert aiohttp_span.data["http"]["method"] == "GET" + assert aiohttp_span.data["http"]["params"] == "secret=" + assert aiohttp_span.stack + assert isinstance(aiohttp_span.stack, list) + assert len(aiohttp_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(tornado_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + def test_request_header_capture(self) -> None: async def test(): - with async_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): async with aiohttp.ClientSession() as session: # Hack together a manual custom request headers list agent.options.extra_http_headers = ["X-Capture-This", "X-Capture-That"] @@ -528,67 +530,67 @@ async def test(): response = tornado.ioloop.IOLoop.current().run_sync(test) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 tornado_span = get_first_span_by_name(spans, "tornado-server") aiohttp_span = get_first_span_by_name(spans, "aiohttp-client") test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNotNone(tornado_span) - self.assertIsNotNone(aiohttp_span) - self.assertIsNotNone(test_span) + assert tornado_span + assert aiohttp_span + assert test_span - self.assertIsNone(async_tracer.active_span) + assert not get_current_span().is_recording() - self.assertEqual("tornado-server", tornado_span.n) - self.assertEqual("aiohttp-client", aiohttp_span.n) - self.assertEqual("sdk", test_span.n) + assert tornado_span.n == "tornado-server" + assert aiohttp_span.n == "aiohttp-client" + assert test_span.n == "sdk" # Same traceId traceId = test_span.t - self.assertEqual(traceId, aiohttp_span.t) - self.assertEqual(traceId, tornado_span.t) + assert traceId == aiohttp_span.t + assert traceId == tornado_span.t # Parent relationships - self.assertEqual(aiohttp_span.p, test_span.s) - self.assertEqual(tornado_span.p, aiohttp_span.s) + assert aiohttp_span.p == test_span.s + assert tornado_span.p == aiohttp_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertIsNone(aiohttp_span.ec) - self.assertIsNone(tornado_span.ec) - - self.assertEqual(200, tornado_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", tornado_span.data["http"]["url"]) - self.assertEqual("secret=", tornado_span.data["http"]["params"]) - self.assertEqual("GET", tornado_span.data["http"]["method"]) - self.assertIsNone(tornado_span.stack) - - self.assertEqual(200, aiohttp_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/", aiohttp_span.data["http"]["url"]) - self.assertEqual("GET", aiohttp_span.data["http"]["method"]) - self.assertEqual("secret=", aiohttp_span.data["http"]["params"]) - self.assertIsNotNone(aiohttp_span.stack) - self.assertIsInstance(aiohttp_span.stack, list) - self.assertGreater(len(aiohttp_span.stack), 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], tornado_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - self.assertIn("X-Capture-This", tornado_span.data["http"]["header"]) - self.assertEqual("this", tornado_span.data["http"]["header"]["X-Capture-This"]) - self.assertIn("X-Capture-That", tornado_span.data["http"]["header"]) - self.assertEqual("that", tornado_span.data["http"]["header"]["X-Capture-That"]) - - def test_response_header_capture(self): + assert not test_span.ec + assert not aiohttp_span.ec + assert not tornado_span.ec + + assert tornado_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == tornado_span.data["http"]["url"] + assert tornado_span.data["http"]["params"] == "secret=" + assert tornado_span.data["http"]["method"] == "GET" + assert not tornado_span.stack + + assert aiohttp_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/" == aiohttp_span.data["http"]["url"] + assert aiohttp_span.data["http"]["method"] == "GET" + assert aiohttp_span.data["http"]["params"] == "secret=" + assert aiohttp_span.stack + assert isinstance(aiohttp_span.stack, list) + assert len(aiohttp_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(tornado_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + assert "X-Capture-This" in tornado_span.data["http"]["header"] + assert tornado_span.data["http"]["header"]["X-Capture-This"] == "this" + assert "X-Capture-That" in tornado_span.data["http"]["header"] + assert tornado_span.data["http"]["header"]["X-Capture-That"] == "that" + + def test_response_header_capture(self) -> None: async def test(): - with async_tracer.start_active_span('test'): + with tracer.start_as_current_span("test"): async with aiohttp.ClientSession() as session: # Hack together a manual custom response headers list agent.options.extra_http_headers = ["X-Capture-This-Too", "X-Capture-That-Too"] @@ -598,60 +600,60 @@ async def test(): response = tornado.ioloop.IOLoop.current().run_sync(test) spans = self.recorder.queued_spans() - self.assertEqual(3, len(spans)) + assert len(spans) == 3 tornado_span = get_first_span_by_name(spans, "tornado-server") aiohttp_span = get_first_span_by_name(spans, "aiohttp-client") test_span = get_first_span_by_name(spans, "sdk") - self.assertIsNotNone(tornado_span) - self.assertIsNotNone(aiohttp_span) - self.assertIsNotNone(test_span) + assert tornado_span + assert aiohttp_span + assert test_span - self.assertIsNone(async_tracer.active_span) + assert not get_current_span().is_recording() - self.assertEqual("tornado-server", tornado_span.n) - self.assertEqual("aiohttp-client", aiohttp_span.n) - self.assertEqual("sdk", test_span.n) + assert tornado_span.n == "tornado-server" + assert aiohttp_span.n == "aiohttp-client" + assert test_span.n == "sdk" # Same traceId traceId = test_span.t - self.assertEqual(traceId, aiohttp_span.t) - self.assertEqual(traceId, tornado_span.t) + assert traceId == aiohttp_span.t + assert traceId == tornado_span.t # Parent relationships - self.assertEqual(aiohttp_span.p, test_span.s) - self.assertEqual(tornado_span.p, aiohttp_span.s) + assert aiohttp_span.p == test_span.s + assert tornado_span.p == aiohttp_span.s # Error logging - self.assertIsNone(test_span.ec) - self.assertIsNone(aiohttp_span.ec) - self.assertIsNone(tornado_span.ec) - - self.assertEqual(200, tornado_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/response_headers", tornado_span.data["http"]["url"]) - self.assertEqual("secret=", tornado_span.data["http"]["params"]) - self.assertEqual("GET", tornado_span.data["http"]["method"]) - self.assertIsNone(tornado_span.stack) - - self.assertEqual(200, aiohttp_span.data["http"]["status"]) - self.assertEqual(testenv["tornado_server"] + "/response_headers", aiohttp_span.data["http"]["url"]) - self.assertEqual("GET", aiohttp_span.data["http"]["method"]) - self.assertEqual("secret=", aiohttp_span.data["http"]["params"]) - self.assertIsNotNone(aiohttp_span.stack) - self.assertIsInstance(aiohttp_span.stack, list) - self.assertGreater(len(aiohttp_span.stack), 1) - - self.assertIn("X-INSTANA-T", response.headers) - self.assertEqual(response.headers["X-INSTANA-T"], traceId) - self.assertIn("X-INSTANA-S", response.headers) - self.assertEqual(response.headers["X-INSTANA-S"], tornado_span.s) - self.assertIn("X-INSTANA-L", response.headers) - self.assertEqual(response.headers["X-INSTANA-L"], '1') - self.assertIn("Server-Timing", response.headers) - self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - - self.assertIn("X-Capture-This-Too", tornado_span.data["http"]["header"]) - self.assertEqual("this too", tornado_span.data["http"]["header"]["X-Capture-This-Too"]) - self.assertIn("X-Capture-That-Too", tornado_span.data["http"]["header"]) - self.assertEqual("that too", tornado_span.data["http"]["header"]["X-Capture-That-Too"]) + assert not test_span.ec + assert not aiohttp_span.ec + assert not tornado_span.ec + + assert tornado_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/response_headers" == tornado_span.data["http"]["url"] + assert tornado_span.data["http"]["params"] == "secret=" + assert tornado_span.data["http"]["method"] == "GET" + assert not tornado_span.stack + + assert aiohttp_span.data["http"]["status"] == 200 + assert testenv["tornado_server"] + "/response_headers" == aiohttp_span.data["http"]["url"] + assert aiohttp_span.data["http"]["method"] == "GET" + assert aiohttp_span.data["http"]["params"] == "secret=" + assert aiohttp_span.stack + assert isinstance(aiohttp_span.stack, list) + assert len(aiohttp_span.stack) > 1 + + assert "X-INSTANA-T" in response.headers + assert response.headers["X-INSTANA-T"] == str(traceId) + assert "X-INSTANA-S" in response.headers + assert response.headers["X-INSTANA-S"] == str(tornado_span.s) + assert "X-INSTANA-L" in response.headers + assert response.headers["X-INSTANA-L"] == '1' + assert "Server-Timing" in response.headers + assert response.headers["Server-Timing"] == "intid;desc=%s" % traceId + + assert "X-Capture-This-Too" in tornado_span.data["http"]["header"] + assert tornado_span.data["http"]["header"]["X-Capture-This-Too"] == "this too" + assert "X-Capture-That-Too" in tornado_span.data["http"]["header"] + assert tornado_span.data["http"]["header"]["X-Capture-That-Too"] == "that too" diff --git a/tests/requirements-310-with-tornado.txt b/tests/requirements-310-with-tornado.txt deleted file mode 100644 index d09e89ad..00000000 --- a/tests/requirements-310-with-tornado.txt +++ /dev/null @@ -1,8 +0,0 @@ -# pre 6.0 tornado would try to import 'MutableMapping' from 'collections' -# directly, and in Python 3.10 that doesn't work anymore, so that would fail with: -# venv/lib/python3.10/site-packages/tornado/httputil.py:107: in -# AttributeError: module 'collections' has no attribute 'MutableMapping' -# An alternative would be to disable this in testconf: -# collect_ignore_glob.append("*test_tornado*") -tornado>=6.1 --r requirements-310.txt \ No newline at end of file diff --git a/tests/requirements-310.txt b/tests/requirements-310.txt index 88be77c3..10bcebf9 100644 --- a/tests/requirements-310.txt +++ b/tests/requirements-310.txt @@ -38,6 +38,7 @@ responses<=0.17.0 sanic>=19.9.0 sanic-testing>=24.6.0 sqlalchemy>=2.0.0 +tornado>=6.4.1 uvicorn>=0.13.4 urllib3>=1.26.5 diff --git a/tests/requirements-312.txt b/tests/requirements-312.txt index e2fdf83d..b7dcbcb1 100644 --- a/tests/requirements-312.txt +++ b/tests/requirements-312.txt @@ -36,6 +36,7 @@ responses<=0.17.0 sanic>=19.9.0 sanic-testing>=24.6.0 sqlalchemy>=2.0.0 +tornado>=6.4.1 uvicorn>=0.13.4 urllib3>=1.26.5 diff --git a/tests/requirements-313.txt b/tests/requirements-313.txt index 46e24cc6..32795005 100644 --- a/tests/requirements-313.txt +++ b/tests/requirements-313.txt @@ -48,6 +48,7 @@ responses<=0.17.0 #sanic>=19.9.0 #sanic-testing>=24.6.0 sqlalchemy>=2.0.0 +tornado>=6.4.1 uvicorn>=0.13.4 urllib3>=1.26.5 diff --git a/tests/requirements.txt b/tests/requirements.txt index 01cdd36f..1f9c9e3e 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -37,7 +37,7 @@ responses<=0.17.0 sanic>=19.9.0 sanic-testing>=24.6.0 sqlalchemy>=2.0.0 -tornado>=4.5.3,<6.0 +tornado>=6.4.1 uvicorn>=0.13.4 urllib3>=1.26.5 httpx>=0.27.0