diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryDataConsumer.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryDataConsumer.cs index fad2a0f958..53c43d6231 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryDataConsumer.cs +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryDataConsumer.cs @@ -9,7 +9,6 @@ using Microsoft.Testing.Platform.Extensions.TestHost; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.IPC.Models; -using Microsoft.Testing.Platform.Messages; using Microsoft.Testing.Platform.Services; namespace Microsoft.Testing.Extensions.Policy; @@ -47,14 +46,20 @@ public async Task ConsumeAsync(IDataProducer dataProducer, IData value, Cancella return; } - if (Array.IndexOf(TestNodePropertiesCategories.WellKnownTestNodeTestRunOutcomeFailedProperties, nodeState.GetType()) != -1) + if (nodeState is FailedTestNodeStateProperty or ErrorTestNodeStateProperty +#pragma warning disable CS0618, MTP0001 // Type or member is obsolete + or TimeoutTestNodeStateProperty or CancelledTestNodeStateProperty) +#pragma warning restore CS0618, MTP0001 // Type or member is obsolete { ApplicationStateGuard.Ensure(_retryFailedTestsLifecycleCallbacks is not null); ApplicationStateGuard.Ensure(_retryFailedTestsLifecycleCallbacks.Client is not null); await _retryFailedTestsLifecycleCallbacks.Client.RequestReplyAsync(new FailedTestRequest(testNodeUpdateMessage.TestNode.Uid), cancellationToken).ConfigureAwait(false); } - if (Array.IndexOf(TestNodePropertiesCategories.WellKnownTestNodeTestRunOutcomeProperties, nodeState.GetType()) != -1) + if (nodeState is PassedTestNodeStateProperty or FailedTestNodeStateProperty or ErrorTestNodeStateProperty +#pragma warning disable CS0618, MTP0001 // Type or member is obsolete + or TimeoutTestNodeStateProperty or CancelledTestNodeStateProperty) +#pragma warning restore CS0618, MTP0001 // Type or member is obsolete { _totalTests++; } diff --git a/src/Platform/Microsoft.Testing.Platform/Extensions/AbortForMaxFailedTestsExtension.cs b/src/Platform/Microsoft.Testing.Platform/Extensions/AbortForMaxFailedTestsExtension.cs index 63c2c2884c..db55f985ef 100644 --- a/src/Platform/Microsoft.Testing.Platform/Extensions/AbortForMaxFailedTestsExtension.cs +++ b/src/Platform/Microsoft.Testing.Platform/Extensions/AbortForMaxFailedTestsExtension.cs @@ -4,7 +4,6 @@ using Microsoft.Testing.Platform.Capabilities.TestFramework; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions.Messages; -using Microsoft.Testing.Platform.Messages; using Microsoft.Testing.Platform.Resources; using Microsoft.Testing.Platform.Services; @@ -67,8 +66,12 @@ public async Task ConsumeAsync(IDataProducer dataProducer, IData value, Cancella return; } - if (Array.IndexOf(TestNodePropertiesCategories.WellKnownTestNodeTestRunOutcomeFailedProperties, testNodeStateProperty.GetType()) != -1 && - ++_failCount >= _maxFailedTests.Value && + if (testNodeStateProperty is FailedTestNodeStateProperty or ErrorTestNodeStateProperty + or TimeoutTestNodeStateProperty +#pragma warning disable CS0618, MTP0001 // Type or member is obsolete + or CancelledTestNodeStateProperty +#pragma warning restore CS0618, MTP0001 // Type or member is obsolete + && ++_failCount >= _maxFailedTests.Value && // If already triggered, don't do it again. !_policiesService.IsMaxFailedTestsTriggered) { diff --git a/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs b/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs index cb3192958a..d36363fd5f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs @@ -5,7 +5,6 @@ using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.Extensions.OutputDevice; using Microsoft.Testing.Platform.Helpers; -using Microsoft.Testing.Platform.Messages; using Microsoft.Testing.Platform.OutputDevice; using Microsoft.Testing.Platform.Resources; using Microsoft.Testing.Platform.Telemetry; @@ -80,10 +79,17 @@ public Task ConsumeAsync(IDataProducer dataProducer, IData value, CancellationTo { case DiscoveredTestNodeStateProperty: _openTelemetryResultHandler?.NotifyDiscovered(); + // In discovery mode, discovered tests count toward the "ran" total. + if (_isDiscovery) + { + _totalRanTests++; + } + break; case PassedTestNodeStateProperty passed: _openTelemetryResultHandler?.NotifyPassed(message.TestNode, passed); + _totalRanTests++; break; case FailedTestNodeStateProperty: @@ -93,10 +99,23 @@ public Task ConsumeAsync(IDataProducer dataProducer, IData value, CancellationTo case CancelledTestNodeStateProperty: #pragma warning restore CS0618, MTP0001 // Type or member is obsolete _openTelemetryResultHandler?.NotifyFailed(message.TestNode, executionState); + _failedTestsCount++; + _totalRanTests++; break; case SkippedTestNodeStateProperty skipped: _openTelemetryResultHandler?.NotifySkipped(message.TestNode, skipped); + // DESIGN: Skipped tests are intentionally excluded from `_totalRanTests`. + // An all-skipped (or zero-test) run leaves `_totalRanTests == 0` and yields exit code + // `ExitCode.ZeroTests` (8) in `GetProcessExitCode`. This is the strict default chosen in + // #3216 / #3243 ("Skipped tests count as not run") to surface the common "invalid filter + // ran nothing" mistake. The documented opt-out for users who legitimately expect + // all-skipped runs is `--ignore-exit-code 8`. + // + // Two other layers mirror this decision and must stay in lockstep: + // - TerminalTestReporter.Summary.cs (`allTestsWereSkipped`) + // - Microsoft.Testing.Platform.MSBuild InvokeTestingPlatformTask (run-summary verdict) + // Do not relax this without revisiting those sites and the design discussion above. break; case InProgressTestNodeStateProperty: @@ -108,34 +127,6 @@ public Task ConsumeAsync(IDataProducer dataProducer, IData value, CancellationTo break; } - Type outcomeType = executionState.GetType(); - if (Array.IndexOf(TestNodePropertiesCategories.WellKnownTestNodeTestRunOutcomeFailedProperties, outcomeType) != -1) - { - _failedTestsCount++; - } - - if (_isDiscovery - && Array.IndexOf(TestNodePropertiesCategories.WellKnownTestNodeDiscoveredProperties, outcomeType) != -1) - { - _totalRanTests++; - } - - // DESIGN: Skipped tests are intentionally excluded from `_totalRanTests`. - // `WellKnownTestNodeTestRunOutcomeProperties` does not contain `SkippedTestNodeStateProperty`, so an - // all-skipped (or zero-test) run leaves `_totalRanTests == 0` and yields exit code `ExitCode.ZeroTests` (8) - // in `GetProcessExitCode`. This is the strict default chosen in #3216 / #3243 ("Skipped tests count as not - // run") to surface the common "invalid filter ran nothing" mistake. The documented opt-out for users who - // legitimately expect all-skipped runs is `--ignore-exit-code 8`. - // - // Two other layers mirror this decision and must stay in lockstep: - // - TerminalTestReporter.Summary.cs (`allTestsWereSkipped`) - // - Microsoft.Testing.Platform.MSBuild InvokeTestingPlatformTask (run-summary verdict) - // Do not relax this without revisiting those sites and the design discussion above. - else if (Array.IndexOf(TestNodePropertiesCategories.WellKnownTestNodeTestRunOutcomeProperties, outcomeType) != -1) - { - _totalRanTests++; - } - return Task.CompletedTask; }