コード例 #1
0
    def test_ended_span(self):
        """"Events, attributes are not allowed after span is ended"""
        tracer = trace.Tracer("test_ended_span")

        other_context1 = trace_api.SpanContext(
            trace_id=trace.generate_trace_id(),
            span_id=trace.generate_span_id(),
        )

        with tracer.start_span("root") as root:
            # everything should be empty at the beginning
            self.assertEqual(len(root.attributes), 0)
            self.assertEqual(len(root.events), 0)
            self.assertEqual(len(root.links), 0)

            # call end first time
            root.end()
            end_time0 = root.end_time

            # call it a second time
            root.end()
            # end time shouldn't be changed
            self.assertEqual(end_time0, root.end_time)

            root.set_attribute("component", "http")
            self.assertEqual(len(root.attributes), 0)

            root.add_event("event1")
            self.assertEqual(len(root.events), 0)

            root.add_link(other_context1)
            self.assertEqual(len(root.links), 0)

            root.update_name("xxx")
            self.assertEqual(root.name, "root")
コード例 #2
0
    def test_start_as_current_span_explicit(self):
        tracer = trace.Tracer("test_start_as_current_span_explicit")

        other_parent = trace_api.SpanContext(
            trace_id=0x000000000000000000000000DEADBEEF,
            span_id=0x00000000DEADBEF0,
        )

        self.assertIsNone(tracer.get_current_span())

        # Test with the implicit root span
        with tracer.start_as_current_span("root") as root:
            self.assertIs(tracer.get_current_span(), root)

            self.assertIsNotNone(root.start_time)
            self.assertIsNone(root.end_time)

            with tracer.start_as_current_span("stepchild",
                                              other_parent) as child:
                # The child should become the current span as usual, but its
                # parent should be the one passed in, not the
                # previously-current span.
                self.assertIs(tracer.get_current_span(), child)
                self.assertNotEqual(child.parent, root)
                self.assertIs(child.parent, other_parent)

            # After exiting the child's scope the last span on the stack should
            # become current, not the child's parent.
            self.assertNotEqual(tracer.get_current_span(), other_parent)
            self.assertIs(tracer.get_current_span(), root)
            self.assertIsNotNone(child.end_time)
コード例 #3
0
    def test_shutdown(self):
        tracer = trace.Tracer()

        memory_exporter = InMemorySpanExporter()
        span_processor = export.SimpleExportSpanProcessor(memory_exporter)
        tracer.add_span_processor(span_processor)

        with tracer.start_span("foo"):
            with tracer.start_span("bar"):
                with tracer.start_span("xxx"):
                    pass

        span_list = memory_exporter.get_finished_spans()
        self.assertEqual(len(span_list), 3)

        memory_exporter.shutdown()

        # after shutdown no new spans are accepted
        with tracer.start_span("foo"):
            with tracer.start_span("bar"):
                with tracer.start_span("xxx"):
                    pass

        span_list = memory_exporter.get_finished_spans()
        self.assertEqual(len(span_list), 3)
コード例 #4
0
    def test_default_sampler(self):
        tracer = trace.Tracer()

        # Check that the default tracer creates real spans via the default
        # sampler
        root_span = tracer.start_span(name="root span", parent=None)
        self.assertIsInstance(root_span, trace.Span)
        child_span = tracer.start_span(name="child span", parent=root_span)
        self.assertIsInstance(child_span, trace.Span)
コード例 #5
0
    def test_sampler_no_sampling(self):
        tracer = trace.Tracer()
        tracer.sampler = sampling.ALWAYS_OFF

        # Check that the default tracer creates no-op spans if the sampler
        # decides not to sampler
        root_span = tracer.start_span(name="root span", parent=None)
        self.assertIsInstance(root_span, trace_api.DefaultSpan)
        child_span = tracer.start_span(name="child span", parent=root_span)
        self.assertIsInstance(child_span, trace_api.DefaultSpan)
コード例 #6
0
    def test_start_span_invalid_spancontext(self):
        """If an invalid span context is passed as the parent, the created
        span should use a new span id.

        Invalid span contexts should also not be added as a parent. This
        eliminates redundant error handling logic in exporters.
        """
        tracer = trace.Tracer("test_start_span_invalid_spancontext")
        new_span = tracer.start_span("root",
                                     parent=trace_api.INVALID_SPAN_CONTEXT)
        self.assertTrue(new_span.context.is_valid())
        self.assertIsNone(new_span.parent)
コード例 #7
0
    def test_get_finished_spans(self):
        tracer = trace.Tracer()

        memory_exporter = InMemorySpanExporter()
        span_processor = export.SimpleExportSpanProcessor(memory_exporter)
        tracer.add_span_processor(span_processor)

        with tracer.start_span("foo"):
            with tracer.start_span("bar"):
                with tracer.start_span("xxx"):
                    pass

        span_list = memory_exporter.get_finished_spans()
        spans_names_list = [span.name for span in span_list]
        self.assertListEqual(["xxx", "bar", "foo"], spans_names_list)
コード例 #8
0
    def test_clear(self):
        tracer = trace.Tracer()

        memory_exporter = InMemorySpanExporter()
        span_processor = export.SimpleExportSpanProcessor(memory_exporter)
        tracer.add_span_processor(span_processor)

        with tracer.start_span("foo"):
            with tracer.start_span("bar"):
                with tracer.start_span("xxx"):
                    pass

        memory_exporter.clear()
        span_list = memory_exporter.get_finished_spans()
        self.assertEqual(len(span_list), 0)
コード例 #9
0
    def test_simple_span_processor(self):
        tracer = trace.Tracer()

        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list)
        span_processor = export.SimpleExportSpanProcessor(my_exporter)
        tracer.add_span_processor(span_processor)

        with tracer.start_as_current_span("foo"):
            with tracer.start_as_current_span("bar"):
                with tracer.start_as_current_span("xxx"):
                    pass

        self.assertListEqual(["xxx", "bar", "foo"], spans_names_list)
コード例 #10
0
    def test_ended_span(self):
        """"Events, attributes are not allowed after span is ended"""
        tracer = trace.Tracer("test_ended_span")

        other_context1 = trace_api.SpanContext(
            trace_id=trace.generate_trace_id(),
            span_id=trace.generate_span_id(),
        )

        with tracer.start_as_current_span("root") as root:
            # everything should be empty at the beginning
            self.assertEqual(len(root.attributes), 0)
            self.assertEqual(len(root.events), 0)
            self.assertEqual(len(root.links), 0)

            # call end first time
            root.end()
            end_time0 = root.end_time

            # call it a second time
            root.end()
            # end time shouldn't be changed
            self.assertEqual(end_time0, root.end_time)

            root.set_attribute("component", "http")
            self.assertEqual(len(root.attributes), 0)

            root.add_event("event1")
            self.assertEqual(len(root.events), 0)

            root.add_link(other_context1)
            self.assertEqual(len(root.links), 0)

            root.update_name("xxx")
            self.assertEqual(root.name, "root")

            new_status = trace_api.status.Status(
                trace_api.status.StatusCanonicalCode.CANCELLED,
                "Test description",
            )
            root.set_status(new_status)
            # default status
            self.assertTrue(root.status.is_ok)
            self.assertEqual(
                root.status.canonical_code,
                trace_api.status.StatusCanonicalCode.OK,
            )
            self.assertIs(root.status.description, None)
コード例 #11
0
    def test_start_span_explicit(self):
        tracer = trace.Tracer("test_start_span_explicit")

        other_parent = trace_api.SpanContext(
            trace_id=0x000000000000000000000000DEADBEEF,
            span_id=0x00000000DEADBEF0,
        )

        self.assertIsNone(tracer.get_current_span())

        root = tracer.start_span("root")
        self.assertIsNotNone(root.start_time)
        self.assertIsNone(root.end_time)

        # Test with the implicit root span
        with tracer.use_span(root, True):
            self.assertIs(tracer.get_current_span(), root)

            with tracer.start_span("stepchild", other_parent) as child:
                # The child's parent should be the one passed in,
                # not the current span.
                self.assertNotEqual(child.parent, root)
                self.assertIs(child.parent, other_parent)

                self.assertIsNotNone(child.start_time)
                self.assertIsNone(child.end_time)

                # The child should inherit its context from the explicit
                # parent, not the current span.
                child_context = child.get_context()
                self.assertEqual(other_parent.trace_id, child_context.trace_id)
                self.assertNotEqual(
                    other_parent.span_id, child_context.span_id
                )
                self.assertEqual(
                    other_parent.trace_state, child_context.trace_state
                )
                self.assertEqual(
                    other_parent.trace_options, child_context.trace_options
                )

                # Verify start_span() did not set the current span.
                self.assertIs(tracer.get_current_span(), root)

            # Verify ending the child did not set the current span.
            self.assertIs(tracer.get_current_span(), root)
            self.assertIsNotNone(child.end_time)
コード例 #12
0
    def test_start_span_implicit(self):
        tracer = trace.Tracer("test_start_span_implicit")

        self.assertIsNone(tracer.get_current_span())

        root = tracer.start_span("root")
        self.assertIsNotNone(root.start_time)
        self.assertIsNone(root.end_time)
        self.assertEqual(root.kind, trace_api.SpanKind.INTERNAL)

        with tracer.use_span(root, True):
            self.assertIs(tracer.get_current_span(), root)

            with tracer.start_span(
                "child", kind=trace_api.SpanKind.CLIENT
            ) as child:
                self.assertIs(child.parent, root)
                self.assertEqual(child.kind, trace_api.SpanKind.CLIENT)

                self.assertIsNotNone(child.start_time)
                self.assertIsNone(child.end_time)

                # The new child span should inherit the parent's context but
                # get a new span ID.
                root_context = root.get_context()
                child_context = child.get_context()
                self.assertEqual(root_context.trace_id, child_context.trace_id)
                self.assertNotEqual(
                    root_context.span_id, child_context.span_id
                )
                self.assertEqual(
                    root_context.trace_state, child_context.trace_state
                )
                self.assertEqual(
                    root_context.trace_options, child_context.trace_options
                )

                # Verify start_span() did not set the current span.
                self.assertIs(tracer.get_current_span(), root)

            self.assertIsNotNone(child.end_time)

        self.assertIsNone(tracer.get_current_span())
        self.assertIsNotNone(root.end_time)
コード例 #13
0
    def test_start_as_current_span_implicit(self):
        tracer = trace.Tracer("test_start_as_current_span_implicit")

        self.assertIsNone(tracer.get_current_span())

        with tracer.start_as_current_span("root") as root:
            self.assertIs(tracer.get_current_span(), root)

            with tracer.start_as_current_span("child") as child:
                self.assertIs(tracer.get_current_span(), child)
                self.assertIs(child.parent, root)

            # After exiting the child's scope the parent should become the
            # current span again.
            self.assertIs(tracer.get_current_span(), root)
            self.assertIsNotNone(child.end_time)

        self.assertIsNone(tracer.get_current_span())
        self.assertIsNotNone(root.end_time)
コード例 #14
0
    def test_simple_span_processor_no_context(self):
        """Check that we process spans that are never made active.

        SpanProcessors should act on a span's start and end events whether or
        not it is ever the active span.
        """
        tracer = trace.Tracer()

        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list)
        span_processor = export.SimpleExportSpanProcessor(my_exporter)
        tracer.add_span_processor(span_processor)

        with tracer.start_span("foo"):
            with tracer.start_span("bar"):
                with tracer.start_span("xxx"):
                    pass

        self.assertListEqual(["xxx", "bar", "foo"], spans_names_list)
コード例 #15
0
    def test_start_span_implicit(self):
        tracer = trace.Tracer("test_start_span_implicit")

        self.assertIsNone(tracer.get_current_span())

        with tracer.start_span("root") as root:
            self.assertIs(tracer.get_current_span(), root)

            self.assertIsNotNone(root.start_time)
            self.assertIsNone(root.end_time)
            self.assertEqual(root.kind, trace_api.SpanKind.INTERNAL)

            with tracer.start_span("child",
                                   kind=trace_api.SpanKind.CLIENT) as child:
                self.assertIs(tracer.get_current_span(), child)
                self.assertIs(child.parent, root)
                self.assertEqual(child.kind, trace_api.SpanKind.CLIENT)

                self.assertIsNotNone(child.start_time)
                self.assertIsNone(child.end_time)

                # The new child span should inherit the parent's context but
                # get a new span ID.
                root_context = root.get_context()
                child_context = child.get_context()
                self.assertEqual(root_context.trace_id, child_context.trace_id)
                self.assertNotEqual(root_context.span_id,
                                    child_context.span_id)
                self.assertEqual(root_context.trace_state,
                                 child_context.trace_state)
                self.assertEqual(root_context.trace_options,
                                 child_context.trace_options)

            # After exiting the child's scope the parent should become the
            # current span again.
            self.assertIs(tracer.get_current_span(), root)
            self.assertIsNotNone(child.end_time)

        self.assertIsNone(tracer.get_current_span())
        self.assertIsNotNone(root.end_time)
コード例 #16
0
    def test_add_span_processor_after_span_creation(self):
        tracer = trace.Tracer()

        spans_calls_list = []  # filled by MySpanProcessor
        expected_list = []  # filled by hand

        # Span processors are created but not added to the tracer yet
        sp = MySpanProcessor("SP1", spans_calls_list)

        with tracer.start_as_current_span("foo"):
            with tracer.start_as_current_span("bar"):
                with tracer.start_as_current_span("baz"):
                    # add span processor after spans have been created
                    tracer.add_span_processor(sp)

                expected_list.append(span_event_end_fmt("SP1", "baz"))

            expected_list.append(span_event_end_fmt("SP1", "bar"))

        expected_list.append(span_event_end_fmt("SP1", "foo"))

        self.assertListEqual(spans_calls_list, expected_list)
コード例 #17
0
    def test_simple_span_processor(self):
        class MySpanExporter(export.SpanExporter):
            def __init__(self, destination):
                self.destination = destination

            def export(self, spans: trace.Span) -> export.SpanExportResult:
                self.destination.extend(span.name for span in spans)
                return export.SpanExportResult.SUCCESS

        tracer = trace.Tracer()

        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list)
        span_processor = export.SimpleExportSpanProcessor(my_exporter)
        tracer.add_span_processor(span_processor)

        with tracer.start_span("foo"):
            with tracer.start_span("bar"):
                with tracer.start_span("xxx"):
                    pass

        self.assertListEqual(["xxx", "bar", "foo"], spans_names_list)
コード例 #18
0
    def test_span_members(self):
        tracer = trace.Tracer("test_span_members")

        other_context1 = trace_api.SpanContext(
            trace_id=trace.generate_trace_id(),
            span_id=trace.generate_span_id(),
        )
        other_context2 = trace_api.SpanContext(
            trace_id=trace.generate_trace_id(),
            span_id=trace.generate_span_id(),
        )
        other_context3 = trace_api.SpanContext(
            trace_id=trace.generate_trace_id(),
            span_id=trace.generate_span_id(),
        )

        self.assertIsNone(tracer.get_current_span())

        with tracer.start_span("root") as root:
            # attributes
            root.set_attribute("component", "http")
            root.set_attribute("http.method", "GET")
            root.set_attribute("http.url",
                               "https://example.com:779/path/12/?q=d#123")
            root.set_attribute("http.status_code", 200)
            root.set_attribute("http.status_text", "OK")
            root.set_attribute("misc.pi", 3.14)

            # Setting an attribute with the same key as an existing attribute
            # SHOULD overwrite the existing attribute's value.
            root.set_attribute("attr-key", "attr-value1")
            root.set_attribute("attr-key", "attr-value2")

            self.assertEqual(len(root.attributes), 7)
            self.assertEqual(root.attributes["component"], "http")
            self.assertEqual(root.attributes["http.method"], "GET")
            self.assertEqual(
                root.attributes["http.url"],
                "https://example.com:779/path/12/?q=d#123",
            )
            self.assertEqual(root.attributes["http.status_code"], 200)
            self.assertEqual(root.attributes["http.status_text"], "OK")
            self.assertEqual(root.attributes["misc.pi"], 3.14)
            self.assertEqual(root.attributes["attr-key"], "attr-value2")

            # events
            root.add_event("event0")
            root.add_event("event1", {"name": "birthday"})
            now = util.time_ns()
            root.add_lazy_event(
                trace_api.Event("event2", now, {"name": "hello"}))

            self.assertEqual(len(root.events), 3)

            self.assertEqual(root.events[0].name, "event0")
            self.assertEqual(root.events[0].attributes, {})

            self.assertEqual(root.events[1].name, "event1")
            self.assertEqual(root.events[1].attributes, {"name": "birthday"})

            self.assertEqual(root.events[2].name, "event2")
            self.assertEqual(root.events[2].attributes, {"name": "hello"})
            self.assertEqual(root.events[2].timestamp, now)

            # links
            root.add_link(other_context1)
            root.add_link(other_context2, {"name": "neighbor"})
            root.add_lazy_link(
                trace_api.Link(other_context3, {"component": "http"}))

            self.assertEqual(len(root.links), 3)
            self.assertEqual(root.links[0].context.trace_id,
                             other_context1.trace_id)
            self.assertEqual(root.links[0].context.span_id,
                             other_context1.span_id)
            self.assertEqual(root.links[0].attributes, {})
            self.assertEqual(root.links[1].context.trace_id,
                             other_context2.trace_id)
            self.assertEqual(root.links[1].context.span_id,
                             other_context2.span_id)
            self.assertEqual(root.links[1].attributes, {"name": "neighbor"})
            self.assertEqual(root.links[2].context.span_id,
                             other_context3.span_id)
            self.assertEqual(root.links[2].attributes, {"component": "http"})

            # name
            root.update_name("toor")
            self.assertEqual(root.name, "toor")
コード例 #19
0
    def test_span_members(self):
        tracer = trace.Tracer("test_span_members")

        other_context1 = trace_api.SpanContext(
            trace_id=trace.generate_trace_id(),
            span_id=trace.generate_span_id(),
        )
        other_context2 = trace_api.SpanContext(
            trace_id=trace.generate_trace_id(),
            span_id=trace.generate_span_id(),
        )

        self.assertIsNone(tracer.get_current_span())

        with tracer.start_span("root") as root:
            root.set_attribute("component", "http")
            root.set_attribute("http.method", "GET")
            root.set_attribute("http.url",
                               "https://example.com:779/path/12/?q=d#123")
            root.set_attribute("http.status_code", 200)
            root.set_attribute("http.status_text", "OK")
            root.set_attribute("misc.pi", 3.14)

            # Setting an attribute with the same key as an existing attribute
            # SHOULD overwrite the existing attribute's value.
            root.set_attribute("attr-key", "attr-value1")
            root.set_attribute("attr-key", "attr-value2")

            root.add_event("event0")
            root.add_event("event1", {"name": "birthday"})

            root.add_link(other_context1)
            root.add_link(other_context2, {"name": "neighbor"})

            root.update_name("toor")
            self.assertEqual(root.name, "toor")

            # The public API does not expose getters.
            # Checks by accessing the span members directly

            self.assertEqual(len(root.attributes), 7)
            self.assertEqual(root.attributes["component"], "http")
            self.assertEqual(root.attributes["http.method"], "GET")
            self.assertEqual(
                root.attributes["http.url"],
                "https://example.com:779/path/12/?q=d#123",
            )
            self.assertEqual(root.attributes["http.status_code"], 200)
            self.assertEqual(root.attributes["http.status_text"], "OK")
            self.assertEqual(root.attributes["misc.pi"], 3.14)
            self.assertEqual(root.attributes["attr-key"], "attr-value2")

            self.assertEqual(len(root.events), 2)
            self.assertEqual(root.events[0],
                             trace.Event(name="event0", attributes={}))
            self.assertEqual(
                root.events[1],
                trace.Event(name="event1", attributes={"name": "birthday"}),
            )

            self.assertEqual(len(root.links), 2)
            self.assertEqual(root.links[0].context.trace_id,
                             other_context1.trace_id)
            self.assertEqual(root.links[0].context.span_id,
                             other_context1.span_id)
            self.assertEqual(root.links[0].attributes, {})
            self.assertEqual(root.links[1].context.trace_id,
                             other_context2.trace_id)
            self.assertEqual(root.links[1].context.span_id,
                             other_context2.span_id)
            self.assertEqual(root.links[1].attributes, {"name": "neighbor"})
コード例 #20
0
    def test_span_processor(self):
        tracer = trace.Tracer()

        spans_calls_list = []  # filled by MySpanProcessor
        expected_list = []  # filled by hand

        # Span processors are created but not added to the tracer yet
        sp1 = MySpanProcessor("SP1", spans_calls_list)
        sp2 = MySpanProcessor("SP2", spans_calls_list)

        with tracer.start_as_current_span("foo"):
            with tracer.start_as_current_span("bar"):
                with tracer.start_as_current_span("baz"):
                    pass

        # at this point lists must be empty
        self.assertEqual(len(spans_calls_list), 0)

        # add single span processor
        tracer.add_span_processor(sp1)

        with tracer.start_as_current_span("foo"):
            expected_list.append(span_event_start_fmt("SP1", "foo"))

            with tracer.start_as_current_span("bar"):
                expected_list.append(span_event_start_fmt("SP1", "bar"))

                with tracer.start_as_current_span("baz"):
                    expected_list.append(span_event_start_fmt("SP1", "baz"))

                expected_list.append(span_event_end_fmt("SP1", "baz"))

            expected_list.append(span_event_end_fmt("SP1", "bar"))

        expected_list.append(span_event_end_fmt("SP1", "foo"))

        self.assertListEqual(spans_calls_list, expected_list)

        spans_calls_list.clear()
        expected_list.clear()

        # go for multiple span processors
        tracer.add_span_processor(sp2)

        with tracer.start_as_current_span("foo"):
            expected_list.append(span_event_start_fmt("SP1", "foo"))
            expected_list.append(span_event_start_fmt("SP2", "foo"))

            with tracer.start_as_current_span("bar"):
                expected_list.append(span_event_start_fmt("SP1", "bar"))
                expected_list.append(span_event_start_fmt("SP2", "bar"))

                with tracer.start_as_current_span("baz"):
                    expected_list.append(span_event_start_fmt("SP1", "baz"))
                    expected_list.append(span_event_start_fmt("SP2", "baz"))

                expected_list.append(span_event_end_fmt("SP1", "baz"))
                expected_list.append(span_event_end_fmt("SP2", "baz"))

            expected_list.append(span_event_end_fmt("SP1", "bar"))
            expected_list.append(span_event_end_fmt("SP2", "bar"))

        expected_list.append(span_event_end_fmt("SP1", "foo"))
        expected_list.append(span_event_end_fmt("SP2", "foo"))

        # compare if two lists are the same
        self.assertListEqual(spans_calls_list, expected_list)
コード例 #21
0
    def test_shutdown(self):
        tracer = trace.Tracer()

        mock_processor1 = mock.Mock(spec=trace.SpanProcessor)
        tracer.add_span_processor(mock_processor1)

        mock_processor2 = mock.Mock(spec=trace.SpanProcessor)
        tracer.add_span_processor(mock_processor2)

        tracer.shutdown()

        self.assertEqual(mock_processor1.shutdown.call_count, 1)
        self.assertEqual(mock_processor2.shutdown.call_count, 1)

        shutdown_python_code = """
import atexit
from unittest import mock

from opentelemetry.sdk import trace

mock_processor = mock.Mock(spec=trace.SpanProcessor)

def print_shutdown_count():
    print(mock_processor.shutdown.call_count)

# atexit hooks are called in inverse order they are added, so do this before
# creating the tracer
atexit.register(print_shutdown_count)

tracer = trace.Tracer({tracer_parameters})
tracer.add_span_processor(mock_processor)

{tracer_shutdown}
"""

        def run_general_code(shutdown_on_exit, explicit_shutdown):
            tracer_parameters = ""
            tracer_shutdown = ""

            if not shutdown_on_exit:
                tracer_parameters = "shutdown_on_exit=False"

            if explicit_shutdown:
                tracer_shutdown = "tracer.shutdown()"

            return subprocess.check_output([
                # use shutil to avoid calling python outside the
                # virtualenv on windows.
                shutil.which("python"),
                "-c",
                shutdown_python_code.format(
                    tracer_parameters=tracer_parameters,
                    tracer_shutdown=tracer_shutdown,
                ),
            ])

        # test default shutdown_on_exit (True)
        out = run_general_code(True, False)
        self.assertTrue(out.startswith(b"1"))

        # test that shutdown is called only once even if Tracer.shutdown is
        # called explicitely
        out = run_general_code(True, True)
        self.assertTrue(out.startswith(b"1"))

        # test shutdown_on_exit=False
        out = run_general_code(False, False)
        self.assertTrue(out.startswith(b"0"))
コード例 #22
0
 def setUp(self):
     self.tracer = trace.Tracer("test_span")
コード例 #23
0
 def test_extends_api(self):
     tracer = trace.Tracer()
     self.assertIsInstance(tracer, trace_api.Tracer)