Skip to content

[#313] Stabilize flaky ExchangeLockTest deadlock tests - #314

Open
vharseko wants to merge 1 commit into
OpenIdentityPlatform:masterfrom
vharseko:tests/313-exchange-lock-deadlock
Open

vharseko wants to merge 1 commit into
OpenIdentityPlatform:masterfrom
vharseko:tests/313-exchange-lock-deadlock

Conversation

@vharseko

Copy link
Copy Markdown
Member

Summary

ExchangeLockTest.deadlock is flaky on CI (#313): it fails on assertTrue(a._committed ^ b._committed).

Deadlock detection in TransactionIndex.wwDependency is distributed. Each waiter calls source.setDepends(target) and then isDeadlocked(source), and no victim is selected. If both lockers of a two-way deadlock link their edges before either one checks, both see the cycle, both get UNCOMMITTED, and both roll back. The deadlock is still resolved, but with two victims instead of one, so "exactly one committed" does not hold. multiWayDeadlock has the same race: assertEquals(1, succeeded) can see 0.

This is the same mechanism that #256 fixed test-side for TransactionIndexTest.testDeadlockedWwDependency.

Changes

  • deadlock: assert that at most one locker commits, instead of exactly one.
  • multiWayDeadlock: assert succeeded <= 1 instead of == 1.
  • Both tests: every locker that did not commit must have been rolled back with a RollbackException, so an unrelated failure is still caught.
  • Assertion messages now include the elapsed time and each locker's commit flag and exception.
  • Locker._exception is now volatile, consistent with the other shared fields.

No product code is changed. A deterministic victim choice in wwDependency would change library behavior and is not needed for correctness.

Testing

  • mvn -pl persistit/core test -Dtest=ExchangeLockTest (JDK 17): 8 tests, 0 failures.
  • 300 iterations of deadlock and multiWayDeadlock in one JVM: 0 failures. The race did not reproduce locally, so this run only shows that the tests do not regress.

Fixes #313

…tests

Deadlock detection in TransactionIndex.wwDependency is distributed: every
waiter links its dependency and then checks for a cycle, with no victim
selection. When both lockers of a two-way deadlock link their edges before
either checks, both see the cycle and both roll back, so the assertion
"exactly one committed" fails (seen on ubuntu-latest JDK 17). The same
race applies to multiWayDeadlock.

Assert the invariants that do hold instead: at most one locker commits,
and every locker that did not commit was rolled back with a
RollbackException. Include elapsed time, commit flags and exceptions in
the assertion messages so a future failure is diagnosable.

Fixes OpenIdentityPlatform#313
@vharseko vharseko added the tests Test code changes label Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests Test code changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flaky ExchangeLockTest.deadlock: both lockers can abort on a two-way deadlock

1 participant