Exemple #1
0
    def setUp(self):
        tracer_provider = TracerProvider()
        self.exporter = OTLPSpanExporter()
        tracer_provider.add_span_processor(
            SimpleExportSpanProcessor(self.exporter)
        )
        self.tracer = tracer_provider.get_tracer(__name__)

        self.server = server(ThreadPoolExecutor(max_workers=10))

        self.server.add_insecure_port("[::]:55680")

        self.server.start()

        event_mock = Mock(
            **{
                "timestamp": 1591240820506462784,
                "attributes": OrderedDict([("a", 1), ("b", False)]),
            }
        )

        type(event_mock).name = PropertyMock(return_value="a")

        self.span = Span(
            "a",
            context=Mock(
                **{
                    "trace_state": OrderedDict([("a", "b"), ("c", "d")]),
                    "span_id": 10217189687419569865,
                    "trace_id": 67545097771067222548457157018666467027,
                }
            ),
            resource=SDKResource(OrderedDict([("a", 1), ("b", False)])),
            parent=Mock(**{"span_id": 12345}),
            attributes=OrderedDict([("a", 1), ("b", True)]),
            events=[event_mock],
            links=[
                Mock(
                    **{
                        "context.trace_id": 1,
                        "context.span_id": 2,
                        "attributes": OrderedDict([("a", 1), ("b", False)]),
                        "kind": SpanKind.INTERNAL,
                    }
                )
            ],
            instrumentation_info=InstrumentationInfo(
                name="name", version="version"
            ),
        )

        self.span.start()
        self.span.end()
    def _translate_span(self, span: Span) -> model_pb2.Span:

        ctx = span.get_span_context()
        # pb2 span expects in byte format
        trace_id = _trace_id_to_bytes(ctx.trace_id)
        span_id = _span_id_to_bytes(ctx.span_id)

        start_time = _proto_timestamp_from_epoch_nanos(span.start_time)
        end_time = _proto_timestamp_from_epoch_nanos(span.end_time)
        duration = _duration_from_two_time_stamps(start_time, end_time)

        tags = self._extract_tags(span)
        refs = self._extract_refs(span)
        logs = self._extract_logs(span)

        flags = int(ctx.trace_flags)

        process = model_pb2.Process(service_name=self.svc_name,
                                    tags=_extract_resource_tags(span))
        jaeger_span = model_pb2.Span(
            trace_id=trace_id,
            span_id=span_id,
            operation_name=span.name,
            references=refs,
            flags=flags,
            start_time=start_time,
            duration=duration,
            tags=tags,
            logs=logs,
            process=process,
        )
        return jaeger_span
    def _translate_span(self, span: Span) -> TCollector.Span:
        ctx = span.get_span_context()
        trace_id = ctx.trace_id
        span_id = ctx.span_id

        start_time_us = _nsec_to_usec_round(span.start_time)
        duration_us = _nsec_to_usec_round(span.end_time - span.start_time)

        parent_id = span.parent.span_id if span.parent else 0

        tags = self._extract_tags(span)
        refs = self._extract_refs(span)
        logs = self._extract_logs(span)

        flags = int(ctx.trace_flags)

        jaeger_span = TCollector.Span(
            traceIdHigh=_get_trace_id_high(trace_id),
            traceIdLow=_get_trace_id_low(trace_id),
            spanId=_convert_int_to_i64(span_id),
            operationName=span.name,
            startTime=start_time_us,
            duration=duration_us,
            tags=tags,
            logs=logs,
            references=refs,
            flags=flags,
            parentSpanId=_convert_int_to_i64(parent_id),
        )
        return jaeger_span
Exemple #4
0
def single_line_json(span: Span) -> str:
    """Format tracing spans as single-line JSON.

    By default, the ConsoleSpanExporter spits out verbose JSON across multiple lines.
    I'd like to be able to slurp these spans up into some kind of data store so that I
    can poke at them, and the easiest way to do that is to have one span per line.
    """
    json = span.to_json(indent=None)
    assert isinstance(json, str)
    return json + os.linesep
    def on_end(self, span: Span) -> None:
        if self.done:
            logger.warning("Already shutdown, dropping span.")
            return

        ctx = span.get_span_context()
        trace_id = ctx.trace_id

        with self.traces_lock:
            self.traces_spans_ended_count[trace_id] += 1
            if self.is_trace_exportable(trace_id):
                self.check_traces_queue.appendleft(trace_id)
 def test_ok_request(self):
     """Test the functionality when Server Span is ended."""
     span_processor = AzureMetricsSpanProcessor()
     test_span = Span(
         name="test",
         kind=SpanKind.SERVER,
         context=SpanContext(
             trace_id=36873507687745823477771305566750195431,
             span_id=12030755672171557338,
             is_remote=False,
         ),
     )
     test_span._start_time = 5000000
     test_span._end_time = 15000000
     span_processor.on_end(test_span)
     self.assertEqual(span_processor.dependency_count, 0)
     self.assertEqual(span_processor.dependency_duration, 0)
     self.assertEqual(span_processor.failed_dependency_count, 0)
     self.assertEqual(span_processor.request_count, 1)
     self.assertEqual(span_processor.request_duration, 10)
     self.assertEqual(span_processor.failed_request_count, 0)
Exemple #7
0
    def on_start(self, span: Span) -> None:
        ctx = span.get_context()
        trace_id = ctx.trace_id

        with self.traces_lock:
            # check upper bound on number of spans for trace before adding new
            # span
            if self.traces_spans_count[trace_id] == self.max_trace_size:
                logger.warning("Max spans for trace, spans will be dropped.")
                self._spans_dropped = True
                return

            # add span to end of list for a trace and update the counter
            self.traces[trace_id].append(span)
            self.traces_spans_count[trace_id] += 1
    def test_export(self):
        trace_id = "6e0c63257de34c92bf9efcd03927272e"
        span_id = "95bb5edabd45950f"
        span_datas = [
            Span(
                name="span_name",
                context=SpanContext(
                    trace_id=int(trace_id, 16),
                    span_id=int(span_id, 16),
                    is_remote=False,
                ),
                parent=None,
                kind=SpanKind.INTERNAL,
            )
        ]

        cloud_trace_spans = {
            "name":
            "projects/{}/traces/{}/spans/{}".format(self.project_id, trace_id,
                                                    span_id),
            "span_id":
            span_id,
            "parent_span_id":
            None,
            "display_name":
            TruncatableString(value="span_name", truncated_byte_count=0),
            "attributes":
            ProtoSpan.Attributes(attribute_map={}),
            "links":
            None,
            "status":
            None,
            "time_events":
            None,
            "start_time":
            None,
            "end_time":
            None,
        }

        client = mock.Mock()

        exporter = CloudTraceSpanExporter(self.project_id, client=client)

        exporter.export(span_datas)

        client.create_span.assert_called_with(**cloud_trace_spans)
        self.assertTrue(client.create_span.called)
Exemple #9
0
def _encode_span(sdk_span: SDKSpan) -> PB2SPan:
    span_context = sdk_span.get_span_context()
    return PB2SPan(
        trace_id=_encode_trace_id(span_context.trace_id),
        span_id=_encode_span_id(span_context.span_id),
        trace_state=_encode_trace_state(span_context.trace_state),
        parent_span_id=_encode_parent_id(sdk_span.parent),
        name=sdk_span.name,
        kind=_SPAN_KIND_MAP[sdk_span.kind],
        start_time_unix_nano=sdk_span.start_time,
        end_time_unix_nano=sdk_span.end_time,
        attributes=_encode_attributes(sdk_span.attributes),
        events=_encode_events(sdk_span.events),
        links=_encode_links(sdk_span.links),
        status=_encode_status(sdk_span.status),
    )
Exemple #10
0
    def test_export(self):
        trace_id = "6e0c63257de34c92bf9efcd03927272e"
        span_id = "95bb5edabd45950f"

        # Create span and associated data.
        resource_info = Resource({
            "cloud.account.id": 123,
            "host.id": "host",
            "cloud.zone": "US",
            "cloud.provider": "gcp",
            "gcp.resource_type": "gce_instance",
        })
        span = Span(
            name="span_name",
            context=SpanContext(
                trace_id=int(trace_id, 16),
                span_id=int(span_id, 16),
                is_remote=False,
            ),
            parent=None,
            kind=SpanKind.INTERNAL,
            resource=resource_info,
            attributes={"attr_key": "attr_value"},
        )

        # pylint: disable=protected-access
        span._start_time = int(time_ns() - (60 * 1e9))
        span._end_time = time_ns()
        span_data = [span]

        # Setup the trace exporter.
        channel = grpc.insecure_channel(self.address)
        transport = trace_service_grpc_transport.TraceServiceGrpcTransport(
            channel=channel)
        client = TraceServiceClient(transport=transport)
        trace_exporter = CloudTraceSpanExporter(self.project_id, client=client)

        # Export the spans and verify the results.
        result = trace_exporter.export(span_data)
        self.assertEqual(result, SpanExportResult.SUCCESS)
 def test_export_not_retryable(self):
     exporter = self._exporter
     test_span = Span(
         name="test",
         context=SpanContext(
             trace_id=36873507687745823477771305566750195431,
             span_id=12030755672171557338,
             is_remote=False,
         ),
     )
     test_span.start()
     test_span.end()
     with mock.patch(
             "azure_monitor.export.trace.AzureMonitorSpanExporter._transmit"
     ) as transmit:  # noqa: E501
         transmit.return_value = ExportResult.FAILED_NOT_RETRYABLE
         result = exporter.export([test_span])
         self.assertEqual(result, SpanExportResult.FAILED_NOT_RETRYABLE)
 def test_export_exception(self, logger_mock):
     test_span = Span(
         name="test",
         context=SpanContext(
             trace_id=36873507687745823477771305566750195431,
             span_id=12030755672171557338,
             is_remote=False,
         ),
     )
     test_span.start()
     test_span.end()
     exporter = self._exporter
     with mock.patch(
             "azure_monitor.export.trace.AzureMonitorSpanExporter._transmit",
             throw(Exception),
     ):  # noqa: E501
         result = exporter.export([test_span])
         self.assertEqual(result, SpanExportResult.FAILED_NOT_RETRYABLE)
         self.assertEqual(logger_mock.exception.called, True)
 def test_export_failure(self):
     exporter = self._exporter
     with mock.patch(
             "azure_monitor.export.trace.AzureMonitorSpanExporter._transmit"
     ) as transmit:  # noqa: E501
         test_span = Span(
             name="test",
             context=SpanContext(
                 trace_id=36873507687745823477771305566750195431,
                 span_id=12030755672171557338,
                 is_remote=False,
             ),
         )
         test_span.start()
         test_span.end()
         transmit.return_value = ExportResult.FAILED_RETRYABLE
         exporter.export([test_span])
     self.assertEqual(len(os.listdir(exporter.storage.path)), 1)
     self.assertIsNone(exporter.storage.get())
 def test_export_failure(self, span_to_envelope_mock):
     span_to_envelope_mock.return_value = ["bar"]
     exporter = AzureMonitorSpanExporter(
         storage_path=os.path.join(TEST_FOLDER, self.id()))
     with mock.patch(
             "azure_monitor.trace.AzureMonitorSpanExporter._transmit"
     ) as transmit:  # noqa: E501
         test_span = Span(
             name="test",
             context=SpanContext(
                 trace_id=36873507687745823477771305566750195431,
                 span_id=12030755672171557338,
             ),
         )
         test_span.start()
         test_span.end()
         transmit.return_value = ExportResult.FAILED_RETRYABLE
         exporter.export([test_span])
     self.assertEqual(len(os.listdir(exporter.storage.path)), 1)
     self.assertIsNone(exporter.storage.get())
 def test_export_success(self):
     exporter = self._exporter
     test_span = Span(
         name="test",
         context=SpanContext(
             trace_id=36873507687745823477771305566750195431,
             span_id=12030755672171557338,
             is_remote=False,
         ),
     )
     test_span.start()
     test_span.end()
     with mock.patch(
             "azure_monitor.export.trace.AzureMonitorSpanExporter._transmit"
     ) as transmit:  # noqa: E501
         transmit.return_value = ExportResult.SUCCESS
         storage_mock = mock.Mock()
         exporter._transmit_from_storage = storage_mock
         exporter.export([test_span])
         self.assertEqual(storage_mock.call_count, 1)
         self.assertEqual(len(os.listdir(exporter.storage.path)), 0)
 def test_document_collection(self):
     """Test the document collection."""
     span_processor = AzureMetricsSpanProcessor()
     span_processor.is_collecting_documents = True
     test_span = Span(
         name="test",
         kind=SpanKind.SERVER,
         context=SpanContext(
             trace_id=36873507687745823477771305566750195431,
             span_id=12030755672171557338,
             is_remote=False,
         ),
     )
     test_span.set_status(Status(StatusCanonicalCode.INTERNAL, "test"))
     test_span._start_time = 5000000
     test_span._end_time = 15000000
     span_processor.on_end(test_span)
     document = span_processor.documents.pop()
     self.assertIsNotNone(document)
     self.assertEqual(document.name,
                      "Microsoft.ApplicationInsights.Request")
 def test_failed_dependency(self):
     """Test the functionality when Client Span is ended."""
     span_processor = AzureMetricsSpanProcessor()
     test_span = Span(
         name="test",
         kind=SpanKind.CLIENT,
         context=SpanContext(
             trace_id=36873507687745823477771305566750195431,
             span_id=12030755672171557338,
             is_remote=False,
         ),
     )
     test_span.set_status(Status(StatusCanonicalCode.INTERNAL, "test"))
     test_span._start_time = 5000000
     test_span._end_time = 15000000
     span_processor.on_end(test_span)
     self.assertEqual(span_processor.request_count, 0)
     self.assertEqual(span_processor.request_duration, 0)
     self.assertEqual(span_processor.failed_request_count, 0)
     self.assertEqual(span_processor.dependency_count, 1)
     self.assertEqual(span_processor.dependency_duration, 10)
     self.assertEqual(span_processor.failed_dependency_count, 1)
class TestOTLPSpanExporter(TestCase):
    def setUp(self):
        tracer_provider = TracerProvider()
        self.exporter = OTLPSpanExporter()
        tracer_provider.add_span_processor(
            SimpleExportSpanProcessor(self.exporter)
        )
        self.tracer = tracer_provider.get_tracer(__name__)

        self.server = server(ThreadPoolExecutor(max_workers=10))

        self.server.add_insecure_port("[::]:55678")

        self.server.start()

        event_mock = Mock(
            **{
                "timestamp": 1591240820506462784,
                "attributes": OrderedDict([("a", 1), ("b", False)]),
            }
        )

        type(event_mock).name = PropertyMock(return_value="a")

        self.span = Span(
            "a",
            context=Mock(
                **{
                    "trace_state": OrderedDict([("a", "b"), ("c", "d")]),
                    "span_id": 10217189687419569865,
                    "trace_id": 67545097771067222548457157018666467027,
                }
            ),
            resource=SDKResource(OrderedDict([("a", 1), ("b", False)])),
            parent=Mock(**{"span_id": 12345}),
            attributes=OrderedDict([("a", 1), ("b", True)]),
            events=[event_mock],
            links=[
                Mock(
                    **{
                        "context.trace_id": 1,
                        "context.span_id": 2,
                        "attributes": OrderedDict([("a", 1), ("b", False)]),
                        "kind": SpanKind.INTERNAL,
                    }
                )
            ],
        )

        self.span.start()
        self.span.end()

    def tearDown(self):
        self.server.stop(None)

    @patch("opentelemetry.ext.otlp.trace_exporter.expo")
    @patch("opentelemetry.ext.otlp.trace_exporter.sleep")
    def test_unavailable(self, mock_sleep, mock_expo):

        mock_expo.configure_mock(**{"return_value": [1]})

        add_TraceServiceServicer_to_server(
            TraceServiceServicerUNAVAILABLE(), self.server
        )
        self.assertEqual(
            self.exporter.export([self.span]), SpanExportResult.FAILURE
        )
        mock_sleep.assert_called_with(1)

    @patch("opentelemetry.ext.otlp.trace_exporter.expo")
    @patch("opentelemetry.ext.otlp.trace_exporter.sleep")
    def test_unavailable_delay(self, mock_sleep, mock_expo):

        mock_expo.configure_mock(**{"return_value": [1]})

        add_TraceServiceServicer_to_server(
            TraceServiceServicerUNAVAILABLEDelay(), self.server
        )
        self.assertEqual(
            self.exporter.export([self.span]), SpanExportResult.FAILURE
        )
        mock_sleep.assert_called_with(4)

    def test_success(self):
        add_TraceServiceServicer_to_server(
            TraceServiceServicerSUCCESS(), self.server
        )
        self.assertEqual(
            self.exporter.export([self.span]), SpanExportResult.SUCCESS
        )

    def test_translate_spans(self):

        expected = ExportTraceServiceRequest(
            resource_spans=[
                ResourceSpans(
                    resource=CollectorResource(
                        attributes=[
                            AttributeKeyValue(key="a", int_value=1),
                            AttributeKeyValue(key="b", bool_value=False),
                        ]
                    ),
                    instrumentation_library_spans=[
                        InstrumentationLibrarySpans(
                            spans=[
                                CollectorSpan(
                                    # pylint: disable=no-member
                                    name="a",
                                    start_time_unix_nano=self.span.start_time,
                                    end_time_unix_nano=self.span.end_time,
                                    trace_state="a=b,c=d",
                                    span_id=int.to_bytes(
                                        10217189687419569865, 8, "big"
                                    ),
                                    trace_id=int.to_bytes(
                                        67545097771067222548457157018666467027,
                                        16,
                                        "big",
                                    ),
                                    parent_span_id=(
                                        b"\000\000\000\000\000\00009"
                                    ),
                                    kind=CollectorSpan.SpanKind.INTERNAL,
                                    attributes=[
                                        AttributeKeyValue(
                                            key="a", int_value=1
                                        ),
                                        AttributeKeyValue(
                                            key="b", bool_value=True
                                        ),
                                    ],
                                    events=[
                                        CollectorSpan.Event(
                                            name="a",
                                            time_unix_nano=1591240820506462784,
                                            attributes=[
                                                AttributeKeyValue(
                                                    key="a", int_value=1
                                                ),
                                                AttributeKeyValue(
                                                    key="b", int_value=False
                                                ),
                                            ],
                                        )
                                    ],
                                    status=Status(code=0, message=""),
                                    links=[
                                        CollectorSpan.Link(
                                            trace_id=int.to_bytes(
                                                1, 16, "big"
                                            ),
                                            span_id=int.to_bytes(2, 8, "big"),
                                            attributes=[
                                                AttributeKeyValue(
                                                    key="a", int_value=1
                                                ),
                                                AttributeKeyValue(
                                                    key="b", bool_value=False
                                                ),
                                            ],
                                        )
                                    ],
                                )
                            ]
                        )
                    ],
                ),
            ]
        )

        # pylint: disable=protected-access
        self.assertEqual(expected, self.exporter._translate_spans([self.span]))
Exemple #19
0
    def test_span_to_envelope(self):
        from opentelemetry.trace import Link, SpanContext, SpanKind
        from opentelemetry.trace.status import StatusCanonicalCode
        from opentelemetry.sdk.trace import Span

        exporter = AzureMonitorSpanExporter(
            instrumentation_key='12345678-1234-5678-abcd-12345678abcd'
        )

        parent_span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557338,
            ),
        )

        start_time = 1575494316027612800
        end_time = start_time + 1001000000

        # SpanKind.CLIENT HTTP
        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.method': 'GET',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
                'http.status_code': 200,
            },
            events=None,
            links=None,
            kind=SpanKind.CLIENT
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.iKey,
            '12345678-1234-5678-abcd-12345678abcd')
        self.assertEqual(
            envelope.name,
            'Microsoft.ApplicationInsights.RemoteDependency')
        self.assertEqual(
            envelope.tags['ai.operation.parentId'],
            'a6f5d48acb4d31da')
        self.assertEqual(
            envelope.tags['ai.operation.id'],
            '1bbd944a73a05d89eab5d3740a213ee7')
        self.assertEqual(
            envelope.time,
            '2019-12-04T21:18:36.027613Z')
        self.assertEqual(
            envelope.data.baseData.name,
            'GET//wiki/Rabbit')
        self.assertEqual(
            envelope.data.baseData.data,
            'https://www.wikipedia.org/wiki/Rabbit')
        self.assertEqual(
            envelope.data.baseData.target,
            'www.wikipedia.org')
        self.assertEqual(
            envelope.data.baseData.id,
            'a6f5d48acb4d31d9')
        self.assertEqual(
            envelope.data.baseData.resultCode,
            '200')
        self.assertEqual(
            envelope.data.baseData.duration,
            '0.00:00:01.001')
        self.assertEqual(
            envelope.data.baseData.type,
            'HTTP')
        self.assertEqual(
            envelope.data.baseType,
            'RemoteDependencyData')

        # SpanKind.CLIENT unknown type
        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={},
            events=None,
            links=None,
            kind=SpanKind.CLIENT
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.iKey,
            '12345678-1234-5678-abcd-12345678abcd')
        self.assertEqual(
            envelope.name,
            'Microsoft.ApplicationInsights.RemoteDependency')
        self.assertEqual(
            envelope.tags['ai.operation.parentId'],
            'a6f5d48acb4d31da')
        self.assertEqual(
            envelope.tags['ai.operation.id'],
            '1bbd944a73a05d89eab5d3740a213ee7')
        self.assertEqual(
            envelope.time,
            '2019-12-04T21:18:36.027613Z')
        self.assertEqual(
            envelope.data.baseData.name,
            'test')
        self.assertEqual(
            envelope.data.baseData.id,
            'a6f5d48acb4d31d9')
        self.assertEqual(
            envelope.data.baseData.duration,
            '0.00:00:01.001')
        self.assertEqual(
            envelope.data.baseData.type,
            None)
        self.assertEqual(
            envelope.data.baseType,
            'RemoteDependencyData')

        # SpanKind.CLIENT missing method
        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
                'http.status_code': 200,
            },
            events=None,
            links=None,
            kind=SpanKind.CLIENT
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.iKey,
            '12345678-1234-5678-abcd-12345678abcd')
        self.assertEqual(
            envelope.name,
            'Microsoft.ApplicationInsights.RemoteDependency')
        self.assertEqual(
            envelope.tags['ai.operation.parentId'],
            'a6f5d48acb4d31da')
        self.assertEqual(
            envelope.tags['ai.operation.id'],
            '1bbd944a73a05d89eab5d3740a213ee7')
        self.assertEqual(
            envelope.time,
            '2019-12-04T21:18:36.027613Z')
        self.assertEqual(
            envelope.data.baseData.name,
            'test')
        self.assertEqual(
            envelope.data.baseData.data,
            'https://www.wikipedia.org/wiki/Rabbit')
        self.assertEqual(
            envelope.data.baseData.target,
            'www.wikipedia.org')
        self.assertEqual(
            envelope.data.baseData.id,
            'a6f5d48acb4d31d9')
        self.assertEqual(
            envelope.data.baseData.resultCode,
            '200')
        self.assertEqual(
            envelope.data.baseData.duration,
            '0.00:00:01.001')
        self.assertEqual(
            envelope.data.baseData.type,
            'HTTP')
        self.assertEqual(
            envelope.data.baseType,
            'RemoteDependencyData')

        # SpanKind.SERVER HTTP - 200 request
        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.method': 'GET',
                'http.path': '/wiki/Rabbit',
                'http.route': '/wiki/Rabbit',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
                'http.status_code': 200,
            },
            events=None,
            links=None,
            kind=SpanKind.SERVER
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.iKey,
            '12345678-1234-5678-abcd-12345678abcd')
        self.assertEqual(
            envelope.name,
            'Microsoft.ApplicationInsights.Request')
        self.assertEqual(
            envelope.tags['ai.operation.parentId'],
            'a6f5d48acb4d31da')
        self.assertEqual(
            envelope.tags['ai.operation.id'],
            '1bbd944a73a05d89eab5d3740a213ee7')
        self.assertEqual(
            envelope.tags['ai.operation.name'],
            'GET /wiki/Rabbit')
        self.assertEqual(
            envelope.time,
            '2019-12-04T21:18:36.027613Z')
        self.assertEqual(
            envelope.data.baseData.id,
            'a6f5d48acb4d31d9')
        self.assertEqual(
            envelope.data.baseData.duration,
            '0.00:00:01.001')
        self.assertEqual(
            envelope.data.baseData.responseCode,
            '200')
        self.assertEqual(
            envelope.data.baseData.name,
            'GET /wiki/Rabbit')
        self.assertEqual(
            envelope.data.baseData.success,
            True)
        self.assertEqual(
            envelope.data.baseData.url,
            'https://www.wikipedia.org/wiki/Rabbit')
        self.assertEqual(
            envelope.data.baseType,
            'RequestData')

        # SpanKind.SERVER HTTP - Failed request
        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.method': 'GET',
                'http.path': '/wiki/Rabbit',
                'http.route': '/wiki/Rabbit',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
                'http.status_code': 400,
            },
            events=None,
            links=None,
            kind=SpanKind.SERVER
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.iKey,
            '12345678-1234-5678-abcd-12345678abcd')
        self.assertEqual(
            envelope.name,
            'Microsoft.ApplicationInsights.Request')
        self.assertEqual(
            envelope.tags['ai.operation.parentId'],
            'a6f5d48acb4d31da')
        self.assertEqual(
            envelope.tags['ai.operation.id'],
            '1bbd944a73a05d89eab5d3740a213ee7')
        self.assertEqual(
            envelope.tags['ai.operation.name'],
            'GET /wiki/Rabbit')
        self.assertEqual(
            envelope.time,
            '2019-12-04T21:18:36.027613Z')
        self.assertEqual(
            envelope.data.baseData.id,
            'a6f5d48acb4d31d9')
        self.assertEqual(
            envelope.data.baseData.duration,
            '0.00:00:01.001')
        self.assertEqual(
            envelope.data.baseData.responseCode,
            '400')
        self.assertEqual(
            envelope.data.baseData.name,
            'GET /wiki/Rabbit')
        self.assertEqual(
            envelope.data.baseData.success,
            False)
        self.assertEqual(
            envelope.data.baseData.url,
            'https://www.wikipedia.org/wiki/Rabbit')
        self.assertEqual(
            envelope.data.baseType,
            'RequestData')

        # SpanKind.SERVER unknown type
        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.method': 'GET',
                'http.path': '/wiki/Rabbit',
                'http.route': '/wiki/Rabbit',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
                'http.status_code': 400,
            },
            events=None,
            links=None,
            kind=SpanKind.SERVER
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.iKey,
            '12345678-1234-5678-abcd-12345678abcd')
        self.assertEqual(
            envelope.name,
            'Microsoft.ApplicationInsights.Request')
        self.assertEqual(
            envelope.tags['ai.operation.parentId'],
            'a6f5d48acb4d31da')
        self.assertEqual(
            envelope.tags['ai.operation.id'],
            '1bbd944a73a05d89eab5d3740a213ee7')
        self.assertEqual(
            envelope.time,
            '2019-12-04T21:18:36.027613Z')
        self.assertEqual(
            envelope.data.baseData.id,
            'a6f5d48acb4d31d9')
        self.assertEqual(
            envelope.data.baseData.duration,
            '0.00:00:01.001')
        self.assertEqual(
            envelope.data.baseType,
            'RequestData')

        # SpanKind.INTERNAL
        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=None,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={'key1': 'value1'},
            events=None,
            links=None,
            kind=SpanKind.INTERNAL
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.iKey,
            '12345678-1234-5678-abcd-12345678abcd')
        self.assertEqual(
            envelope.name,
            'Microsoft.ApplicationInsights.RemoteDependency')
        self.assertRaises(
            KeyError,
            lambda: envelope.tags['ai.operation.parentId'])
        self.assertEqual(
            envelope.tags['ai.operation.id'],
            '1bbd944a73a05d89eab5d3740a213ee7')
        self.assertEqual(
            envelope.time,
            '2019-12-04T21:18:36.027613Z')
        self.assertEqual(
            envelope.data.baseData.name,
            'test')
        self.assertEqual(
            envelope.data.baseData.duration,
            '0.00:00:01.001')
        self.assertEqual(
            envelope.data.baseData.id,
            'a6f5d48acb4d31d9')
        self.assertEqual(
            envelope.data.baseData.type,
            'InProc')
        self.assertEqual(
            envelope.data.baseType,
            'RemoteDependencyData')

        # Attributes
        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.method': 'GET',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
                'http.status_code': 200,
                'test': 'asd'
            },
            events=None,
            links=None,
            kind=SpanKind.CLIENT
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            len(envelope.data.baseData.properties), 2)
        self.assertEqual(
            envelope.data.baseData.properties['component'], 'http')
        self.assertEqual(envelope.data.baseData.properties['test'], 'asd')

        # Links
        links = []
        links.append(Link(context=SpanContext(
                trace_id=36873507687745823477771305566750195432,
                span_id=12030755672171557338,
            )))
        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.method': 'GET',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
                'http.status_code': 200,
            },
            events=None,
            links=links,
            kind=SpanKind.CLIENT
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            len(envelope.data.baseData.properties), 2)
        links_json = '[{"operation_Id": ' + \
            '"1bbd944a73a05d89eab5d3740a213ee8", "id": "a6f5d48acb4d31da"}]'
        self.assertEqual(envelope.data.baseData.properties['_MS.links'], links_json)

        
        # Status
        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.method': 'GET',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
                'http.status_code': 500,
            },
            events=None,
            links=None,
            kind=SpanKind.SERVER
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.data.baseData.responseCode, '500')
        self.assertFalse(envelope.data.baseData.success)

        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.method': 'GET',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
                'http.status_code': 500,
            },
            events=None,
            links=None,
            kind=SpanKind.CLIENT
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.data.baseData.resultCode, '500')
        self.assertFalse(envelope.data.baseData.success)

        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.method': 'GET',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
            },
            events=None,
            links=None,
            kind=SpanKind.SERVER
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        span.status = StatusCanonicalCode.OK
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.data.baseData.responseCode, '0')
        self.assertTrue(envelope.data.baseData.success)

        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.method': 'GET',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
            },
            events=None,
            links=None,
            kind=SpanKind.CLIENT
        )
        span.status = StatusCanonicalCode.OK
        span.start_time = start_time
        span.end_time = end_time
        span.status = StatusCanonicalCode.OK
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.data.baseData.resultCode, '0')
        self.assertTrue(envelope.data.baseData.success)

        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.method': 'GET',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
            },
            events=None,
            links=None,
            kind=SpanKind.SERVER
        )
        span.start_time = start_time
        span.end_time = end_time
        span.status = StatusCanonicalCode.UNKNOWN
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.data.baseData.responseCode, '2')
        self.assertFalse(envelope.data.baseData.success)

        span = Span(
            name='test',
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                'component': 'http',
                'http.method': 'GET',
                'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
            },
            events=None,
            links=None,
            kind=SpanKind.CLIENT
        )
        span.start_time = start_time
        span.end_time = end_time
        span.status = StatusCanonicalCode.UNKNOWN
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.data.baseData.resultCode, '2')
        self.assertFalse(envelope.data.baseData.success)
    def test_span_to_envelope(self):
        options = {
            "instrumentation_key": "12345678-1234-5678-abcd-12345678abcd"
        }
        exporter = AzureMonitorSpanExporter(**options)

        parent_span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557338,
            ),
        )

        start_time = 1575494316027613500
        end_time = start_time + 1001000000

        # SpanKind.CLIENT HTTP
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.method": "GET",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 200,
            },
            events=None,
            links=[],
            kind=SpanKind.CLIENT,
        )
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd")
        self.assertEqual(envelope.name,
                         "Microsoft.ApplicationInsights.RemoteDependency")
        self.assertEqual(envelope.tags["ai.operation.parentId"],
                         "a6f5d48acb4d31da")
        self.assertEqual(
            envelope.tags["ai.operation.id"],
            "1bbd944a73a05d89eab5d3740a213ee7",
        )
        self.assertEqual(envelope.time, "2019-12-04T21:18:36.027613Z")
        self.assertEqual(envelope.data.base_data.name, "GET//wiki/Rabbit")
        self.assertEqual(
            envelope.data.base_data.data,
            "https://www.wikipedia.org/wiki/Rabbit",
        )
        self.assertEqual(envelope.data.base_data.target, "www.wikipedia.org")
        self.assertEqual(envelope.data.base_data.id, "a6f5d48acb4d31d9")
        self.assertEqual(envelope.data.base_data.result_code, "200")
        self.assertEqual(envelope.data.base_data.duration, "0.00:00:01.001")
        self.assertEqual(envelope.data.base_data.type, "HTTP")
        self.assertEqual(envelope.data.base_type, "RemoteDependencyData")

        # SpanKind.CLIENT unknown type
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={},
            events=None,
            links=[],
            kind=SpanKind.CLIENT,
        )
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd")
        self.assertEqual(envelope.name,
                         "Microsoft.ApplicationInsights.RemoteDependency")
        self.assertEqual(envelope.tags["ai.operation.parentId"],
                         "a6f5d48acb4d31da")
        self.assertEqual(
            envelope.tags["ai.operation.id"],
            "1bbd944a73a05d89eab5d3740a213ee7",
        )
        self.assertEqual(envelope.time, "2019-12-04T21:18:36.027613Z")
        self.assertEqual(envelope.data.base_data.name, "test")
        self.assertEqual(envelope.data.base_data.id, "a6f5d48acb4d31d9")
        self.assertEqual(envelope.data.base_data.duration, "0.00:00:01.001")
        self.assertEqual(envelope.data.base_data.type, None)
        self.assertEqual(envelope.data.base_type, "RemoteDependencyData")

        # SpanKind.CLIENT missing method
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 200,
            },
            events=None,
            links=[],
            kind=SpanKind.CLIENT,
        )
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd")
        self.assertEqual(envelope.name,
                         "Microsoft.ApplicationInsights.RemoteDependency")
        self.assertEqual(envelope.tags["ai.operation.parentId"],
                         "a6f5d48acb4d31da")
        self.assertEqual(
            envelope.tags["ai.operation.id"],
            "1bbd944a73a05d89eab5d3740a213ee7",
        )
        self.assertEqual(envelope.time, "2019-12-04T21:18:36.027613Z")
        self.assertEqual(envelope.data.base_data.name, "test")
        self.assertEqual(
            envelope.data.base_data.data,
            "https://www.wikipedia.org/wiki/Rabbit",
        )
        self.assertEqual(envelope.data.base_data.target, "www.wikipedia.org")
        self.assertEqual(envelope.data.base_data.id, "a6f5d48acb4d31d9")
        self.assertEqual(envelope.data.base_data.result_code, "200")
        self.assertEqual(envelope.data.base_data.duration, "0.00:00:01.001")
        self.assertEqual(envelope.data.base_data.type, "HTTP")
        self.assertEqual(envelope.data.base_type, "RemoteDependencyData")

        # SpanKind.SERVER HTTP - 200 request
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.method": "GET",
                "http.path": "/wiki/Rabbit",
                "http.route": "/wiki/Rabbit",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 200,
            },
            events=None,
            links=[],
            kind=SpanKind.SERVER,
        )
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd")
        self.assertEqual(envelope.name,
                         "Microsoft.ApplicationInsights.Request")
        self.assertEqual(envelope.tags["ai.operation.parentId"],
                         "a6f5d48acb4d31da")
        self.assertEqual(
            envelope.tags["ai.operation.id"],
            "1bbd944a73a05d89eab5d3740a213ee7",
        )
        self.assertEqual(envelope.tags["ai.operation.name"],
                         "GET /wiki/Rabbit")
        self.assertEqual(envelope.time, "2019-12-04T21:18:36.027613Z")
        self.assertEqual(envelope.data.base_data.id, "a6f5d48acb4d31d9")
        self.assertEqual(envelope.data.base_data.duration, "0.00:00:01.001")
        self.assertEqual(envelope.data.base_data.response_code, "200")
        self.assertEqual(envelope.data.base_data.name, "GET /wiki/Rabbit")
        self.assertEqual(envelope.data.base_data.success, True)
        self.assertEqual(
            envelope.data.base_data.url,
            "https://www.wikipedia.org/wiki/Rabbit",
        )
        self.assertEqual(envelope.data.base_type, "RequestData")

        # SpanKind.SERVER HTTP - Failed request
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.method": "GET",
                "http.path": "/wiki/Rabbit",
                "http.route": "/wiki/Rabbit",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 400,
            },
            events=None,
            links=[],
            kind=SpanKind.SERVER,
        )
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd")
        self.assertEqual(envelope.name,
                         "Microsoft.ApplicationInsights.Request")
        self.assertEqual(envelope.tags["ai.operation.parentId"],
                         "a6f5d48acb4d31da")
        self.assertEqual(
            envelope.tags["ai.operation.id"],
            "1bbd944a73a05d89eab5d3740a213ee7",
        )
        self.assertEqual(envelope.tags["ai.operation.name"],
                         "GET /wiki/Rabbit")
        self.assertEqual(envelope.time, "2019-12-04T21:18:36.027613Z")
        self.assertEqual(envelope.data.base_data.id, "a6f5d48acb4d31d9")
        self.assertEqual(envelope.data.base_data.duration, "0.00:00:01.001")
        self.assertEqual(envelope.data.base_data.response_code, "400")
        self.assertEqual(envelope.data.base_data.name, "GET /wiki/Rabbit")
        self.assertEqual(envelope.data.base_data.success, False)
        self.assertEqual(
            envelope.data.base_data.url,
            "https://www.wikipedia.org/wiki/Rabbit",
        )
        self.assertEqual(envelope.data.base_type, "RequestData")

        # SpanKind.SERVER unknown type
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.method": "GET",
                "http.path": "/wiki/Rabbit",
                "http.route": "/wiki/Rabbit",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 400,
            },
            events=None,
            links=[],
            kind=SpanKind.SERVER,
        )
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd")
        self.assertEqual(envelope.name,
                         "Microsoft.ApplicationInsights.Request")
        self.assertEqual(envelope.tags["ai.operation.parentId"],
                         "a6f5d48acb4d31da")
        self.assertEqual(
            envelope.tags["ai.operation.id"],
            "1bbd944a73a05d89eab5d3740a213ee7",
        )
        self.assertEqual(envelope.time, "2019-12-04T21:18:36.027613Z")
        self.assertEqual(envelope.data.base_data.id, "a6f5d48acb4d31d9")
        self.assertEqual(envelope.data.base_data.duration, "0.00:00:01.001")
        self.assertEqual(envelope.data.base_type, "RequestData")

        # SpanKind.INTERNAL
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=None,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={"key1": "value1"},
            events=None,
            links=[],
            kind=SpanKind.INTERNAL,
        )
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.ikey, "12345678-1234-5678-abcd-12345678abcd")
        self.assertEqual(envelope.name,
                         "Microsoft.ApplicationInsights.RemoteDependency")
        self.assertRaises(KeyError,
                          lambda: envelope.tags["ai.operation.parentId"])
        self.assertEqual(
            envelope.tags["ai.operation.id"],
            "1bbd944a73a05d89eab5d3740a213ee7",
        )
        self.assertEqual(envelope.time, "2019-12-04T21:18:36.027613Z")
        self.assertEqual(envelope.data.base_data.name, "test")
        self.assertEqual(envelope.data.base_data.duration, "0.00:00:01.001")
        self.assertEqual(envelope.data.base_data.id, "a6f5d48acb4d31d9")
        self.assertEqual(envelope.data.base_data.type, "InProc")
        self.assertEqual(envelope.data.base_type, "RemoteDependencyData")

        # Attributes
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.method": "GET",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 200,
                "test": "asd",
            },
            events=None,
            links=[],
            kind=SpanKind.CLIENT,
        )
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(len(envelope.data.base_data.properties), 2)
        self.assertEqual(envelope.data.base_data.properties["component"],
                         "http")
        self.assertEqual(envelope.data.base_data.properties["test"], "asd")

        # Links
        links = []
        links.append(
            Link(context=SpanContext(
                trace_id=36873507687745823477771305566750195432,
                span_id=12030755672171557338,
            )))
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.method": "GET",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 200,
            },
            events=None,
            links=links,
            kind=SpanKind.CLIENT,
        )
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(len(envelope.data.base_data.properties), 2)
        json_dict = json.loads(
            envelope.data.base_data.properties["_MS.links"])[0]
        self.assertEqual(json_dict["id"], "a6f5d48acb4d31da")

        # Status
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.method": "GET",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 500,
            },
            events=None,
            links=[],
            kind=SpanKind.SERVER,
        )
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.data.base_data.response_code, "500")
        self.assertFalse(envelope.data.base_data.success)

        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.method": "GET",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 500,
            },
            events=None,
            links=[],
            kind=SpanKind.CLIENT,
        )
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.data.base_data.result_code, "500")
        self.assertFalse(envelope.data.base_data.success)

        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.method": "GET",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
            },
            events=None,
            links=[],
            kind=SpanKind.SERVER,
        )
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.data.base_data.response_code, "0")
        self.assertTrue(envelope.data.base_data.success)

        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.method": "GET",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
            },
            events=None,
            links=[],
            kind=SpanKind.CLIENT,
        )
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.data.base_data.result_code, "0")
        self.assertTrue(envelope.data.base_data.success)

        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.method": "GET",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
            },
            events=None,
            links=[],
            kind=SpanKind.SERVER,
        )
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        span.status = Status(canonical_code=StatusCanonicalCode.UNKNOWN)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.data.base_data.response_code, "2")
        self.assertFalse(envelope.data.base_data.success)

        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "http",
                "http.method": "GET",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
            },
            events=None,
            links=[],
            kind=SpanKind.CLIENT,
        )
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        span.status = Status(canonical_code=StatusCanonicalCode.UNKNOWN)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.data.base_data.result_code, "2")
        self.assertFalse(envelope.data.base_data.success)

        # Server route attribute
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "HTTP",
                "http.method": "GET",
                "http.route": "/wiki/Rabbit",
                "http.path": "/wiki/Rabbitz",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 400,
            },
            events=None,
            links=[],
            kind=SpanKind.SERVER,
        )
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(
            envelope.data.base_data.properties["request.name"],
            "GET /wiki/Rabbit",
        )
        self.assertEqual(
            envelope.data.base_data.properties["request.url"],
            "https://www.wikipedia.org/wiki/Rabbit",
        )

        # Server method attribute missing
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "HTTP",
                "http.path": "/wiki/Rabbitz",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 400,
            },
            events=None,
            links=[],
            kind=SpanKind.SERVER,
        )
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        envelope = exporter.span_to_envelope(span)
        self.assertIsNone(envelope.data.base_data.name)

        # Server route attribute missing
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "HTTP",
                "http.method": "GET",
                "http.path": "/wiki/Rabbitz",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 400,
            },
            events=None,
            links=[],
            kind=SpanKind.SERVER,
        )
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        envelope = exporter.span_to_envelope(span)
        self.assertEqual(envelope.data.base_data.name, "GET")
        self.assertEqual(
            envelope.data.base_data.properties["request.name"],
            "GET /wiki/Rabbitz",
        )
        self.assertEqual(
            envelope.data.base_data.properties["request.url"],
            "https://www.wikipedia.org/wiki/Rabbit",
        )

        # Server route and path attribute missing
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "HTTP",
                "http.method": "GET",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 400,
            },
            events=None,
            links=[],
            kind=SpanKind.SERVER,
        )
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        envelope = exporter.span_to_envelope(span)
        self.assertIsNone(
            envelope.data.base_data.properties.get("request.name"))
        self.assertEqual(
            envelope.data.base_data.properties["request.url"],
            "https://www.wikipedia.org/wiki/Rabbit",
        )

        # Server http.url missing
        span = Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
            ),
            parent=parent_span,
            sampler=None,
            trace_config=None,
            resource=None,
            attributes={
                "component": "HTTP",
                "http.method": "GET",
                "http.route": "/wiki/Rabbit",
                "http.path": "/wiki/Rabbitz",
                "http.status_code": 400,
            },
            events=None,
            links=[],
            kind=SpanKind.SERVER,
        )
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        span.status = Status(canonical_code=StatusCanonicalCode.OK)
        envelope = exporter.span_to_envelope(span)
        self.assertIsNone(envelope.data.base_data.url)
        self.assertIsNone(
            envelope.data.base_data.properties.get("request.url"))
    def test_export(self):
        resource_info = Resource({
            "cloud.account.id": 123,
            "host.id": "host",
            "cloud.zone": "US",
            "cloud.provider": "gcp",
            "gcp.resource_type": "gce_instance",
        })
        span_datas = [
            Span(
                name="span_name",
                context=SpanContext(
                    trace_id=int(self.example_trace_id, 16),
                    span_id=int(self.example_span_id, 16),
                    is_remote=False,
                ),
                parent=None,
                kind=SpanKind.INTERNAL,
                resource=resource_info,
                attributes={"attr_key": "attr_value"},
            )
        ]

        cloud_trace_spans = {
            "name":
            "projects/{}/traces/{}/spans/{}".format(self.project_id,
                                                    self.example_trace_id,
                                                    self.example_span_id),
            "span_id":
            self.example_span_id,
            "parent_span_id":
            None,
            "display_name":
            TruncatableString(value="span_name", truncated_byte_count=0),
            "attributes":
            ProtoSpan.Attributes(
                attribute_map={
                    "g.co/r/gce_instance/zone":
                    _format_attribute_value("US"),
                    "g.co/r/gce_instance/instance_id":
                    _format_attribute_value("host"),
                    "g.co/r/gce_instance/project_id":
                    _format_attribute_value("123"),
                    "g.co/agent":
                    self.agent_code,
                    "attr_key":
                    _format_attribute_value("attr_value"),
                }),
            "links":
            None,
            "status":
            Status(code=StatusCode.UNSET.value),
            "time_events":
            None,
            "start_time":
            None,
            "end_time":
            None,
            # pylint: disable=no-member
            "span_kind":
            ProtoSpan.SpanKind.INTERNAL,
        }

        client = mock.Mock()

        exporter = CloudTraceSpanExporter(self.project_id, client=client)

        exporter.export(span_datas)

        self.assertTrue(client.batch_write_spans.called)
        client.batch_write_spans.assert_called_with(
            "projects/{}".format(self.project_id), [cloud_trace_spans])