You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Mocha] Stabilize saga integration tests against timing flakes - #9947
The saga IntegrationTests slept for a fixed time (Task.Delay) between steps and before asserting on store state, which flaked under CI load: the Main Branch Coverage run had Saga_Should_TimeoutWithCustomResponse fail with Expected: 0, Actual: 1.
A saga dispatches a transition's messages before its state is committed, and a correlated message that arrives before that commit finds no instance and is discarded, so no fixed delay makes these tests reliable. Each test now waits until the saga state its next message depends on is persisted before sending that message, then polls for the expected state or for the instance to be deleted, bounded by the existing 10 s timeout.
Saga_Should_ExecuteThroughSteps waits for Started to be persisted before the first TriggerEvent, and for the saga to finish consuming that event before sending the second. The in-memory saga store exposes a transition's new state before it commits, so the end of the consume, which comes after the commit, is the reliable signal. The timeout tests wait until the saga is persisted before sending SagaTimedOutEvent.
Saga_Should_SupportRequestResponse uses a new GatedTriggerRequestHandler that holds the reply, parking the saga in AwaitingResponse until its persisted state is observed; releasing the reply then drives finalization and deletion.
Test plan
IntegrationTests: 10/10 passing on net8.0, net9.0, net10.0, and net11.0.
Full Mocha.Sagas.Tests suite: 612 passed, 4 skipped, 0 failed across the four target frameworks.
With a temporary local saga store whose commit takes 2 s, the four tests still pass. With one that holds back a transition's commit until the next transition has committed, Saga_Should_ExecuteThroughSteps passes.
glen-84
changed the title
Stabilize Mocha saga integration tests against timing flakes
[Mocha] Stabilize saga integration tests against timing flakes
Oct 9, 2026
Wait for the first transition's commit, not just State == "Triggered". The in-memory store loads the object already held by InMemorySagaStateStorage, and Saga.HandleEvent changes its State before the consumer commits. This poll can therefore pass while the first save is still in flight; the second event may finish and delete the saga before that save commits, leaving a state behind and making this test flaky. Use a commit-visible signal or snapshot before publishing the second event.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
IntegrationTestsslept for a fixed time (Task.Delay) between steps and before asserting on store state, which flaked under CI load: theMain Branch Coveragerun hadSaga_Should_TimeoutWithCustomResponsefail withExpected: 0, Actual: 1.Saga_Should_ExecuteThroughStepswaits forStartedto be persisted before the firstTriggerEvent, and for the saga to finish consuming that event before sending the second. The in-memory saga store exposes a transition's new state before it commits, so the end of the consume, which comes after the commit, is the reliable signal. The timeout tests wait until the saga is persisted before sendingSagaTimedOutEvent.Saga_Should_SupportRequestResponseuses a newGatedTriggerRequestHandlerthat holds the reply, parking the saga inAwaitingResponseuntil its persisted state is observed; releasing the reply then drives finalization and deletion.Test plan
IntegrationTests: 10/10 passing on net8.0, net9.0, net10.0, and net11.0.Mocha.Sagas.Testssuite: 612 passed, 4 skipped, 0 failed across the four target frameworks.Saga_Should_ExecuteThroughStepspasses.