Re-enable net481 code coverage once coverlet .NET Framework instrumentation is fixed
- Dominant language
- C#
- Stars
- 4.9k
- Forks
- 1.1k
- Avg merge
- 20h 23m
- Merged PRs (30d)
- 103
Description
Code coverage collection is currently disabled for the `net481` target because coverlet 8.0.0 crashes when instrumenting .NET Framework assemblies. This issue tracks re-enabling it once the upstream bugs are fixed.
## Issue
Debug/x64 PR builds fail at **test execution** (not compilation), with every test in the `net481` leg throwing:
```text
System.TypeInitializationException : The type initializer for
'Coverlet.Core.Instrumentation.Tracker.Microsoft.Private.Windows.Polyfills.Tests_d6550c7c-fd38-4022-a909-2613cf55c4ed'
threw an exception.
---- System.IO.FileNotFoundException : Could not load file or assembly
'System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
or one of its dependencies. The system cannot find the file specified.
```
Only this leg is affected because `eng/pipelines/build-PR.yml` enables `Coverage` solely for public Debug x64 builds.
## Root cause
Commit f3422f95a (dotnet/winforms#14371) bumped `CoverletMSBuildPackageVersion` from 6.0.0 to 8.0.0 in `eng/Versions.props`.
Coverlet 8.0.0 selects its task assembly by **MSBuild host, not target framework** (`buildMultiTargeting/coverlet.msbuild.props`):
```xml
$(MSBuildThisFileDirectory)..\tasks\net8.0\
```
Arcade builds with `dotnet build`, so the `net8.0` flavor is loaded. Its `coverlet.core.dll` references `System.Runtime 8.0.0.0` (the `netstandard2.0` flavor, and 6.0.0, reference `netstandard 2.0.0.0`). The instrumenter copies its tracker template IL out of the loaded `coverlet.core.dll` into the assembly under test, carrying that reference along — so the tracker injected into our **net481** test assembly references an assembly the .NET Framework CLR cannot resolve, and its static constructor throws on the first recorded hit.
This is an acknowledged upstream regression, not an intentional change: [coverlet-coverage/coverlet#1818](https://github.com/coverlet-coverage/coverlet/issues/1818) (identical repro on `net481`/x64, labeled `bug`, fixed in coverlet 8.0.1).
## Temporary fix
In `Directory.Build.props`, inside the `'$(Coverage)' == 'true'` group:
```xml
false
```
Tests still build and run; only .NET Framework coverage *collection* is skipped. There is no real loss of signal — that leg was producing a red build and no valid coverage data.
Affected projects (the only ones that are both `IsTestProject=true` and target `net481`):
| Project | Effect |
| --- | --- |
| `Microsoft.Private.Windows.Polyfills.Tests` | No longer contributes coverage (its `$(NetCurrent)` leg already had `CollectCoverage=false`) |
| `System.Private.Windows.Core.Tests` | `net481` leg not instrumented; .NET leg unchanged |
## Change needed once coverlet fixes this
Do **not** simply bump the package version — every release after 6.x is still broken for .NET Framework. All references below are in the [coverlet-coverage/coverlet](https://github.com/coverlet-coverage/coverlet) repo:
| Version | .NET Framework behaviour |
| --- | --- |
| 6.0.x | Works (tracker references `netstandard 2.0.0.0`) |
| 8.0.0 | This crash ([coverlet-coverage/coverlet#1818](https://github.com/coverlet-coverage/coverlet/issues/1818)) |
| 8.0.1 | Crash fixed, but no coverage reported at all ([coverlet-coverage/coverlet#1842](https://github.com/coverlet-coverage/coverlet/issues/1842)) |
| 10.0.0 | Fixes coverlet#1842; the fix for silent zero coverage since 8.0.0 ([coverlet-coverage/coverlet#1985](https://github.com/coverlet-coverage/coverlet/pull/1985)) is still unreleased |
| 10.0.1 | New regression: `TypeInitializationException: Could not load type 'System.Collections.Concurrent.ConcurrentBag\`1'` on `net481` ([coverlet-coverage/coverlet#2009](https://github.com/coverlet-coverage/coverlet/issues/2009)); fix ([coverlet-coverage/coverlet#2010](https://github.com/coverlet-coverage/coverlet/pull/2010)) unreleased |
Wait for [coverlet-coverage/coverlet#1985](https://github.com/coverlet-coverage/coverlet/pull/1985) and [coverlet-coverage/coverlet#2010](https://github.com/coverlet-coverage/coverlet/pull/2010) to ship in a release, then:
1. Update `CoverletMSBuildPackageVersion` in `eng/Versions.props`.
2. Remove the `CollectCoverage` override and its explanatory comment from `Directory.Build.props`.
3. Verify a `net481` coverage file is actually produced under `artifacts\bin\\Debug\net481\coverage\` — the failure mode in [coverlet-coverage/coverlet#1842](https://github.com/coverlet-coverage/coverlet/issues/1842) is silent, so a green build alone does not confirm success.
Contributor guide
Assessment
This issue has not been assessed yet.