What happens
ha-integration-tests is failing on main most of the time, and it fails on a different test almost every run.
The last 8 runs of the Java CI - test workflow on main:
| commit |
result |
run |
83448ea6 |
success |
job |
7469a248 |
failure |
job |
9337abf1 |
failure |
job |
50130d37 |
failure |
job |
e64160a3 |
failure |
job |
64aaa29f |
success |
job |
4bd617e1 |
failure |
job |
af0dc719 |
failure |
job |
6 of 8 failed. These are unrelated commits (a logger config change, an SQL arithmetic fix, a Duration fix, ...), so
this is the suite, not the changes.
The failures are non-deterministic, not a broken test
The clearest evidence: the same commit was run twice on #5685 and failed both times on disjoint sets of tests.
| run |
failing tests |
| 1st (53m33s) |
RaftMigrationCompactionRaceIT.migrationStyleBulkInsertAcrossManyTypesNeverEmitsCannotFindIndexes |
| 2nd (55m55s) |
Issue5410AbandonedTicketReleaseIT.abandonedEntryReleasesItsPhase2TicketOnceApplied, Issue5569SlotMergeDeleteRaftIT.mergedDeletesReplicateIntact, RaftHTTPGraphConcurrentIT.oneEdgePerTxMultiThreads |
Every test that failed in run 1 passed in run 2, and vice versa. Final tally of run 2: Tests run: 199, Failures: 2, Errors: 1, Skipped: 4.
Shape of the failures
All timing-related rather than assertion-related. Representative:
com.arcadedb.server.ha.raft.ReplicationDispatchedTimeoutException:
Group commit interrupted while awaiting quorum result (entry was dispatched to Raft; outcome unknown)
and the runs are full of leader churn:
WARNI [ArcadeStateMachine] Leader churn: ArcadeDB_2 (localhost:2482) re-elected (term=2, 7958 ms since last
leader change). Either a heartbeat stall triggered an election (CPU/GC pauses, disk stalls, network blips, or
appender threads saturated by bulk-load replication ...)
That is consistent with a 3-node Raft cluster not getting enough CPU/IO headroom on a shared GitHub runner: elections
fire, quorum waits time out, and whichever test happens to be mid-commit is the one that fails.
Why it matters
Suggested directions
Rather than a specific fix, the useful first step is deciding which of these it is:
- Runner capacity. If elections are firing because the 3 in-process nodes are starved, the durable fix is
raising arcadedb.ha.electionTimeoutMin/Max (and possibly EXPLICIT_LOCK_TIMEOUT / COMMIT_LOCK_TIMEOUT, both
5 s by default) for the CI profile only, so a real deadlock still fails fast locally. engine/CLAUDE.md already
documents that these timeouts are a known source of intermittent CI failures under contention.
- Genuine races. If the same handful of ITs dominate across many runs, they are worth fixing individually
rather than blanket-retiming. Collecting per-test failure counts over ~20 runs would tell them apart.
- Interim: consider marking the suite non-blocking, or adding a single automatic retry for it, so its result
stops being ignored by default. Whatever is chosen, it should be explicit - the current state is an implicit
"ignore this check" that everyone has to learn.
Related: #5701 (the coverage report does not wait for this job, so its coverage is silently missing from every PR).
Found while verifying that an HA failure on #5685 (issue #5677) was unrelated to that change - ha-raft/src
contains no reference to HashIndex, INDEX_TYPE.HASH or UNIQUE_HASH, so the changed code never executes in this
suite.
What happens
ha-integration-testsis failing onmainmost of the time, and it fails on a different test almost every run.The last 8 runs of the
Java CI - testworkflow onmain:83448ea67469a2489337abf150130d37e64160a364aaa29f4bd617e1af0dc7196 of 8 failed. These are unrelated commits (a logger config change, an SQL arithmetic fix, a Duration fix, ...), so
this is the suite, not the changes.
The failures are non-deterministic, not a broken test
The clearest evidence: the same commit was run twice on #5685 and failed both times on disjoint sets of tests.
RaftMigrationCompactionRaceIT.migrationStyleBulkInsertAcrossManyTypesNeverEmitsCannotFindIndexesIssue5410AbandonedTicketReleaseIT.abandonedEntryReleasesItsPhase2TicketOnceApplied,Issue5569SlotMergeDeleteRaftIT.mergedDeletesReplicateIntact,RaftHTTPGraphConcurrentIT.oneEdgePerTxMultiThreadsEvery test that failed in run 1 passed in run 2, and vice versa. Final tally of run 2:
Tests run: 199, Failures: 2, Errors: 1, Skipped: 4.Shape of the failures
All timing-related rather than assertion-related. Representative:
and the runs are full of leader churn:
That is consistent with a 3-node Raft cluster not getting enough CPU/IO headroom on a shared GitHub runner: elections
fire, quorum waits time out, and whichever test happens to be mid-commit is the one that fails.
Why it matters
re-run is likely to fail on something else.
maintoo, it carries no signal: a genuine HA regression in a PR would be indistinguishablefrom the background noise. This came up concretely on fix(engine) #5677: store a LINK hash-index key compressed, and refuse an unencodable key type at creation #5685, where establishing that the failure was pre-existing
took two 55-minute runs plus a survey of main's history.
Suggested directions
Rather than a specific fix, the useful first step is deciding which of these it is:
raising
arcadedb.ha.electionTimeoutMin/Max(and possiblyEXPLICIT_LOCK_TIMEOUT/COMMIT_LOCK_TIMEOUT, both5 s by default) for the CI profile only, so a real deadlock still fails fast locally.
engine/CLAUDE.mdalreadydocuments that these timeouts are a known source of intermittent CI failures under contention.
rather than blanket-retiming. Collecting per-test failure counts over ~20 runs would tell them apart.
stops being ignored by default. Whatever is chosen, it should be explicit - the current state is an implicit
"ignore this check" that everyone has to learn.
Related: #5701 (the coverage report does not wait for this job, so its coverage is silently missing from every PR).
Found while verifying that an HA failure on #5685 (issue #5677) was unrelated to that change -
ha-raft/srccontains no reference to
HashIndex,INDEX_TYPE.HASHorUNIQUE_HASH, so the changed code never executes in thissuite.