Skip to content

Fix ForceDirectedLayout.Tests CI crash: exclude native C ABI shim from code coverage#196

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/forcedirectedlayout-coverage-crash
May 31, 2026
Merged

Fix ForceDirectedLayout.Tests CI crash: exclude native C ABI shim from code coverage#196
matt-edmondson merged 1 commit into
mainfrom
fix/forcedirectedlayout-coverage-crash

Conversation

@matt-edmondson
Copy link
Copy Markdown
Contributor

Problem

CI run 26700545963 failed. All 498 tests pass, but the test host for ForceDirectedLayout.Tests crashes during code-coverage teardown:

Unhandled exception. System.Exception: Pipe was disconnected.
   at Microsoft.CodeCoverage.Interprocess.LoggerClient.ReadMessageFromPipe()
   ...TestingPlatformCoverageDynamicTestSessionLifetimeHandler.OnTestSessionFinishingAsync

→ process exit 0xE0434352, test-platform exit 7, job exit 1.

It is the only test assembly referencing code with [UnmanagedCallersOnly] native entry points (NativeExports). On the .NET 10 runner the coverage engine takes that assembly down the dynamic native-instrumentation path, which crashes — consistent with the .NET 10 dynamic-native-instrumentation breaking change and microsoft/codecoverage#202.

Fix

Mark NativeExports with [ExcludeFromCodeCoverage]. Those boundary methods are reachable only via native function pointers and cannot be exercised by managed tests anyway, so excluding them keeps the coverage instrumenter away from them while preserving coverage for the rest of the engine.

Rejected alternative: setting EnableMicrosoftTestingExtensionsCodeCoverage=false on the project breaks the run a different way — CI passes --coverage to every test app, so a project without the extension fails with an unknown-option error (verified: exit 5, only 478/498 tests run).

Also suppresses two new SonarAnalyzer warnings with justifications:

  • S1244 on Vec2D ==/Equals — exact equality is intentional for a blittable value type; a tolerance would break the Equals/GetHashCode contract.
  • S6640 on the unsafe NativeExports class — unsafe is required for C ABI pointer marshalling.

Verification

  • Clean Release build, 0 errors.
  • Exact KtsuBuild test command (dotnet test --coverage --coverage-output coverage.xml --report-trx …) → 498 pass, exit 0, coverage + TRX still produced.
  • ⚠️ The crash is CI-environment-specific — not reproducible locally across 6+ faithful invocations (local always uses the in-process collector). This CI run is the real verification.

🤖 Generated with Claude Code

ForceDirectedLayout.Tests crashed the Microsoft dynamic code-coverage collector during teardown (System.Exception: Pipe was disconnected, process exit 0xE0434352, test-platform exit 7) on the .NET 10 CI runner. It is the only test assembly referencing code with [UnmanagedCallersOnly] native entry points (NativeExports); the coverage engine takes that path and crashes per the .NET 10 dynamic-native-instrumentation behavior change.

Mark NativeExports with [ExcludeFromCodeCoverage] - those boundary methods are reachable only via native function pointers and cannot be exercised by managed tests anyway, so excluding them keeps the coverage instrumenter away from them while preserving coverage for the rest of the engine. (Disabling the coverage extension for the project is not viable: CI passes --coverage to every test app, so a project without the extension fails with an unknown-option error.)

Also suppress two new SonarAnalyzer warnings with justifications: S1244 on Vec2D ==/Equals (exact equality is intentional for a blittable value type; a tolerance would break the Equals/GetHashCode contract) and S6640 on the unsafe NativeExports class (unsafe is required for C ABI pointer marshalling).
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
11 Security Hotspots
23.5% Coverage on New Code (required ≥ 80%)
C Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@matt-edmondson matt-edmondson merged commit f764464 into main May 31, 2026
5 of 6 checks passed
@matt-edmondson matt-edmondson deleted the fix/forcedirectedlayout-coverage-crash branch May 31, 2026 03:07
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