Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: microsoft/vstest
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6411dc2d85c5ae88a4eb786e0a7daa3ce978fc20
Choose a base ref
...
head repository: microsoft/vstest
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0b289d54af2f0b7aba88364cd6e2718ac69cbd49
Choose a head ref
  • 19 commits
  • 180 files changed
  • 8 contributors

Commits on Aug 10, 2026

  1. Configuration menu
    Copy the full SHA
    7a6c166 View commit details
    Browse the repository at this point in the history
  2. Fix logger concurrency correctness and TRX write reliability (#16326)

    * Fix logger concurrency correctness and TRX write reliability
    
    Both TrxLogger and HtmlLogger register event handlers that are invoked
    concurrently during parallel test execution, but several pieces of their
    mutable state were plain non-thread-safe collections.
    
    TrxLogger:
    - _runLevelErrorsAndWarnings is now a ConcurrentQueue<RunInfo>.
    - _runLevelStdOut is now a ConcurrentQueue<string> instead of a StringBuilder;
      the run level informational message is materialized on read with the same
      AppendLine-per-message formatting as before.
    - CreateTestRun had a check-then-act race that could create more than one
      TestRun. It is replaced by GetOrCreateTestRun, which uses double checked
      locking, and LoggerTestRun is published with Volatile so that a reader that
      sees a non-null reference also sees a fully initialized TestRun.
    - TestElementAggregation._testLinks was a plain Dictionary mutated through a
      non-atomic ContainsKey + Add. Mutation and enumeration are now guarded by a
      lock. A lock is used rather than ConcurrentDictionary so that the insertion
      order of test links, which is meaningful for ordered tests, is preserved.
    - PopulateTrxFile only caught UnauthorizedAccessException, so a disk full or
      any other IO failure silently dropped the TRX file with an unhandled
      exception. It now reports IOException, UnauthorizedAccessException,
      XmlException, NotSupportedException and SecurityException using the new
      localized TrxLoggerWriteFailed resource.
    
    HtmlLogger:
    - TestResultHandler used TryGetValue + TryAdd + ResultCollectionList.Add, which
      could publish duplicate collections for the same source. It now uses the
      atomic GetOrAdd and only the winning thread publishes the collection.
    - ResultList, FailedResultList, InnerTestResults and the run level message
      lists are appended through lock protected helpers, so no result or message
      can be lost. The lists are still created lazily, so the null versus empty
      semantics observed by the serialized XML are unchanged.
    
    Fixes #16320
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: 32aa1e90-526a-4b49-97cc-1297638d7520
    
    * Correct two inaccurate code comments from review feedback
    
    - TestRunDetails._syncLock no longer describes ResultCollectionList as
      lazily created, since that field is initialized inline. Only the run
      level message lists are created on first use.
    - GetOrCreateTestRun no longer says Started is set to DateTime.Now in
      Initialize; TestRunStartTime is captured with DateTime.UtcNow.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: 32aa1e90-526a-4b49-97cc-1297638d7520
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: 32aa1e90-526a-4b49-97cc-1297638d7520
    azat-msft and Copilot authored Aug 10, 2026
    Configuration menu
    Copy the full SHA
    17c14fe View commit details
    Browse the repository at this point in the history

Commits on Aug 12, 2026

  1. Restore custom data collector platform tests (#16354)

    * Restore custom data collector platform tests
    
    Use the existing out-of-process collector test asset through the supported discovery path, and complete its secondary event channel before ending each run.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    🤖
    
    * Copy collector from resolved project output
    
    Use the ProjectReference target path instead of assuming its configuration matches the solution configuration.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    🤖
    
    * Always close collector event client
    
    Reject invalid event ports and stop the secondary communication client even when setup or validation fails.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    Copilot-Session: 74aae65f-0435-4727-b13a-ff1e80980b3f
    
    🤖
    nohwnd authored Aug 12, 2026
    Configuration menu
    Copy the full SHA
    d8f6af1 View commit details
    Browse the repository at this point in the history

Commits on Aug 13, 2026

  1. Revive socket client and server tests (#16348)

    * Revive socket client and server tests
    
    Stop socket listeners deterministically and serialize socket server startup, accept, and shutdown so port 0 listeners cannot escape Stop.
    
    Replace unbounded waits and stale post-close assertions, and re-enable the two stable socket test classes.
    
    🤖
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    * Fix SocketServer accept lock scope
    
    🤖
    
    * Harden SocketServer shutdown regression
    
    🤖
    
    * Scope SocketServer shutdown handling
    
    🤖
    
    ---------
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    nohwnd and Copilot authored Aug 13, 2026
    Configuration menu
    Copy the full SHA
    a3b36a6 View commit details
    Browse the repository at this point in the history

Commits on Aug 14, 2026

  1. Configuration menu
    Copy the full SHA
    5210ceb View commit details
    Browse the repository at this point in the history
  2. Retarget the MTP client onto Microsoft.Testing.Platform.ServerMode.Cl…

    …ient.Sources (#16300)
    
    * Retarget the MTP client onto Microsoft.Testing.Platform.ServerClient.Source
    
    testfx now ships vstest's MTP server-mode JSON-RPC client as a source-only
    package built from the MTP server's own protocol and serialization source, so
    the wire format cannot drift from the server.
    
    Delete vstest's transport core (MtpServerConnection, MtpJson, MtpConstants,
    MtpClientHelpers) and retarget the glue onto the package's IMtpServerClient:
    launch via MtpServerClient.Launch, drive Initialize/Discover/Run/Exit, read
    node updates from the TestNodesUpdated event with typed MtpTestNodeUpdate
    accessors, and bridge EqtTrace through DelegateMtpClientLogger.
    MtpClientOptionsFactory centralizes option construction and log-level mapping.
    
    The package is a compile-time source dependency (PrivateAssets=all), so no
    runtime dependency and no public API are added.
    
    Blocked on testfx publishing the package (microsoft/testfx#10085); references
    an interim local feed, so CI cannot restore it yet.
    
    * Commit the interim local MTP client feed so restore works everywhere
    
    NuGet.config pointed local-mtp at the absolute path Q:\q\local-mtp-feed, which
    is machine-local and does not exist in CI, so restore failed with an incorrect
    path. Move the feed under the repo at eng/local-mtp-feed, point NuGet.config at
    that repo-relative path, and commit the package into the feed. .gitignore keeps
    ignoring *.nupkg but adds a negation for eng/local-mtp-feed/*.nupkg so the feed
    package is tracked.
    
    The package is the fresh Design-A drop of
    Microsoft.Testing.Platform.ServerClient.Source 2.4.0-dev, which builds
    CrossPlatEngine clean on net462, netstandard2.0, and net8.0 (0 errors, 0
    warnings) with the retargeted glue. Interim only; remove the feed once
    microsoft/testfx#10085 ships the package to a public feed.
    
    🤖
    
    * Order remote NuGet feeds before the interim local feed in test asset restore
    
    The acceptance tests restore the TestAssets solution, which transitively
    restores product projects like CrossPlatEngine that now reference the interim
    local-mtp feed. Passing that local-folder feed to dotnet restore alongside the
    remote https feeds triggered two NuGet quirks, both surfacing as NU1301: a
    relative --source path is rooted at each restored project's directory, and a
    local-folder source placed before the remote sources mis-normalizes the https
    URLs into per-project relative paths.
    
    Resolve relative local-folder sources to absolute paths and emit the remote
    sources first so all local-folder sources come last; remote feeds keep their
    configured order. Only needed while the MTP client package lives on the interim
    local feed, and harmless once testfx#10085 ships it to a public feed.
    
    🤖
    
    * Key MTP environment variable dictionary case-insensitively on Windows
    
    Both places that collect environment variables for the MTP application
    launch now share one comparer: case-insensitive on Windows, case-sensitive
    elsewhere. Before, the runsettings path used that comparer but the
    data-collector-only path used a plain ordinal dictionary, so a run with no
    runsettings variables but with data-collector variables lost the
    case-folding the classic testhost path applied on Windows. The package
    options dictionary is ordinal, so deduping here preserves the classic
    Windows semantics before the values reach it.
    
    🤖
    
    * Consume official B-fixed MTP client source drop (testfx#10085)
    
    Replaces the interim 2.4.0-dev pack with the official drop that fixes the
    STJ number-decode bug: untyped JSON numbers were hard-cast to Int32, so node
    bags carrying doubles (durations) or longs (timestamps) threw FormatException
    and faulted the MTP read loop on the net8 client. The fix decodes numbers
    generically (ReadNumber: TryGetInt32 -> TryGetInt64 -> TryGetUInt64 -> double).
    
    Pinned to the unique version 2.4.0-dev.20260721161520 to avoid NuGet
    same-version cache collisions while the package is served from the committed
    local feed.
    
    MtpUnderVstestTests: net11.0 (STJ) axis now 7/7 (was 0/7); net481 (Jsonite)
    axis 5/7. The 2 remaining failures are a pre-existing net462 TRX-logger load
    issue that also breaks classic non-MTP trx tests, unrelated to this retarget.
    
    🤖
    
    * Align interim MTP client pin to the coordinator's canonical numberfix drop
    
    Swaps the interim feed pack and pin from the timestamped unique
    2.4.0-dev.20260721161520 to the coordinator's canonical uniquely-named drop
    2.4.0-dev.numberfix (MD5 FC7F7A9F68EF482718B61DC9DA5F38B4). Byte-equivalent
    fixed content -- the packed net8 Json.Deserializers.cs decodes untyped JSON
    numbers via ReadNumber at both sinks (L55/L97, helper L344), same as the prior
    drop -- this only adopts the stable canonical interim identity the package
    owner is standardizing on across consumers.
    
    Validation unchanged: MtpUnderVstestTests net11.0 (STJ) axis 7/7, full suite
    12/14 (the 2 remaining failures are the pre-existing net462 TRX-logger load
    issue, unrelated to this retarget).
    
    🤖
    
    * Add MTP converter/options unit tests and fix numeric and trait coercion
    
    The retarget onto Microsoft.Testing.Platform.ServerClient.Source left the MTP
    glue with no unit coverage at all - the only tests were the end-to-end
    MtpUnderVstestTests. The conversion code is now pure and dependency-free, so
    cover it directly.
    
    Add MtpTestNodeConverterTests and MtpClientOptionsFactoryTests (55 tests)
    covering the normalized-Node contract, per-formatter number boxing, outcome
    mapping, the action-node filter, vstest bridge properties, standard
    output/error, traits, duration and log-level mapping.
    
    Three fixes fall out of writing them:
    
    - TryGetRawInt wrapped out-of-range values with unchecked((int)l), turning a
      bad line number into a plausible-looking wrong answer. Range-check instead so
      the property stays at its visibly-unset default.
    - AddTraits collapsed every non-string trait value to an empty string. The two
      formatters box JSON scalars differently, so a numeric or boolean trait was
      silently dropped on one formatter and kept on the other. Format invariantly.
    - MtpClientOptionsFactory re-read VSTEST_CONNECTION_TIMEOUT and hardcoded the
      90-second default instead of calling EnvironmentHelper.GetConnectionTimeout,
      which seven other vstest call sites already use and which also traces the
      override.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: cd0793f4-d530-44b6-b881-fed3be6aa52f
    
    * Fix MTP client shutdown and fail loudly on a missing node uid
    
    Retargeting onto the source package changed exit from a fire-and-forget
    notification into an awaited request/response call, which introduced two
    regressions:
    
    - Exit was awaited on the run's own cancellation token. Cancelling or aborting
      a run is exactly when that token is already cancelled, so ExitAsync threw
      immediately and the graceful shutdown handshake was skipped in the one case
      it matters most.
    - The await was unbounded, so a test application that never acknowledges exit
      would hang discovery or execution indefinitely. The notification it replaced
      could not block at all.
    
    Route both proxy managers through MtpServerClientFactory: TryExit runs on its
    own bounded token, swallows failures (the caller disposes the client next,
    which tears the process down regardless), and is called from a finally block so
    a failed or cancelled run still shuts the application down.
    
    The factory also exposes a replaceable Launch delegate so the managers can be
    driven against a fake server in unit tests; production always uses
    MtpServerClient.Launch.
    
    Separately, BuildUids substituted FullyQualifiedName when a TestCase carried no
    MTP.TestNode.Uid. The server projects node.Uid alone when building a run filter
    and never reads any other field, so that substitution produced a filter
    matching nothing: the run reported success having executed zero of the tests
    the user selected, with no error anywhere. Throw instead, with a comment
    explaining why no fallback is correct.
    
    Adds 15 tests covering the shutdown paths, the uid filter, and both manager
    flows against a fake MTP server.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: cd0793f4-d530-44b6-b881-fed3be6aa52f
    
    * Add non-ASCII MTP acceptance coverage for UTF-8 frame length
    
    MTP frames declare Content-Length in UTF-8 bytes, but the transport shipped by
    Microsoft.Testing.Platform.ServerClient.Source reads that number of characters:
    it rents a char buffer of Content-Length and calls StreamReader.ReadBlockAsync.
    For any frame carrying multi-byte UTF-8 the two disagree, so the reader
    under-reads and leaves the body's tail to be parsed as the next frame's headers
    - the connection desynchronizes from the following message onward.
    
    vstest's deleted MtpServerConnection was byte-correct here (it read Content-Length
    bytes into a byte[] and then UTF-8-decoded), so the retarget is a regression, not
    an inherited defect. Client-to-server traffic is ASCII in practice, which is why
    it has not surfaced; node updates flow the other way and carry user-authored test
    names.
    
    Give MtpMSTestProject a test whose display name mixes German umlauts (2 bytes
    each), Japanese (3 bytes each) and an emoji (4 bytes, 2 chars), and mirror it in
    MtpPureProject. Because the corruption lands on the message *after* the offending
    one, its mere presence makes the whole run fail rather than just that test, so
    every existing MTP scenario now exercises the transport with multi-byte content.
    Adds a dedicated test asserting the name survives into the TRX.
    
    These fail until the fix lands upstream in testfx.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: cd0793f4-d530-44b6-b881-fed3be6aa52f
    
    * Narrow the non-ASCII MTP test name to the BMP and fix the collector count
    
    Running the acceptance test revealed two things worth recording.
    
    First, an end-to-end MTP run cannot reproduce the Content-Length byte-vs-char
    framing bug: the .NET MTP server serializes with System.Text.Json, whose default
    encoder escapes every non-ASCII character to \\uXXXX, so the bytes on the wire
    are ASCII and the byte count coincidentally equals the character count. The
    framing bug is real but has to be proved at the unit level against the transport
    directly, which is what the companion testfx change does. This test is therefore
    a name-integrity guard, and its comments now say so rather than overclaiming.
    
    Second, the emoji originally in the name exposed a separate defect: astral-plane
    characters are escaped by System.Text.Json as a surrogate pair and arrive in the
    TRX as the literal text \\ud83c\\udf89 instead of the character. BMP characters
    decode correctly. That is its own bug, tracked separately, so the name is
    narrowed to BMP multi-byte characters (umlauts 2 bytes, Japanese 3 bytes) which
    still exercise the byte-denominated length without tripping over it.
    
    Also updates the out-of-proc data collector's expected per-test-case attachment
    count, which follows the test count.
    
    MtpUnderVstestTests: 16/16 on both console axes.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: cd0793f4-d530-44b6-b881-fed3be6aa52f
    
    * Consume the MTP client drop with the Content-Length framing fix
    
    Replaces the interim local-feed pack with a build of microsoft/testfx#10297,
    which stacks the Content-Length byte/char fix onto #10085. The transport now
    reads exactly Content-Length bytes and UTF-8-decodes them, symmetric with the
    write path, and reads the headers through the same byte-level buffer so no
    StreamReader can buffer part of the body across the boundary.
    
    That drop also carries #10085's ServerRequestHandler signature change (the
    result is now constrained to a serializable dictionary), so FakeMtpServerClient
    is updated to match.
    
    Verification on this drop:
    - CrossPlatEngine builds clean on net462, netstandard2.0 and net8.0.
    - MTP unit tests 140/140 (70 per axis, net11.0 and net481).
    - MtpUnderVstestTests 16/16 on both console axes.
    
    Note the 16/16: the two /logger:trx failures reported against the earlier drop
    do not reproduce here, so they look like a local deployment issue rather than
    anything in the retarget.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: cd0793f4-d530-44b6-b881-fed3be6aa52f
    
    * Repin the interim MTP client to the uniquely-named utf8fix1 drop
    
    Swaps the interim feed pack from the plain 2.4.0-dev build output to the
    coordinator's canonical 2.4.0-dev.utf8fix1 drop of microsoft/testfx#10297.
    
    Byte-equivalent content: all 184 contentFiles are identical between the two
    packs, including TcpMessageHandler.cs with both ReadExactlyAsync and the
    TrimPreamble BOM tolerance. Only the version metadata differs.
    
    The rename is the point. While the package is served from a committed local
    folder, NuGet caches by version, so a plain 2.4.0-dev risks silently resolving a
    stale cache entry from an earlier drop of the same name. The unique suffix makes
    that impossible, matching the convention the branch already used for
    2.4.0-dev.numberfix.
    
    Re-verified from a cleared package cache: CrossPlatEngine clean on all three
    TFMs, MTP unit tests 140/140, MtpUnderVstestTests 16/16.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: cd0793f4-d530-44b6-b881-fed3be6aa52f
    
    * Address expert review feedback on the MTP hardening
    
    Localize the missing-uid error. The message reaches the user verbatim -
    StartTestRun funnels ex.Message into HandleLogMessage(Error) - and every other
    user-facing TestPlatformException in this assembly is resourced, so a hardcoded
    English string formatted with CurrentCulture was self-contradictory. Adds
    MtpTestCaseMissingNodeUid to Resources.resx, the generated designer property,
    and a trans-unit to all 13 xlf files. The text now also states the remedy
    (re-run discovery, or run without a selection) rather than only naming the
    failure, and the comment records that aborting the whole source is deliberate:
    silently running the addressable subset would recreate the same class of bug in
    a smaller form.
    
    Mark the three new test classes DoNotParallelize. MSTest parallelizes across
    classes at MethodLevel by default here, and these classes mutate process-global
    state - the MtpServerClientFactory.Launch seam and VSTEST_CONNECTION_TIMEOUT -
    so a save/restore in TestInitialize/TestCleanup could restore one class's value
    while another class's test was still relying on its own. That would have flaked
    in CI looking like a product bug.
    
    Close a hole in the float range guard. (float)int.MaxValue rounds *up* to
    2147483648f, so comparing a float directly against int.MaxValue let that value
    through and the cast then saturated - precisely the plausible-looking wrong
    answer the guard exists to reject. Widen to double before comparing, and extend
    the regression test to cover it.
    
    Capture ProcessId before the exit handshake instead of reading it afterwards,
    when the process may already be gone.
    
    Test fixes: TryExitDoesNotUseAnAlreadyCancelledRunToken was vacuous (it built a
    cancelled token it never passed anywhere) and LaunchDefaultsToTheRealClientLauncher
    asserted only non-null, which any delegate satisfies. Both now assert something
    that fails if the behaviour regresses. Adds the missing mixed-selection case,
    where only some tests carry a uid.
    
    Also fixes a stale test-count comment and softens an overclaim in
    MtpPureProject, which no test currently references.
    
    Unit tests 142/142 across net11.0 and net481; MtpUnderVstestTests 16/16 on both
    console axes.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: cd0793f4-d530-44b6-b881-fed3be6aa52f
    
    * Consume the latest MTP client drop from testfx#10297
    
    Picks up the two commits that landed on the testfx branch after the utf8fix1
    pack: the header line buffer is now reused across lines instead of allocated per
    line (server mode emits a notification per test, so that was a real hot-path
    allocation), plus comments recording why Content-Length is intentionally not
    capped and why the framing tests are not cross-TFM coverage.
    
    Both changes are to TcpMessageHandler, which compiles into CrossPlatEngine, so
    they are verified here rather than assumed. Re-verified from a cleared NuGet
    package cache:
    
    - CrossPlatEngine builds clean on net462, netstandard2.0 and net8.0.
    - MTP unit tests 142/142 across net11.0 and net481.
    - MtpUnderVstestTests 16/16 on both console axes.
    - testfx's own ServerClient unit tests 48/48, confirming the shared transport is
      still good on both formatter paths.
    
    The buffer is safe to hold as instance state for the same reason the existing
    read offsets are: reads are single-threaded, driven by exactly one read loop.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: cd0793f4-d530-44b6-b881-fed3be6aa52f
    
    * Consume the published MTP client package; drop the interim local feed
    
    testfx#10085 shipped the source-only MTP server-mode client to the
    dnceng-public dotnet-tools feed (already configured in NuGet.config), under
    its final name Microsoft.Testing.Platform.ServerMode.Client.Sources. Repin
    CrossPlatEngine from the interim local-feed drop
    (Microsoft.Testing.Platform.ServerClient.Source 2.4.0-dev.utf8fix2) to the
    published 2.4.0-preview.26410.1 and remove the whole interim scaffolding:
    
    - eng/local-mtp-feed and its NuGet.config source + .gitignore exception.
    - The GetNugetSourceParameters feed-order workaround in IntegrationTestBuild,
      which only existed to make a local-folder source restore alongside the
      remote https feeds. With no local folder it reverts to the simple base.
    
    The published package compiles its own down-level nullable-annotation
    polyfills on net462/netstandard2.0, which collide with the identical set
    CrossPlatEngine already imports from CoreUtilities (CS0436). Define
    MTP_CLIENT_EXCLUDE_NULLABLE_ATTRIBUTES so the package defers to those; it is
    a no-op on net8.0 where the attributes are in-box.
    
    The C# namespace (Microsoft.Testing.Platform.ServerMode.Client) is unchanged,
    so the retarget glue and azat's unit tests bind to the published package with
    no code change. Restore resolves 2.4.0-preview.26410.1 from the real feed with
    no local folder; build is clean on all three TFMs.
    
    🤖
    
    * Enable the MTP testhost in the non-ASCII acceptance test
    
    RunMtpApplicationPreservesNonAsciiTestNames drove the MTP app with a plain
    InvokeVsTest, which stopped detecting the app after main merged #16337
    (MTP testhost disabled by default). Align it with every other MTP-driving
    test by using InvokeVsTestWithMtpTestHostEnabled, so the net11.0 runner
    finds the testhost again. net11.0 is back to a full pass; the remaining
    net481 /logger:trx failures are the pre-existing environmental logger-load
    issue on the desktop runner, unrelated to this change.
    
    🤖
    
    * Reject fractional MTP line numbers
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    * Reject selected MTP nodes without UIDs
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Azat Muzafarov <azatm@microsoft.com>
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: cd0793f4-d530-44b6-b881-fed3be6aa52f
    3 people authored Aug 14, 2026
    Configuration menu
    Copy the full SHA
    9cbb02d View commit details
    Browse the repository at this point in the history

Commits on Aug 17, 2026

  1. Fix MsCoverageReferencedPathMaps: skip during design-time builds and …

    …add BuildInParallel (#16043)
    
    - Add 'DesignTimeBuild' != 'true' condition to MsCoverageReferencedPathMaps target
      to prevent it from running during IDE design-time builds (fixes #15105).
      Design-time builds are frequent background builds triggered by VS for
      IntelliSense/code analysis, and running MSBuild on all referenced projects
      during each of these builds causes significant IDE slowdowns.
    
    - Add BuildInParallel="true" to the MSBuild task to parallelize the invocation
      across referenced projects, reducing build times for solutions with many
      dependencies (partial fix for #15295).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    nohwnd and Copilot authored Aug 17, 2026
    Configuration menu
    Copy the full SHA
    ae77b29 View commit details
    Browse the repository at this point in the history

Commits on Aug 18, 2026

  1. [main] Source code updates from dotnet/dotnet (#16334)

    * Update dependencies from build 325270
    Updated Dependencies:
    Microsoft.Diagnostics.NETCore.Client (Version 0.2.0-preview.26365.101 -> 0.2.0-preview.26401.101)
    [[ commit created by automation ]]
    
    * Update dependencies from build 326717
    Updated Dependencies:
    Microsoft.Diagnostics.NETCore.Client (Version 0.2.0-preview.26401.101 -> 0.2.0-preview.26411.119)
    [[ commit created by automation ]]
    
    ---------
    
    Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
    dotnet-maestro[bot] and dotnet-maestro[bot] authored Aug 18, 2026
    Configuration menu
    Copy the full SHA
    d2c19c0 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    b207e49 View commit details
    Browse the repository at this point in the history
  3. Pass arguments to PowerShell with -File instead of -command (#16363)

    * Document build script argument injection in AGENTS.md
    
    build.cmd and test.cmd splice %* unquoted into a powershell -command
    string, so a semicolon in an argument is parsed as a statement
    separator. Passing a semicolon-delimited project list to
    test.cmd -projects executed the trailing .csproj paths, which Windows
    opens in Visual Studio by file association. Three agent sessions hit
    this at the same time and opened eighteen IDE instances.
    
    Adds a Known Gotchas entry explaining the mechanism, and a pointer from
    the Build section.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: a9a4717a-d9de-4964-81c0-91b6a7c68da3
    
    * Pass arguments to PowerShell with -File instead of -command
    
    The .cmd wrappers spliced %* into a powershell -command string, so
    everything the caller passed was parsed by PowerShell as source code
    instead of being treated as data.
    
    Two things went wrong because of that. A semicolon inside an argument
    became a statement separator, so test.cmd -projects
    "test\A\A.csproj;test\B\B.csproj" ran the script with only the first
    project and then executed the remaining .csproj paths as their own
    statements, and because .csproj is file-associated with Visual Studio on
    Windows, each one opened an IDE. Three agents ran that form at the same
    time and opened eighteen instances of Visual Studio. Separately,
    -command collapsed every non-zero exit code to 1, so the
    exit $LastExitCode at the end of eng/build.ps1 never forwarded the real
    code, including the 8 that means the filter matched no tests.
    
    -File passes everything after the script path as a literal argument, so a
    semicolon separated project list now reaches Arcade intact, which is what
    its own help text already promises, and exit codes survive.
    
    Because arguments are no longer re-parsed, MSBuild properties need one
    level of quoting instead of two, so the documented single test command in
    AGENTS.md changes from /p:TestRunnerAdditionalArguments="'--filter Name'"
    to /p:TestRunnerAdditionalArguments="--filter Name". Both produce the
    same value.
    
    eng/common is left alone, those files come from Arcade.
    
    Verified locally: build.cmd succeeds with 0 errors and returns 0,
    test.cmd -help with a semicolon list in -projects no longer executes the
    trailing paths and starts no Visual Studio, and a probe script confirms
    exit codes 0, 8 and 42 now survive where -command turned 8 and 42 into 1.
    
    🤖
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: a9a4717a-d9de-4964-81c0-91b6a7c68da3
    
    * Use the on-disk casing for eng/build.ps1
    
    build.cmd, test.cmd and restore.cmd referenced eng\Build.ps1, but the
    tracked file is eng/build.ps1. It resolves anyway on case insensitive
    NTFS, it does not when per directory case sensitivity is enabled, and
    open-vs.cmd and open-code.cmd already used the lowercase form.
    
    Also correct AGENTS.md, it claimed all six wrappers call eng/build.ps1
    while eng/RestoreInternal.cmd calls eng/common/build.ps1.
    
    From PR review feedback.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: a9a4717a-d9de-4964-81c0-91b6a7c68da3
    
    ---------
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: a9a4717a-d9de-4964-81c0-91b6a7c68da3
    nohwnd and Copilot authored Aug 18, 2026
    Configuration menu
    Copy the full SHA
    7e06f03 View commit details
    Browse the repository at this point in the history
  4. Respect console logger verbosity from a settings file (#16044)

    * Fix LoggerRunSettings verbosity being silently overridden by MSBuild task
    
    When dotnet test is run with --settings <runsettings>, the MSBuild VSTest
    task always injected --logger:Console;Verbosity=X. This caused
    AddLoggerToRunSettings to remove the existing console logger entry (from
    LoggerRunSettings in the settings file) and replace it with one carrying
    only the MSBuild-derived verbosity — discarding the user's configured
    verbosity.
    
    Root cause: two cooperating issues.
    
    1. TestTaskUtils.CreateCommandLineArguments always included Verbosity=X
       in the auto-injected --logger arg even when a settings file was in use.
    
    2. LoggerUtilities.AddLoggerToRunSettings unconditionally removed and
       replaced an existing logger, losing its Configuration when the new
       logger had no Configuration of its own.
    
    Fix:
    - When isRunSettingsEnabled=true (settings file provided), omit Verbosity
      from the auto-injected logger arg so the settings file can supply it.
    - In AddLoggerToRunSettings, when the incoming logger has no Configuration
      (no CLI params) but an existing logger does, preserve the existing
      Configuration rather than discarding it.
    
    Fixes #10369
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix: scope settings-file verbosity skip to VSTestTask only; VSTestTask2 always injects MSBuild-derived verbosity
    
    The 'don't inject Verbosity when settings file is present' fix was
    applied to both VSTestTask (Console logger) and VSTestTask2 (MSBuildLogger).
    For VSTestTask2, the MSBuildLogger verbosity is driven by MSBuild, not
    the user's settings file, so it must always receive the MSBuild-derived
    verbosity. Scope the suppression to task is VSTestTask only.
    
    Also adds a test explicitly covering VSTestTask2 + settings file.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add E2E test: logger verbosity from .runsettings is respected
    
    Regression test for #10369. Runs dotnet test with a .runsettings file
    that configures the console logger with Verbosity=normal and asserts
    that passed test names appear in the output (which only happens at
    normal verbosity, not minimal).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Migrate nuspec to MSBuild pack (batch 1: simple packages) (#16125)
    
    * Migrate Filter.Source package from nuspec to MSBuild pack
    
    Remove the hand-crafted .nuspec file for Microsoft.TestPlatform.Filter.Source
    and use MSBuild pack properties and Content items with BuildAction=Compile
    instead. This is the first step in moving away from nuspec files (issue #15650).
    
    - Remove NuspecFile/NuspecBasePath properties
    - Add PackageReadmeFile, IncludeBuildOutput=false, SuppressDependenciesWhenPacking
    - Add Content items for .cs files with correct contentFiles pack paths
    - Delete Microsoft.TestPlatform.Filter.Source.nuspec
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Migrate AdapterUtilities package from nuspec to MSBuild pack
    
    Remove the hand-crafted .nuspec file for Microsoft.TestPlatform.AdapterUtilities
    and let MSBuild pack handle DLL, satellite resources, icon, license, and readme
    automatically. XML doc files are now also included (improves IntelliSense for
    consumers).
    
    - Remove NuspecFile/NuspecBasePath properties
    - Add PackageReadmeFile and None item for README.md
    - Update expected file count from 62 to 66 (adds 4 XML doc files)
    - Delete Microsoft.TestPlatform.AdapterUtilities.nuspec
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Migrate TrxLogger package from nuspec to MSBuild pack
    
    Remove the hand-crafted .nuspec file for Microsoft.TestPlatform.Extensions.TrxLogger
    and use MSBuild pack properties instead.
    
    - Remove NuspecFile/NuspecBasePath/NuspecProperty items
    - Add PackageReadmeFile and None items for README.md and ThirdPartyNotices.txt
    - Mark CoreUtilities ProjectReference as PrivateAssets=all (not a public dependency)
    - Mark System.Security.Principal.Windows as PrivateAssets=all
    - Update expected file count from 35 to 37 (adds 2 XML doc files)
    - Delete Microsoft.TestPlatform.Extensions.TrxLogger.nuspec
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Migrate Build and ObjectModel packages from nuspec to MSBuild pack
    
    Build package:
    - Remove 3 nuspec files (normal, sourcebuild, VMR variants)
    - Source build's TargetFrameworks override handles single-TFM naturally
    - Add SuppressDependenciesWhenPacking and NoWarn=NU5128 for MSBuild task package
    - Add Pack metadata on .targets Content item
    
    ObjectModel package:
    - Remove nuspec file
    - Use TargetsForTfmSpecificContentInPackage to bundle CoreUtilities and
      PlatformAbstractions DLLs plus satellite resources
    - ValueTuple and Collections.Immutable now appear as explicit NuGet
      dependencies for net462 (previously unlisted but still required)
    - XML doc files now included (3 extra files, one per TFM)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: preserve locale subdirectories when packing satellite resources
    
    Use %(RecursiveDir) in the PackagePath for the CoreUtilities and
    PlatformAbstractions satellite resource globs so that locale
    subdirectories (cs/, de/, fr/, ...) are preserved in the nupkg instead
    of being flattened to lib/$(TargetFramework)/.
    
    Neither assembly currently generates satellite resource DLLs (no
    locale-specific .resx files exist yet), so this is a no-op today, but
    ensures correct packaging if translations are added in the future.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * revert: align ObjectModel.csproj satellite resource PackagePath with main
    
    Remove %(RecursiveDir) from the satellite resource PackagePath to match
    what main has after PR #16125. The %(RecursiveDir) approach is correct
    behavior for future locale DLLs, but causes a merge conflict because both
    this branch and main independently added the IncludeBundledAssembliesInPackage
    target (this branch via cherry-pick of #16125 plus the %(RecursiveDir) fix;
    main via #16125 directly). Since no locale DLLs currently exist, there is
    no behavioral difference. A targeted follow-up to main can add %(RecursiveDir)
    when needed.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: align packaging files with main (batch 2 nuspec migration)
    
    Remove stale nuspec files and reset csproj files to match the batch 2
    nuspec-to-MSBuild-pack migration (PR #16132 / d6418b3) that was merged
    to main after this branch was created. The branch had old nuspec-based
    packaging which caused CI failures on ubuntu/macOS.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * style: add comment explaining NU5128 suppression in TestPlatform.Build.csproj
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * revert: remove NU5128 comment from TestPlatform.Build.csproj to match main
    
    The previous commit added an explanatory comment before <NoWarn>;NU5128</NoWarn>.
    Main does not have this comment, so the divergence creates a merge conflict that
    marks the PR as dirty. Removing it makes the file identical to main and allows
    GitHub to auto-merge.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * style: add comment explaining NU5128 suppression in TestPlatform.Build.csproj
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: remove NU5128 comment to align with main and resolve merge conflict
    
    The NU5128 comment was added in 5107fc4 but main (PR #16132, commit d6418b3)
    independently added the same NoWarn line without the comment. This creates
    a 3-way merge conflict. Removing the comment aligns the PR branch with main,
    resolving the dirty merge state without a large merge commit.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * style: add comment explaining NU5128 suppression in TestPlatform.Build.csproj
    
    The reviewer requested a comment explaining why NU5128 is suppressed — the
    .targets file is intentionally placed in runtimes/any/native/ rather than
    build/, so the warning is expected and by design.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: remove NU5128 comment to match main and resolve merge conflict
    
    The NU5128 comment was added per reviewer suggestion, but PR #16125
    independently added the same <NoWarn> line to main without the comment.
    This creates a 3-way merge conflict that cannot be auto-resolved.
    
    Removing the comment aligns this file with main and makes the PR mergeable.
    The comment can be added to main directly as a follow-up.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * style: add comment explaining NU5128 suppression in TestPlatform.Build.csproj
    
    The NU5128 suppression is intentional: the .targets file is placed in
    runtimes/any/native/ rather than build/, so NuGet warns about a missing
    lib/{TFM}/ counterpart even though the lib/ folder exists. Adding a comment
    makes the intent explicit for future readers.
    
    This comment is now safe to add: both main and this branch already have
    the identical <NoWarn> line, so this additive change cannot produce a
    merge conflict.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: remove NU5128 comment to align with main and clear merge conflict
    
    Both this PR and main (PR #16125) independently migrated from nuspec to
    MSBuild pack in Microsoft.TestPlatform.Build.csproj. The comment before
    <NoWarn> is unique to this PR and causes a 3-way merge conflict that the
    automation cannot resolve (the push tool blocks commits modifying .github/
    files, which are part of any merge commit from main).
    
    Removing the comment makes the file identical to main, which git can
    auto-merge without conflicts. The NU5128 suppression itself is unchanged.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * style: add comment explaining NU5128 suppression in TestPlatform.Build.csproj
    
    The NU5128 suppression was explicitly requested by reviewer to explain
    why the warning is expected. The .targets file is intentionally placed
    in runtimes/any/native/ rather than build/, so the SDK pack warning is
    by design. This is not a conflict with main — main has the NoWarn line
    without the comment, and this comment is a PR-specific improvement that
    does not affect behavior.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * sync: pick up upstream improvements from main
    
    - Task.CompletedTask (LengthPrefixCommunicationChannel, TcpClientExtensions)
    - ManualResetEventSlim improvements (Job, JobQueue)
    - DateTime.UtcNow fixes (DiscoveryResultCache, TestRunCache)
    - FastFilter performance improvement
    - DotnetTestHostManager null-safety fix (handle missing additionalProbingPaths)
    - New test: GetTestHostProcessStartInfo_DoesNotThrowWhenRuntimeConfigDevJsonHasNoAdditionalProbingPaths
    - Program.cs comment, Resources.resx update, XLF translations
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: align Microsoft.TestPlatform.CLI packaging with main (nuspec → MSBuild pack)
    
    Replace CLI.csproj with main's MSBuild pack approach and delete stale .nuspec files.
    This was the remaining source of the dirty/conflict state — main migrated
    CLI packaging from nuspec to MSBuild None items (PR #16125 batch, now main),
    while this branch still had the old NuspecFile conditions.
    
    Also align eng/expected-dll-frameworks.json with main (4 entries for
    System.Memory.dll and System.Threading.Tasks.Extensions.dll).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: align Microsoft.TestPlatform.Build.csproj with main to resolve merge conflict
    
    Remove the NU5128 explanatory comment that was causing an add-add conflict with
    main (which independently added the same <NoWarn> line without the comment via
    PR #16166). Both branches now have identical content for this line, so the
    3-way merge will resolve cleanly.
    
    The comment can be added to main as a follow-up.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * style: add comment explaining NU5128 suppression in TestPlatform.Build.csproj
    
    The reviewer explicitly requested a comment explaining why NU5128 is suppressed.
    The .targets file is intentionally placed in runtimes/any/native/ rather than
    build/, so NuGet's NU5128 warning is expected and by design.
    
    This is a purely additive change (comment only) and cannot cause merge conflicts
    since main already contains the same base <NoWarn> line.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: remove NU5128 comment to resolve merge conflict with main
    
    The NU5128 comment was added per reviewer request but causes an
    add-add conflict: both this branch and main added content at the
    same location in csproj. Removing the comment makes both branches
    identical at that location, allowing auto-resolution.
    
    The comment can be added directly to main as a follow-up.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: remove Windows-Review category from RunDotnetTestWithNativeDll to match main
    
    This aligns the PR branch with main's change (PR #16067) which removed
    the [TestCategory("Windows-Review")] restriction from this test. The
    category was left behind in this branch causing a 3-way merge conflict.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: align DiscoveryResultCache and TestRunCache with main to resolve merge conflict
    
    Pick up InitialCapacity pre-allocation from main (#16165) to resolve the
    3-way merge conflict caused by the cd3cc9e sync commit applying the
    DateTime.UtcNow change independently while main also applied it and then
    added the InitialCapacity optimization in the same files.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: align packaging .csproj files with main to resolve merge conflicts
    
    Use forward slashes in PackagePath and adopt _CliContentTfm property
    from main to fix merge conflicts caused by packaging changes in main.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: resolve merge conflicts with main
    
    Resolve 4 conflicting files to allow clean merge into main:
    
    - Resources.fr.xlf, Resources.pt-BR.xlf, Resources.zh-Hans.xlf:
      Use main's updated translations for EnableBlameUsage (state='translated'
      with procdump info) instead of the PR's needs-review-translation state
    
    - DotnetTestTests.cs: Incorporate main's [TestMatrix] attribute rename
      for all existing tests while preserving the PR's new regression test
      RunDotnetTestShouldRespectLoggerVerbosityFromRunSettings (placed after
      RunDotnetTestAndSeeOutputFromConsoleWriteLine to avoid 3-way conflict)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: restore NetCoreTargetFrameworkDataSource attributes in DotnetTestTests
    
    The conflict resolution commit (22c21d0) replaced all
    [NetCoreTargetFrameworkDataSource(useDesktopRunner: false)] attributes
    with [TestMatrix(console: Net, testHost: Net)] to match main's style.
    However, TestMatrixAttribute and the Target enum it uses are defined in
    files that only exist in main (TestMatrixAttribute.cs, GlobalUsings.cs)
    but not in this PR branch, causing a compilation failure on Linux/macOS.
    
    Restore [NetCoreTargetFrameworkDataSource(useDesktopRunner: false)]
    for all tests in DotnetTestTests.cs — equivalent behavior to
    [TestMatrix(console: Net, testHost: Net)] and compatible with the
    types available in this PR branch.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: move RunDotnetTestShouldRespectLoggerVerbosityFromRunSettings to end of class to resolve merge conflict with main
    
    The new test was inserted before RunDotnetTestWithNativeDll at a position where
    main independently changed the [NetCoreTargetFrameworkDataSource] attribute to
    [TestMatrix]. This caused a 3-way merge conflict. Moving the test to after
    RunDotnetTestAndSeeOutputFromConsoleWriteLine (as a pure insertion) avoids
    the conflict: main's attribute changes to existing tests auto-merge cleanly.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: replace [TestMatrix] with [NetCoreTargetFrameworkDataSource] in new regression test
    
    TestMatrixAttribute does not exist in this PR branch — it was introduced in
    main after this branch was cut. Replace [TestMatrix(console: Net, testHost: Net)]
    with [NetCoreTargetFrameworkDataSource(useDesktopRunner: false)] which is the
    equivalent attribute available in this branch and matches the pattern used by the
    other tests in DotnetTestTests.cs.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: restore NetCoreAppMinimum TFM to CrossPlatEngine and update expected-dll-frameworks
    
    CrossPlatEngine.csproj was missing $(NetCoreAppMinimum) (net8.0) from its
    TargetFrameworks. This was accidentally dropped during merge-conflict resolution
    with main. Without net8.0, the DLL falls back to netstandard2.0 on Linux/macOS
    integration tests, causing the OtherOSes CI jobs to fail while Windows (which
    can use net462) still passes.
    
    Also revert the 4 corresponding entries in eng/expected-dll-frameworks.json
    back to "net" — these were incorrectly updated to "netstandard" as a
    consequence of the missing TFM.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * style: add explanatory comment for NU5128 suppression in TestPlatform.Build.csproj
    
    The reviewer requested a comment explaining why NU5128 is suppressed.
    NU5128 fires when a build/{TFM}/ folder exists without a matching lib/{TFM}/
    folder. The SDK pack auto-generates build/netstandard2.0/ metadata even though
    the main content is in lib/netstandard2.0/. The .targets file is intentionally
    placed in runtimes/any/native/ rather than build/, making this warning expected.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: align DotnetTestTests with main to resolve merge conflict
    
    The merge conflict in DotnetTestTests.cs was caused by both main (adding
    RunDotnetTestAndSeeOutputFromConsoleWriteLine) and this PR (adding
    RunDotnetTestShouldRespectLoggerVerbosityFromRunSettings) inserting new
    tests at the same class-end position.
    
    Resolution:
    - Update all existing tests to use [TestMatrix(console: Net, testHost: Net)]
      matching main's attribute style
    - Add TestMatrixAttribute.cs and CompatibilityMatrixAttribute.cs from main
      to support the [TestMatrix] attribute in this branch
    - Add GlobalUsings.cs to make Target enum members unqualified
    - Keep both RunDotnetTestAndSeeOutputFromConsoleWriteLine (from main) and
      RunDotnetTestShouldRespectLoggerVerbosityFromRunSettings (PR's regression
      test) at the end of the class in the correct order
    
    This makes the PR's DotnetTestTests.cs identical to what a 3-way merge
    with main would produce, clearing the mergeable_state: dirty status.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: remove NU5128 comment to resolve merge conflict with main
    
    The reviewer-requested comment creates an add/add conflict with main
    because both the PR branch and main independently rewrote Build.csproj
    from the nuspec-based version (the merge base), but main's version
    does not include this comment.
    
    Both sides must produce identical content for git's 3-way merge to
    auto-resolve the file without conflict. Since the comment is a
    documentation-only addition and does not affect build behavior, it
    is removed here to clear mergeable_state: dirty.
    
    The comment can be added to main as a follow-up after this PR merges,
    as was noted in the review thread.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix settings argument assertion
    
    🤖
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    * Retry CI after transient Windows timeouts
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    * Fix verbosity acceptance test on Unix
    
    Assert on the skipped test name, which normal verbosity emits consistently on Windows, Linux, and macOS. Passing test names are not emitted by the MTP path on Unix.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    Copilot-Session: a96bafe8-bea8-423a-822e-d1a5ab43cb8a
    
    🤖
    
    * Avoid platform-specific test summary assertion
    
    The MTP output uses the VSTest summary format on Unix, while ValidateSummaryStatus expects the dotnet test format. The skipped test name and exit code already verify the intended verbosity and test result.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    Copilot-Session: a96bafe8-bea8-423a-822e-d1a5ab43cb8a
    
    🤖
    
    * Address review feedback on logger verbosity handling
    
    Match <Verbosity> only when it sits directly under <Configuration>, so a
    Verbosity element belonging to another logger's schema no longer suppresses
    the MSBuild-derived verbosity. The match stays case-insensitive, like the
    rest of the settings parsing.
    
    Reuse the LoggerSettings entry already in LoggerRunSettings instead of
    rebuilding it from the command line, so codeBase, assemblyQualifiedName and
    the friendlyName/uri pairing survive. Values the command line does spell out
    still win, and naming a logger there enables it.
    
    Explain why the File.Exists guard stays: XDocument.Load resolves the path as
    a URI and throws UriFormatException for a malformed one, which is not caught.
    
    🤖
    
    * Cover the uri form of the console logger in the preservation tests
    
    The three preservation tests all identify the logger by friendlyName. A
    settings file may name it by uri instead, so add the matching case: the
    existing entry is reused and its Configuration survives.
    
    🤖
    
    * Assert the dev version in the logger verbosity acceptance test
    
    The test passes /p:PackageVersion but never checks it took effect, so it
    would still pass against a released Microsoft.NET.Test.Sdk and exercise the
    shipped code instead of the fix. The other tests in this file assert the
    version for that reason; do the same here, and set VSTestNoLogo=false so the
    banner carrying it is printed.
    
    🤖
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
    3 people authored Aug 18, 2026
    Configuration menu
    Copy the full SHA
    5193be4 View commit details
    Browse the repository at this point in the history
  5. Remove reflection-based deserialization setters (#16356)

    * Remove reflection-based deserialization setters
    
    Use internal ObjectModel access for protocol deserialization, remove Jsonite's compiler backing-field lookup, and preserve immutable data-collection IDs through explicit constructors.
    
    Await the optional code coverage merge task through its declared result type and guard malformed plugin metadata.
    
    Fix #16353
    
    🤖
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    * Fix serializer mixed-version compatibility
    
    Construct discovery criteria through its existing public API so newer CommunicationUtilities binaries continue to work with older ObjectModel assemblies. Keep narrowly scoped compatibility paths for immutable protocol identifiers and protected data-collection constructors.
    
    Add empty adapter-map coverage and retain the NativeAOT direct path.
    
    🤖
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    * Use Release configuration for NativeAOT test
    
    Make the publish configuration match the executable path asserted by the compatibility test.
    
    🤖
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    * Handle missing AdapterSourceMap and normalize the NativeAOT consumer path
    
    DiscoveryCriteriaConverter passed the deserialized AdapterSourceMap straight to
    DiscoveryCriteriaFactory.Create, so a payload that omits the property or sets it
    to null threw NullReferenceException inside the factory. Default it to an empty
    dictionary, which is what the Jsonite path on .NET Framework already does.
    
    NativeAotCompatibilityTests built the published executable path with literal ".."
    segments and never normalized it. Process.Start measures the path as given, so on
    a longer checkout path it exceeded MAX_PATH and failed with "filename or extension
    is too long" instead of running the consumer.
    
    Also correct the NativeAotTranslationLayerConsumer comment that claimed
    trimming/AoT warnings fail the publish, which the properties below it disable.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    * Call DataCollectionContext constructors directly
    
    CommunicationUtilities is already a friend assembly of ObjectModel, so the
    protected internal constructors are reachable without GetConstructor/Invoke.
    Microsoft.TestPlatform.Common already calls them this way.
    
    Also name the actual returned type when the reflected code coverage merge
    method does not return Task<IList<string>>, and pin that shape with a test, so
    a package update that changes it fails loudly instead of silently returning
    unmerged coverage files.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    * Drop the friend grant to the NativeAOT test asset
    
    The consumer reached the internal converters directly, so CommunicationUtilities
    had to grant InternalsVisibleTo to a test asset signed with a key that is checked
    into this repository. Anyone can sign an assembly with that key and read the
    internals of a shipping assembly.
    
    Round trip through JsonDataSerializer instead, the same public entry point
    vstest.console and testhost use. It reaches the same converters underneath, so the
    linker still analyzes them, and the grant and the asset signing are both gone.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    nohwnd and Copilot authored Aug 18, 2026
    Configuration menu
    Copy the full SHA
    da2d6ea View commit details
    Browse the repository at this point in the history
  6. Remove two stale IDE0060 suppressions (#16373)

    * Remove stale IDE0060 suppressions
    
    Delete the unused VersionAttribute and remove obsolete parameters from the attach-debugger conversion. Cover payload propagation and negotiated callback serialization.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    🤖
    
    * Fix AttachDebuggerInfo variable typo
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    nohwnd and Copilot authored Aug 18, 2026
    Configuration menu
    Copy the full SHA
    1faab3d View commit details
    Browse the repository at this point in the history

Commits on Aug 19, 2026

  1. Compile the MTP client out of source-only builds (#16385)

    microsoft/testfx is not a VMR repo, so Microsoft.Testing.Platform.ServerMode.Client.Sources
    is not produced in a source-only build and gets restored from an external feed. The VMR sees
    that as a prebuilt and fails the build, and since .NET 10 there is no per-repo prebuilt
    baseline to exclude it with.
    
    Condition the PackageReference on DotNetBuildSourceOnly and compile out the code that needs
    it: Client/MTP in CrossPlatEngine, MtpTestRuntimeProvider, and the MTP tests. Running MTP
    applications under vstest is opt-in and off by default, so this only drops that feature from
    source-only builds. Normal builds are not affected.
    
    Temporary until the package is available to source-build, see dotnet/dotnet#8349.
    
    🤖
    nohwnd authored Aug 19, 2026
    Configuration menu
    Copy the full SHA
    7e128f4 View commit details
    Browse the repository at this point in the history
  2. Fix the single-test command in AGENTS.md that eng/build.ps1 rejects (#…

    …16387)
    
    AGENTS.md documented the filter as /p:TestRunnerAdditionalArguments="--filter
    TestName", in the build table and again as the argument-quoting example, but
    eng/build.ps1 throws on exactly that string. Use the -filter parameter.
    
    Two neighbouring rows failed the same way: -projects is resolved with
    Resolve-Path, so -projects smoke fails with "Cannot find path" (smoke is the
    -smokeTest switch), and -p is not an Arcade alias for --projects.
    
    The skill file claimed test.sh takes -filter and -smokeTest. It does not:
    test.sh calls arcade's eng/common/build.sh directly and never goes through
    eng/build.ps1, so on Linux/macOS the filter is an MSBuild property.
    
    Verified: ./test.cmd -c Release -filter "FullyQualifiedName~MtpProxyExecutionManagerTests"
    exits 0 and selects 7 tests out of 40 test runs.
    
    🤖
    nohwnd authored Aug 19, 2026
    Configuration menu
    Copy the full SHA
    6b5328f View commit details
    Browse the repository at this point in the history
  3. Enable CA1310 and make culture-sensitive string comparisons ordinal (#…

    …16388)
    
    * Enable CA1310 and make culture-sensitive string comparisons ordinal
    
    StartsWith(string), EndsWith(string) and string.Compare(string, string) use the
    current culture on every platform, including .NET 8+. Two of the sites decide
    real behaviour: whether the runner is launched through dotnet, and how
    runsettings XML attribute names are matched.
    
    Every call now passes StringComparison.Ordinal, so nothing changes case
    sensitivity. The two string.Compare(a, b) == 0 sites read as string.Equals,
    which is what they meant.
    
    🤖
    
    * Fix two CA1310 sites the local solution build did not compile
    
    The #if NETCOREAPP branch in DotnetTestHostManager is only compiled by
    source-build, which forces TargetFrameworks to NetCurrent, and
    test/TestAssets is a separate solution that the main build never touches.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: 916ae4af-e718-4f5b-800a-7647d30d4ebd
    
    ---------
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: 916ae4af-e718-4f5b-800a-7647d30d4ebd
    nohwnd and Copilot authored Aug 19, 2026
    Configuration menu
    Copy the full SHA
    0f5ac69 View commit details
    Browse the repository at this point in the history
  4. [fix] Fix backslash normalization in VSTestCLIRunSettings on Unix (#1…

    …5795)
    
    * Fix backslash normalization in VSTestCLIRunSettings on Unix
    
    When VSTestCLIRunSettings was declared as string[] in MSBuild tasks,
    MSBuild would wrap each value in an ITaskItem whose ItemSpec normalizes
    path separators on Unix — converting backslashes to forward slashes.
    This silently corrupted run settings that contained backslash characters,
    such as regex patterns passed via 'dotnet test -- NUnit.Where=...' .
    
    Fix: change VSTestCLIRunSettings from string[] to string in ITestTask,
    VSTestTask, and VSTestTask2. The string value is then split by newlines
    and semicolons within TestTaskUtils.CreateCommandLineArguments, avoiding
    ITaskItem creation and the associated path normalization.
    
    Multiple settings remain supported: they can be separated by semicolons
    (backward-compatible with MSBuild's default item separator) or newlines.
    
    Fixes #15043
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add acceptance test for CLI run settings backslash preservation
    
    Adds BackslashParameterTestProject and an acceptance test verifying
    that backslashes in TestRunParameters survive through the MSBuild
    task without being normalized to forward slashes.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs: add coverage gap note to backslash integration test
    
    Explain that the test is Windows-only due to patched dotnet not being
    published on non-Windows, and that the unit test
    CreateArgumentShouldPreserveBackslashesInCLIRunSettings is the primary
    regression guard for the Unix-specific bug path.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * test: enable backslash CLIRunSettings test on Unix
    
    Remove the [TestCategory("Windows-Review")] restriction and the
    now-stale Windows-only comment from RunDotnetTestWithCLIRunSettingsContainingBackslashes.
    Patched dotnet is now published cross-platform (see #16067), so the
    test can run on Linux/macOS CI as well.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * test: add Windows-Review category to backslash CLI run settings test
    
    The test uses patched dotnet which is only published on Windows.
    The primary regression guard for the Unix backslash normalization fix
    is the unit test CreateArgumentShouldPreserveBackslashesInCLIRunSettings.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * test: enable backslash CLIRunSettings integration test on all platforms
    
    Remove [TestCategory("Windows-Review")] from RunDotnetTestWithCLIRunSettingsContainingBackslashes.
    The bug this test guards against (ITaskItem backslash normalization) manifests on Unix,
    so the test must run cross-platform to provide meaningful regression coverage.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Only forward VSTestCLIRunSettings when it has entries, and refresh onto main
    
    Blank or separator-only VSTestCLIRunSettings appended a lone -- to the
    vstest.console command line. Split the value first and emit the separator
    only when at least one setting survives.
    
    Adds unit tests for semicolon separated and CRLF separated input and for the
    blank cases, aligns the backslash acceptance test with the neighbouring
    inline settings test so a failure reports the run summary, and moves the new
    test asset to its alphabetical place in TestAssets.slnx.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    * Pin the locally built MSBuild task in the backslash acceptance test
    
    RunDotnetTestWithCLIRunSettingsContainingBackslashes kept failing on Linux and
    macOS with 'Namespace//.Class//b'. That doubled slash is what ITaskItem.ItemSpec
    produces on Unix, so the inner dotnet test was still running the old string[]
    binding even though this branch declares VSTestCLIRunSettings as string. I
    checked the binding on Linux with a small MSBuild project, a string parameter
    keeps the value intact and a string[] parameter turns it into exactly the value
    that CI reported.
    
    Pass /p:VSTestTaskAssemblyFile so the run loads the task from the package we
    just built instead of whatever Microsoft.TestPlatform.Build.dll the SDK happens
    to ship, and check the file is there first, so a missing path fails with a clear
    message instead of quietly falling back.
    
    Add a unit test that asserts VSTestCLIRunSettings stays a string on both
    VSTestTask and VSTestTask2. That is the regression worth guarding against and it
    runs on every platform.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    🤖
    
    * Note that a single run setting cannot contain a semicolon
    
    MSBuild unescapes the property before it reaches the scalar string parameter, so
    %3B arrives as a plain semicolon and SplitCLIRunSettings splits on it. The old
    string[] parameter kept that as one entry, so the escape route is gone. That is
    deliberate, the array form rewrote backslashes to forward slashes on Unix and
    broke every setting that held a regex.
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    
    🤖
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Co-authored-by: Jakub Jares <nohwnd@users.noreply.github.com>
    3 people authored Aug 19, 2026
    Configuration menu
    Copy the full SHA
    499c9af View commit details
    Browse the repository at this point in the history
  5. Guard against a missing PATH in the NativeAOT publish test (#16380)

    The indexer on psi.Environment throws KeyNotFoundException when the runner
    has no PATH. Read it with TryGetValue instead, and set the Visual Studio
    Installer directory on its own when PATH is missing.
    
    This was reviewed and fixed on #16374, but #16356 merged without it.
    
    🤖
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    nohwnd and Copilot authored Aug 19, 2026
    Configuration menu
    Copy the full SHA
    daac823 View commit details
    Browse the repository at this point in the history
  6. Align expert reviewer verdicts with safe outputs (#16381)

    The delegated reviewer still recommends APPROVE while the workflow rejects it, causing deterministic safe_outputs failures. Return COMMENT for clean reviews.
    
    🤖
    
    Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
    nohwnd and Copilot authored Aug 19, 2026
    Configuration menu
    Copy the full SHA
    0b289d5 View commit details
    Browse the repository at this point in the history
Loading