opentelemetry-python icon indicating copy to clipboard operation
opentelemetry-python copied to clipboard

Investigate otlp exporter test failure with python 3.13

Open xrmx opened this issue 8 months ago • 1 comments
trafficstars

=================================== FAILURES ===================================
_____________ TestOTLPExporterMixin.test_shutdown_wait_last_export _____________

self = <tests.test_otlp_exporter_mixin.TestOTLPExporterMixin testMethod=test_shutdown_wait_last_export>

    def test_shutdown_wait_last_export(self):
        result_mock = Mock()
        rpc_error = RpcError()
    
        def code(self):
            return StatusCode.UNAVAILABLE
    
        def trailing_metadata(self):
            return {
                "google.rpc.retryinfo-bin": RetryInfo(
                    retry_delay=Duration(nanos=int(1e7))
                ).SerializeToString()
            }
    
        rpc_error.code = MethodType(code, rpc_error)
        rpc_error.trailing_metadata = MethodType(trailing_metadata, rpc_error)
    
        class OTLPMockExporter(OTLPExporterMixin):
            _result = result_mock
            _stub = Mock(
                **{"return_value": Mock(**{"Export.side_effect": rpc_error})}
            )
    
Exporter already shutdown, ignoring call
Exporter already shutdown, ignoring call
            def _translate_data(
                self, data: Sequence[SDKDataT]
            ) -> ExportServiceRequestT:
                pass
    
            @property
            def _exporting(self) -> str:
                return "mock"
    
        otlp_mock_exporter = OTLPMockExporter()
    
        # pylint: disable=protected-access
        export_thread = threading.Thread(
            target=otlp_mock_exporter._export, args=({},)
        )
        export_thread.start()
        try:
            # pylint: disable=protected-access
            self.assertTrue(otlp_mock_exporter._export_lock.locked())
            # delay is 1 second while the default shutdown timeout is 30_000 milliseconds
            start_time = time_ns()
            otlp_mock_exporter.shutdown()
            now = time_ns()
            self.assertGreaterEqual(now, (start_time + 30 / 1000))
            # pylint: disable=protected-access
            self.assertTrue(otlp_mock_exporter._shutdown)
            # pylint: disable=protected-access
>           self.assertFalse(otlp_mock_exporter._export_lock.locked())
E           AssertionError: True is not false

exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_exporter_mixin.py:208: AssertionError
------------------------------ Captured log call -------------------------------
WARNING  opentelemetry.exporter.otlp.proto.grpc.exporter:exporter.py:327 Transient error StatusCode.UNAVAILABLE encountered while exporting mock to localhost:4317, retrying in 0.01s.
WARNING  opentelemetry.exporter.otlp.proto.grpc.exporter:exporter.py:327 Transient error StatusCode.UNAVAILABLE encountered while exporting mock to localhost:4317, retrying in 0.01s.
=============================== warnings summary ===============================
<frozen importlib._bootstrap>:488
  <frozen importlib._bootstrap>:488: DeprecationWarning: Type google._upb._message.MessageMapContainer uses PyType_Spec with a metaclass that has custom tp_new. This is deprecated and will no longer be allowed in Python 3.14.

<frozen importlib._bootstrap>:488
  <frozen importlib._bootstrap>:488: DeprecationWarning: Type google._upb._message.ScalarMapContainer uses PyType_Spec with a metaclass that has custom tp_new. This is deprecated and will no longer be allowed in Python 3.14.

exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py::TestOTLPMetricExporter::test_shutdown_wait_last_export
  /home/runner/work/opentelemetry-python/opentelemetry-python/.tox/py313-test-opentelemetry-exporter-otlp-proto-grpc/lib/python3.13/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread Thread-22 (export)
  
  Traceback (most recent call last):
    File "/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/threading.py", line 1041, in _bootstrap_inner
      self.run()
      ~~~~~~~~^^
    File "/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/threading.py", line 992, in run
      self._target(*self._args, **self._kwargs)
      ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/home/runner/work/opentelemetry-python/opentelemetry-python/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/metric_exporter/__init__.py", line 164, in export
      return self._export(data=metrics_data)
             ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
    File "/home/runner/work/opentelemetry-python/opentelemetry-python/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py", line 298, in _export
      self._client.Export(
      ~~~~~~~~~~~~~~~~~~~^
          request=self._translate_data(data),
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          metadata=self._headers,
          ^^^^^^^^^^^^^^^^^^^^^^^
          timeout=self._timeout,
          ^^^^^^^^^^^^^^^^^^^^^^
      )
      ^
    File "/home/runner/work/opentelemetry-python/opentelemetry-python/.tox/py313-test-opentelemetry-exporter-otlp-proto-grpc/lib/python3.13/site-packages/grpc/_channel.py", line 1178, in __call__
      ) = self._blocking(
          ~~~~~~~~~~~~~~^
          request, timeout, metadata, credentials, wait_for_ready, compression
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      )
      ^
    File "/home/runner/work/opentelemetry-python/opentelemetry-python/.tox/py313-test-opentelemetry-exporter-otlp-proto-grpc/lib/python3.13/site-packages/grpc/_channel.py", line 1146, in _blocking
      call = self._channel.segregated_call(
          cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS,
      ...<12 lines>...
          self._registered_call_handle,
      )
    File "src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi", line 547, in grpc._cython.cygrpc.Channel.segregated_call
    File "src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi", line 403, in grpc._cython.cygrpc._segregated_call
    File "src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi", line 407, in grpc._cython.cygrpc._segregated_call
  ValueError: Cannot invoke RPC on closed channel!
  
    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py::TestOTLPSpanExporter::test_shutdown_wait_last_export
  /home/runner/work/opentelemetry-python/opentelemetry-python/.tox/py313-test-opentelemetry-exporter-otlp-proto-grpc/lib/python3.13/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread Thread-48 (export)
  
  Traceback (most recent call last):
    File "/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/threading.py", line 1041, in _bootstrap_inner
      self.run()
      ~~~~~~~~^^
    File "/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/threading.py", line 992, in run
      self._target(*self._args, **self._kwargs)
      ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/home/runner/work/opentelemetry-python/opentelemetry-python/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py", line 143, in export
      return self._export(spans)
             ~~~~~~~~~~~~^^^^^^^
    File "/home/runner/work/opentelemetry-python/opentelemetry-python/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py", line 298, in _export
      self._client.Export(
      ~~~~~~~~~~~~~~~~~~~^
          request=self._translate_data(data),
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          metadata=self._headers,
          ^^^^^^^^^^^^^^^^^^^^^^^
          timeout=self._timeout,
          ^^^^^^^^^^^^^^^^^^^^^^
      )
      ^
    File "/home/runner/work/opentelemetry-python/opentelemetry-python/.tox/py313-test-opentelemetry-exporter-otlp-proto-grpc/lib/python3.13/site-packages/grpc/_channel.py", line 1178, in __call__
      ) = self._blocking(
          ~~~~~~~~~~~~~~^
          request, timeout, metadata, credentials, wait_for_ready, compression
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      )
      ^
Exporter already shutdown, ignoring call
    File "/home/runner/work/opentelemetry-python/opentelemetry-python/.tox/py313-test-opentelemetry-exporter-otlp-proto-grpc/lib/python3.13/site-packages/grpc/_channel.py", line 1146, in _blocking
      call = self._channel.segregated_call(
          cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS,
      ...<12 lines>...
          self._registered_call_handle,
      )
    File "src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi", line 547, in grpc._cython.cygrpc.Channel.segregated_call
    File "src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi", line 403, in grpc._cython.cygrpc._segregated_call
    File "src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi", line 407, in grpc._cython.cygrpc._segregated_call
  ValueError: Cannot invoke RPC on closed channel!
  
    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

xrmx avatar Mar 06 '25 17:03 xrmx

BTW I refactored this test a bunch in https://github.com/open-telemetry/opentelemetry-python/pull/4504 if you want to take a look.. Note that this test was duplicated in all the exporters and had a 30 second sleep (I reduced it to a few seconds in my refactor).

DylanRussell avatar Apr 03 '25 14:04 DylanRussell

I think this is fixed @xrmx or no longer relevant?

aabmass avatar Sep 10 '25 20:09 aabmass

These were from CI, I don't think I have seen them in a few, closing.

xrmx avatar Sep 11 '25 07:09 xrmx