def test_aggregated_resources_multiple_detectors(self): resource_detector1 = mock.Mock(spec=resources.ResourceDetector) resource_detector1.detect.return_value = resources.Resource( {"key1": "value1"}) resource_detector2 = mock.Mock(spec=resources.ResourceDetector) resource_detector2.detect.return_value = resources.Resource({ "key2": "value2", "key3": "value3" }) resource_detector3 = mock.Mock(spec=resources.ResourceDetector) resource_detector3.detect.return_value = resources.Resource({ "key2": "try_to_overwrite_existing_value", "key3": "try_to_overwrite_existing_value", "key4": "value4", }) # New values should not overwrite existing values self.assertEqual( resources.get_aggregated_resources( [resource_detector1, resource_detector2, resource_detector3]), resources.Resource({ "key1": "value1", "key2": "value2", "key3": "value3", "key4": "value4", }), )
def test_aggregated_resources_with_static_resource(self): static_resource = resources.Resource({"static_key": "static_value"}) self.assertEqual( resources.get_aggregated_resources( [], initial_resource=static_resource), static_resource, ) # Static resource values should never be overwritten resource_detector = mock.Mock(spec=resources.ResourceDetector) resource_detector.detect.return_value = resources.Resource({ "static_key": "try_to_overwrite_existing_value", "key": "value" }) self.assertEqual( resources.get_aggregated_resources( [resource_detector], initial_resource=static_resource), resources.Resource({ "static_key": "static_value", "key": "value" }), )
def test_resource_merge(self): left = resources.Resource({"service": "ui"}) right = resources.Resource({"host": "service-host"}) self.assertEqual( left.merge(right), resources.Resource({"service": "ui", "host": "service-host"}), ) schema_urls = ( "https://opentelemetry.io/schemas/1.2.0", "https://opentelemetry.io/schemas/1.3.0", ) left = resources.Resource.create({}, None) right = resources.Resource.create({}, None) self.assertEqual(left.merge(right).schema_url, "") left = resources.Resource.create({}, None) right = resources.Resource.create({}, schema_urls[0]) self.assertEqual(left.merge(right).schema_url, schema_urls[0]) left = resources.Resource.create({}, schema_urls[0]) right = resources.Resource.create({}, None) self.assertEqual(left.merge(right).schema_url, schema_urls[0]) left = resources.Resource.create({}, schema_urls[0]) right = resources.Resource.create({}, schema_urls[0]) self.assertEqual(left.merge(right).schema_url, schema_urls[0]) left = resources.Resource.create({}, schema_urls[0]) right = resources.Resource.create({}, schema_urls[1]) with self.assertLogs(level=ERROR) as log_entry: self.assertEqual(left.merge(right), left) self.assertIn(schema_urls[0], log_entry.output[0]) self.assertIn(schema_urls[1], log_entry.output[0])
def test_aggregated_resources_with_default_destroying_static_resource( self, ): static_resource = resources.Resource({"static_key": "static_value"}) self.assertEqual( resources.get_aggregated_resources( [], initial_resource=static_resource ), static_resource, ) resource_detector = mock.Mock(spec=resources.ResourceDetector) resource_detector.detect.return_value = resources.Resource( {"static_key": "try_to_overwrite_existing_value", "key": "value"} ) self.assertEqual( resources.get_aggregated_resources( [resource_detector], initial_resource=static_resource ), resources.Resource( { "static_key": "try_to_overwrite_existing_value", "key": "value", } ), )
def test_resource_merge(self): left = resources.Resource({"service": "ui"}) right = resources.Resource({"host": "service-host"}) self.assertEqual( left.merge(right), resources.Resource({"service": "ui", "host": "service-host"}), )
def test_create(self): attributes = { "service": "ui", "version": 1, "has_bugs": True, "cost": 112.12, } expected_attributes = { "service": "ui", "version": 1, "has_bugs": True, "cost": 112.12, resources.TELEMETRY_SDK_NAME: "opentelemetry", resources.TELEMETRY_SDK_LANGUAGE: "python", resources.TELEMETRY_SDK_VERSION: resources.OPENTELEMETRY_SDK_VERSION, resources.SERVICE_NAME: "unknown_service", } resource = resources.Resource.create(attributes) self.assertIsInstance(resource, resources.Resource) self.assertEqual(resource.attributes, expected_attributes) os.environ[resources.OTEL_RESOURCE_ATTRIBUTES] = "key=value" resource = resources.Resource.create(attributes) self.assertIsInstance(resource, resources.Resource) expected_with_envar = expected_attributes.copy() expected_with_envar["key"] = "value" self.assertEqual(resource.attributes, expected_with_envar) os.environ[resources.OTEL_RESOURCE_ATTRIBUTES] = "" resource = resources.Resource.create_empty() self.assertEqual(resource, resources._EMPTY_RESOURCE) resource = resources.Resource.create(None) self.assertEqual( resource, resources._DEFAULT_RESOURCE.merge( resources.Resource({resources.SERVICE_NAME: "unknown_service"})), ) resource = resources.Resource.create({}) self.assertEqual( resource, resources._DEFAULT_RESOURCE.merge( resources.Resource({resources.SERVICE_NAME: "unknown_service"})), )
def test_resource_merge_empty_string(self): """Verify Resource.merge behavior with the empty string. Attributes from the source Resource take precedence, with the exception of the empty string. """ left = resources.Resource({"service": "ui", "host": ""}) right = resources.Resource( {"host": "service-host", "service": "not-ui"} ) self.assertEqual( left.merge(right), resources.Resource({"service": "not-ui", "host": "service-host"}), )
def test_span_to_envelope_tags(self): exporter = self._exporter test_span = trace._Span( name="test", context=SpanContext( trace_id=36873507687745823477771305566750195431, span_id=12030755672171557338, is_remote=False, ), ) test_span.start() test_span.end() envelope = exporter._span_to_envelope(test_span) self.assertIsNotNone(envelope.tags) self.assertIsNone(envelope.tags.get("ai.cloud.role")) self.assertIsNone(envelope.tags.get("ai.cloud.roleInstance")) self.assertIsNotNone(envelope.tags.get("ai.device.id")) self.assertIsNotNone(envelope.tags.get("ai.device.locale")) self.assertIsNotNone(envelope.tags.get("ai.device.osVersion")) self.assertIsNotNone(envelope.tags.get("ai.device.type")) self.assertIsNotNone(envelope.tags.get("ai.internal.sdkVersion")) test_span.resource = resources.Resource( {"service.name": "testServiceName", "service.namespace": "testServiceNamespace", "service.instance.id": "testServiceInstanceId"}) envelope = exporter._span_to_envelope(test_span) self.assertEqual(envelope.tags.get("ai.cloud.role"), "testServiceNamespace.testServiceName") self.assertEqual(envelope.tags.get( "ai.cloud.roleInstance"), "testServiceInstanceId")
def test_multiple_with_whitespace(self): detector = resources.OTELResourceDetector() os.environ["OTEL_RESOURCE_ATTRIBUTES"] = " k = v , k2 = v2 " self.assertEqual(detector.detect(), resources.Resource({ "k": "v", "k2": "v2" }))
def test_invalid_key_value_pairs(self): detector = resources.OTELResourceDetector() os.environ[ resources.OTEL_RESOURCE_ATTRIBUTES ] = "k=v,k2=v2,invalid,,foo=bar=baz," self.assertEqual( detector.detect(), resources.Resource({"k": "v", "k2": "v2", "foo": "bar=baz"}), )
def test_aggregated_resources_no_detectors(self): aggregated_resources = resources.get_aggregated_resources([]) self.assertEqual( aggregated_resources, resources._DEFAULT_RESOURCE.merge( resources.Resource( {resources.SERVICE_NAME: "unknown_service"}, "" ) ), )
def test_resource_detector_ignore_error(self): resource_detector = mock.Mock(spec=resources.ResourceDetector) resource_detector.detect.side_effect = Exception() resource_detector.raise_on_error = False self.assertEqual( resources.get_aggregated_resources([resource_detector]), resources._DEFAULT_RESOURCE.merge( resources.Resource( {resources.SERVICE_NAME: "unknown_service"}, "" ) ), )
def test_span_to_envelope_partA(self): exporter = self._exporter resource = resources.Resource({ "service.name": "testServiceName", "service.namespace": "testServiceNamespace", "service.instance.id": "testServiceInstanceId" }) context = SpanContext( trace_id=36873507687745823477771305566750195431, span_id=12030755672171557338, is_remote=False, ) test_span = trace._Span( name="test", context=context, resource=resource, attributes={"enduser.id": "testId"}, parent=context, ) test_span.start() test_span.end() envelope = exporter._span_to_envelope(test_span) self.assertEqual(envelope.instrumentation_key, "1234abcd-5678-4efa-8abc-1234567890ab") self.assertIsNotNone(envelope.tags) self.assertEqual(envelope.tags.get("ai.device.id"), azure_monitor_context["ai.device.id"]) self.assertEqual(envelope.tags.get("ai.device.locale"), azure_monitor_context["ai.device.locale"]) self.assertEqual(envelope.tags.get("ai.device.osVersion"), azure_monitor_context["ai.device.osVersion"]) self.assertEqual(envelope.tags.get("ai.device.type"), azure_monitor_context["ai.device.type"]) self.assertEqual(envelope.tags.get("ai.internal.sdkVersion"), azure_monitor_context["ai.internal.sdkVersion"]) self.assertEqual(envelope.tags.get("ai.cloud.role"), "testServiceNamespace.testServiceName") self.assertEqual(envelope.tags.get("ai.cloud.roleInstance"), "testServiceInstanceId") self.assertEqual(envelope.tags.get("ai.internal.nodeName"), "testServiceInstanceId") self.assertEqual(envelope.tags.get("ai.operation.id"), "{:032x}".format(context.trace_id)) self.assertEqual(envelope.tags.get("ai.user.id"), "testId") self.assertEqual(envelope.tags.get("ai.operation.parentId"), "{:016x}".format(context.span_id))
def test_aggregated_resources_multiple_detectors(self): resource_detector1 = mock.Mock(spec=resources.ResourceDetector) resource_detector1.detect.return_value = resources.Resource( {"key1": "value1"} ) resource_detector2 = mock.Mock(spec=resources.ResourceDetector) resource_detector2.detect.return_value = resources.Resource( {"key2": "value2", "key3": "value3"} ) resource_detector3 = mock.Mock(spec=resources.ResourceDetector) resource_detector3.detect.return_value = resources.Resource( { "key2": "try_to_overwrite_existing_value", "key3": "try_to_overwrite_existing_value", "key4": "value4", } ) self.assertEqual( resources.get_aggregated_resources( [resource_detector1, resource_detector2, resource_detector3] ), resources._DEFAULT_RESOURCE.merge( resources.Resource( {resources.SERVICE_NAME: "unknown_service"}, "" ) ).merge( resources.Resource( { "key1": "value1", "key2": "try_to_overwrite_existing_value", "key3": "try_to_overwrite_existing_value", "key4": "value4", } ) ), )
def test_invalid_resource_attribute_values(self): resource = resources.Resource( { resources.SERVICE_NAME: "test", "non-primitive-data-type": {}, "invalid-byte-type-attribute": b"\xd8\xe1\xb7\xeb\xa8\xe5 \xd2\xb7\xe1", "": "empty-key-value", None: "null-key-value", "another-non-primitive": uuid.uuid4(), } ) self.assertEqual( resource.attributes, { resources.SERVICE_NAME: "test", }, ) self.assertEqual(len(resource.attributes), 1)
def test_span_to_envelope_partA_default(self): exporter = self._exporter resource = resources.Resource({"service.name": "testServiceName"}) context = SpanContext( trace_id=36873507687745823477771305566750195431, span_id=12030755672171557338, is_remote=False, ) test_span = trace._Span( name="test", context=context, resource=resource, ) test_span.start() test_span.end() envelope = exporter._span_to_envelope(test_span) self.assertEqual(envelope.tags.get("ai.cloud.role"), "testServiceName") self.assertEqual(envelope.tags.get("ai.cloud.roleInstance"), platform.node())
def test_one_with_whitespace(self): detector = resources.OTELResourceDetector() os.environ["OTEL_RESOURCE"] = " k = v " self.assertEqual(detector.detect(), resources.Resource({"k": "v"}))
def test_one(self): detector = resources.OTELResourceDetector() os.environ["OTEL_RESOURCE_ATTRIBUTES"] = "k=v" self.assertEqual(detector.detect(), resources.Resource({"k": "v"}))
def test_aggregated_resources_different_schema_urls(self): resource_detector1 = mock.Mock(spec=resources.ResourceDetector) resource_detector1.detect.return_value = resources.Resource( {"key1": "value1"}, "" ) resource_detector2 = mock.Mock(spec=resources.ResourceDetector) resource_detector2.detect.return_value = resources.Resource( {"key2": "value2", "key3": "value3"}, "url1" ) resource_detector3 = mock.Mock(spec=resources.ResourceDetector) resource_detector3.detect.return_value = resources.Resource( { "key2": "try_to_overwrite_existing_value", "key3": "try_to_overwrite_existing_value", "key4": "value4", }, "url2", ) resource_detector4 = mock.Mock(spec=resources.ResourceDetector) resource_detector4.detect.return_value = resources.Resource( { "key2": "try_to_overwrite_existing_value", "key3": "try_to_overwrite_existing_value", "key4": "value4", }, "url1", ) self.assertEqual( resources.get_aggregated_resources( [resource_detector1, resource_detector2] ), resources._DEFAULT_RESOURCE.merge( resources.Resource( {resources.SERVICE_NAME: "unknown_service"}, "" ) ).merge( resources.Resource( {"key1": "value1", "key2": "value2", "key3": "value3"}, "url1", ) ), ) with self.assertLogs(level=ERROR) as log_entry: self.assertEqual( resources.get_aggregated_resources( [resource_detector2, resource_detector3] ), resources._DEFAULT_RESOURCE.merge( resources.Resource( {resources.SERVICE_NAME: "unknown_service"}, "" ) ).merge( resources.Resource( {"key2": "value2", "key3": "value3"}, "url1" ) ), ) self.assertIn("url1", log_entry.output[0]) self.assertIn("url2", log_entry.output[0]) with self.assertLogs(level=ERROR): self.assertEqual( resources.get_aggregated_resources( [ resource_detector2, resource_detector3, resource_detector4, resource_detector1, ] ), resources._DEFAULT_RESOURCE.merge( resources.Resource( {resources.SERVICE_NAME: "unknown_service"}, "" ) ).merge( resources.Resource( { "key1": "value1", "key2": "try_to_overwrite_existing_value", "key3": "try_to_overwrite_existing_value", "key4": "value4", }, "url1", ) ), ) self.assertIn("url1", log_entry.output[0]) self.assertIn("url2", log_entry.output[0])
def test_service_name_env(self): detector = resources.OTELResourceDetector() self.assertEqual( detector.detect(), resources.Resource({"service.name": "test-srv-name"}), )
def test_service_name_env_precedence(self): detector = resources.OTELResourceDetector() self.assertEqual( detector.detect(), resources.Resource({"service.name": "from-service-name"}), )