Repository navigation
[rel/4.5] Stabilize MSTest cleanup cancellation tests - #12304
Conversation
There was a problem hiding this comment.
Note
🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.
Reviewed VerifyNonCooperativeGlobalCleanupAsync in TestMethodInfoTests.cs. I found no blocking issues.
- Flakiness: Cancelling the local cleanup explicitly after
localEntered, instead of racing a 100ms fixture timer, removes the timing dependence. TheLongRunningstart for the non-sync-context path avoids thread-pool starvation from the blocking monitor. - Coverage: The new assertions are useful. They check that local cancellation doesn't bypass global cleanup and that the invocation still waits for it.
- Cleanup: The
finallywaits on the invocation and the dispatched or worker tasks together. It restoresPlatformServiceProvider.Instanceonly when those operations completed, so a hung operation can't leak into later tests. - Nit (non-blocking):
localSourceis written on the cleanup thread and read on the test thread. It is safe in practice becauselocalEntered.TrySetResultruns after the assignment andRunContinuationsAsynchronouslygives ordering. Thefinallyread oflocalSource?.Cancel()can run before startup, so it correctly tolerates null.
No inline findings.
This comment has been minimized.
This comment has been minimized.
|
Final test-triage resolution — Azure Pipelines build 1672618 Analysis is final and the evidence is complete. Build Signatures:
The other failed records are the intentional retry probes in the Windows app-model diagnostics artifacts. Their messages ("deliberately fails the first retry attempt", "The first AppContainer host fails so Retry must activate a second host") describe planned failures, so they are not defects. No issue was created: no matching open issue was found, and the evidence points to this pull request rather than a recurring problem on main or scheduled builds. Build-compilation analysis is left to Build Failure Analysis.
|
Pull request
Summary
Backport only the cleanup-test stabilization slice of #12296 to
rel/4.5for MSTest 4.5.3 / MTP 2.5.3.The local cleanup now signals that it has started before the test cancels its actual source, instead of racing a 100 ms fixture timeout against dispatch. The blocking monitor uses a dedicated long-running task, and cleanup joins the original invocation and workers before restoring
PlatformServiceProvider.Instance.Exactly one file changes:
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Execution/TestMethodInfoTests.cs(33 additions, 10 deletions). The helper matches upstream exactly. Excludes the analyzer and fatal-process probe portions of #12296, whose fixtures are absent from this release. No production code, dependencies, APIs, target frameworks, test deadlines, or assembly scheduling change. The existing five-second whole-test deadline remains intact, and the C# UTF-8 BOM is preserved.Design and decision record
This is a bounded test-harness backport using the rationale and implementation from #12296, not a feature or architecture change; a separate decision record is not needed.
d54bb2c77ae35141b0ea15472782c34b933ceaab55c9b81067a493fe2d9fd12d88dd22d426f457ca50fef0b4c0b41523b49fa6ff9e3142f3a42468dd8e7878aeeef0df67a9749ca9ec4fc84265a89325a41161c7d315bfaf0ef5ec67be22767e01ae9e1aThe fixed runs used this exact test-file blob; its identity was checked again after committing, with no source changes after validation.
Isolation: this assembly uses the internal sequential
TestContainerengine, not MSTest's parallel scheduler. Scope remains off. The process-local service provider and dummy lifecycle callbacks keep their existing ownership. Started/release rendezvous and bounded joins cover the original worker lifetime before shared-state restoration. No locks, opt-outs, or serialization settings were added or removed.Demonstration
Test-only change: no product UI or package demonstration is applicable. The before/after result reports contain the same 24 noncooperative cases per target, with no failed or skipped cases.
Validation and regression proof
Executed on Windows x64 with the release-pinned SDK
12.0.100-alpha.1.26480.103, repository build scripts, desktop MSBuild, and Release configuration. Both baseline and fixed builds completed with exit 0, zero warnings and zero errors, retaining all five project TFMs.The following commands were executed from the repository root in
cmd.exe. The PATH/PATHEXT changes are process-local; they repair native lookup of the already-installed Windows PowerShell, without changing repository/global settings or installing a machine-wide Windows SDK.Each host below was executed on both states with these arguments, using its own phase/TFM result directory. All ten host commands returned exit 0. The loop is a compact reproduction of those five expanded host invocations; run it with
$phase = 'baseline'after the baseline build and$phase = 'fixed'after the fixed build.All 30 TRX/JUnit/CTRF report files were parsed. Each format contains the same exact 24 expected method names for every phase/TFM, all passing: 120 baseline + 120 fixed executions, not three times that number. The three direct helper consumers executed exactly once in every run:
NonCooperativeTimeoutWaitsForGlobalCleanupAfterLocalCancellationNonCooperativeTimeoutOnSynchronizationContextWaitsForGlobalCleanupAfterLocalCancellationNonCooperativeTimeoutCancelsRenewedGlobalCleanupAtOriginalDeadlineReports and console logs are retained locally under
artifacts\TestResults\cleanup-backport\{baseline,fixed}\<TFM>\; binary logs are at the paths above. These local artifacts have not been uploaded.git diff --checkand the staged diff check passed; the committed helper was compared with upstream and the BOM verified.Test-value evidence
NonCooperative*selectionEvidence gap: the original intermittent 100 ms startup race was not reproduced in the local baseline, so these results are green-before/green-after preservation evidence, not a claimed deterministic red/green reproduction of that flake. No production mutation, full-suite, packaging or acceptance run was performed; this backport changes only the unit-test helper.