Use HTTP transport for browser dotnettestcli#10143
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9cf9bdca-8f9a-436e-a367-6689c3fe8fa3
There was a problem hiding this comment.
Pull request overview
Adds an authenticated HTTP transport for the dotnettestcli protocol, enabling browser-WASM while preserving binary framing and named-pipe compatibility.
Changes:
- Adds HTTP request/reply transport, bootstrap validation, and diagnostic redaction.
- Adds unit and browser-WASM gateway coverage.
- Updates protocol documentation, resources, help expectations, and API baselines.
Show a summary per file
| File | Description |
|---|---|
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Microsoft.Testing.Platform.UnitTests.csproj |
Links HTTP transport into supported test targets. |
test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/DotnetTestHttpClientTests.cs |
Tests HTTP framing, authentication, ordering, and failures. |
test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs |
Tests transport option validation. |
test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineArgumentsRedactorTests.cs |
Tests token and endpoint redaction. |
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs |
Updates hidden option expectations. |
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.cs |
Updates all-extension option expectations. |
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/BrowserWasmExecutionTests.cs |
Adds live browser-WASM HTTP gateway scenarios. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/Transport/DotnetTestHttpClient.cs |
Implements authenticated HTTP request/reply transport. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/DotnetTestDataConsumer.cs |
Enables browser-compatible consumption. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestHelper.cs |
Resolves selected transport. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestConnection.cs |
Integrates HTTP and guards named-pipe operations. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf |
Adds localized resource entries. |
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx |
Defines transport messages and descriptions. |
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.cs |
Exposes new resources to tests. |
src/Platform/Microsoft.Testing.Platform/OutputDevice/DotnetTestPassthroughOutputDevice.cs |
Removes obsolete browser suppressions. |
src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeConnectionBase.cs |
Generalizes framing to streams and adds size limits. |
src/Platform/Microsoft.Testing.Platform/InternalAPI/InternalAPI.Unshipped.txt |
Tracks new and changed internal APIs. |
src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs |
Registers and validates HTTP bootstrap options. |
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineArgumentsRedactor.cs |
Redacts sensitive bootstrap arguments. |
src/Platform/Microsoft.Testing.Platform/Builder/TestApplication.cs |
Uses redaction for diagnostic logging. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/InternalAPI/InternalAPI.Unshipped.txt |
Tracks shared framing API changes. |
src/Platform/Microsoft.Testing.Extensions.Retry/InternalAPI/InternalAPI.Unshipped.txt |
Tracks shared framing API changes. |
src/Platform/Microsoft.Testing.Extensions.MSBuild/InternalAPI.Unshipped.txt |
Tracks shared framing API changes. |
src/Platform/Microsoft.Testing.Extensions.HangDump/InternalAPI/InternalAPI.Unshipped.txt |
Tracks shared framing API changes. |
docs/mstest-runner-protocol/004-protocol-dotnet-test-pipe.md |
Documents HTTP transport and gateway contract. |
Review details
- Files reviewed: 37/37 changed files
- Comments generated: 3
- Review effort level: Medium
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9cf9bdca-8f9a-436e-a367-6689c3fe8fa3
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (2)
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/Transport/DotnetTestHttpClient.cs:134
- On
netstandard2.0consumers,HttpResponseMessage.Contentcan be null. A valid 2xx response with no body therefore throwsNullReferenceExceptionhere instead of the transport's expectedIOExceptionfor a missing content type/frame. Read the media type null-safely so an absent body follows the existing validation error path.
if (!MediaType.Equals(httpResponse.Content.Headers.ContentType?.MediaType, StringComparison.OrdinalIgnoreCase))
{
throw new IOException(
$"The dotnet test HTTP gateway returned content type '{httpResponse.Content.Headers.ContentType?.MediaType ?? "missing"}' instead of '{MediaType}'.");
}
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineArgumentsRedactor.cs:49
- A bearer token may validly begin with
-, but this branch treats such a separate argument as an unrelated option and logs it verbatim. Logging occurs before command-line validation, so--dotnet-test-http-token -secretexposes the token even though parsing later rejects the launch. When a sensitive value is pending, fail closed by redacting an unrecognized option-shaped argument; only recognized sensitive options should replace the pending state.
else
{
redacted[i] = arg;
redactNextValue = false;
sanitizeNextEndpoint = false;
}
- Files reviewed: 37/37 changed files
- Comments generated: 0 new
- Review effort level: Medium
|
@copilot resolve the merge conflicts in this pull request |
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9cf9bdca-8f9a-436e-a367-6689c3fe8fa3
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9cf9bdca-8f9a-436e-a367-6689c3fe8fa3
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9cf9bdca-8f9a-436e-a367-6689c3fe8fa3
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9cf9bdca-8f9a-436e-a367-6689c3fe8fa3
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9cf9bdca-8f9a-436e-a367-6689c3fe8fa3
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
src/Platform/Microsoft.Testing.Platform/CommandLine/Parser.cs:56
- A response-file path after a malformed sensitive option still leaks. For example,
---dotnet-test-http-token @secret-tokenleavescurrentOptionnull, so the response-file error reportssecret-tokenverbatim even though the argument redactor recognizes this sequence as sensitive. Derive the diagnostic path from the redacted argument sequence so malformed/leading-whitespace sensitive options are covered too.
bool containsSensitiveValue =
PlatformCommandLineProvider.DotNetTestHttpTokenOptionKey.Equals(currentOption, StringComparison.OrdinalIgnoreCase)
|| PlatformCommandLineProvider.DotNetTestHttpEndpointOptionKey.Equals(currentOption, StringComparison.OrdinalIgnoreCase);
string diagnosticPath = containsSensitiveValue ? "***REDACTED***" : responseFilePath;
- Files reviewed: 43/43 changed files
- Comments generated: 0 new
- Review effort level: Medium
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9cf9bdca-8f9a-436e-a367-6689c3fe8fa3
This comment has been minimized.
This comment has been minimized.
🧪 Test quality grade — PR #1014345 new test methods graded across 5 files. Every test grades A (90–100). The suite demonstrates exceptional quality: meaningful DataRow parameterization covering security-relevant boundary cases, precise
This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with
|
Summary
Uses authenticated HTTP request/reply as the browser-compatible transport for
--server dotnettestcli, replacing the WebSocket implementation from #10118 while preserving the existing versioned binary serializer/message contract and legacy--dotnet-test-pipe <name>behavior.The primary channel is entirely host-initiated request/reply. Each existing framed host request becomes one authenticated binary HTTP POST, and the response body contains exactly one existing framed reply. Exactly one request is allowed in flight, preserving protocol ordering without polling, SSE, redirects, or retries.
Merge order
#10149 is the focused revert of the WebSocket implementation from #10118. This HTTP branch was implemented independently from the WebSocket branch, so it is expected to report conflicts while #10118 remains on
main.main.Do not merge this PR before #10149.
Bootstrap
Hidden pre-launch options:
--dotnet-test-transport pipeis also accepted explicitly. Omitting the transport continues to infer the legacy named-pipe path from--dotnet-test-pipe.SDK HTTP gateway contract
For every host-initiated protocol interaction, the SDK gateway accepts:
A successful response must be
2xx, useContent-Type: application/octet-stream, and contain exactly one complete existing dotnettestcli frame. The frame remains the existing little-endian length prefix, serializer ID, and versioned serializer payload; no serializer IDs, field IDs, layouts, or supported protocol versions change.The gateway must:
POST,Authorization, andContent-Type;HTTP has no persistent disconnect signal: loss is detected by the current or next POST. SDK-initiated reverse control (
ServerControlPipeName, currently cancellation) remains named-pipe-only and outside this primary-channel change.Why HTTP
HttpClient/fetch; no custom JavaScript transportThe current protocol only needs host-initiated request/reply. HTTP therefore delivers the required behavior with substantially less permanent browser-specific code, a bearer header instead of a URL token, and no wire-version change. The accepted tradeoffs are per-request overhead, CORS/PNA requirements, and weaker idle disconnect detection.
Safety and review hardening
application/octet-streamresponses before frame decoding.All review comments through commit
1af0d2098are addressed and replied to.Validation
DotnetTestHttpClientTests: 16/16 passed.CommandLineArgumentsRedactorTests: 7/7 passed.PlatformCommandLineProviderTests: 100/100 passed.BrowserWasmExecution_DotnetTestHttpTransportExercisesLiveGateway: passed under Node/browser-wasm, covering handshake, help, discovery, execution/session traffic, bearer auth, framing, ordering, unauthorized response, disconnect, and cancellation.DotnetTestPipeBaselineTests: 5/5 passed..\build.cmd -pack -bl /p:RepositoryCommit=a467c796c566b855eb645d6752eedbc00f8204de: succeeded with 0 warnings and 0 errors; produced packages passed content and metadata validation.