Fix non-deterministic branch coverage in HedgingExecutionContext hedging delay tests#2997
Conversation
…ing delay tests Replace the single non-deterministic TryWaitForCompletedExecutionAsync_HedgedExecution_Ok test with two focused, deterministic tests: 1. DelayFiresFirst_ReturnsNull: primary task delay (1h) > hedging delay (5s). Advance only 10s to fire the hedging delay without completing the primary, so whenAnyHedgedTask.IsCompleted is deterministically false → returns null. 2. TaskCompletesBeforeDelay_ReturnsTask: primary task delay (5s) < hedging delay (1h). Advance only 10s to complete the primary without firing the hedging delay timer, so whenAnyHedgedTask.IsCompleted is deterministically true → returns non-null. Both tests assert the return value explicitly so mutation tests reliably fail when the condition at HedgingExecutionContext.cs:132 is inverted. Co-authored-by: martincostello <1439341+martincostello@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2997 +/- ##
=======================================
Coverage 96.15% 96.15%
=======================================
Files 310 310
Lines 7135 7135
Branches 1005 1005
=======================================
Hits 6861 6861
Misses 221 221
Partials 53 53
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Refactoring to make the tests a bit more readable and a little less repetitive.
There was a problem hiding this comment.
Pull request overview
This PR fixes flaky mutation/branch coverage around the whenAnyHedgedTask.IsCompleted check in HedgingExecutionContext<T>.TryWaitForCompletedExecutionAsync(...) by replacing a timing-racy hedging-delay test with two deterministic tests that explicitly drive each branch.
Changes:
- Replaced the previous single hedging-delay test with two deterministic tests that separately assert the “delay fires first” and “task completes first” outcomes.
- Preserved
continueOnCapturedContext = true/falsecoverage for both new tests. - Minor refactors/cleanup in the test file (consistent attribute ordering, reuse of common
TimeSpanvalues, a few additional safety assertions).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Updated [Polly](https://github.com/App-vNext/Polly) from 8.6.6 to 8.7.0. <details> <summary>Release notes</summary> _Sourced from [Polly's releases](https://github.com/App-vNext/Polly/releases)._ ## 8.7.0 ## Highlights * Adds caller cancellation token propagation in hedging and timeout strategies by @DaRosenberg in App-vNext/Polly#3094 * Telemetry refactoring by @martincostello in App-vNext/Polly#2985 ## What's Changed * Update zizmor to 1.22.0 by @martincostello in App-vNext/Polly#2955 * Increase test timeout by @martincostello in App-vNext/Polly#2956 * Disable secrets-outside-env audit by @martincostello in App-vNext/Polly#2969 * Update zizmor to 1.23.1 by @martincostello in App-vNext/Polly#2970 * Update .NET NuGet packages by @martincostello in App-vNext/Polly#2982 * Add AGENTS.md by @martincostello in App-vNext/Polly#2983 * Fix typo in HTTP client integrations documentation by @alexravenna in App-vNext/Polly#2984 * Remove unused constant by @martincostello in App-vNext/Polly#2986 * Fix non-deterministic branch coverage in HedgingExecutionContext hedging delay tests by @Copilot in App-vNext/Polly#2997 * Bump GitHubActionsTestLogger to 3.0.2 by @martincostello in App-vNext/Polly#3000 * Bump actionlint to v1.7.12 by @martincostello in App-vNext/Polly#3006 * Bump sign by @martincostello in App-vNext/Polly#3008 * Move Public API baselines by @martincostello in App-vNext/Polly#3016 * Formatting tweaks by @martincostello in App-vNext/Polly#3017 * Formatting tweaks by @martincostello in App-vNext/Polly#3018 * Remove ZIZMOR_VERSION by @martincostello in App-vNext/Polly#3025 * Assert nullable has result by @martincostello in App-vNext/Polly#3028 * Update deprecated action input by @martincostello in App-vNext/Polly#3035 * Move dependabot to Friday by @martincostello in App-vNext/Polly#3044 * Fix tag comment by @martincostello in App-vNext/Polly#3045 * Fix dependabot group by @martincostello in App-vNext/Polly#3047 * Pin runner images by @martincostello in App-vNext/Polly#3065 * Bump Refit to 10.2.0 by @martincostello in App-vNext/Polly#3096 * Disable Azure deployments by @martincostello in App-vNext/Polly#3105 ## New Contributors * @alexravenna made their first contribution in App-vNext/Polly#2984 * @DaRosenberg made their first contribution in App-vNext/Polly#3094 **Full Changelog**: App-vNext/Polly@8.6.6...8.7.0 Commits viewable in [compare view](App-vNext/Polly@8.6.6...8.7.0). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updated [Polly](https://github.com/App-vNext/Polly) from 8.6.6 to 8.7.0. <details> <summary>Release notes</summary> _Sourced from [Polly's releases](https://github.com/App-vNext/Polly/releases)._ ## 8.7.0 ## Highlights * Adds caller cancellation token propagation in hedging and timeout strategies by @DaRosenberg in App-vNext/Polly#3094 * Telemetry refactoring by @martincostello in App-vNext/Polly#2985 ## What's Changed * Update zizmor to 1.22.0 by @martincostello in App-vNext/Polly#2955 * Increase test timeout by @martincostello in App-vNext/Polly#2956 * Disable secrets-outside-env audit by @martincostello in App-vNext/Polly#2969 * Update zizmor to 1.23.1 by @martincostello in App-vNext/Polly#2970 * Update .NET NuGet packages by @martincostello in App-vNext/Polly#2982 * Add AGENTS.md by @martincostello in App-vNext/Polly#2983 * Fix typo in HTTP client integrations documentation by @alexravenna in App-vNext/Polly#2984 * Remove unused constant by @martincostello in App-vNext/Polly#2986 * Fix non-deterministic branch coverage in HedgingExecutionContext hedging delay tests by @Copilot in App-vNext/Polly#2997 * Bump GitHubActionsTestLogger to 3.0.2 by @martincostello in App-vNext/Polly#3000 * Bump actionlint to v1.7.12 by @martincostello in App-vNext/Polly#3006 * Bump sign by @martincostello in App-vNext/Polly#3008 * Move Public API baselines by @martincostello in App-vNext/Polly#3016 * Formatting tweaks by @martincostello in App-vNext/Polly#3017 * Formatting tweaks by @martincostello in App-vNext/Polly#3018 * Remove ZIZMOR_VERSION by @martincostello in App-vNext/Polly#3025 * Assert nullable has result by @martincostello in App-vNext/Polly#3028 * Update deprecated action input by @martincostello in App-vNext/Polly#3035 * Move dependabot to Friday by @martincostello in App-vNext/Polly#3044 * Fix tag comment by @martincostello in App-vNext/Polly#3045 * Fix dependabot group by @martincostello in App-vNext/Polly#3047 * Pin runner images by @martincostello in App-vNext/Polly#3065 * Bump Refit to 10.2.0 by @martincostello in App-vNext/Polly#3096 * Disable Azure deployments by @martincostello in App-vNext/Polly#3105 ## New Contributors * @alexravenna made their first contribution in App-vNext/Polly#2984 * @DaRosenberg made their first contribution in App-vNext/Polly#3094 **Full Changelog**: App-vNext/Polly@8.6.6...8.7.0 Commits viewable in [compare view](App-vNext/Polly@8.6.6...8.7.0). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
The mutation tests for
HedgingExecutionContext<T>were flaky because the condition at line 132 (if (!whenAnyHedgedTask.IsCompleted)) was not reliably exercised by both branches. The single existing test advanced the fake clock by a full day, firing both the hedging delay timer and the primary task timer simultaneously — making the outcome of theIsCompletedcheck dependent on non-deterministic async continuation scheduling.Changes
TryWaitForCompletedExecutionAsync_HedgedExecution_Okwith two deterministic, explicitly-asserted tests:DelayFiresFirst_ReturnsNull— primary task delay (1 h) exceeds hedging delay (5 s); advancing only 10 s fires the hedging delay while the primary is still running, sowhenAnyHedgedTask.IsCompletedis deterministicallyfalseand the method deterministically returnsnull(result.ShouldBeNull()).TaskCompletesBeforeDelay_ReturnsTask— primary task delay (5 s) is less than hedging delay (1 h); advancing only 10 s completes the primary before the hedging delay timer fires, sowhenAnyHedgedTask.IsCompletedis deterministicallytrueand the method deterministically returns the completed execution (result.ShouldNotBeNull()).continueOnCapturedContext = true/false, preserving the originalConfigureAwaitflag coverage.With these changes, inverting the condition at line 132 will always cause at least one test to fail.
Confirm the following
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.