Skip to content

Conversation

@Arkatufus
Copy link
Contributor

Fix: Deflake Make_sure_async_works in TestEventListener tests

Summary

  • Addressed racy/flaky behavior in Akka.TestKit.Tests.TestEventListenerTests.CustomEventFilterDebugTests.Make_sure_async_works observed on resource‑constrained CI VMs.
  • Preserved the original test intent: ensure EventFilter continues intercepting logs emitted after the ExpectAsync action delegate returns using “regular .NET async”.
  • Minimal, test‑only change; no timeouts altered and no public API changes.

Theory / Root Cause

  • The test previously used Task.Delay(...).ContinueWith(...) to emit a log after the ExpectAsync action returned. Under constrained CI environments:
    • ContinueWith schedules onto TaskScheduler.Current, which can be bound to the TestKit’s SynchronizationContext and is sensitive to thread pool starvation.
    • Continuations may be delayed or not pumped quickly enough, causing the delayed log to arrive after EventFilter.ExpectAsync times out.
  • EventFilter/TestKit async semantics have been corrected previously (e.g., issues InternalExpectAsync does not await actionAsync() - causing actionAsync to run as a detached task #5537 and InterceptAsync seems to run func() as a detached task #5586): ExpectAsync/InterceptAsync now properly await async delegates. The flake is a test design fragility, not a production code defect.
  • A theoretical micro‑race exists in EventFilter setup (publishing Mute before wiring EventMatched handlers), but it is not the primary cause here since the log is scheduled “later”.

Assumptions (Test Intent)

  • Validate that standard .NET async usage interops correctly with EventFilter:
    • The action delegate completes, and a later async log is still intercepted within the expected window.
    • it should work with .NET async alone.

Change

  • Replace Task.Delay(...).ContinueWith(...) with a fire‑and‑forget .NET async task decoupled from the current context:
    • Task.Run(async () => { await Task.Delay(10).ConfigureAwait(false); LogMessage("whatever"); });
  • Keep the rest of the test unchanged: still calls ExpectAsync(1, TimeSpan.FromSeconds(2), action) and returns immediately from action.

Why This Preserves Intent and Fixes Flakiness

  • Still uses “regular .NET async” (Task.Run + await + ConfigureAwait(false)).
  • Ensures the delayed log occurs after the action returns, so EventFilter must remain active and intercept it.
  • Avoids ContinueWith + ambient SynchronizationContext timing/pumping issues; reduces susceptibility to thread pool starvation in CI.
  • No timeout changes; purely a deterministic mechanism for the delayed emission.

Copy link
Member

@Aaronontheweb Aaronontheweb left a comment

Choose a reason for hiding this comment

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

Skeptical about the AI assessment of this

await _testingEventFilter.ForLogLevel(LogLevel).ExpectAsync(1, TimeSpan.FromSeconds(2), () =>
{
#pragma warning disable CS4014 // intentionally fire-and-forget to verify filter after action returns
_ = Task.Run(async () =>
Copy link
Member

Choose a reason for hiding this comment

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

is the ConfigureAwait(false) the only meaningful change here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, its the Task.Run()

@Aaronontheweb Aaronontheweb added akka-testkit Akka.NET Testkit issues tests labels Sep 16, 2025
…Arkatufus/akka.net into tests/TestKit-TestEventListenerTests_01
@Aaronontheweb
Copy link
Member

Separate test that failed: Akka.TestKit.Tests.TestKitBaseTests.WithinTests.Within_should_respect_minimum_time

Failed: Block took 00:00:01.3719852, exceeding 00:00:01.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

akka-testkit Akka.NET Testkit issues tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants