Skip to content

Fix non-deterministic branch coverage in HedgingExecutionContext hedging delay tests#2997

Merged
martincostello merged 3 commits into
mainfrom
copilot/investigate-test-coverage-hedging-context
Mar 19, 2026
Merged

Fix non-deterministic branch coverage in HedgingExecutionContext hedging delay tests#2997
martincostello merged 3 commits into
mainfrom
copilot/investigate-test-coverage-hedging-context

Conversation

Copilot AI commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

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 the IsCompleted check dependent on non-deterministic async continuation scheduling.

Changes

  • Replaced TryWaitForCompletedExecutionAsync_HedgedExecution_Ok with 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, so whenAnyHedgedTask.IsCompleted is deterministically false and the method deterministically returns null (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, so whenAnyHedgedTask.IsCompleted is deterministically true and the method deterministically returns the completed execution (result.ShouldNotBeNull()).
  • Both tests are parameterised with continueOnCapturedContext = true/false, preserving the original ConfigureAwait flag coverage.

With these changes, inverting the condition at line 132 will always cause at least one test to fail.

Confirm the following

  • I started this PR by branching from the head of the default branch
  • I have targeted the PR to merge into the default branch
  • I have included unit tests for the issue/feature
  • I have successfully run a local build

💡 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.

…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>
Copilot AI changed the title [WIP] Investigate and improve test coverage for HedgingExecutionContext Fix non-deterministic branch coverage in HedgingExecutionContext hedging delay tests Mar 19, 2026
Copilot AI requested a review from martincostello March 19, 2026 17:01
@codecov

codecov Bot commented Mar 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.15%. Comparing base (fee0048) to head (04043fe).
⚠️ Report is 5 commits behind head on main.
✅ All tests successful. No failed tests found.

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           
Flag Coverage Δ
linux 96.15% <ø> (ø)
macos 96.15% <ø> (ø)
windows 96.15% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Refactoring to make the tests a bit more readable and a little less repetitive.
@martincostello martincostello marked this pull request as ready for review March 19, 2026 18:17
Copilot AI review requested due to automatic review settings March 19, 2026 18:17
@martincostello martincostello enabled auto-merge (squash) March 19, 2026 18:17
@martincostello martincostello merged commit 51c138e into main Mar 19, 2026
30 checks passed
@martincostello martincostello deleted the copilot/investigate-test-coverage-hedging-context branch March 19, 2026 18:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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/false coverage for both new tests.
  • Minor refactors/cleanup in the test file (consistent attribute ordering, reuse of common TimeSpan values, a few additional safety assertions).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

IhateTrains pushed a commit to ParadoxGameConverters/ImperatorToCK3 that referenced this pull request Jun 11, 2026
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>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=Polly&package-manager=nuget&previous-version=8.6.6&new-version=8.7.0)](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>
github-actions Bot pushed a commit to IntelliTect/EssentialCSharp.ListingManager that referenced this pull request Jun 11, 2026
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>
This was referenced Jun 11, 2026
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.

3 participants