Skip to content

Fix flaky HazelcastReplicatedmapConsumerTest (18% failure rate)#24590

Merged
davsclaus merged 1 commit into
mainfrom
fix-flaky-test-hazelcastreplicatedmapconsumertest
Jul 11, 2026
Merged

Fix flaky HazelcastReplicatedmapConsumerTest (18% failure rate)#24590
davsclaus merged 1 commit into
mainfrom
fix-flaky-test-hazelcastreplicatedmapconsumertest

Conversation

@gnodet

@gnodet gnodet commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Claude Code on behalf of gnodet

Fixes the persistent flakiness of HazelcastReplicatedmapConsumerTest (18% failure rate on Develocity — 35/194 runs failing). The prior fix (CAMEL-22506) added map.clear() + mock reset in @BeforeEach, but that approach itself introduces the flakiness because clear() fires async REMOVED events through the still-active Hazelcast entry listener.

Root cause: map.clear() in @BeforeEach fires async REMOVED events that bleed between tests because the Hazelcast EntryListener is still registered. Additionally, testRemove() calls map.remove() immediately after map.put() without waiting for the ADDED event to be processed, creating a race condition.

Fix:

  • @BeforeEach: Stop routes before clearing the map to deregister the entry listener (via HazelcastReplicatedmapConsumer.doStop()), preventing stale REMOVED events from reaching mock endpoints. Restart routes after clearing and resetting mocks.
  • testRemove(): Wait for the ADDED event to be delivered before calling remove(), eliminating the put/remove race.
  • testEvict(): Replace redundant Awaitility-wrapped MockEndpoint.assertIsSatisfied() with the native latch-based timed assertion (per project conventions — Awaitility polls on top of an already-waiting mechanism).

Test plan

  • All 3 tests pass locally
  • Validated with 100 consecutive runs — 0 failures (vs. ~18 expected failures without fix)
  • Code formatted with mvn formatter:format impsort:sort
  • CI build passed (Java 17 ✅, Java 25 ✅) — run 29100025144

@gnodet gnodet marked this pull request as ready for review July 10, 2026 14:22
@gnodet gnodet requested review from davsclaus and oscerd July 10, 2026 14:23
@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean fix for the flaky test. The root cause analysis is correct — async REMOVED events from map.clear() in resetState() were bleeding into the next test's mock expectations.

All three changes look good:

  1. Route stop/start around map.clear() — deregisters the Hazelcast entry listener so clear() doesn't fire events into the mock
  2. testEvict() — correctly replaced Awaitility.await().untilAsserted(() -> MockEndpoint.assertIsSatisfied(...)) with the native MockEndpoint.assertIsSatisfied(context, 30000, TimeUnit.MILLISECONDS) — avoids polling-on-top-of-latch per project conventions
  3. testRemove() — Awaitility wait for ADDED event counter before removing is the right pattern (mid-test condition that MockEndpoint can't express natively)

LGTM.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of Guillaume Nodet

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • components/camel-hazelcast

🔬 Scalpel shadow comparison — Scalpel: 1 tested, 0 compile-only — current: 9 all tested

Maveniverse Scalpel detected 1 affected modules (current approach: 9).

Modules only in current approach (8)
  • camel-jbang-mcp
  • camel-jbang-plugin-mcp
  • camel-jbang-plugin-route-parser
  • camel-jbang-plugin-tui
  • camel-jbang-plugin-validate
  • camel-launcher-container
  • camel-yaml-dsl-validator
  • camel-yaml-dsl-validator-maven-plugin

Skip-tests mode would test 1 modules (1 direct + 0 downstream), skip tests for 0 (generated code, meta-modules)

Modules Scalpel would test (1)
  • camel-hazelcast

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

All tested modules (9 modules)
  • Camel :: HazelCast
  • Camel :: JBang :: MCP
  • Camel :: JBang :: Plugin :: MCP
  • Camel :: JBang :: Plugin :: Route Parser
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: JBang :: Plugin :: Validate
  • Camel :: Launcher :: Container
  • Camel :: YAML DSL :: Validator
  • Camel :: YAML DSL :: Validator Maven Plugin

⚙️ View full build and test results

Root cause: map.clear() in @beforeeach fires async REMOVED events that
bleed between tests because the Hazelcast entry listener is still active.
Additionally, testRemove() calls map.remove() immediately after put()
without waiting for the ADDED event, creating a race condition.

Fix:
- Stop routes before clearing the map to deregister the entry listener,
  preventing stale REMOVED events from reaching mock endpoints
- Restart routes after clearing and resetting mocks
- In testRemove(), wait for the ADDED event before calling remove()
- Replace redundant Awaitility-wrapped MockEndpoint assertion in
  testEvict() with the native latch-based timed assertion

Validated with 100 consecutive runs (0 failures).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@davsclaus davsclaus force-pushed the fix-flaky-test-hazelcastreplicatedmapconsumertest branch from c771ae5 to fa10df6 Compare July 11, 2026 18:04
@davsclaus davsclaus added the test label Jul 11, 2026
@davsclaus davsclaus added this to the 4.22.0 milestone Jul 11, 2026
@davsclaus davsclaus merged commit 35c8b58 into main Jul 11, 2026
5 checks passed
@davsclaus davsclaus deleted the fix-flaky-test-hazelcastreplicatedmapconsumertest branch July 11, 2026 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants