diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py index b874a4c777..e2be41fb05 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py @@ -75,6 +75,14 @@ class OTLPSpanExporterForTesting( ], ): def __init__(self, **kwargs): + # Default to the explicit IPv4 loopback address rather than + # "localhost", which can resolve to the IPv6 loopback address + # ("::1") first depending on the OS/environment. The mock server + # used by these tests only binds to 127.0.0.1, so resolving + # "localhost" to ::1 would cause tests to try to connect to an + # unrelated service (if any) listening on ::1:4317 instead of the + # mock server, producing confusing, environment-dependent failures. + kwargs.setdefault("endpoint", "http://127.0.0.1:4317") super().__init__( TraceServiceStub, SpanExportResult, @@ -277,7 +285,7 @@ def test_otlp_exporter_otlp_compression_unspecified(self, mock_insecure_channel) """No env or kwarg should be NoCompression""" OTLPSpanExporterForTesting(insecure=True) mock_insecure_channel.assert_called_once_with( - "localhost:4317", + "127.0.0.1:4317", compression=Compression.NoCompression, options=( ( @@ -339,7 +347,7 @@ def test_otlp_exporter_otlp_compression_envvar(self, mock_insecure_channel): """Just OTEL_EXPORTER_OTLP_COMPRESSION should work""" OTLPSpanExporterForTesting(insecure=True) mock_insecure_channel.assert_called_once_with( - "localhost:4317", + "127.0.0.1:4317", compression=Compression.Gzip, options=( ( @@ -529,7 +537,7 @@ def test_timeout_set_correctly(self): ) after = time.time() self.assertEqual( - "Failed to export traces to localhost:4317, error code: StatusCode.DEADLINE_EXCEEDED, error details: Deadline Exceeded", + "Failed to export traces to 127.0.0.1:4317, error code: StatusCode.DEADLINE_EXCEEDED, error details: Deadline Exceeded", warning.records[-1].message, ) self.assertEqual(mock_trace_service.num_requests, 2) @@ -565,7 +573,7 @@ def test_permanent_failure(self): self.assertEqual(exporter.export([self.span]), SpanExportResult.FAILURE) self.assertEqual( warning.records[-1].message, - "Failed to export traces to localhost:4317, error code: StatusCode.ALREADY_EXISTS, error details: This already exists.", + "Failed to export traces to 127.0.0.1:4317, error code: StatusCode.ALREADY_EXISTS, error details: This already exists.", ) metrics_data = self.metric_reader.get_metrics_data() @@ -683,5 +691,5 @@ def test_retryable_error_codes_custom(self): def assert_standard_metric_attrs(self, attributes): self.assertEqual(attributes["otel.component.type"], "otlp_grpc_span_exporter") self.assertTrue(attributes["otel.component.name"].startswith("otlp_grpc_span_exporter/")) - self.assertEqual(attributes["server.address"], "localhost") + self.assertEqual(attributes["server.address"], "127.0.0.1") self.assertEqual(attributes["server.port"], 4317)