Add live Azure DevOps test result publishing#8297
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds opt-in live Azure DevOps test-result publishing to the existing Azure DevOps reporting extension, using REST APIs plus multi-process run coordination.
Changes:
- Adds new
--publish-azdo-*CLI options and wires the live publisher intoAddAzureDevOpsProvider(). - Implements REST client, result batching, run-id coordination, and localized resource strings.
- Adds unit coverage and updates all-extensions help/info expectations.
Show a summary per file
| File | Description |
|---|---|
Directory.Packages.props |
Adds System.Text.Json package version. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Microsoft.Testing.Extensions.AzureDevOpsReport.csproj |
References System.Text.Json. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/AzureDevOpsCommandLineOptions.cs |
Adds live publishing option names. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/AzureDevOpsCommandLineProvider.cs |
Registers and validates new CLI options. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/AzureDevOpsExtensions.cs |
Wires publisher as data consumer and session lifetime handler. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/AzureDevOpsLivePublishingModels.cs |
Adds live publishing constants and DTOs. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/AzureDevOpsRunIdCoordinator.cs |
Adds multi-process run-id coordination. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/AzureDevOpsTestResultsClient.cs |
Adds Azure DevOps REST client. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/AzureDevOpsTestResultsPublisher.cs |
Adds live result publishing lifecycle and batching. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/IAzureDevOpsTestResultsClient.cs |
Adds internal client abstraction. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/AzureDevOpsResources.resx |
Adds localized strings for options and warnings. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.cs.xlf |
Updates Czech localization resources. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.de.xlf |
Updates German localization resources. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.es.xlf |
Updates Spanish localization resources. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.fr.xlf |
Updates French localization resources. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.it.xlf |
Updates Italian localization resources. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.ja.xlf |
Updates Japanese localization resources. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.ko.xlf |
Updates Korean localization resources. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.pl.xlf |
Updates Polish localization resources. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.pt-BR.xlf |
Updates Portuguese localization resources. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.ru.xlf |
Updates Russian localization resources. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.tr.xlf |
Updates Turkish localization resources. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.zh-Hans.xlf |
Updates Simplified Chinese localization resources. |
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/Resources/xlf/AzureDevOpsResources.zh-Hant.xlf |
Updates Traditional Chinese localization resources. |
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.cs |
Updates help/info expectations for new options. |
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/AzureDevOpsLivePublishingTests.cs |
Adds live publishing unit tests. |
Copilot's findings
- Files reviewed: 26/26 changed files
- Comments generated: 6
|
@copilot address review comments |
…n id validation, cleanup token, cross-platform path, resx typo Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
All six review comments addressed in commit
|
|
@copilot address review comments |
There was a problem hiding this comment.
Copilot's findings
Comments suppressed due to low confidence (2)
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.cs:360
- This expected provider description still uses
AzureDev Ops, while the resource string now usesAzure DevOps; the--infoacceptance expectation should be updated to the corrected spelling.
Description: Azure DevOps report generator to write errors to the output in a way that AzureDev Ops understands.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.cs:373
- This expected option description still uses
AzureDev Ops, but the option resource now saysAzure DevOps, so this--infoexpectation will not match the generated output.
Description: Enable Azure DevOps report generator to write errors to the output in a way that AzureDev Ops understands.
- Files reviewed: 26/26 changed files
- Comments generated: 3
|
@copilot address review comments |
All six review comments were already addressed in commit |
|
@copilot address review comments |
… OCE in flush, add background flush loop Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
…ore OCE filter on second catch Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
All three review comments addressed across two commits: Issue A — Acceptance test string fix (
Issue B — OCE preventing finalization (
Issue C — Background flush loop (
Using real All 34 AzureDevOps unit tests still pass (0 warnings, 0 errors). |
All three open review comments are addressed in the existing commits (
Build: 0 warnings, 0 errors. Unit tests: 34/34 passed. |
Use comparer.GetType().Name (simple name) instead of .ToString() (full name) so the rendered diagnostic message matches the AssertTests.AreAll.cs expectations and is consistent with Assert.Contains. This resolves the failing AreAllDistinct_*_WithComparer_HasDuplicate_ShouldFail tests in CI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Status update on this PR: Review comments
Failing CI tests ( |
C10 (run-state semantics): stop marking the Azure DevOps run as 'Aborted' just because individual tests failed. ExitCode.Success and ExitCode.AtLeastOneTestFailed are both normal completions; anything else (TestSessionAborted, TestHostProcessExitedNonGracefully, TestAdapterTestSessionFailure, MinimumExpectedTestsPolicyViolation, ...) plus session cancellation or HasTestAdapterTestSessionFailure now mark the run as Aborted. Embeds ExitCodes.cs as a shared source file matching the TrxReport extension. C11 (lease-read race): replace nullable TryReadLeaseFile with a tri-state LeaseReadResult (NotFound/Active/Expired/TransientReadError). TryAcquireOwnerAsync only deletes/clobbers the owner file on NotFound or Expired; an unreadable file (sharing-violation/partial write/garbage JSON) is treated as an active lease so two processes can't both create runs. CleanupStaleParticipants applies the same logic for participant files. C12 (joiner give-up): WaitForRunIdFileAsync now also takes the owner file path. After the initial CoordinationReadRetryCount budget, it keeps polling while the owner lease still looks Active/TransientReadError (or Expired with the owner PID still alive), capped by the new CoordinationJoinerMaxWaitTime option (default 2 minutes). A healthy slow CreateTestRunAsync no longer makes joiners abandon and silently stop publishing. New regression tests cover Completed-vs-Aborted state mapping for failing/aborted/canceled/adapter-failure exit paths, unreadable owner-file preservation, joiner waiting through an exhausted retry budget while owner lease is valid, and joiner take-over when the owner lease has expired with a dead PID. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Addressed all 12 review comments — pushed in e7f511a. Already in place from earlier review pass (commit 70d72f2)
Newly addressed in e7f511a
Validation
Reply posted on each conversation thread above with concrete file:line citations. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Part 1 of the brainstorm in #5951 — adds opt-in live test-result publishing to the Azure DevOps Tests tab via the REST API. No
Microsoft.TeamFoundationServer.Clientdependency; justHttpClient+System.Text.Json.Why
Today, getting results into the AzDO Tests tab requires generating a TRX and adding a downstream
PublishTestResults@2task. Two real problems:This PR publishes results to a single AzDO run as tests finish, with no TRX dependency.
What
Two new opt-in CLI options on
Microsoft.Testing.Extensions.AzureDevOpsReport:--publish-azdo-test-resultsSYSTEM_ACCESSTOKEN/SYSTEM_COLLECTIONURI/SYSTEM_TEAMPROJECTis missing.--publish-azdo-run-name <name><assembly> (<tfm>) on <agent>(or<stage>/<job>when present, sanitized). Requires--publish-azdo-test-results.Wired into the existing
AddAzureDevOpsProvider()— no new public API.How it works
Authorization: Basic base64(":<SYSTEM_ACCESSTOKEN>")(AzDO's standard PAT-as-basic-auth pattern). Token never logged.POST {project}/_apis/test/runs?api-version=7.1at session start, batchedPOST .../results?api-version=7.1asTestNodeUpdateMessages flow in,PATCH .../runs/{id}?api-version=7.1toCompleted(orAbortedon cancellation) at session end.AzureDevOpsRunIdCoordinatorwrites aazdo-runid.<buildId>.{owner,json,participant.<pid>.json}set underTestResultsDirectory. The first process creates the run; joiners read the id and publish into the same run. The owner waits for participants to drain (bounded timeout, defaults to 30s) before finalizing.HttpRequestException,IOException,SocketException, andTaskCanceledException(3 attempts, exponential backoff, 429 honorsRetry-After). All callbacks catchException ex when ex is not OperationCanceledExceptionand log a warning — publishing failures never fail the test run.Timeoutand per-request linkedCancellationTokenSource(15s).Highlights from the expert-reviewer round
Implementation went through one full round of
expert-reviewer. Critical/major issues addressed:FinalizeRunAsyncwait (no infinite hang on recycled PIDs).azdo-runid.jsonfrom a prior build no longer poisons the next build (ExpiresAtvalidated; coordination filenames keyed byBUILD_BUILDID; owner failures clean up the owner file).Exception ex when ex is not OperationCanceledExceptionsoJsonException/IOException/SocketExceptionno longer escapeIDataConsumercallbacks.HttpClient.Timeout+ per-request linked CTS — eliminates publisher-wide deadlock on a hung endpoint._lastFlushTimeis nowlong ticks+Interlocked.Read/Exchange(no tornDateTimeOffsetreads).ReadAsByteArrayAsync(ct)/ReadAsStringAsync(ct)under#if NET.HttpRequestException or IOException or SocketException or TaskCanceledException.[JsonPropertyName]on every wire DTO (request and response).automatedTestStoragenow strips the extension so it matches legacy TRX-uploaded history keys.Environment.ProcessId/int.MaxValuefor alive/dead PIDs and unique temp dirs underPath.GetTempPath()with cleanup-on-failure.Owner re-election on owner-process crash is deferred behind a clear
TODO(AzureDevOpsRunIdCoordinator.cs) with periodic lease renewal so a clean run never trips the bounded wait.Tests
127 unit tests pass. New coverage in
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/AzureDevOpsLivePublishingTests.cs:Retry-After.HelpInfoAllExtensionsTestsexpectations updated for the new options (both--helpand--infoblocks, alphabetical order preserved).Build status (local)
.\.dotnet\dotnet.exe build src\Platform\Microsoft.Testing.Extensions.AzureDevOpsReport\Microsoft.Testing.Extensions.AzureDevOpsReport.csproj -c Debug— 0 warnings, 0 errors..\.dotnet\dotnet.exe test test\UnitTests\Microsoft.Testing.Extensions.UnitTests\Microsoft.Testing.Extensions.UnitTests.csproj— 127/127 passed..\build.cmd -pack— 0 warnings, 0 errors.Out of scope (deliberate)
Checklist
/t:UpdateXlf, not hand-edited).\build.cmdgreen (0 warnings, 0 errors)Refs #5951