Skip to content

fix: test_successful_wait_for_connection test: make HashableMock thread-safe to fix flaky Windows CI#766

Draft
mykaul wants to merge 1 commit intoscylladb:masterfrom
mykaul:fix/hashable-mock-thread-safety
Draft

fix: test_successful_wait_for_connection test: make HashableMock thread-safe to fix flaky Windows CI#766
mykaul wants to merge 1 commit intoscylladb:masterfrom
mykaul:fix/hashable-mock-thread-safety

Conversation

@mykaul
Copy link
Copy Markdown

@mykaul mykaul commented Mar 26, 2026

Summary

Fixes flaky test_successful_wait_for_connection failure on Windows CI:

TypeError: __hash__ method should return an integer

at cassandra/pool.py:582 (connection in self._trash).

Root cause

HashableMock subclasses NonCallableMagicMock and overrides __hash__ to return id(self). However, MagicMixin.__init__ replaces __hash__ on the type with a MagicMock object before any test runs — making the original override dead code that never executes.

The MagicMock standing in for __hash__ happens to return a hash-compatible value in single-threaded use, but MagicMock.__call__ is not thread-safe. In test_successful_wait_for_connection, two threads call pool.return_connection() on the same HashableMock concurrently, which triggers hash() via connection in self._trash (a set membership check). Under Windows thread scheduling, the concurrent MagicMock.__call__ can return a non-integer, causing the TypeError.

Fix

Restore a plain function as the class-level __hash__ in HashableMock.__init__, after MagicMixin has finished its work. This ensures hash() always resolves to a real, thread-safe function returning id(self).

Verification

  • All 10 pool tests pass
  • test_successful_wait_for_connection passes 100/100 runs in a loop

Pre-review checklist

  • I have split my patch into logically separate commits.
  • All commit messages clearly explain what they change and why.
  • I added relevant tests for new features and bug fixes.
  • All commits compile, pass static checks and pass test.
  • PR description sums up the changes and reasons why they should be introduced.
  • I have provided docstrings for the public items that I want to introduce.
  • I have adjusted the documentation in ./docs/source/.
  • I added appropriate Fixes: annotations to PR description.

…ixin

NonCallableMagicMock.__init__ (via MagicMixin) replaces __hash__ on the
type with a MagicMock object. That MagicMock is not thread-safe, so
concurrent hash() calls — e.g. `connection in self._trash` in pool.py
return_connection — can raise `TypeError: __hash__ method should return
an integer` under concurrent access on Windows.

The previous __hash__ override was dead code: MagicMixin.__init__ always
replaced it with a MagicMock before any test could call it.

Fix by restoring a plain function as the class-level __hash__ after
super().__init__ runs, so hash() always resolves to a real function
instead of a thread-unsafe MagicMock callable.

Fixes flaky test_successful_wait_for_connection on Windows CI.
@mykaul mykaul marked this pull request as draft March 26, 2026 10:12
@mykaul mykaul changed the title fix: make HashableMock thread-safe to fix flaky Windows CI fix: test_successful_wait_for_connection test: make HashableMock thread-safe to fix flaky Windows CI Mar 26, 2026
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