fix(mtp): send run request test selection as tests not testCases - #3755
Open
Evangelink wants to merge 2 commits into
Open
fix(mtp): send run request test selection as tests not testCases#3755Evangelink wants to merge 2 commits into
tests not testCases#3755Evangelink wants to merge 2 commits into
Conversation
The MTP runner serialized the `testing/runTests` test selection under `testCases`, but Microsoft.Testing.Platform reads it as `tests` (`JsonRpcStrings.Tests`). The property is optional server-side, so the misnamed selection was dropped silently and the server ran the entire suite instead of the selection. The likely origin is the testfx ServerMode sample this client was ported from, where the C# member is named `TestCases` but the wire name is `tests`. Also omit absent optional properties instead of writing explicit nulls. The platform probes `location.*` with TryGetValue and then asserts the value is not null, so a `"location.file": null` on a node echoed back reads as present but invalid and fails the request. This was latent while nodes only flowed server to client, and would have become live as soon as the rename made selection work. Add wire-format tests that assert the raw JSON. The existing round-trip test deserializes with Stryker's own record, so it passes for any property name and could not detect the mismatch. Fixes stryker-mutator#3754 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes the Microsoft Testing Platform (MTP) runner’s testing/runTests request payload to match the server-mode JSON-RPC contract, ensuring test selection is honored (instead of being silently ignored and running the entire suite) and preventing failures caused by sending explicit null location fields.
Changes:
- Serialize the run test selection under JSON property
tests(nottestCases) and omit it when null to represent “run all tests”. - Omit
TestNodeoptionallocation.*properties when they are null to avoid server-side assertions triggered by explicit JSON nulls. - Add wire-format unit tests that validate the raw JSON payload shape against the platform’s expectations.
Show a summary per file
| File | Description |
|---|---|
| src/Stryker.TestRunner.MicrosoftTestPlatform/Models/TestNode.cs | Omits nullable location.* fields during serialization to avoid invalid explicit-null properties on the wire. |
| src/Stryker.TestRunner.MicrosoftTestPlatform/Models/RunTestsRequest.cs | Renames the serialized selection property to tests and omits it when null, matching MTP protocol behavior. |
| src/Stryker.TestRunner.MicrosoftTestPlatform.UnitTest/RpcWireFormatTests.cs | Adds raw-JSON assertions to guard the wire contract (selection name + null-vs-absent behavior). |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 1
- Review effort level: Lite
`Serialize<T>` returned `JsonDocument.Parse(...).RootElement` from an undisposed document. `JsonDocument` owns the pooled memory backing its elements, so the buffer was never returned to the pool and the element lifetime was tied to an object nothing held. Dispose the document and return a cloned element, which is detached from the document and remains valid after it. 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.
Fixes #3754
Problem
The MTP runner serialized the
testing/runTeststest selection under the JSON nametestCases, but Microsoft.Testing.Platform reads it astests:interface RunTestsParams { tests?: TestNode[], runId: GUID }JsonRpcMethods.cs->public const string Tests = "tests";GetOptionalPropertyFromJson(properties, JsonRpcStrings.Tests)testsis optional server-side, so an unrecognisedtestCasesis dropped without any error or warning and the server falls through to running the entire test suite.The likely origin is the testfx
samples/Playground/ServerModesample this client was ported from, where the C# member isTestCasesbut the wire name istests:Present since the MTP runner was introduced in #3404.
Second, related defect
TestNode's optionallocation.*members were written as explicit nulls. The platform probes them withTryGetValue- which succeeds on an explicit null - and then asserts non-null:This was latent while
TestNodes only flowed server -> client, and would have become live the moment the rename made selection actually work: every test the framework reported without location info would fail the run request. Both parts have to land together, so they are in one commit.The same applies to the selection itself, which is now omitted rather than sent as
"tests": nullwhen running every test.Changes
RunTestsRequest.TestCasesserializes astests, omitted when null.TestNodelocation properties omitted when null.RpcWireFormatTestsasserting the raw JSON payload.Why the existing tests did not catch this
Two independent reasons, both worth noting because they explain the blind spot:
SingleMicrosoftTestPlatformRunner.RunAssemblyTestsAsynccurrently always passestestUidFilter: null, so no selection is ever sent in practice and the wrong name was never exercised against a real server.TestingPlatformClientTests.FakeTestServerdeserializes using Stryker's ownRunTestsRequestrecord, so the name matches on both ends and the test passes for any name.The new tests therefore assert the raw JSON rather than round-tripping through Stryker's records, so they are anchored to the platform's contract instead of to our own types.
Verification
Stryker.TestRunner.MicrosoftTestPlatform.UnitTestsuite: 213/213 pass (3 consecutive runs).Stryker.slnxbuilds with 0 errors.Scope
Deliberately narrow. Actually using a selection (passing a real
testUidFilter) only pays off once MTP coverage is per-test rather than cumulative, so that belongs in a follow-up. This change is a prerequisite for it and is correct on its own: it makes the payload match the protocol.Note: I could not apply the 🐛 Bug label to the linked issue (requires admin rights) - a maintainer may want to add it.