def test_constructor_default(self):
        """Test the default values assigned by constructor."""
        exporter = datadog.DatadogSpanExporter()

        self.assertEqual(exporter.agent_url, "http://localhost:8126")
        self.assertIsNone(exporter.service)
        self.assertIsNotNone(exporter.agent_writer)
    def test_sampling_rate(self):
        context = trace_api.SpanContext(
            trace_id=0x000000000000000000000000DEADBEEF,
            span_id=0x34BF92DEEFC58C92,
            is_remote=False,
            trace_flags=trace_api.TraceFlags(trace_api.TraceFlags.SAMPLED),
        )
        sampler = sampling.TraceIdRatioBased(0.5)

        span = trace.Span(name="sampled",
                          context=context,
                          parent=None,
                          sampler=sampler)
        span.start()
        span.end()

        # pylint: disable=protected-access
        exporter = datadog.DatadogSpanExporter()
        datadog_spans = [
            span.to_dict() for span in exporter._translate_to_datadog([span])
        ]

        self.assertEqual(len(datadog_spans), 1)

        actual = [
            span["metrics"].get(datadog.constants.SAMPLE_RATE_METRIC_KEY)
            if "metrics" in span else None for span in datadog_spans
        ]
        expected = [0.5]
        self.assertListEqual(actual, expected)
    def test_origin(self):
        context = trace_api.SpanContext(
            trace_id=0x000000000000000000000000DEADBEEF,
            span_id=trace_api.INVALID_SPAN,
            is_remote=True,
            trace_state=trace_api.TraceState(
                {datadog.constants.DD_ORIGIN: "origin-service"}),
        )

        root_span = trace.Span(name="root", context=context, parent=None)
        child_span = trace.Span(name="child",
                                context=context,
                                parent=root_span)
        root_span.start()
        child_span.start()
        child_span.end()
        root_span.end()

        # pylint: disable=protected-access
        exporter = datadog.DatadogSpanExporter()
        datadog_spans = [
            span.to_dict()
            for span in exporter._translate_to_datadog([root_span, child_span])
        ]

        self.assertEqual(len(datadog_spans), 2)

        actual = [
            span["meta"].get(datadog.constants.DD_ORIGIN)
            if "meta" in span else None for span in datadog_spans
        ]
        expected = ["origin-service", None]
        self.assertListEqual(actual, expected)
    def test_service_name_fallback(self):
        context = trace_api.SpanContext(
            trace_id=0x000000000000000000000000DEADBEEF,
            span_id=0x34BF92DEEFC58C92,
            is_remote=False,
            trace_flags=trace_api.TraceFlags(trace_api.TraceFlags.SAMPLED),
        )
        trace_api.get_tracer_provider().sampler = sampling.TraceIdRatioBased(
            0.5)

        resource_with_default_name = Resource(
            attributes={
                "key_resource": "some_resource",
                "service.name": "unknown_service",
            })

        span = trace._Span(
            name="sampled",
            context=context,
            parent=None,
            resource=resource_with_default_name,
        )
        span.start()
        span.end()

        # pylint: disable=protected-access
        exporter = datadog.DatadogSpanExporter(service="fallback_service_name")
        datadog_spans = [
            span.to_dict() for span in exporter._translate_to_datadog([span])
        ]

        self.assertEqual(len(datadog_spans), 1)

        span = datadog_spans[0]
        self.assertEqual(span["service"], "fallback_service_name")
    def test_constructor_environ(self):
        exporter = datadog.DatadogSpanExporter()

        self.assertEqual(exporter.agent_url, "http://agent:8126")
        self.assertEqual(exporter.service, "test-service")
        self.assertEqual(exporter.env, "test")
        self.assertEqual(exporter.version, "0.0.1")
        self.assertEqual(exporter.tags, {"team": "testers"})
        self.assertIsNotNone(exporter.agent_writer)
    def test_constructor_explicit(self):
        """Test the constructor passing all the options."""
        agent_url = "http://localhost:8126"
        exporter = datadog.DatadogSpanExporter(
            agent_url=agent_url,
            service="explicit",
        )

        self.assertEqual(exporter.agent_url, agent_url)
        self.assertEqual(exporter.service, "explicit")
        self.assertIsNone(exporter.env)
        self.assertIsNone(exporter.version)
        self.assertEqual(exporter.tags, {})

        exporter = datadog.DatadogSpanExporter(
            agent_url=agent_url,
            service="explicit",
            env="test",
            version="0.0.1",
            tags="",
        )

        self.assertEqual(exporter.agent_url, agent_url)
        self.assertEqual(exporter.service, "explicit")
        self.assertEqual(exporter.env, "test")
        self.assertEqual(exporter.version, "0.0.1")
        self.assertEqual(exporter.tags, {})

        exporter = datadog.DatadogSpanExporter(
            agent_url=agent_url,
            service="explicit",
            env="test",
            version="0.0.1",
            tags="team:testers,layer:app",
        )

        self.assertEqual(exporter.agent_url, agent_url)
        self.assertEqual(exporter.service, "explicit")
        self.assertEqual(exporter.env, "test")
        self.assertEqual(exporter.version, "0.0.1")
        self.assertEqual(exporter.tags, {"team": "testers", "layer": "app"})
    def test_translate_to_datadog(self):
        # pylint: disable=invalid-name
        self.maxDiff = None

        span_names = ("test1", "test2", "test3")
        trace_id = 0x6E0C63257DE34C926F9EFCD03927272E
        trace_id_low = 0x6F9EFCD03927272E
        span_id = 0x34BF92DEEFC58C92
        parent_id = 0x1111111111111111
        other_id = 0x2222222222222222

        base_time = 683647322 * 10**9  # in ns
        start_times = (
            base_time,
            base_time + 150 * 10**6,
            base_time + 300 * 10**6,
        )
        durations = (50 * 10**6, 100 * 10**6, 200 * 10**6)
        end_times = (
            start_times[0] + durations[0],
            start_times[1] + durations[1],
            start_times[2] + durations[2],
        )

        span_context = trace_api.SpanContext(trace_id,
                                             span_id,
                                             is_remote=False)
        parent_context = trace_api.SpanContext(trace_id,
                                               parent_id,
                                               is_remote=False)
        other_context = trace_api.SpanContext(trace_id,
                                              other_id,
                                              is_remote=False)

        instrumentation_info = InstrumentationInfo(__name__, "0")

        otel_spans = [
            trace.Span(
                name=span_names[0],
                context=span_context,
                parent=parent_context,
                kind=trace_api.SpanKind.CLIENT,
                instrumentation_info=instrumentation_info,
            ),
            trace.Span(
                name=span_names[1],
                context=parent_context,
                parent=None,
                instrumentation_info=instrumentation_info,
            ),
            trace.Span(
                name=span_names[2],
                context=other_context,
                parent=None,
            ),
        ]

        otel_spans[0].start(start_time=start_times[0])
        otel_spans[0].end(end_time=end_times[0])

        otel_spans[1].start(start_time=start_times[1])
        otel_spans[1].end(end_time=end_times[1])

        otel_spans[2].start(start_time=start_times[2])
        otel_spans[2].end(end_time=end_times[2])

        # pylint: disable=protected-access
        exporter = datadog.DatadogSpanExporter()
        datadog_spans = [
            span.to_dict()
            for span in exporter._translate_to_datadog(otel_spans)
        ]

        expected_spans = [
            dict(
                trace_id=trace_id_low,
                parent_id=parent_id,
                span_id=span_id,
                name="tests.test_datadog_exporter.CLIENT",
                resource=span_names[0],
                start=start_times[0],
                duration=durations[0],
                error=0,
                service="test-service",
                meta={
                    "env": "test",
                    "team": "testers"
                },
            ),
            dict(
                trace_id=trace_id_low,
                parent_id=0,
                span_id=parent_id,
                name="tests.test_datadog_exporter.INTERNAL",
                resource=span_names[1],
                start=start_times[1],
                duration=durations[1],
                error=0,
                service="test-service",
                meta={
                    "env": "test",
                    "team": "testers",
                    "version": "0.0.1"
                },
            ),
            dict(
                trace_id=trace_id_low,
                parent_id=0,
                span_id=other_id,
                name=span_names[2],
                resource=span_names[2],
                start=start_times[2],
                duration=durations[2],
                error=0,
                service="test-service",
                meta={
                    "env": "test",
                    "team": "testers",
                    "version": "0.0.1"
                },
            ),
        ]

        self.assertEqual(datadog_spans, expected_spans)