async def test_trace_parent_propagation_sampled(instrument, event_loop, zuqa_client, waiting_httpserver): waiting_httpserver.serve_content("") url = waiting_httpserver.url + "/hello_world" zuqa_client.begin_transaction("transaction") async with aiohttp.ClientSession() as session: async with session.get(waiting_httpserver.url) as resp: status = resp.status text = await resp.text() zuqa_client.end_transaction("MyView") transactions = zuqa_client.events[constants.TRANSACTION] spans = zuqa_client.spans_for_transaction(transactions[0]) headers = waiting_httpserver.requests[0].headers assert constants.TRACEPARENT_HEADER_NAME in headers trace_parent = TraceParent.from_string( headers[constants.TRACEPARENT_HEADER_NAME]) assert trace_parent.trace_id == transactions[0]["trace_id"] assert trace_parent.span_id == spans[0]["id"] assert trace_parent.trace_options.recorded if zuqa_client.config.use_elastic_traceparent_header: assert constants.TRACEPARENT_LEGACY_HEADER_NAME in headers assert headers[constants.TRACEPARENT_HEADER_NAME] == headers[ constants.TRACEPARENT_LEGACY_HEADER_NAME] else: assert constants.TRACEPARENT_LEGACY_HEADER_NAME not in headers
def test_trace_parent_propagation_unsampled(instrument, zuqa_client, waiting_httpserver): waiting_httpserver.serve_content("") url = waiting_httpserver.url + "/hello_world" transaction_object = zuqa_client.begin_transaction("transaction") transaction_object.is_sampled = False urlopen(url) zuqa_client.end_transaction("MyView") transactions = zuqa_client.events[TRANSACTION] spans = zuqa_client.spans_for_transaction(transactions[0]) assert not spans headers = waiting_httpserver.requests[0].headers assert constants.TRACEPARENT_HEADER_NAME in headers trace_parent = TraceParent.from_string( headers[constants.TRACEPARENT_HEADER_NAME]) assert trace_parent.trace_id == transactions[0]["trace_id"] assert trace_parent.span_id == transaction_object.id assert not trace_parent.trace_options.recorded if zuqa_client.config.use_elastic_traceparent_header: assert constants.TRACEPARENT_LEGACY_HEADER_NAME in headers assert headers[constants.TRACEPARENT_HEADER_NAME] == headers[ constants.TRACEPARENT_LEGACY_HEADER_NAME] else: assert constants.TRACEPARENT_LEGACY_HEADER_NAME not in headers
def test_requests_instrumentation_via_session(instrument, zuqa_client, waiting_httpserver): waiting_httpserver.serve_content("") url = waiting_httpserver.url + "/hello_world" zuqa_client.begin_transaction("transaction.test") with capture_span("test_request", "test"): s = requests.Session() s.get(url, allow_redirects=False) zuqa_client.end_transaction("MyView") transactions = zuqa_client.events[TRANSACTION] spans = zuqa_client.spans_for_transaction(transactions[0]) assert spans[0]["name"].startswith("GET 127.0.0.1:") assert url == spans[0]["context"]["http"]["url"] assert constants.TRACEPARENT_HEADER_NAME in waiting_httpserver.requests[ 0].headers trace_parent = TraceParent.from_string( waiting_httpserver.requests[0].headers[ constants.TRACEPARENT_HEADER_NAME]) assert trace_parent.trace_id == transactions[0]["trace_id"] # this should be the span id of `requests`, not of urllib3 assert trace_parent.span_id == spans[0]["id"] assert trace_parent.trace_options.recorded
def test_requests_instrumentation(instrument, zuqa_client, waiting_httpserver): waiting_httpserver.serve_content("") url = waiting_httpserver.url + "/hello_world" parsed_url = compat.urlparse.urlparse(url) zuqa_client.begin_transaction("transaction.test") with capture_span("test_request", "test"): requests.get(url, allow_redirects=False) zuqa_client.end_transaction("MyView") transactions = zuqa_client.events[TRANSACTION] spans = zuqa_client.spans_for_transaction(transactions[0]) assert spans[0]["name"].startswith("GET 127.0.0.1:") assert spans[0]["type"] == "external" assert spans[0]["subtype"] == "http" assert url == spans[0]["context"]["http"]["url"] assert spans[0]["context"]["destination"]["service"] == { "name": "http://127.0.0.1:%d" % parsed_url.port, "resource": "127.0.0.1:%d" % parsed_url.port, "type": "external", } assert constants.TRACEPARENT_HEADER_NAME in waiting_httpserver.requests[ 0].headers trace_parent = TraceParent.from_string( waiting_httpserver.requests[0].headers[ constants.TRACEPARENT_HEADER_NAME]) assert trace_parent.trace_id == transactions[0]["trace_id"] # this should be the span id of `requests`, not of urllib3 assert trace_parent.span_id == spans[0]["id"] assert trace_parent.trace_options.recorded
async def test_trace_parent_propagation_sampled_headers_none( instrument, event_loop, zuqa_client, waiting_httpserver, sampled): """ Test that we don't blow up if headers are explicitly set to None """ waiting_httpserver.serve_content("") url = waiting_httpserver.url + "/hello_world" transaction = zuqa_client.begin_transaction("transaction") transaction.is_sampled = sampled async with aiohttp.ClientSession() as session: async with session.get(waiting_httpserver.url, headers=None) as resp: status = resp.status text = await resp.text() zuqa_client.end_transaction("MyView") transactions = zuqa_client.events[constants.TRANSACTION] spans = zuqa_client.spans_for_transaction(transactions[0]) headers = waiting_httpserver.requests[0].headers assert constants.TRACEPARENT_HEADER_NAME in headers trace_parent = TraceParent.from_string( headers[constants.TRACEPARENT_HEADER_NAME]) assert trace_parent.trace_id == transactions[0]["trace_id"] if sampled: assert trace_parent.span_id == spans[0]["id"] else: assert trace_parent.span_id == transactions[0]["id"]
def test_trace_parent_propagation_sampled(instrument, zuqa_client, waiting_httpserver): waiting_httpserver.serve_content("") url = waiting_httpserver.url + "/hello_world" zuqa_client.begin_transaction("transaction") pool = urllib3.PoolManager(timeout=0.1) r = pool.request("GET", url) zuqa_client.end_transaction("MyView") transactions = zuqa_client.events[TRANSACTION] spans = zuqa_client.spans_for_transaction(transactions[0]) headers = waiting_httpserver.requests[0].headers assert constants.TRACEPARENT_HEADER_NAME in headers trace_parent = TraceParent.from_string( headers[constants.TRACEPARENT_HEADER_NAME]) assert trace_parent.trace_id == transactions[0]["trace_id"] assert trace_parent.span_id == spans[0]["id"] assert trace_parent.trace_options.recorded if zuqa_client.config.use_elastic_traceparent_header: assert constants.TRACEPARENT_LEGACY_HEADER_NAME in headers assert headers[constants.TRACEPARENT_HEADER_NAME] == headers[ constants.TRACEPARENT_LEGACY_HEADER_NAME] else: assert constants.TRACEPARENT_LEGACY_HEADER_NAME not in headers
def test_trace_parent_wrong_format(caplog): header = "00" with caplog.at_level("DEBUG", "zuqa.utils"): trace_parent = TraceParent.from_string(header) assert trace_parent is None assert_any_record_contains(caplog.records, "Invalid traceparent header format, value 00")
def test_trace_parent_wrong_trace_options_field(caplog): header = "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-xx" with caplog.at_level("DEBUG", "zuqa.utils"): trace_parent = TraceParent.from_string(header) assert trace_parent is None assert_any_record_contains(caplog.records, "Invalid trace-options field, value xx")
def test_trace_parent(zuqa_client): trace_parent = TraceParent.from_string( "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-03") zuqa_client.begin_transaction("test", trace_parent=trace_parent) transaction = zuqa_client.end_transaction("test", "OK") data = transaction.to_dict() assert data["trace_id"] == "0af7651916cd43dd8448eb211c80319c" assert data["parent_id"] == "b7ad6b7169203331"
def test_trace_parent_wrong_version_255(caplog): """Version FF or 255 is explicitly forbidden""" header = "ff-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-03" with caplog.at_level("DEBUG", "zuqa.utils"): trace_parent = TraceParent.from_string(header) assert trace_parent is None assert_any_record_contains(caplog.records, "Invalid version field, value 255")
def test_span_only_dropped(instrument, zuqa_client, waiting_httpserver): """test that urllib instrumentation does not fail if no parent span can be found""" waiting_httpserver.serve_content("") url = waiting_httpserver.url + "/hello_world" transaction_object = zuqa_client.begin_transaction("transaction") for i in range(2): with capture_span("test", "test"): urlopen(url) zuqa_client.end_transaction("bla", "OK") trace_parent_1 = TraceParent.from_string( waiting_httpserver.requests[0].headers[ constants.TRACEPARENT_HEADER_NAME]) trace_parent_2 = TraceParent.from_string( waiting_httpserver.requests[1].headers[ constants.TRACEPARENT_HEADER_NAME]) assert trace_parent_1.span_id != transaction_object.id # second request should use transaction id as span id because there is no span assert trace_parent_2.span_id == transaction_object.id
def test_tracer_inject_map(tracer): span_context = OTSpanContext(trace_parent=TraceParent.from_string( "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01")) carrier = {} tracer.inject(span_context, Format.TEXT_MAP, carrier) assert carrier[ constants. TRACEPARENT_HEADER_NAME] == b"00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01" if tracer._agent.config.use_elastic_traceparent_header: assert carrier[constants.TRACEPARENT_LEGACY_HEADER_NAME] == carrier[ constants.TRACEPARENT_HEADER_NAME]
def test_tracestate_propagation(instrument, zuqa_client, waiting_httpserver, is_sampled): traceparent = TraceParent.from_string( "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-03", "foo=bar,baz=bazzinga") waiting_httpserver.serve_content("") url = waiting_httpserver.url + "/hello_world" transaction_object = zuqa_client.begin_transaction( "transaction", trace_parent=traceparent) transaction_object.is_sampled = is_sampled urlopen(url) zuqa_client.end_transaction("MyView") headers = waiting_httpserver.requests[0].headers assert headers[constants.TRACESTATE_HEADER_NAME] == "foo=bar,baz=bazzinga"
async def test_tracestate_propagation(instrument, event_loop, zuqa_client, waiting_httpserver, is_sampled): traceparent = TraceParent.from_string( "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-03", "foo=bar,baz=bazzinga") waiting_httpserver.serve_content("") url = waiting_httpserver.url + "/hello_world" transaction_object = zuqa_client.begin_transaction( "transaction", trace_parent=traceparent) transaction_object.is_sampled = is_sampled async with aiohttp.ClientSession() as session: async with session.get(waiting_httpserver.url) as resp: status = resp.status text = await resp.text() zuqa_client.end_transaction("MyView") headers = waiting_httpserver.requests[0].headers assert headers[constants.TRACESTATE_HEADER_NAME] == "foo=bar,baz=bazzinga"
def test_tracer_inject_binary(tracer): span_context = OTSpanContext(trace_parent=TraceParent.from_string( "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01")) with pytest.raises(opentracing.UnsupportedFormatException): tracer.inject(span_context, Format.BINARY, {})
def test_trace_parent_to_str(): header = "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-03" trace_parent = TraceParent.from_string(header) result = trace_parent.to_string() assert isinstance(result, str) assert header == result
def test_unknown_header_components_ignored(): header = "01-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-03-xyz" trace_parent = TraceParent.from_string(header) assert trace_parent.to_string( ) == "01-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-03"
def test_tracing_options(tracing_bits, expected): header = "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-{}".format( tracing_bits) trace_parent = TraceParent.from_string(header) assert trace_parent.trace_options.recorded == expected["recorded"]