From e55f11e3acb4403d9f8f625389d9730711ae8fa7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 17 Oct 2025 21:40:48 +0000 Subject: [PATCH 1/2] =?UTF-8?q?[sdk]=20Source=20update=20ffb7660=20?= =?UTF-8?q?=E2=86=92=20fec417b=20Diff:=20https://github.com/dotnet/sdk/com?= =?UTF-8?q?pare/ffb766009286aab6419d3e2e241b9351d0bb9d2b..fec417b441e58933?= =?UTF-8?q?1f35ad7b8d26832cb2f88821?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: https://github.com/dotnet/sdk/commit/ffb766009286aab6419d3e2e241b9351d0bb9d2b To: https://github.com/dotnet/sdk/commit/fec417b441e589331f35ad7b8d26832cb2f88821 [[ commit created by automation ]] --- .../Commands/Test/VSTest/TestCommand.cs | 45 ++++++++---- ...enDotnetTestBuildsAndRunsTestfromCsproj.cs | 22 ++++++ .../Test/TestCommandParserTests.cs | 73 ++++++++++++++++++- src/source-manifest.json | 4 +- 4 files changed, 124 insertions(+), 20 deletions(-) diff --git a/src/sdk/src/Cli/dotnet/Commands/Test/VSTest/TestCommand.cs b/src/sdk/src/Cli/dotnet/Commands/Test/VSTest/TestCommand.cs index a17cc0031e1..9a1700f82a8 100644 --- a/src/sdk/src/Cli/dotnet/Commands/Test/VSTest/TestCommand.cs +++ b/src/sdk/src/Cli/dotnet/Commands/Test/VSTest/TestCommand.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.CommandLine; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.Versioning; using System.Text.RegularExpressions; @@ -39,14 +40,14 @@ public static int Run(ParseResult parseResult) VSTestTrace.SafeWriteTrace(() => $"Argument list: '{commandLineParameters}'"); } - // settings parameters are after -- (including --), these should not be considered by the parser - string[] settings = [.. args.SkipWhile(a => a != "--")]; - // all parameters before -- - args = [.. args.TakeWhile(a => a != "--")]; + (args, string[] settings) = SeparateSettingsFromArgs(args); // Fix for https://github.com/Microsoft/vstest/issues/1453 // Run dll/exe directly using the VSTestForwardingApp - if (ContainsBuiltTestSources(args)) + // Note: ContainsBuiltTestSources need to know how many settings are there, to skip those from unmatched tokens + // When we don't have settings, we pass 0. + // When we have settings, we want to exclude the '--' as it doesn't end up in unmatched tokens, so we pass settings.Length - 1 + if (ContainsBuiltTestSources(parseResult, GetSettingsCount(settings))) { return ForwardToVSTestConsole(parseResult, args, settings, testSessionCorrelationId); } @@ -54,6 +55,26 @@ public static int Run(ParseResult parseResult) return ForwardToMsbuild(parseResult, settings, testSessionCorrelationId); } + internal /*internal for testing*/ static (string[] Args, string[] Settings) SeparateSettingsFromArgs(string[] args) + { + // settings parameters are after -- (including --), these should not be considered by the parser + string[] settings = [.. args.SkipWhile(a => a != "--")]; + // all parameters before -- + args = [.. args.TakeWhile(a => a != "--")]; + return (args, settings); + } + + internal /*internal for testing*/ static int GetSettingsCount(string[] settings) + { + if (settings.Length == 0) + { + return 0; + } + + Debug.Assert(settings[0] == "--", "Settings should start with --"); + return settings.Length - 1; + } + private static int ForwardToMsbuild(ParseResult parseResult, string[] settings, string testSessionCorrelationId) { // Workaround for https://github.com/Microsoft/vstest/issues/1503 @@ -295,18 +316,14 @@ internal static int RunArtifactPostProcessingIfNeeded(string testSessionCorrelat } } - private static bool ContainsBuiltTestSources(string[] args) + internal /*internal for testing*/ static bool ContainsBuiltTestSources(ParseResult parseResult, int settingsLength) { - for (int i = 0; i < args.Length; i++) + for (int i = 0; i < parseResult.UnmatchedTokens.Count - settingsLength; i++) { - string arg = args[i]; - if (arg.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || arg.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) + string arg = parseResult.UnmatchedTokens[i]; + if (!arg.StartsWith("-") && + (arg.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || arg.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))) { - var previousArg = i > 0 ? args[i - 1] : null; - if (previousArg != null && CommonOptions.PropertiesOption.Aliases.Contains(previousArg)) - { - return false; - } return true; } } diff --git a/src/sdk/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestfromCsproj.cs b/src/sdk/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestfromCsproj.cs index 96b0e9edb73..6c054f61cee 100644 --- a/src/sdk/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestfromCsproj.cs +++ b/src/sdk/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestfromCsproj.cs @@ -836,6 +836,28 @@ public void PropertiesEndingWithDotDllShouldNotFail(string property) result.ExitCode.Should().Be(1); } + [Fact] + public void DistributedLoggerEndingWithDotDllShouldBePassedToMSBuild() + { + var testProjectDirectory = CopyAndRestoreVSTestDotNetCoreTestApp([]); + + CommandResult result = new DotnetTestCommand(Log, disableNewOutput: true) + .WithWorkingDirectory(testProjectDirectory) + .Execute(ConsoleLoggerOutputNormal.Concat(["-dl:my.dll"])); + + if (!TestContext.IsLocalized()) + { + // This ensures that this was passed to MSBuild and not vstest.console. + result.StdOut.Should().Contain("error MSB1021: Cannot create an instance of the logger my.dll."); + } + else + { + result.StdOut.Should().Contain("MSB1021"); + } + + result.ExitCode.Should().Be(1); + } + private string CopyAndRestoreVSTestDotNetCoreTestApp(object[] parameters, [CallerMemberName] string callingMethod = "") { // Copy VSTestCore project in output directory of project dotnet-vstest.Tests diff --git a/src/sdk/test/dotnet.Tests/CommandTests/Test/TestCommandParserTests.cs b/src/sdk/test/dotnet.Tests/CommandTests/Test/TestCommandParserTests.cs index 9b86d3c92c4..1c780c37bc1 100644 --- a/src/sdk/test/dotnet.Tests/CommandTests/Test/TestCommandParserTests.cs +++ b/src/sdk/test/dotnet.Tests/CommandTests/Test/TestCommandParserTests.cs @@ -1,10 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - -using System.CommandLine; using Microsoft.DotNet.Cli.Commands.Test; +using Microsoft.DotNet.Cli.Extensions; +using TestCommand = Microsoft.DotNet.Cli.Commands.Test.TestCommand; namespace Microsoft.DotNet.Cli.Test.Tests { @@ -14,7 +13,7 @@ public class TestCommandParserTests public void SurroundWithDoubleQuotesWithNullThrows() { Assert.Throws(() => - TestCommandParser.SurroundWithDoubleQuotes(null)); + TestCommandParser.SurroundWithDoubleQuotes(null!)); } [Theory] @@ -74,5 +73,71 @@ public void VSTestCommandIncludesPropertiesOption() propertyOption.Should().NotBeNull("VSTest command should include CommonOptions.PropertiesOption to support /p Property=Value syntax"); propertyOption.Aliases.Should().Contain("/p", "PropertiesOption should include /p alias for MSBuild compatibility"); } + + [Fact] + public void DllDetectionShouldExcludeRunArgumentsAndGlobalProperties() + { + var parseResult = Parser.Parse("""test -p:"RunConfig=abd.dll" -- RunConfig=abd.dll -p:"RunConfig=abd.dll" --results-directory hey.dll"""); + var args = parseResult.GetArguments(); + + (args, string[] settings) = TestCommand.SeparateSettingsFromArgs(args); + int settingsCount = TestCommand.GetSettingsCount(settings); + settingsCount.Should().Be(4); + + // Our unmatched tokens for this test case are only the settings (after the `--`). + Assert.Equal(settingsCount, parseResult.UnmatchedTokens.Count); + + Assert.Equal("--", settings[0]); + Assert.Equal(settings.Length, settingsCount + 1); + for (int i = 1; i <= settingsCount; i++) + { + Assert.Equal(settings[^i], parseResult.UnmatchedTokens[^i]); + } + + TestCommand.ContainsBuiltTestSources(parseResult, settingsCount).Should().Be(false); + } + + [Fact] + public void DllDetectionShouldBeTrueWhenPresentAloneEvenIfDuplicatedInSettings() + { + var parseResult = Parser.Parse("""test abd.dll -- abd.dll"""); + var args = parseResult.GetArguments(); + + (args, string[] settings) = TestCommand.SeparateSettingsFromArgs(args); + int settingsCount = TestCommand.GetSettingsCount(settings); + settingsCount.Should().Be(1); + + // Our unmatched tokens here are all the settings, plus the abd.dll before the `--`. + Assert.Equal(settingsCount + 1, parseResult.UnmatchedTokens.Count); + + Assert.Equal("--", settings[0]); + Assert.Equal(settings.Length, settingsCount + 1); + for (int i = 1; i <= settingsCount; i++) + { + Assert.Equal(settings[^i], parseResult.UnmatchedTokens[^i]); + } + + TestCommand.ContainsBuiltTestSources(parseResult, settingsCount).Should().Be(true); + } + + [Theory] + [InlineData("abd.dll", true)] + [InlineData("abd.dll --", true)] + [InlineData("-dl:abd.dll", false)] + [InlineData("-dl:abd.dll --", false)] + [InlineData("-abcd:abd.dll", false)] + [InlineData("-abcd:abd.dll --", false)] + [InlineData("-p:abd.dll", false)] + [InlineData("-p:abd.dll --", false)] + public void DllDetectionShouldWorkWhenNoSettings(string testArgs, bool expectedContainsBuiltTestSource) + { + var parseResult = Parser.Parse($"test {testArgs}"); + var args = parseResult.GetArguments(); + + (args, string[] settings) = TestCommand.SeparateSettingsFromArgs(args); + int settingsCount = TestCommand.GetSettingsCount(settings); + settingsCount.Should().Be(0); + TestCommand.ContainsBuiltTestSources(parseResult, settingsCount).Should().Be(expectedContainsBuiltTestSource); + } } } diff --git a/src/source-manifest.json b/src/source-manifest.json index 008b9b6d084..114fdd19e0c 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -91,10 +91,10 @@ "commitSha": "082359066ee0064039b9b1f1f025bdd0507d06de" }, { - "barId": 287503, + "barId": -1, "path": "sdk", "remoteUri": "https://github.com/dotnet/sdk", - "commitSha": "ffb766009286aab6419d3e2e241b9351d0bb9d2b" + "commitSha": "fec417b441e589331f35ad7b8d26832cb2f88821" }, { "barId": 287459, From bb8b61beed874f5374cedc7584e892d1b0df0348 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 17 Oct 2025 21:40:49 +0000 Subject: [PATCH 2/2] =?UTF-8?q?[sdk]=20Source=20update=20fec417b=20?= =?UTF-8?q?=E2=86=92=200235c63=20Diff:=20https://github.com/dotnet/sdk/com?= =?UTF-8?q?pare/fec417b441e589331f35ad7b8d26832cb2f88821..0235c63abd7d470d?= =?UTF-8?q?8701643be7fd7b003bdc0ae4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: https://github.com/dotnet/sdk/commit/fec417b441e589331f35ad7b8d26832cb2f88821 To: https://github.com/dotnet/sdk/commit/0235c63abd7d470d8701643be7fd7b003bdc0ae4 [[ commit created by automation ]] --- src/sdk/eng/Versions.props | 8 ++++---- src/source-manifest.json | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sdk/eng/Versions.props b/src/sdk/eng/Versions.props index ce1167cea3c..7bb89cb6b11 100644 --- a/src/sdk/eng/Versions.props +++ b/src/sdk/eng/Versions.props @@ -38,14 +38,14 @@ 36 20 - 19 - 8 + $([MSBuild]::Add($(VersionFeature), 22)) + $([MSBuild]::Add($(VersionFeature), 11)) <_NET70ILLinkPackVersion>7.0.100-1.23211.1 - $([MSBuild]::Add($(VersionFeature80), 1)) - $([MSBuild]::Add($(VersionFeature90), 1)) + $(VersionFeature80) + $(VersionFeature90) diff --git a/src/source-manifest.json b/src/source-manifest.json index 114fdd19e0c..9c9a22bb36e 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -91,10 +91,10 @@ "commitSha": "082359066ee0064039b9b1f1f025bdd0507d06de" }, { - "barId": -1, + "barId": 287649, "path": "sdk", "remoteUri": "https://github.com/dotnet/sdk", - "commitSha": "fec417b441e589331f35ad7b8d26832cb2f88821" + "commitSha": "0235c63abd7d470d8701643be7fd7b003bdc0ae4" }, { "barId": 287459,