Esempio n. 1
0
 def test_log_unfinished_spans_disabled(self, log):
     # the trace finished status logging is disabled
     tracer = DummyTracer()
     ctx = Context()
     # manually create a root-child trace
     root = Span(tracer=tracer, name="root")
     child_1 = Span(tracer=tracer,
                    name="child_1",
                    trace_id=root.trace_id,
                    parent_id=root.span_id)
     child_2 = Span(tracer=tracer,
                    name="child_2",
                    trace_id=root.trace_id,
                    parent_id=root.span_id)
     child_1._parent = root
     child_2._parent = root
     ctx.add_span(root)
     ctx.add_span(child_1)
     ctx.add_span(child_2)
     # close only the parent
     root.finish()
     # the logger has never been invoked to print unfinished spans
     for call, _ in log.call_args_list:
         msg = call[0]
         assert "the trace has %d unfinished spans" not in msg
Esempio n. 2
0
def test_on_finish_multi_callback():
    m1 = mock.Mock()
    m2 = mock.Mock()
    s = Span(None, "test", on_finish=[m1, m2])
    s.finish()
    m1.assert_called_once_with(s)
    m2.assert_called_once_with(s)
Esempio n. 3
0
 def test_finish(self):
     # ensure span.finish() marks the end time of the span
     s = Span(None, "test.span")
     sleep = 0.05
     time.sleep(sleep)
     s.finish()
     assert s.duration >= sleep, "%s < %s" % (s.duration, sleep)
Esempio n. 4
0
 def test_log_unfinished_spans(self, log):
     # when the root parent is finished, notify if there are spans still pending
     tracer = get_dummy_tracer()
     tracer.debug_logging = True
     ctx = Context()
     # manually create a root-child trace
     root = Span(tracer=tracer, name='root')
     child_1 = Span(tracer=tracer, name='child_1', trace_id=root.trace_id, parent_id=root.span_id)
     child_2 = Span(tracer=tracer, name='child_2', trace_id=root.trace_id, parent_id=root.span_id)
     child_1._parent = root
     child_2._parent = root
     ctx.add_span(root)
     ctx.add_span(child_1)
     ctx.add_span(child_2)
     # close only the parent
     root.finish()
     ok_(ctx.is_finished() is False)
     unfinished_spans_log = log.call_args_list[-3][0][2]
     child_1_log = log.call_args_list[-2][0][1]
     child_2_log = log.call_args_list[-1][0][1]
     eq_(2, unfinished_spans_log)
     ok_('name child_1' in child_1_log)
     ok_('name child_2' in child_2_log)
     ok_('duration 0.000000s' in child_1_log)
     ok_('duration 0.000000s' in child_2_log)
Esempio n. 5
0
 def test_finish_set_span_duration(self):
     # If set the duration on a span, the span should be recorded with this
     # duration
     s = Span(tracer=None, name="test.span")
     s.duration = 1337.0
     s.finish()
     assert s.duration == 1337.0
Esempio n. 6
0
 def test_setter_casts_duration_ns_as_int(self):
     s = Span(tracer=None, name="test.span")
     s.duration = 3.2
     s.finish()
     assert s.duration == 3.2
     assert s.duration_ns == 3200000000
     assert isinstance(s.duration_ns, int)
Esempio n. 7
0
def test_custom_msgpack_encode(encoding):
    encoder = MSGPACK_ENCODERS[encoding](1 << 20, 1 << 20)
    refencoder = REF_MSGPACK_ENCODERS[encoding]()

    trace = gen_trace(nspans=50)

    # Note that we assert on the decoded versions because the encoded
    # can vary due to non-deterministic map key/value positioning
    encoder.put(trace)
    assert decode(refencoder.encode_traces([trace])) == decode(encoder.encode())

    ref_encoded = refencoder.encode_traces([trace, trace])
    encoder.put(trace)
    encoder.put(trace)
    encoded = encoder.encode()
    assert decode(encoded) == decode(ref_encoded)

    # Empty trace (not that this should be done in practice)
    encoder.put([])
    assert decode(refencoder.encode_traces([[]])) == decode(encoder.encode())

    s = Span(None, None)
    # Need to .finish() to have a duration since the old implementation will not encode
    # duration_ns, the new one will encode as None
    s.finish()
    encoder.put([s])
    assert decode(refencoder.encode_traces([[s]])) == decode(encoder.encode())
Esempio n. 8
0
 def test_log_unfinished_spans(self, log):
     # when the root parent is finished, notify if there are spans still pending
     tracer = get_dummy_tracer()
     tracer.debug_logging = True
     ctx = Context()
     # manually create a root-child trace
     root = Span(tracer=tracer, name='root')
     child_1 = Span(tracer=tracer,
                    name='child_1',
                    trace_id=root.trace_id,
                    parent_id=root.span_id)
     child_2 = Span(tracer=tracer,
                    name='child_2',
                    trace_id=root.trace_id,
                    parent_id=root.span_id)
     child_1._parent = root
     child_2._parent = root
     ctx.add_span(root)
     ctx.add_span(child_1)
     ctx.add_span(child_2)
     # close only the parent
     root.finish()
     assert ctx.is_finished() is False
     unfinished_spans_log = log.call_args_list[-3][0][2]
     child_1_log = log.call_args_list[-2][0][1]
     child_2_log = log.call_args_list[-1][0][1]
     assert 2 == unfinished_spans_log
     assert 'name child_1' in child_1_log
     assert 'name child_2' in child_2_log
     assert 'duration 0.000000s' in child_1_log
     assert 'duration 0.000000s' in child_2_log
Esempio n. 9
0
def test_finish_set_span_duration():
    # If set the duration on a span, the span should be recorded with this
    # duration
    s = Span(tracer=None, name='test.span')
    s.duration = 1337.0
    s.finish()
    assert s.duration == 1337.0
Esempio n. 10
0
def test_log_unfinished_spans(log, tracer_with_debug_logging):
    # when the root parent is finished, notify if there are spans still pending
    tracer = tracer_with_debug_logging
    ctx = Context()
    # manually create a root-child trace
    root = Span(tracer=tracer, name="root")
    child_1 = Span(tracer=tracer,
                   name="child_1",
                   trace_id=root.trace_id,
                   parent_id=root.span_id)
    child_2 = Span(tracer=tracer,
                   name="child_2",
                   trace_id=root.trace_id,
                   parent_id=root.span_id)
    child_1._parent = root
    child_2._parent = root
    ctx.add_span(root)
    ctx.add_span(child_1)
    ctx.add_span(child_2)
    # close only the parent
    root.finish()
    unfinished_spans_log = log.call_args_list[-3][0][2]
    child_1_log = log.call_args_list[-2][0][1]
    child_2_log = log.call_args_list[-1][0][1]
    assert 2 == unfinished_spans_log
    assert "name child_1" in child_1_log
    assert "name child_2" in child_2_log
    assert "duration 0.000000s" in child_1_log
    assert "duration 0.000000s" in child_2_log
Esempio n. 11
0
 def test_log_unfinished_spans_disabled(self, log):
     # the trace finished status logging is disabled
     tracer = get_dummy_tracer()
     tracer.debug_logging = False
     ctx = Context()
     # manually create a root-child trace
     root = Span(tracer=tracer, name='root')
     child_1 = Span(tracer=tracer,
                    name='child_1',
                    trace_id=root.trace_id,
                    parent_id=root.span_id)
     child_2 = Span(tracer=tracer,
                    name='child_2',
                    trace_id=root.trace_id,
                    parent_id=root.span_id)
     child_1._parent = root
     child_2._parent = root
     ctx.add_span(root)
     ctx.add_span(child_1)
     ctx.add_span(child_2)
     # close only the parent
     root.finish()
     assert ctx.is_finished() is False
     # the logger has never been invoked to print unfinished spans
     for call, _ in log.call_args_list:
         msg = call[0]
         assert 'the trace has %d unfinished spans' not in msg
Esempio n. 12
0
def test_finish_called_multiple_times():
    # we should only record a span the first time finish is called on it
    dt = DummyTracer()
    assert dt.spans_recorded == 0
    s = Span(dt, 'bar')
    s.finish()
    s.finish()
    assert dt.spans_recorded == 1
Esempio n. 13
0
    def test_span_type(self):
        s = Span(name="test.span",
                 service="s",
                 resource="r",
                 span_type=SpanTypes.WEB)
        s.finish()

        assert s.span_type == "web"
Esempio n. 14
0
 def test_finish_called_multiple_times(self):
     # we should only record a span the first time finish is called on it
     ctx = Context()
     s = Span(self.tracer, 'bar', context=ctx)
     ctx.add_span(s)
     s.finish()
     s.finish()
     self.assert_span_count(1)
Esempio n. 15
0
def test_span_boolean_err():
    s = Span(tracer=None, name="foo.bar", service="s", resource="r")
    s.error = True
    s.finish()

    d = s.to_dict()
    assert d
    eq_(d["error"], 1)
    eq_(type(d["error"]), int)
Esempio n. 16
0
    def test_span_boolean_err(self):
        s = Span(tracer=None, name="foo.bar", service="s", resource="r")
        s.error = True
        s.finish()

        d = s.to_dict()
        assert d
        assert d["error"] == 1
        assert type(d["error"]) == int
Esempio n. 17
0
 def test_duration_zero(self):
     s = Span(tracer=None,
              name="foo.bar",
              service="s",
              resource="r",
              start=123)
     s.finish(finish_time=123)
     assert s.duration_ns == 0
     assert s.duration == 0
 def test_context_sampled(self):
     # a context is sampled if the spans are sampled
     ctx = Context()
     span = Span(tracer=None, name='fake_span')
     ctx.add_span(span)
     span.finish()
     trace, sampled = ctx.get()
     assert sampled is True
     assert ctx.sampling_priority is None
Esempio n. 19
0
def test_finish_set_span_duration():
    # If set the duration on a span, the span should be recorded with this
    # duration
    dt = DummyTracer()
    assert dt.last_span is None
    s = Span(dt, 'foo')
    s.duration = 1337.0
    s.finish()
    assert dt.last_span.duration == 1337.0
Esempio n. 20
0
    def test_span_boolean_err(self):
        s = Span(tracer=None, name='foo.bar', service='s', resource='r')
        s.error = True
        s.finish()

        d = s.to_dict()
        assert d
        assert d['error'] == 1
        assert type(d['error']) == int
Esempio n. 21
0
def test_span_boolean_err():
    s = Span(tracer=None, name='foo.bar', service='s', resource='r')
    s.error = True
    s.finish()

    d = s.to_dict()
    assert d
    eq_(d['error'], 1)
    eq_(type(d['error']), int)
Esempio n. 22
0
def test_finish_called_multiple_times():
    # we should only record a span the first time finish is called on it
    dt = DummyTracer()
    ctx = Context()
    s = Span(dt, 'bar', context=ctx)
    ctx.add_span(s)
    s.finish()
    s.finish()
    assert dt.spans_recorded == 1
Esempio n. 23
0
def test_span_boolean_err():
    s = Span(tracer=None, name="foo.bar", service="s",  resource="r")
    s.error = True
    s.finish()

    d = s.to_dict()
    assert d
    eq_(d["error"], 1)
    eq_(type(d["error"]), int)
Esempio n. 24
0
def test_finish_called_multiple_times():
    # we should only record a span the first time finish is called on it
    dt = DummyTracer()
    ctx = Context()
    s = Span(dt, 'bar', context=ctx)
    ctx.add_span(s)
    s.finish()
    s.finish()
    assert dt.spans_recorded == 1
Esempio n. 25
0
    def test_get_report_hostname_enabled(self, get_hostname):
        get_hostname.return_value = "test-hostname"

        with self.override_global_config(dict(report_hostname=True)):
            # Create a context and add a span and finish it
            ctx = Context()
            span = Span(tracer=None, name="fake_span")
            ctx.add_span(span)
            span.finish()
            assert span.get_tag(HOSTNAME_KEY) == "test-hostname"
Esempio n. 26
0
def test_span_pprint():
    root = Span(None,
                "test.span",
                service="s",
                resource="r",
                span_type=SpanTypes.WEB)
    root.set_tag("t", "v")
    root.set_metric("m", 1.0)
    root.finish()
    actual = root.pprint()
    assert "name='test.span'" in actual
    assert "service='s'" in actual
    assert "resource='r'" in actual
    assert "type='web'" in actual
    assert "error=0" in actual
    assert ("tags={'t': 'v'}" if six.PY3 else "tags={'t': u'v'}") in actual
    assert "metrics={'m': 1.0}" in actual
    assert re.search("id=[0-9]+", actual) is not None
    assert re.search("trace_id=[0-9]+", actual) is not None
    assert "parent_id=None" in actual
    assert re.search("duration=[0-9.]+", actual) is not None
    assert re.search("start=[0-9.]+", actual) is not None
    assert re.search("end=[0-9.]+", actual) is not None

    root = Span(None,
                "test.span",
                service="s",
                resource="r",
                span_type=SpanTypes.WEB)
    actual = root.pprint()
    assert "duration=None" in actual
    assert "end=None" in actual

    root = Span(None,
                "test.span",
                service="s",
                resource="r",
                span_type=SpanTypes.WEB)
    root.error = 1
    actual = root.pprint()
    assert "error=1" in actual

    root = Span(None,
                "test.span",
                service="s",
                resource="r",
                span_type=SpanTypes.WEB)
    root.set_tag(u"😌", u"😌")
    actual = root.pprint()
    assert (u"tags={'😌': '😌'}"
            if six.PY3 else "tags={u'\\U0001f60c': u'\\U0001f60c'}") in actual

    root = Span(None, "test.span", service=object())
    actual = root.pprint()
    assert "service=<object object at" in actual
 def test_get_trace(self):
     # it should return the internal trace structure
     # if the context is finished
     ctx = Context()
     span = Span(tracer=None, name='fake_span')
     ctx.add_span(span)
     span.finish()
     trace, sampled = ctx.get()
     assert [span] == trace
     assert sampled is True
     # the context should be empty
     assert 0 == len(ctx._trace)
     assert ctx._current_span is None
Esempio n. 28
0
    def test_duration_int(self):
        s = Span(tracer=None, name="foo.bar", service="s", resource="r")
        s.finish()
        assert isinstance(s.duration_ns, int)
        assert isinstance(s.duration, float)

        s = Span(tracer=None,
                 name="foo.bar",
                 service="s",
                 resource="r",
                 start=123)
        s.finish(finish_time=123.2)
        assert s.duration_ns == 200000000
        assert s.duration == 0.2

        s = Span(tracer=None,
                 name="foo.bar",
                 service="s",
                 resource="r",
                 start=123.1)
        s.finish(finish_time=123.2)
        assert s.duration_ns == 100000000
        assert s.duration == 0.1

        s = Span(tracer=None,
                 name="foo.bar",
                 service="s",
                 resource="r",
                 start=122)
        s.finish(finish_time=123)
        assert s.duration_ns == 1000000000
        assert s.duration == 1
Esempio n. 29
0
def test_span_to_dict():
    s = Span(tracer=None, name="foo.bar", service="s", resource="r")
    s.span_type = "foo"
    s.set_tag("a", "1")
    s.set_meta("b", "2")
    s.finish()

    d = s.to_dict()
    assert d
    eq_(d["span_id"], s.span_id)
    eq_(d["trace_id"], s.trace_id)
    eq_(d["parent_id"], s.parent_id)
    eq_(d["meta"], {"a": "1", "b": "2"})
    eq_(d["type"], "foo")
 def test_context_priority(self):
     # a context is sampled if the spans are sampled
     ctx = Context()
     for priority in [USER_REJECT, AUTO_REJECT, AUTO_KEEP, USER_KEEP, None, 999]:
         ctx.sampling_priority = priority
         span = Span(tracer=None, name=('fake_span_%s' % repr(priority)))
         ctx.add_span(span)
         span.finish()
         # It's "normal" to have sampled be true even when priority sampling is
         # set to 0 or -1. It would stay false even even with priority set to 2.
         # The only criteria to send (or not) the spans to the agent should be
         # this "sampled" attribute, as it's tightly related to the trace weight.
         assert priority == ctx.sampling_priority
         trace, sampled = ctx.get()
         assert sampled is True, 'priority has no impact on sampled status'
Esempio n. 31
0
    def test_span_type(self):
        s = Span(tracer=None, name="test.span", service="s", resource="r", span_type=SpanTypes.WEB)
        s.set_tag("a", "1")
        s.set_meta("b", "2")
        s.finish()

        d = s.to_dict()
        assert d
        assert d["span_id"] == s.span_id
        assert d["trace_id"] == s.trace_id
        assert d["parent_id"] == s.parent_id
        assert d["meta"] == {"a": "1", "b": "2"}
        assert d["type"] == "web"
        assert d["error"] == 0
        assert type(d["error"]) == int
Esempio n. 32
0
    def test_span_type(self):
        s = Span(tracer=None, name='test.span', service='s', resource='r', span_type=SpanTypes.WEB)
        s.set_tag('a', '1')
        s.set_meta('b', '2')
        s.finish()

        d = s.to_dict()
        assert d
        assert d['span_id'] == s.span_id
        assert d['trace_id'] == s.trace_id
        assert d['parent_id'] == s.parent_id
        assert d['meta'] == {'a': '1', 'b': '2'}
        assert d['type'] == 'web'
        assert d['error'] == 0
        assert type(d['error']) == int
    def test_get_report_hostname_default(self, get_hostname):
        get_hostname.return_value = 'test-hostname'

        # Create a context and add a span and finish it
        ctx = Context()
        span = Span(tracer=None, name='fake_span')
        ctx.add_span(span)
        span.finish()

        # Assert that we have not added the tag to the span yet
        assert span.get_tag(HOSTNAME_KEY) is None

        # Assert that retrieving the trace does not set the tag
        trace, _ = ctx.get()
        assert trace[0].get_tag(HOSTNAME_KEY) is None
        assert span.get_tag(HOSTNAME_KEY) is None
Esempio n. 34
0
def test_span_to_dict():
    s = Span(tracer=None, name="test.span", service="s", resource="r")
    s.span_type = "foo"
    s.set_tag("a", "1")
    s.set_meta("b", "2")
    s.finish()

    d = s.to_dict()
    assert d
    eq_(d["span_id"], s.span_id)
    eq_(d["trace_id"], s.trace_id)
    eq_(d["parent_id"], s.parent_id)
    eq_(d["meta"], {"a": "1", "b": "2"})
    eq_(d["type"], "foo")
    eq_(d["error"], 0)
    eq_(type(d["error"]), int)
Esempio n. 35
0
def test_finish():
    # ensure finish will record a span.
    dt = DummyTracer()
    assert dt.last_span is None
    s = Span(dt, "foo")
    assert s.duration is None
    sleep = 0.05
    with s as s1:
        assert s is s1
        time.sleep(sleep)
    assert s.duration >= sleep, "%s < %s" % (s.duration, sleep)
    eq_(s, dt.last_span)

    # ensure finish works with no tracer
    s2 = Span(tracer=None, name="foo")
    s2.finish()
Esempio n. 36
0
 def test_log_unfinished_spans_when_ok(self, log):
     # if the unfinished spans logging is enabled but the trace is finished, don't log anything
     tracer = get_dummy_tracer()
     tracer.debug_logging = True
     ctx = Context()
     # manually create a root-child trace
     root = Span(tracer=tracer, name='root')
     child = Span(tracer=tracer, name='child_1', trace_id=root.trace_id, parent_id=root.span_id)
     child._parent = root
     ctx.add_span(root)
     ctx.add_span(child)
     # close the trace
     child.finish()
     root.finish()
     # the logger has never been invoked to print unfinished spans
     for call, _ in log.call_args_list:
         msg = call[0]
         ok_('the trace has %d unfinished spans' not in msg)
Esempio n. 37
0
 def test_log_unfinished_spans_disabled(self, log):
     # the trace finished status logging is disabled
     tracer = get_dummy_tracer()
     tracer.debug_logging = False
     ctx = Context()
     # manually create a root-child trace
     root = Span(tracer=tracer, name='root')
     child_1 = Span(tracer=tracer, name='child_1', trace_id=root.trace_id, parent_id=root.span_id)
     child_2 = Span(tracer=tracer, name='child_2', trace_id=root.trace_id, parent_id=root.span_id)
     child_1._parent = root
     child_2._parent = root
     ctx.add_span(root)
     ctx.add_span(child_1)
     ctx.add_span(child_2)
     # close only the parent
     root.finish()
     ok_(ctx.is_finished() is False)
     # the logger has never been invoked to print unfinished spans
     for call, _ in log.call_args_list:
         msg = call[0]
         ok_('the trace has %d unfinished spans' not in msg)
Esempio n. 38
0
def test_finish_no_tracer():
    # ensure finish works with no tracer without raising exceptions
    s = Span(tracer=None, name="test.span")
    s.finish()