def test_encoder_propagates_dd_origin(Encoder, item): tracer = DummyTracer() encoder = Encoder(1 << 20, 1 << 20) with tracer.trace("Root") as root: root.context.dd_origin = CI_APP_TEST_ORIGIN for _ in range(999): with tracer.trace("child"): pass trace = tracer.writer.pop() encoder.put(trace) decoded_trace = decode(encoder.encode()) # Ensure encoded trace contains dd_origin tag in all spans assert all((_[item][_ORIGIN_KEY] == b"ciapp-test" for _ in decoded_trace[0]))
def test_encoder_propagates_dd_origin(): tracer = DummyTracer() encoder = MsgpackEncoder(1 << 20, 1 << 20) with tracer.trace("Root") as root: root.context.dd_origin = CI_APP_TEST_ORIGIN for _ in range(999): with tracer.trace("child"): pass # Ensure encoded trace contains dd_origin tag in all spans trace = tracer.writer.pop() encoder.put(trace) decoded_trace = decode(encoder.encode())[0] for span in decoded_trace: assert span[b"meta"][b"_dd.origin"] == b"ciapp-test"
def test_WSGI_extract(self): """Ensure we support the WSGI formatted headers as well.""" tracer = DummyTracer() headers = { "HTTP_X_DATADOG_TRACE_ID": "1234", "HTTP_X_DATADOG_PARENT_ID": "5678", "HTTP_X_DATADOG_SAMPLING_PRIORITY": "1", "HTTP_X_DATADOG_ORIGIN": "synthetics", "HTTP_X_DATADOG_TAGS": "_dd.p.test=value,any=tag", } context = HTTPPropagator.extract(headers) tracer.context_provider.activate(context) with tracer.trace("local_root_span") as span: assert span.trace_id == 1234 assert span.parent_id == 5678 assert span.context.sampling_priority == 1 assert span.context.dd_origin == "synthetics" assert span.context._meta == { "_dd.origin": "synthetics", "_dd.p.test": "value", "any": "tag", }
def test_dd_origin_tagging_spans_via_encoder(benchmark, trace_size): """Propagate dd_origin tags to all spans in [1, 50, 200, 1000] span trace via Encoder""" tracer = DummyTracer() with tracer.trace("pytest-test") as root: root.context.dd_origin = CI_APP_TEST_ORIGIN for _ in range(trace_size - 1): with tracer.trace("") as span: span.set_tag("tag", "value") pass trace = tracer.writer.pop() benchmark(trace_encoder.encode_trace, trace) # Ensure encoded trace contains dd_origin tag in all spans encoded_trace = trace_encoder.encode_trace(trace) decoded_trace = trace_encoder._decode(encoded_trace) for span in decoded_trace: assert span[b"meta"][b"_dd.origin"] == b"ciapp-test"
def test_inject(self): tracer = DummyTracer() ctx = Context(trace_id=1234, sampling_priority=2, dd_origin="synthetics") tracer.context_provider.activate(ctx) with tracer.trace("global_root_span") as span: headers = {} HTTPPropagator.inject(span.context, headers) assert int(headers[HTTP_HEADER_TRACE_ID]) == span.trace_id assert int(headers[HTTP_HEADER_PARENT_ID]) == span.span_id assert int(headers[HTTP_HEADER_SAMPLING_PRIORITY]) == span.context.sampling_priority assert headers[HTTP_HEADER_ORIGIN] == span.context.dd_origin
def test_inject_tags_many_large(self): """When we have too many tags that cause us to reach the max size limit""" tracer = DummyTracer() meta = {"_dd.p.test_{}".format(i): "test" * 10 for i in range(100)} ctx = Context(trace_id=1234, sampling_priority=2, dd_origin="synthetics", meta=meta) tracer.context_provider.activate(ctx) with tracer.trace("global_root_span") as span: headers = {} HTTPPropagator.inject(span.context, headers) assert HTTP_HEADER_TAGS not in headers assert ctx._meta["_dd.propagation_error"] == "max_size"
def test_inject_tags_unicode(self): """Unicode characters are not allowed""" tracer = DummyTracer() meta = {u"_dd.p.unicode_☺️": u"unicode value ☺️"} ctx = Context(trace_id=1234, sampling_priority=2, dd_origin="synthetics", meta=meta) tracer.context_provider.activate(ctx) with tracer.trace("global_root_span") as span: headers = {} HTTPPropagator.inject(span.context, headers) assert HTTP_HEADER_TAGS not in headers assert ctx._meta["_dd.propagation_error"] == "encoding_error"
def test_inject_tags_invalid(self): tracer = DummyTracer() # DEV: "=" and "," are not allowed in keys or values meta = {"_dd.p.test=": ",value="} ctx = Context(trace_id=1234, sampling_priority=2, dd_origin="synthetics", meta=meta) tracer.context_provider.activate(ctx) with tracer.trace("global_root_span") as span: headers = {} HTTPPropagator.inject(span.context, headers) assert HTTP_HEADER_TAGS not in headers assert ctx._meta["_dd.propagation_error"] == "encoding_error"
def test_inject_tags_large(self): """When we have a single large tag that won't fit""" tracer = DummyTracer() # DEV: Limit is 512 meta = {"_dd.p.test": "long" * 200} ctx = Context(trace_id=1234, sampling_priority=2, dd_origin="synthetics", meta=meta) tracer.context_provider.activate(ctx) with tracer.trace("global_root_span") as span: headers = {} HTTPPropagator.inject(span.context, headers) assert HTTP_HEADER_TAGS not in headers assert ctx._meta["_dd.propagation_error"] == "max_size"
def test_extract(self): tracer = DummyTracer() headers = { "x-datadog-trace-id": "1234", "x-datadog-parent-id": "5678", "x-datadog-sampling-priority": "1", "x-datadog-origin": "synthetics", } context = HTTPPropagator.extract(headers) tracer.context_provider.activate(context) with tracer.trace("local_root_span") as span: assert span.trace_id == 1234 assert span.parent_id == 5678 assert span.context.sampling_priority == 1 assert span.context.dd_origin == "synthetics"
def test_inject_tags_bytes(self): """We properly encode when the meta key as long as it is just ascii characters""" tracer = DummyTracer() # Context._meta allows str and bytes for keys meta = {u"_dd.p.unicode": u"unicode", b"_dd.p.bytes": b"bytes"} ctx = Context(trace_id=1234, sampling_priority=2, dd_origin="synthetics", meta=meta) tracer.context_provider.activate(ctx) with tracer.trace("global_root_span") as span: headers = {} HTTPPropagator.inject(span.context, headers) # The ordering is non-deterministic, so compare as a list of tags tags = set(headers[HTTP_HEADER_TAGS].split(",")) assert tags == set(["_dd.p.unicode=unicode", "_dd.p.bytes=bytes"])
def test_inject(self): tracer = DummyTracer() # We will only pass along `_dd.p.*` tags meta = {"_dd.p.test": "value", "non._dd.p_tag": "value"} ctx = Context(trace_id=1234, sampling_priority=2, dd_origin="synthetics", meta=meta) tracer.context_provider.activate(ctx) with tracer.trace("global_root_span") as span: headers = {} HTTPPropagator.inject(span.context, headers) assert int(headers[HTTP_HEADER_TRACE_ID]) == span.trace_id assert int(headers[HTTP_HEADER_PARENT_ID]) == span.span_id assert int(headers[HTTP_HEADER_SAMPLING_PRIORITY] ) == span.context.sampling_priority assert headers[HTTP_HEADER_ORIGIN] == span.context.dd_origin
def test_inject_tags_previous_error(self): """When we have previously gotten an error, do not try to propagate tags""" tracer = DummyTracer() # This value is valid meta = { "_dd.p.key": "value", "_dd.propagation_error": "some fake test value" } ctx = Context(trace_id=1234, sampling_priority=2, dd_origin="synthetics", meta=meta) tracer.context_provider.activate(ctx) with tracer.trace("global_root_span") as span: headers = {} HTTPPropagator.inject(span.context, headers) assert HTTP_HEADER_TAGS not in headers
def test_extract_invalid_tags(self): # Malformed tags do not fail to extract the rest of the context tracer = DummyTracer() headers = { "x-datadog-trace-id": "1234", "x-datadog-parent-id": "5678", "x-datadog-sampling-priority": "1", "x-datadog-origin": "synthetics", "x-datadog-tags": "malformed=,=tags,", } context = HTTPPropagator.extract(headers) tracer.context_provider.activate(context) with tracer.trace("local_root_span") as span: assert span.trace_id == 1234 assert span.parent_id == 5678 assert span.context.sampling_priority == 1 assert span.context.dd_origin == "synthetics" assert span.context._meta == {"_dd.origin": "synthetics"}