Skip to content

Commit 4f4324a

Browse files
EvangelinkCopilot
andcommitted
Verify retry attempt handshake end to end
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 57c63975-08ac-47bd-a888-5ec9962c472b
1 parent e4a5964 commit 4f4324a

3 files changed

Lines changed: 32 additions & 12 deletions

File tree

test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DotnetTestPipe/DotnetTestPipeOrchestratorHandshakeTests.cs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,29 @@ public async Task DotnetTestPipe_Orchestrator_HandshakesWithFeature()
3939
environmentVariables: new() { { EnvironmentVariableConstants.TESTINGPLATFORM_TELEMETRY_OPTOUT, "1" } },
4040
cancellationToken: TestContext.CancellationToken);
4141

42-
// The orchestrator process and the single (passing) test host it spawned should both have
43-
// connected and handshaked.
42+
// The orchestrator process and both test hosts it spawned should have connected and handshaked.
43+
// The first host reports a failure, causing the retry orchestrator to launch a second host that passes.
4444
Dictionary<byte, string> orchestratorHandshake = Assert.ContainsSingle(result.HandshakesWithHostType(TestHostOrchestratorHostType));
4545

4646
Assert.IsTrue(
4747
orchestratorHandshake.TryGetValue(DotnetTestPipeProtocol.HandshakeProperties.OrchestratorFeature, out string? feature),
4848
"Orchestrator handshake is missing the OrchestratorFeature property.");
4949
Assert.AreEqual(RetryOrchestratorFeature, feature);
50+
Assert.AreEqual("1", orchestratorHandshake[DotnetTestPipeProtocol.HandshakeProperties.AttemptNumber]);
5051

51-
// The actual test host (spawned by the orchestrator) handshakes as a plain TestHost and must
52-
// NOT carry an orchestrator feature.
53-
Dictionary<byte, string> testHostHandshake = Assert.ContainsSingle(result.HandshakesWithHostType(TestHostHostType));
54-
Assert.IsFalse(
55-
testHostHandshake.ContainsKey(DotnetTestPipeProtocol.HandshakeProperties.OrchestratorFeature),
56-
"Test host handshake should not carry the OrchestratorFeature property.");
52+
// The test hosts handshake as plain TestHosts and must not carry an orchestrator feature. Their explicit
53+
// attempt numbers let dotnet test attribute results without inferring attempts from InstanceId changes.
54+
Dictionary<byte, string>[] testHostHandshakes = [.. result.HandshakesWithHostType(TestHostHostType)];
55+
Assert.HasCount(2, testHostHandshakes);
56+
Assert.IsTrue(
57+
testHostHandshakes.All(handshake => !handshake.ContainsKey(DotnetTestPipeProtocol.HandshakeProperties.OrchestratorFeature)),
58+
"Test host handshakes should not carry the OrchestratorFeature property.");
59+
Assert.AreSequenceEqual(
60+
new[] { "1", "2" },
61+
testHostHandshakes
62+
.Select(handshake => handshake[DotnetTestPipeProtocol.HandshakeProperties.AttemptNumber])
63+
.Order()
64+
.ToArray());
5765
}
5866

5967
public sealed class TestAssetFixture() : TestAssetFixtureBase()
@@ -80,7 +88,9 @@ public sealed class TestAssetFixture() : TestAssetFixtureBase()
8088
using Microsoft.Testing.Extensions;
8189
using Microsoft.Testing.Platform.Builder;
8290
using Microsoft.Testing.Platform.Capabilities.TestFramework;
91+
using Microsoft.Testing.Platform.Extensions.Messages;
8392
using Microsoft.Testing.Platform.Extensions.TestFramework;
93+
using Microsoft.Testing.Platform.Messages;
8494
8595
public class Program
8696
{
@@ -94,21 +104,30 @@ public static async Task<int> Main(string[] args)
94104
}
95105
}
96106
97-
public class DummyTestFramework : ITestFramework
107+
public class DummyTestFramework : ITestFramework, IDataProducer
98108
{
99109
public string Uid => nameof(DummyTestFramework);
100110
public string Version => "2.0.0";
101111
public string DisplayName => nameof(DummyTestFramework);
102112
public string Description => nameof(DummyTestFramework);
113+
public Type[] DataTypesProduced => [typeof(TestNodeUpdateMessage)];
103114
public Task<bool> IsEnabledAsync() => Task.FromResult(true);
104115
public Task<CreateTestSessionResult> CreateTestSessionAsync(CreateTestSessionContext context)
105116
=> Task.FromResult(new CreateTestSessionResult() { IsSuccess = true });
106117
public Task<CloseTestSessionResult> CloseTestSessionAsync(CloseTestSessionContext context)
107118
=> Task.FromResult(new CloseTestSessionResult() { IsSuccess = true });
108-
public Task ExecuteRequestAsync(ExecuteRequestContext context)
119+
public async Task ExecuteRequestAsync(ExecuteRequestContext context)
109120
{
121+
string? attemptNumber = Environment.GetEnvironmentVariable("TESTINGPLATFORM_DOTNETTEST_ATTEMPTNUMBER");
122+
TestNodeStateProperty result = attemptNumber == "1"
123+
? new FailedTestNodeStateProperty("Fail the first attempt to exercise retry.")
124+
: PassedTestNodeStateProperty.CachedInstance;
125+
126+
await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(
127+
context.Request.Session.SessionUid,
128+
new TestNode() { Uid = "test-1", DisplayName = "RetryTest", Properties = new(result) }));
129+
110130
context.Complete();
111-
return Task.CompletedTask;
112131
}
113132
}
114133
""";

test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DotnetTestPipe/DotnetTestPipeProtocol.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public static class HandshakeProperties
6161
public const byte ExecutionMode = 10;
6262
public const byte OrchestratorFeature = 11;
6363
public const byte ServerControlPipeName = 12;
64+
public const byte AttemptNumber = 13;
6465
}
6566

6667
public static class ServerControlKinds

test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/DotnetTestConnectionTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using Microsoft.Testing.Platform.Helpers;

0 commit comments

Comments
 (0)