Skip to content

test(util-genai): count distinct singleton objects in test_thread_safe_single_new - #380

Open
pylaterreur wants to merge 1 commit into
signalfx:mainfrom
pylaterreur:fix-singleton-alloc-test
Open

pylaterreur wants to merge 1 commit into
signalfx:mainfrom
pylaterreur:fix-singleton-alloc-test

Conversation

@pylaterreur

Copy link
Copy Markdown

Summary

TestGetTelemetryHandlerSingleton::test_thread_safe_single_new is flaky. It counts a "fresh instance" whenever TelemetryHandler.__new__ returns an object whose _initialized flag is still False. Threads that reach the singleton while the first thread is still inside __init__ get that same, not yet initialized, object, so the test counts them too and fails with TelemetryHandler created 2 fresh instances, expected 1 although __new__ allocated only one instance.

Whether it fails depends on how long the first __init__ takes. With the packages ci-main.yaml installs, I got:

Python Test run on its own Full util/opentelemetry-util-genai/tests/
3.13.15 failed 20 of 20 failed 2 of 10
3.14.7 failed 30 of 30 failed 3 of 20

Changes

Count distinct returned objects instead of _initialized flags. Each allocation is returned by the call that made it, and the list keeps them alive, so the test still fails if __new__ allocates twice.

Validation

With a 20 ms sleep added to TelemetryHandler.__init__ to widen the window, the old count reports 9-10 fresh instances in every run, while the number of distinct objects is always 1. The fixed test passed in all 20 full-suite runs on 3.14, and ruff check / ruff format --check (0.14.1) pass.

Note: the old check also points at a real race this PR doesn't change. Threads that get the instance before the first __init__ finishes see _initialized as False and run __init__ again on the shared object.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GwUvhmzgfkiZ6vo4uGyesN

…_new

test_thread_safe_single_new counted a "fresh instance" whenever
TelemetryHandler.__new__ returned an object whose _initialized flag was
still False. Threads that reach the singleton while the first thread is
still inside __init__ get that same, not yet initialized, object, so the
test counts them too and fails although __new__ allocated only one
instance. Whether that happens depends on how long __init__ takes. With
the packages CI installs, the test failed in 20 of 20 runs on its own on
Python 3.13 (30 of 30 on 3.14), and in the full util-genai suite in 2
of 10 runs on 3.13 and 3 of 20 on 3.14.

Count distinct returned objects instead. Each allocation is returned by
the call that made it, so this still fails if __new__ allocates twice.
@pylaterreur
pylaterreur requested review from a team as code owners October 26, 2026 01:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant