open-telemetry / open-telemetry/opentelemetry-python

Failing test on windows / 3.14t

Open
#5,157 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
2.6k
Forks
1k
Avg merge
4d 15h
Merged PRs (30d)
19

Description

Failure run:
https://github.com/open-telemetry/opentelemetry-python/actions/runs/24994967095/job/73350788900?pr=5153

 ================================== FAILURES ===================================
________ TestMetricReaderStorage.test_creates_view_instrument_matches _________

self = <test_metric_reader_storage.TestMetricReaderStorage testMethod=test_creates_view_instrument_matches>
MockViewInstrumentMatch = <MagicMock name='_ViewInstrumentMatch' id='4851910926352'>

    @patch(
        "opentelemetry.sdk.metrics._internal"
        ".metric_reader_storage._ViewInstrumentMatch"
    )
    def test_creates_view_instrument_matches(
        self, MockViewInstrumentMatch: Mock
    ):
        """It should create a MockViewInstrumentMatch when an instrument
        matches a view"""
        instrument1 = Mock(name="instrument1")
        instrument2 = Mock(name="instrument2")
    
        view1 = mock_view_matching("view_1", instrument1)
        view2 = mock_view_matching("view_2", instrument1, instrument2)
        storage = MetricReaderStorage(
            SdkConfiguration(
                exemplar_filter=Mock(),
                resource=Mock(),
                metric_readers=(),
                views=(view1, view2),
            ),
            MagicMock(
                **{
                    "__getitem__.return_value": AggregationTemporality.CUMULATIVE
                }
            ),
            MagicMock(**{"__getitem__.return_value": DefaultAggregation()}),
        )
    
        # instrument1 matches view1 and view2, so should create two
        # ViewInstrumentMatch objects
        storage.consume_measurement(
            Measurement(1, time_ns(), instrument1, Context())
        )
        self.assertEqual(
            len(MockViewInstrumentMatch.call_args_list),
            2,
            MockViewInstrumentMatch.mock_calls,
        )
        # they should only be created the first time the instrument is seen
        storage.consume_measurement(
            Measurement(1, time_ns(), instrument1, Context())
        )
        self.assertEqual(len(MockViewInstrumentMatch.call_args_list), 2)
    
        # instrument2 matches view2, so should create a single
        # ViewInstrumentMatch
        MockViewInstrumentMatch.call_args_list.clear()
        with self.assertLogs(level=WARNING):
            storage.consume_measurement(
                Measurement(1, time_ns(), instrument2, Context())
            )
>       self.assertEqual(len(MockViewInstrumentMatch.call_args_list), 1)
E       AssertionError: 2 != 1

opentelemetry-sdk\tests\metrics\test_metric_reader_storage.py:116: AssertionError

In the captured output we have the following. We had other occurencies of this and was wrong mocks used in the tests but the test looks unrelated 😓

opentelemetry-sdk/tests/metrics/exponential_histogram/test_exponential_bucket_histogram_aggregation.py::TestExponentialBucketHistogramAggregation::test_boundary_statistics
  D:\a\opentelemetry-python\opentelemetry-python\.tox\py314t-test-opentelemetry-sdk\Lib\site-packages\_pytest\threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread OtelPeriodicExportingMetricReader
  
  Traceback (most recent call last):
    File "C:\hostedtoolcache\windows\Python\3.14.4\x64-freethreaded\Lib\threading.py", line 1082, in _bootstrap_inner
      self._context.run(self.run)
      ~~~~~~~~~~~~~~~~~^^^^^^^^^^
    File "C:\hostedtoolcache\windows\Python\3.14.4\x64-freethreaded\Lib\threading.py", line 1024, in run
      self._target(*self._args, **self._kwargs)
      ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "D:\a\opentelemetry-python\opentelemetry-python\opentelemetry-sdk\src\opentelemetry\sdk\metrics\_internal\export\__init__.py", line 549, in _ticker
      self.collect(timeout_millis=self._export_timeout_millis)
      ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "D:\a\opentelemetry-python\opentelemetry-python\opentelemetry-sdk\src\opentelemetry\sdk\metrics\_internal\export\__init__.py", line 359, in collect
      metrics = self._collect(self, timeout_millis=timeout_millis)
    File "D:\a\opentelemetry-python\opentelemetry-python\opentelemetry-sdk\src\opentelemetry\sdk\metrics\_internal\measurement_consumer.py", line 143, in collect
      result = self._reader_storages[metric_reader].collect()
    File "D:\a\opentelemetry-python\opentelemetry-python\opentelemetry-sdk\src\opentelemetry\sdk\metrics\_internal\metric_reader_storage.py", line 219, in collect
      data=data,
           ^^^^
  UnboundLocalError: cannot access local variable 'data' where it is not associated with a value
  
    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/metric_reader_storage.py, especially collect(), and reproduce the Windows Python 3.14t run linked in the issue. Review opentelemetry-sdk/tests/metrics/test_metric_reader_storage.py and the exponential histogram test; done means the reported assertion and the unhandled-thread exception no longer occur.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
observability-sre, testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.