Skip to content

Port upstream xunit v3 / Microsoft.Testing.Platform v2 migration (App-vNext/Polly@1a80392b) #34

Description

@iancooper

Summary

Port upstream App-vNext/Polly@1a80392b — "Update to xunit v3" (App-vNext/Polly#3131) — to Fences.

Split out of the first upstream sync (#28), where it was triaged port, as its own piece of work. It is too large and too cross-cutting to go through the sync's normal one-commit-at-a-time porting (33 files, +1634 / −139), but it must not be left behind: every later upstream change that touches tests, build scripts, coverage or Stryker config will be written against xunit v3 / Microsoft.Testing.Platform v2. The longer Fences stays on xunit v2, the harder each future sync becomes, and the further we drift from the "rebrand, don't redesign" alignment ADR 0003 commits us to.

What the upstream commit does

From its description, and the diff:

  • xunit v2 → xunit v3 (xunit 2.9.3 → xunit.v3.mtp-v2 / xunit.v3.assert 4.0.0; FsCheck.Xunit → FsCheck.Xunit.v3). Test projects become <OutputType>Exe</OutputType>; Xunit.Abstractions usings go.
  • Microsoft.Testing.Platform v2 as the test runner (Microsoft.Testing.Platform 2.4.0).
  • Replaces coverlet entirely. coverlet.msbuild and the ReportGenerator package are removed; coverage comes from Microsoft.Testing.Extensions.CodeCoverage, written as Cobertura to one file per target framework (coverage.<tfm>.xml). Report generation and threshold enforcement move out of eng/Test.targets into cake.cs tasks (__GenerateCoverageReports, __VerifyCoverageThresholds), which still read each project's <Threshold>.
  • Changes coverage thresholds: Polly.Specs goes from 94,94,91 to 96,95,93 under the new counter.
  • Stryker: disables MinVer during mutation runs to work around a Stryker issue with MTP v2 (eng/stryker-config.json, .github/workflows/mutation-tests.yml).
  • Tooling: adds dotnet-reportgenerator-globaltool 5.5.11 as a local tool and bumps another tool 4.16.0 → 5.0.0 (.config/dotnet-tools.json).
  • Production code changes, made to extend or suppress coverage where mutants went missing: Hedging/Controller/TaskExecution.cs, Retry/RetryHelper.cs, ConcurrentDictionaryExtensions.cs, Telemetry/TelemetryOptions.cs, Telemetry/TelemetryUtil.cs. Each needs checking against ADR 0003 D7 (no public API change) and the .PublicAPI/ baselines.
  • Adds a test collection for tests that depend on the system clock.

Relationship to #14

This directly affects #14, which is about coverlet's unreliable collection and the coverlet 10 upgrade (#6). Upstream no longer uses coverlet at all. See the comment on #14 for the detail. The short version: porting this likely changes #14's question, from "how do we make coverlet reliable" to "how do we validate thresholds under Microsoft's coverage tool". The two should be decided together, not on separate tracks.

Things to settle before implementing

  • Dependencies. This adds, removes and bumps packages and tools. CLAUDE.md forbids dependency changes unless asked, so this issue is the ask. Check that each version is still current when the work starts, and reconcile with whatever Fences' own Dependabot has moved in the meantime.
  • Fences-only test conventions. Fences' tests diverge from upstream's (NSubstitute, Member_Scenario_Outcome naming, test/Paramore.Fences.* project names). The xunit v3 API changes (ITestOutputHelper namespace, async lifetime, TestContext cancellation) have to be applied to Fences' own versions of the files, not copied over.
  • Mutation score. Verification gate 5 says Stryker scores must not regress. The MinVer workaround and any coverage suppressions must keep that true, especially given the mutations-core hang already seen in CI.
  • CI. Codecov upload paths, the validate-packages job, and anything else that reads artifacts/coverage-reports must follow the new layout.

Given the size, this probably merits running through the spec workflow (/spec:requirements → design → tasks) rather than a single PR.

Acceptance

Activity

  1. iancooper commented on Sep 27, 2026

    @iancooper
    MemberAuthor

    Part of App-vNext/Polly@f35bc00d (.NET 11 prep) is waiting on this port. It edits test/Polly.Specs/ContextDictionarySpecs.cs, PolicyOverloadSmokeSpecs.cs and Timeout/TimeoutOverloadSmokeSpecs.cs, and all three files were created by 1a80392b. The build-props half of f35bc00d is ported separately. Those three Specs edits should land with, or straight after, this port. See #28.

  2. added a commit that references this issue on Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions