Skip to content

Fix TestActor initialization race in parallel test startup#8023

Merged
Arkatufus merged 11 commits into
akkadotnet:devfrom
Aaronontheweb:fix/parallel-testkitbase-init-sync
Jan 27, 2026
Merged

Fix TestActor initialization race in parallel test startup#8023
Arkatufus merged 11 commits into
akkadotnet:devfrom
Aaronontheweb:fix/parallel-testkitbase-init-sync

Conversation

@Aaronontheweb
Copy link
Copy Markdown
Member

Summary

  • Add synchronization mechanism to ensure TestActor.PreStart() completes before CreateInitialTestActor returns
  • This fixes a race condition where the TestActor's Create message hasn't been processed yet when another actor tries to send messages to it

Changes

  • InternalTestActor: Add optional ManualResetEventSlim parameter that gets signaled in PreStart() when actor initialization is complete
  • TestKitBase.CreateInitialTestActor: Wait for the init signal before returning, ensuring the actor is fully ready

Root Cause

When running multiple TestKits in parallel (as in ParallelTestActorDeadlockSpec), there was a race between:

  1. TestActor being created (LocalActorRef constructor returns)
  2. TestActor's Create message being processed (which triggers PreStart())
  3. Other actors (like PingerActor) sending messages to TestActor

The ManualResetEventSlim synchronization ensures step 2 completes before CreateInitialTestActor returns.

Test plan

  • ParallelTestActorDeadlockSpec passes 10/10 times locally
  • Akka.TestKit.Tests: 293 tests pass
  • Akka.Tests: 1205 tests pass (1 IPv6 DNS test fails - unrelated)
  • Akka.Streams.Tests: 1801 tests pass
  • CI passes on all platforms

Add synchronization mechanism to ensure TestActor.PreStart() completes
before CreateInitialTestActor returns. This fixes a race condition where
the TestActor's Create message hasn't been processed yet when another
actor (like PingerActor) tries to send messages to it.

Changes:
- InternalTestActor: Add optional ManualResetEventSlim parameter that gets
  signaled in PreStart() when actor initialization is complete
- TestKitBase.CreateInitialTestActor: Wait for the init signal before
  returning, ensuring the actor is fully ready

This provides a deterministic fix for ParallelTestActorDeadlockSpec
failures that were occurring under high parallelism on Windows CI.
Aaronontheweb added a commit to Aaronontheweb/akka.net that referenced this pull request Jan 25, 2026
Wrapped three tests in AssertAllStagesStoppedAsync to ensure proper
cleanup of stream stages before tests complete:

- QueueSource_should_emit_received_message_to_the_stream
- QueueSource_should_reject_elements_when_backpressuring_with_maxBuffer_0
- QueueSource_should_buffer_when_needed (the failing test from PR akkadotnet#8023)

The failure "Failed to stop [QueueSourceSpec-920] within [00:00:05]"
occurred because stream stages weren't properly stopped when tests
ended with just sub.Cancel() without waiting for cleanup.
Aaronontheweb added a commit that referenced this pull request Jan 25, 2026
Wrapped three tests in AssertAllStagesStoppedAsync to ensure proper
cleanup of stream stages before tests complete:

- QueueSource_should_emit_received_message_to_the_stream
- QueueSource_should_reject_elements_when_backpressuring_with_maxBuffer_0
- QueueSource_should_buffer_when_needed (the failing test from PR #8023)

The failure "Failed to stop [QueueSourceSpec-920] within [00:00:05]"
occurred because stream stages weren't properly stopped when tests
ended with just sub.Cancel() without waiting for cleanup.
@Aaronontheweb Aaronontheweb added the akka-testkit Akka.NET Testkit issues label Jan 26, 2026
@Aaronontheweb Aaronontheweb added this to the 1.5.59 milestone Jan 26, 2026
Aaronontheweb added a commit to Aaronontheweb/akka.net that referenced this pull request Jan 26, 2026
1. AtLeastOnceDeliveryReceiveActorSpec.PersistentReceive_must_warn_about_unconfirmed_messages
   - Extended ReceiveWhileAsync timeout from 3s to 5s
   - Warning is sent after 3 redeliveries at 500ms intervals (1.5s min)
   - Extra buffer for CI scheduling delays

2. ReplicatorSpecs.Bugfix_Duplicate_Publish
   - Changed from Within(5s) block with default 3s ExpectMsg timeout
   - Now uses explicit 5s timeout per probe ExpectMsg call
   - Cluster gossip can be slow on busy CI

3. UnhandledMessageEventFilterTests.Unhandled_message_should_produce_info_message
   - Made deterministic by subscribing to UnhandledMessage events
   - Wait for UnhandledMessage to confirm message was processed
   - Guarantees Info log has been published before filter checks
Aaronontheweb added a commit to Aaronontheweb/akka.net that referenced this pull request Jan 26, 2026
1. AtLeastOnceDeliveryReceiveActorSpec.PersistentReceive_must_warn_about_unconfirmed_messages
   - Extended ReceiveWhileAsync timeout from 3s to 5s
   - Warning is sent after 3 redeliveries at 500ms intervals (1.5s min)
   - Extra buffer for CI scheduling delays

2. ReplicatorSpecs.Bugfix_Duplicate_Publish
   - Converted to async TestKit methods (ExpectMsgAsync, ExpectNoMsgAsync)
   - Added explicit 5s timeout for cluster gossip propagation
   - Removed synchronous ExpectMsg calls

3. UnhandledMessageEventFilterTests.Unhandled_message_should_produce_info_message
   - Made deterministic by subscribing to UnhandledMessage events
   - Wait for UnhandledMessage to confirm message was processed
   - Guarantees Info log has been published before filter checks
Aaronontheweb added a commit that referenced this pull request Jan 26, 2026
1. AtLeastOnceDeliveryReceiveActorSpec.PersistentReceive_must_warn_about_unconfirmed_messages
   - Extended ReceiveWhileAsync timeout from 3s to 5s
   - Warning is sent after 3 redeliveries at 500ms intervals (1.5s min)
   - Extra buffer for CI scheduling delays

2. ReplicatorSpecs.Bugfix_Duplicate_Publish
   - Converted to async TestKit methods (ExpectMsgAsync, ExpectNoMsgAsync)
   - Added explicit 5s timeout for cluster gossip propagation
   - Removed synchronous ExpectMsg calls

3. UnhandledMessageEventFilterTests.Unhandled_message_should_produce_info_message
   - Made deterministic by subscribing to UnhandledMessage events
   - Wait for UnhandledMessage to confirm message was processed
   - Guarantees Info log has been published before filter checks
Copy link
Copy Markdown
Contributor

@Arkatufus Arkatufus left a comment

Choose a reason for hiding this comment

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

LGTM

@Arkatufus Arkatufus merged commit e2de40d into akkadotnet:dev Jan 27, 2026
12 checks passed
Aaronontheweb added a commit to Aaronontheweb/akka.net that referenced this pull request Feb 9, 2026
…t#8023)

Add synchronization mechanism to ensure TestActor.PreStart() completes
before CreateInitialTestActor returns. This fixes a race condition where
the TestActor's Create message hasn't been processed yet when another
actor (like PingerActor) tries to send messages to it.

Changes:
- InternalTestActor: Add optional ManualResetEventSlim parameter that gets
  signaled in PreStart() when actor initialization is complete
- TestKitBase.CreateInitialTestActor: Wait for the init signal before
  returning, ensuring the actor is fully ready

This provides a deterministic fix for ParallelTestActorDeadlockSpec
failures that were occurring under high parallelism on Windows CI.
Aaronontheweb added a commit that referenced this pull request Feb 9, 2026
Add synchronization mechanism to ensure TestActor.PreStart() completes
before CreateInitialTestActor returns. This fixes a race condition where
the TestActor's Create message hasn't been processed yet when another
actor (like PingerActor) tries to send messages to it.

Changes:
- InternalTestActor: Add optional ManualResetEventSlim parameter that gets
  signaled in PreStart() when actor initialization is complete
- TestKitBase.CreateInitialTestActor: Wait for the init signal before
  returning, ensuring the actor is fully ready

This provides a deterministic fix for ParallelTestActorDeadlockSpec
failures that were occurring under high parallelism on Windows CI.
This was referenced May 21, 2026
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants