Skip to content

Commit 3ca6812

Browse files
authored
[automated] Merge branch 'release/10.0.1xx' => 'main' (#50868)
2 parents 008f3c9 + 5a0ee7c commit 3ca6812

File tree

72 files changed

+1018
-450
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1018
-450
lines changed

eng/Versions.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
116116
Additionally, set the MinimumVSVersion for the installer UI that's required for targeting NetCurrent -->
117117
<MicrosoftBuildMinimumVersion Condition="'$(DotNetBuildSourceOnly)' != 'true'">17.14.8</MicrosoftBuildMinimumVersion>
118-
<MinimumVSVersion>17.14</MinimumVSVersion>
118+
<MinimumVSVersion>18.0</MinimumVSVersion>
119119
</PropertyGroup>
120120
<PropertyGroup>
121121
<!-- Dependencies from https://github.com/dotnet/emsdk -->

src/Cli/dotnet/Commands/CliCommandStrings.resx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2698,4 +2698,8 @@ Proceed?</value>
26982698
<data name="UnexpectedMessageWithoutHandshake" xml:space="preserve">
26992699
<value>A message of type '{0}' was received before we got any handshakes, which is unexpected.</value>
27002700
</data>
2701-
</root>
2701+
<data name="DotnetTestMismatchingExecutionId" xml:space="preserve">
2702+
<value>Received 'ExecutionId' of value '{0}' for message '{1}' while the 'ExecutionId' received of the handshake message was '{2}'.</value>
2703+
<comment>{Locked="ExecutionId"}</comment>
2704+
</data>
2705+
</root>

src/Cli/dotnet/Commands/Test/MTP/MSBuildHandler.cs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,21 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Collections.Concurrent;
5-
using Microsoft.DotNet.Cli.Commands.Test.Terminal;
65
using Microsoft.DotNet.Cli.Utils;
6+
using Microsoft.DotNet.Cli.Utils.Extensions;
77

88
namespace Microsoft.DotNet.Cli.Commands.Test;
99

10-
internal sealed class MSBuildHandler(BuildOptions buildOptions, TerminalTestReporter output)
10+
internal sealed class MSBuildHandler(BuildOptions buildOptions)
1111
{
1212
private readonly BuildOptions _buildOptions = buildOptions;
13-
private readonly TerminalTestReporter _output = output;
1413

1514
private readonly ConcurrentBag<ParallelizableTestModuleGroupWithSequentialInnerModules> _testApplications = [];
1615
private bool _areTestingPlatformApplications = true;
1716

1817
public bool RunMSBuild()
1918
{
20-
if (!ValidationUtility.ValidateBuildPathOptions(_buildOptions, _output))
19+
if (!ValidationUtility.ValidateBuildPathOptions(_buildOptions))
2120
{
2221
return false;
2322
}
@@ -50,7 +49,7 @@ public bool RunMSBuild()
5049

5150
if (msBuildExitCode != ExitCode.Success)
5251
{
53-
_output.WriteMessage(string.Format(CliCommandStrings.CmdMSBuildProjectsPropertiesErrorDescription, msBuildExitCode));
52+
Reporter.Error.WriteLine(string.Format(CliCommandStrings.CmdMSBuildProjectsPropertiesErrorDescription, msBuildExitCode));
5453
return false;
5554
}
5655

@@ -81,15 +80,15 @@ private int RunBuild(string directoryPath, bool expectProject = false, bool expe
8180

8281
if (!solutionOrProjectFileFound)
8382
{
84-
_output.WriteMessage(message);
83+
Reporter.Error.WriteLine(message);
8584
return ExitCode.GenericFailure;
8685
}
8786

8887
(IEnumerable<ParallelizableTestModuleGroupWithSequentialInnerModules> projects, bool restored) = GetProjectsProperties(projectOrSolutionFilePath, isSolution);
8988

9089
InitializeTestApplications(projects);
9190

92-
return restored ? ExitCode.Success : ExitCode.GenericFailure;
91+
return restored && !_testApplications.IsEmpty ? ExitCode.Success : ExitCode.GenericFailure;
9392
}
9493

9594
private int RunBuild(string filePath, bool isSolution)
@@ -98,7 +97,7 @@ private int RunBuild(string filePath, bool isSolution)
9897

9998
InitializeTestApplications(projects);
10099

101-
return restored ? ExitCode.Success : ExitCode.GenericFailure;
100+
return restored && !_testApplications.IsEmpty ? ExitCode.Success : ExitCode.GenericFailure;
102101
}
103102

104103
private void InitializeTestApplications(IEnumerable<ParallelizableTestModuleGroupWithSequentialInnerModules> moduleGroups)
@@ -110,13 +109,10 @@ private void InitializeTestApplications(IEnumerable<ParallelizableTestModuleGrou
110109
{
111110
_areTestingPlatformApplications = false;
112111

113-
_output.WriteMessage(
112+
Reporter.Error.WriteLine(
114113
string.Format(
115114
CliCommandStrings.CmdUnsupportedVSTestTestApplicationsDescription,
116-
string.Join(Environment.NewLine, vsTestTestProjects.Select(module => Path.GetFileName(module.ProjectFullPath)))),
117-
new SystemConsoleColor { ConsoleColor = ConsoleColor.Red });
118-
119-
_output.DisableTestRunSummary();
115+
string.Join(Environment.NewLine, vsTestTestProjects.Select(module => Path.GetFileName(module.ProjectFullPath))).Red().Bold()));
120116

121117
return;
122118
}

src/Cli/dotnet/Commands/Test/MTP/MicrosoftTestingPlatformTestCommand.cs

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ namespace Microsoft.DotNet.Cli.Commands.Test;
1313
internal partial class MicrosoftTestingPlatformTestCommand : Command, ICustomHelp, ICommandDocument
1414
{
1515
private TerminalTestReporter? _output;
16-
private byte _cancelled;
1716

1817
public MicrosoftTestingPlatformTestCommand(string name, string? description = null) : base(name, description)
1918
{
@@ -32,7 +31,7 @@ public int Run(ParseResult parseResult, bool isHelp = false)
3231
}
3332
finally
3433
{
35-
CompleteRun(exitCode);
34+
_output?.TestExecutionCompleted(DateTimeOffset.Now, exitCode);
3635
}
3736
}
3837

@@ -47,16 +46,14 @@ private int RunInternal(ParseResult parseResult, bool isHelp)
4746
IsDiscovery: parseResult.HasOption(MicrosoftTestingPlatformOptions.ListTestsOption),
4847
EnvironmentVariables: parseResult.GetValue(CommonOptions.EnvOption) ?? ImmutableDictionary<string, string>.Empty);
4948

50-
InitializeOutput(degreeOfParallelism, parseResult, testOptions);
51-
52-
SetupCancelKeyPressHandler();
53-
5449
BuildOptions buildOptions = MSBuildUtility.GetBuildOptions(parseResult);
5550

5651
bool filterModeEnabled = parseResult.HasOption(MicrosoftTestingPlatformOptions.TestModulesFilterOption);
5752
TestApplicationActionQueue actionQueue;
5853
if (filterModeEnabled)
5954
{
55+
InitializeOutput(degreeOfParallelism, parseResult, testOptions);
56+
6057
actionQueue = new TestApplicationActionQueue(degreeOfParallelism, buildOptions, testOptions, _output, OnHelpRequested);
6158
var testModulesFilterHandler = new TestModulesFilterHandler(actionQueue, _output);
6259
if (!testModulesFilterHandler.RunWithTestModulesFilter(parseResult))
@@ -66,12 +63,14 @@ private int RunInternal(ParseResult parseResult, bool isHelp)
6663
}
6764
else
6865
{
69-
var msBuildHandler = new MSBuildHandler(buildOptions, _output);
66+
var msBuildHandler = new MSBuildHandler(buildOptions);
7067
if (!msBuildHandler.RunMSBuild())
7168
{
7269
return ExitCode.GenericFailure;
7370
}
7471

72+
InitializeOutput(degreeOfParallelism, parseResult, testOptions);
73+
7574
// NOTE: Don't create TestApplicationActionQueue before RunMSBuild.
7675
// The constructor will do Task.Run calls matching the degree of parallelism, and if we did that before the build, that can
7776
// be slowing us down unnecessarily.
@@ -98,16 +97,6 @@ private int RunInternal(ParseResult parseResult, bool isHelp)
9897
return exitCode;
9998
}
10099

101-
private void SetupCancelKeyPressHandler()
102-
{
103-
Console.CancelKeyPress += (s, e) =>
104-
{
105-
_output?.StartCancelling();
106-
// We are not sure what the exit code will be, there might be an exception.
107-
CompleteRun(exitCode: null);
108-
};
109-
}
110-
111100
[MemberNotNull(nameof(_output))]
112101
private void InitializeOutput(int degreeOfParallelism, ParseResult parseResult, TestOptions testOptions)
113102
{
@@ -130,6 +119,11 @@ private void InitializeOutput(int degreeOfParallelism, ParseResult parseResult,
130119
MinimumExpectedTests = parseResult.GetValue(MicrosoftTestingPlatformOptions.MinimumExpectedTestsOption),
131120
});
132121

122+
Console.CancelKeyPress += (s, e) =>
123+
{
124+
_output.StartCancelling();
125+
};
126+
133127
// This is ugly, and we need to replace it by passing out some info from testing platform to inform us that some process level retry plugin is active.
134128
var isRetry = parseResult.GetArguments().Contains("--retry-failed-tests");
135129

@@ -143,12 +137,4 @@ private static int GetDegreeOfParallelism(ParseResult parseResult)
143137
degreeOfParallelism = Environment.ProcessorCount;
144138
return degreeOfParallelism;
145139
}
146-
147-
private void CompleteRun(int? exitCode)
148-
{
149-
if (Interlocked.CompareExchange(ref _cancelled, 1, 0) == 0)
150-
{
151-
_output?.TestExecutionCompleted(DateTimeOffset.Now, exitCode);
152-
}
153-
}
154140
}

src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporter.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ internal sealed partial class TerminalTestReporter : IDisposable
5757
private static partial Regex GetFrameRegex();
5858

5959
private int _counter;
60-
private bool _disableTestRunSummary;
6160

6261
/// <summary>
6362
/// Initializes a new instance of the <see cref="TerminalTestReporter"/> class with custom terminal and manual refresh for testing.
@@ -148,17 +147,12 @@ private TestProgressState GetOrAddAssemblyRun(string assembly, string? targetFra
148147
});
149148
}
150149

151-
public void DisableTestRunSummary()
152-
{
153-
_disableTestRunSummary = true;
154-
}
155-
156150
public void TestExecutionCompleted(DateTimeOffset endTime, int? exitCode)
157151
{
158152
_testExecutionEndTime = endTime;
159153
_terminalWithProgress.StopShowingProgress();
160154

161-
if (!_isHelp && !_disableTestRunSummary)
155+
if (!_isHelp)
162156
{
163157
if (_isDiscovery)
164158
{
@@ -844,6 +838,11 @@ public void ArtifactAdded(bool outOfProcess, string? assembly, string? targetFra
844838
/// </summary>
845839
public void StartCancelling()
846840
{
841+
if (_wasCancelled)
842+
{
843+
return;
844+
}
845+
847846
_wasCancelled = true;
848847
_terminalWithProgress.WriteToTerminal(terminal =>
849848
{

src/Cli/dotnet/Commands/Test/MTP/TestApplicationHandler.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ internal void OnDiscoveredTestsReceived(DiscoveredTestMessages discoveredTestMes
100100
throw new InvalidOperationException(string.Format(CliCommandStrings.UnexpectedMessageWithoutHandshake, nameof(DiscoveredTestMessages)));
101101
}
102102

103+
if (discoveredTestMessages.ExecutionId != _handshakeInfo.Value.ExecutionId)
104+
{
105+
// Received 'ExecutionId' of value '{0}' for message '{1}' while the 'ExecutionId' received of the handshake message was '{2}'.
106+
throw new InvalidOperationException(string.Format(CliCommandStrings.DotnetTestMismatchingExecutionId, discoveredTestMessages.ExecutionId, nameof(DiscoveredTestMessages), _handshakeInfo.Value.ExecutionId));
107+
}
108+
103109
foreach (var test in discoveredTestMessages.DiscoveredMessages)
104110
{
105111
_output.TestDiscovered(_handshakeInfo.Value.ExecutionId,
@@ -122,6 +128,12 @@ internal void OnTestResultsReceived(TestResultMessages testResultMessage)
122128
throw new InvalidOperationException(string.Format(CliCommandStrings.UnexpectedMessageWithoutHandshake, nameof(TestResultMessages)));
123129
}
124130

131+
if (testResultMessage.ExecutionId != _handshakeInfo.Value.ExecutionId)
132+
{
133+
// Received 'ExecutionId' of value '{0}' for message '{1}' while the 'ExecutionId' received of the handshake message was '{2}'.
134+
throw new InvalidOperationException(string.Format(CliCommandStrings.DotnetTestMismatchingExecutionId, testResultMessage.ExecutionId, nameof(TestResultMessages), _handshakeInfo.Value.ExecutionId));
135+
}
136+
125137
var handshakeInfo = _handshakeInfo.Value;
126138
foreach (var testResult in testResultMessage.SuccessfulTestMessages)
127139
{
@@ -169,6 +181,12 @@ internal void OnFileArtifactsReceived(FileArtifactMessages fileArtifactMessages)
169181
throw new InvalidOperationException(string.Format(CliCommandStrings.UnexpectedMessageWithoutHandshake, nameof(FileArtifactMessages)));
170182
}
171183

184+
if (fileArtifactMessages.ExecutionId != _handshakeInfo.Value.ExecutionId)
185+
{
186+
// Received 'ExecutionId' of value '{0}' for message '{1}' while the 'ExecutionId' received of the handshake message was '{2}'.
187+
throw new InvalidOperationException(string.Format(CliCommandStrings.DotnetTestMismatchingExecutionId, fileArtifactMessages.ExecutionId, nameof(FileArtifactMessages), _handshakeInfo.Value.ExecutionId));
188+
}
189+
172190
var handshakeInfo = _handshakeInfo.Value;
173191
foreach (var artifact in fileArtifactMessages.FileArtifacts)
174192
{
@@ -193,6 +211,12 @@ internal void OnSessionEventReceived(TestSessionEvent sessionEvent)
193211
throw new InvalidOperationException(string.Format(CliCommandStrings.UnexpectedMessageWithoutHandshake, nameof(DiscoveredTestMessages)));
194212
}
195213

214+
if (sessionEvent.ExecutionId != _handshakeInfo.Value.ExecutionId)
215+
{
216+
// Received 'ExecutionId' of value '{0}' for message '{1}' while the 'ExecutionId' received of the handshake message was '{2}'.
217+
throw new InvalidOperationException(string.Format(CliCommandStrings.DotnetTestMismatchingExecutionId, sessionEvent.ExecutionId, nameof(TestSessionEvent), _handshakeInfo.Value.ExecutionId));
218+
}
219+
196220
if (sessionEvent.SessionType == SessionEventTypes.TestSessionStart)
197221
{
198222
IncreaseTestSessionStart(sessionEvent.SessionUid!);

src/Cli/dotnet/Commands/Test/MTP/ValidationUtility.cs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.CommandLine;
5-
using Microsoft.DotNet.Cli.Commands.Test.Terminal;
65
using Microsoft.DotNet.Cli.Extensions;
76
using Microsoft.DotNet.Cli.Utils;
87

@@ -49,18 +48,18 @@ static void ValidateOptionsIrrelevantToModulesFilter(ParseResult parseResult)
4948
}
5049
}
5150

52-
public static bool ValidateBuildPathOptions(BuildOptions buildPathOptions, TerminalTestReporter output)
51+
public static bool ValidateBuildPathOptions(BuildOptions buildPathOptions)
5352
{
5453
PathOptions pathOptions = buildPathOptions.PathOptions;
5554

5655
if (!string.IsNullOrEmpty(pathOptions.ProjectPath))
5756
{
58-
return ValidateProjectPath(pathOptions.ProjectPath, output);
57+
return ValidateProjectPath(pathOptions.ProjectPath);
5958
}
6059

6160
if (!string.IsNullOrEmpty(pathOptions.SolutionPath))
6261
{
63-
return ValidateSolutionPath(pathOptions.SolutionPath, output);
62+
return ValidateSolutionPath(pathOptions.SolutionPath);
6463
}
6564

6665
return true;
@@ -107,7 +106,7 @@ public static void ValidateSolutionOrProjectOrDirectoryOrModulesArePassedCorrect
107106
}
108107
}
109108

110-
private static bool ValidateSolutionPath(string path, TerminalTestReporter output)
109+
private static bool ValidateSolutionPath(string path)
111110
{
112111
// If it's a directory, just check if it exists
113112
if (Directory.Exists(path))
@@ -118,14 +117,14 @@ private static bool ValidateSolutionPath(string path, TerminalTestReporter outpu
118117
// If it's not a directory, validate as a file path
119118
if (!CliConstants.SolutionExtensions.Contains(Path.GetExtension(path)))
120119
{
121-
output.WriteMessage(string.Format(CliCommandStrings.CmdInvalidSolutionFileExtensionErrorDescription, path));
120+
Reporter.Error.WriteLine(string.Format(CliCommandStrings.CmdInvalidSolutionFileExtensionErrorDescription, path));
122121
return false;
123122
}
124123

125-
return ValidateFilePathExists(path, output);
124+
return ValidateFilePathExists(path);
126125
}
127126

128-
private static bool ValidateProjectPath(string path, TerminalTestReporter output)
127+
private static bool ValidateProjectPath(string path)
129128
{
130129
// If it's a directory, just check if it exists
131130
if (Directory.Exists(path))
@@ -136,18 +135,18 @@ private static bool ValidateProjectPath(string path, TerminalTestReporter output
136135
// If it's not a directory, validate as a file path
137136
if (!Path.GetExtension(path).EndsWith("proj", StringComparison.OrdinalIgnoreCase))
138137
{
139-
output.WriteMessage(string.Format(CliCommandStrings.CmdInvalidProjectFileExtensionErrorDescription, path));
138+
Reporter.Error.WriteLine(string.Format(CliCommandStrings.CmdInvalidProjectFileExtensionErrorDescription, path));
140139
return false;
141140
}
142141

143-
return ValidateFilePathExists(path, output);
142+
return ValidateFilePathExists(path);
144143
}
145144

146-
private static bool ValidateFilePathExists(string filePath, TerminalTestReporter output)
145+
private static bool ValidateFilePathExists(string filePath)
147146
{
148147
if (!File.Exists(filePath))
149148
{
150-
output.WriteMessage(string.Format(CliCommandStrings.CmdNonExistentFileErrorDescription, Path.GetFullPath(filePath)));
149+
Reporter.Error.WriteLine(string.Format(CliCommandStrings.CmdNonExistentFileErrorDescription, Path.GetFullPath(filePath)));
151150
return false;
152151
}
153152

src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)