Skip to content

fix(build): hold the coverage collector at 18.10.0 - #4453

Merged
glennawatson merged 1 commit into
mainfrom
fix/coverage-collector-abandoned-mutex
Sep 4, 2026
Merged

fix(build): hold the coverage collector at 18.10.0#4453
glennawatson merged 1 commit into
mainfrom
fix/coverage-collector-abandoned-mutex

Conversation

@glennawatson

@glennawatson glennawatson commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

What kind of change does this PR introduce?

Build fix. One version pin, no product or test source changes.

What is the new behavior?

A solution-wide run finishes cleanly, and the coverage it reports is complete again.

  • Microsoft.Testing.Extensions.CodeCoverage is held at 18.10.0.

  • Union coverage over a full dotnet test --solution --coverage run, same commit, only the collector version differing:

    collector exit line coverage branch coverage
    18.10.0 0 12820/13537 = 94.703% 1051/1334 = 78.786%
    18.11.0 7 12097/13537 = 89.362% 1005/1334 = 75.337%

    The aborting host never reconciles its buffers, so its data is dropped and the reported number silently falls by about 5.3 points of line coverage. The pin recovers it.

  • The pin carries a comment describing the failure, so the next bump gets checked against it rather than taken on trust.

What is the current behavior?

A test host that has run every test successfully aborts during session teardown, and the run reports exit code 7:

Unhandled exception. System.Threading.AbandonedMutexException: The wait completed due to an abandoned mutex.
   at Microsoft.CodeCoverage.Core.Threading.Mutex.WaitOne(TimeSpan timeout)
   at Microsoft.CodeCoverage.Instrumentation.SharedBufferReconciler.Reconcile(...)
   at Microsoft.Testing.Extensions.CodeCoverage.TestingPlatformCoverageDynamicTestSessionLifetimeHandler.OnTestSessionFinishingAsync(...)

SharedBufferReconciler waits on a cross-process mutex to reconcile coverage buffers. A solution-wide run passes that mutex between many concurrently running hosts, so when one exits while still owning it the next waiter is handed an AbandonedMutexException, which the collector does not handle. The exception goes unhandled, the process aborts with SIGABRT, and the platform maps that to exit code 7.

It lands on whichever assembly loses the race rather than on a particular test, which is why a single arbitrary assembly went red while its near-identical sibling passed in the same run. All 34300 tests pass either way; the crash is purely in teardown.

18.11.0 is the newest published version, so there is no later release to move forward to.

What might this PR break?

  • Nothing shipped. Microsoft.Testing.Extensions.CodeCoverage is test-only tooling and is not a dependency of any published package.
  • Coverage collection is unchanged in shape; 18.10.0 emits the same cobertura the CI coverage job already consumes, and reports more of it.
  • Microsoft.Testing.Platform.MSBuild deliberately stays at 2.4.0. It appears in the stack only as the calling frame; the defect is in the collector.

Checklist

  • I have read the Contribute guide
  • Tests have been added or updated (for bug fixes / features)
  • Docs have been added or updated (for bug fixes / features)
  • Changes target the main branch
  • PR title follows Conventional Commits

Additional information

The crash needs the whole solution running concurrently, not one assembly: looping a single test project 25 times never reproduced it, while a full --coverage solution run reproduced exit 7 on Linux as well. It is a race across hosts, not something specific to the macOS runner.

The stack is not visible through --log-failed, which shows only the runner's exit code; it is in the full job log.

- On 18.11.0 a test host that passed every test aborts with SIGABRT while the
  session finishes, and the run reports exit code 7.
- The collector's SharedBufferReconciler waits on a cross-process mutex. A
  solution-wide run hands that mutex between many hosts, so when one exits still
  owning it the next waiter gets an AbandonedMutexException the collector does
  not handle.
- It hits whichever assembly loses the race, which is why only the macOS leg
  went red.
@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.92%. Comparing base (6a2ef8a) to head (56333ae).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4453   +/-   ##
=======================================
  Coverage   93.92%   93.92%           
=======================================
  Files         359      359           
  Lines       15105    15105           
  Branches     1568     1568           
=======================================
  Hits        14188    14188           
  Misses        674      674           
  Partials      243      243           

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sonarqubecloud

sonarqubecloud Bot commented Sep 4, 2026

Copy link
Copy Markdown

@glennawatson
glennawatson merged commit d2c79cf into main Sep 4, 2026
13 checks passed
@glennawatson
glennawatson deleted the fix/coverage-collector-abandoned-mutex branch September 4, 2026 03:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant