Vendor a neutral SuspendCodeCoverage in PlatformServices (Phase 6e-4c3)#9632
Draft
Evangelink wants to merge 1 commit into
Draft
Conversation
TestDeployment (netfx) wrapped the deployment file copy in `using (new SuspendCodeCoverage())` to pause dynamic code-coverage instrumentation of modules loaded while files are copied. That type came from Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities. Vendor an internal neutral copy at Utilities/SuspendCodeCoverage.cs (namespace ...PlatformServices.Utilities) that reproduces the VSTest behavior byte-for-byte: - On construction: read the current value of the process environment variable "__VANGUARD_SUSPEND_INSTRUMENT__" and set it to "TRUE". - On dispose: restore the previously captured value (idempotent). The environment-variable name and value are the collector IPC contract the dynamic code-coverage (Vanguard) engine reads, so they are preserved exactly. The child-object is internal/sealed with a straightforward idempotent Dispose (the original's Dispose(bool)/GC.SuppressFinalize plumbing has no finalizer to suppress and is behavior-equivalent to the direct restore). TestDeployment now resolves SuspendCodeCoverage via the already-imported PlatformServices.Utilities namespace; the VSTest ObjectModel.Utilities using is removed. With this change PlatformServices has zero `using`/type references to the Microsoft.TestPlatform.ObjectModel package (only string-literal assembly names used for by-name runtime lookup remain), clearing the way to drop the package reference in the capstone. Verified: PlatformServices builds 0-warning (net462 and all real TFMs; netfx-guarded change); PlatformServices.UnitTests 935 (net462) / 897 (net8.0); PlatformServices.Desktop.IntegrationTests 15/15 (exercises the deployment path that runs inside the SuspendCodeCoverage scope). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 6e-4c3 — vendor a neutral
SuspendCodeCoveragePart of the initiative to make
Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServicesplatform-agnostic by removing its dependency onMicrosoft.TestPlatform.ObjectModel. Strict byte-for-byte, no behavior change.What this changes
TestDeployment(netfx) wraps the deployment file-copy inusing (new SuspendCodeCoverage())to pause dynamic code-coverage instrumentation of modules loaded while files are copied. That type came fromMicrosoft.VisualStudio.TestPlatform.ObjectModel.Utilities.This vendors an internal neutral copy at
Utilities/SuspendCodeCoverage.cs(namespace...PlatformServices.Utilities), reproducing the VSTest behavior exactly:__VANGUARD_SUSPEND_INSTRUMENT__, then set it toTRUE.The environment-variable name and value are the collector IPC contract the dynamic code-coverage (Vanguard) engine reads, so they are preserved byte-identical. The wrapper is
internal sealedwith a straightforward idempotentDispose— the original'sDispose(bool)/GC.SuppressFinalizeplumbing has no finalizer to suppress and is behavior-equivalent to the direct restore.TestDeploymentnow resolvesSuspendCodeCoveragethrough its already-presentusing ...PlatformServices.Utilities;; the VSTestObjectModel.Utilitiesusing (and its deferral comment) is removed.Fidelity proof and test-net limitation
The mechanism is a process environment variable (
__VANGUARD_SUSPEND_INSTRUMENT__), not a named event / mutex /EventWaitHandle. There is no signal/listener model — the dynamic code-coverage (Vanguard) collector reads this variable from the process environment when deciding whether to instrument a module being loaded. The fidelity of the vendored copy therefore rests entirely on replicating that wire contract byte-identically against the OSS source (vstestv18.4.0SuspendCodeCoverage.cs).Source-diff (fidelity proof of record) — OSS original vs vendored copy:
Microsoft.TestPlatform.ObjectModel)"__VANGUARD_SUSPEND_INSTRUMENT__""__VANGUARD_SUSPEND_INSTRUMENT__""TRUE""TRUE"EnvironmentVariableTarget.ProcessEnvironmentVariableTarget.ProcessGetEnvironmentVariable(name, Process)→ capture;SetEnvironmentVariable(name, "TRUE", Process)SetEnvironmentVariable(name, prev, Process), guarded by_isDisposedThe only intentional difference is the collapse of the OSS
Dispose()/protected virtual Dispose(bool)/GC.SuppressFinalizeinto a single idempotentDispose()— behavior-equivalent because the OSS type declares no finalizer (soGC.SuppressFinalizeis a no-op anddisposingis alwaystrueon the public path). The name/value/target/sequence — the entire wire contract the collector keys off — are verbatim.Note on the test net:
PlatformServices.Desktop.IntegrationTestsruns with no coverage collector attached, so its green result proves the vendored code does not crash / the deploy path still works — it does not exercise a real collector reading the variable. That is acceptable here precisely because there is no signaling to get wrong: correctness is fully determined by the (source-identical) variable name/value/target above. There is no clean seam to assert the variable mid-deploy without contorting the copy loop, so no brittle probe was added.Result: PlatformServices is ObjectModel-type-free
After this change, PlatformServices has zero
using/type references to theMicrosoft.TestPlatform.ObjectModelpackage — only string-literal assembly names (used for by-name runtime assembly lookup in the AppDomain/source-host wiring) remain. This clears the way to drop the package reference in the capstone (Phase 7).Verification
MSTestAdapter.PlatformServices.UnitTests: 935/935 (net462), 897/897 (net8.0).PlatformServices.Desktop.IntegrationTests: 15/15 (net462) — exercises the deployment path that runs inside theSuspendCodeCoveragescope.Stacking
Stacks on #9631 (Phase 6e-4c2); base branch
dev/amauryleve/vstest-decoupling-sourcehandler. Review/merge after the earlier PRs in the chain reach the base. Do not squash-rebase the base.