Skip to content

Commit 60e41b0

Browse files
Don't keep MTP process alive if pipe disconnects by @Youssef1313 in #6477 (backport to rel/3.10) (#6478)
Co-authored-by: Youssef1313 <youssefvictor00@gmail.com>
1 parent 48481da commit 60e41b0

File tree

6 files changed

+24
-7
lines changed

6 files changed

+24
-7
lines changed

src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpActivityIndicator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public HangDumpActivityIndicator(
6565
string pipeNameEnvironmentVariable = $"{HangDumpConfiguration.PipeName}_{FNV_1aHashHelper.ComputeStringHash(testApplicationModuleInfo.GetCurrentTestApplicationFullPath())}_{namedPipeSuffix}";
6666
string namedPipeName = _environment.GetEnvironmentVariable(pipeNameEnvironmentVariable)
6767
?? throw new InvalidOperationException($"Expected {pipeNameEnvironmentVariable} environment variable set.");
68-
_namedPipeClient = new NamedPipeClient(namedPipeName);
68+
_namedPipeClient = new NamedPipeClient(namedPipeName, _environment);
6969
_namedPipeClient.RegisterSerializer(new ActivityIndicatorMutexNameRequestSerializer(), typeof(ActivityIndicatorMutexNameRequest));
7070
_namedPipeClient.RegisterSerializer(new VoidResponseSerializer(), typeof(VoidResponse));
7171
_namedPipeClient.RegisterSerializer(new SessionEndSerializerRequestSerializer(), typeof(SessionEndSerializerRequest));

src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ private async Task<IResponse> CallbackAsync(IRequest request)
159159
else if (request is ConsumerPipeNameRequest consumerPipeNameRequest)
160160
{
161161
await _logger.LogDebugAsync($"Consumer pipe name received '{consumerPipeNameRequest.PipeName}'").ConfigureAwait(false);
162-
_namedPipeClient = new NamedPipeClient(consumerPipeNameRequest.PipeName);
162+
_namedPipeClient = new NamedPipeClient(consumerPipeNameRequest.PipeName, _environment);
163163
_namedPipeClient.RegisterSerializer(new GetInProgressTestsResponseSerializer(), typeof(GetInProgressTestsResponse));
164164
_namedPipeClient.RegisterSerializer(new GetInProgressTestsRequestSerializer(), typeof(GetInProgressTestsRequest));
165165
_namedPipeClient.RegisterSerializer(new ExitSignalActivityIndicatorTaskRequestSerializer(), typeof(ExitSignalActivityIndicatorTaskRequest));

src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxTestApplicationLifecycleCallbacks.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public async Task BeforeRunAsync(CancellationToken cancellationToken)
6363
{
6464
string namedPipeName = _environment.GetEnvironmentVariable(TrxEnvironmentVariableProvider.TRXNAMEDPIPENAME)
6565
?? throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, ExtensionResources.TrxReportGeneratorMissingTrxNamedPipeEnvironmentVariable, TrxEnvironmentVariableProvider.TRXNAMEDPIPENAME));
66-
NamedPipeClient = new NamedPipeClient(namedPipeName);
66+
NamedPipeClient = new NamedPipeClient(namedPipeName, _environment);
6767
NamedPipeClient.RegisterSerializer(new ReportFileNameRequestSerializer(), typeof(ReportFileNameRequest));
6868
NamedPipeClient.RegisterSerializer(new TestAdapterInformationRequestSerializer(), typeof(TestAdapterInformationRequest));
6969
NamedPipeClient.RegisterSerializer(new VoidResponseSerializer(), typeof(VoidResponse));

src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ await LogTestHostCreatedAsync(
545545
environment.SetEnvironmentVariable(pipeEnvironmentVariable, string.Empty);
546546

547547
// Create client to connect to the monitor
548-
NamedPipeClient client = new(pipeName);
548+
NamedPipeClient client = new(pipeName, environment);
549549
client.RegisterAllSerializers();
550550

551551
// Connect to the monitor

src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33

44
#if NETCOREAPP
55
using System.Buffers;
6-
7-
using Microsoft.Testing.Platform.Helpers;
86
#endif
97

108
using System.IO.Pipes;
119

10+
using Microsoft.Testing.Platform.Helpers;
11+
1212
#if NET
1313
using Microsoft.Testing.Platform.Resources;
1414
#endif
@@ -24,14 +24,21 @@ internal sealed class NamedPipeClient : NamedPipeBase, IClient
2424
private readonly MemoryStream _serializationBuffer = new();
2525
private readonly MemoryStream _messageBuffer = new();
2626
private readonly byte[] _readBuffer = new byte[250000];
27+
private readonly IEnvironment _environment;
2728

2829
private bool _disposed;
2930

3031
public NamedPipeClient(string name)
32+
: this(name, new SystemEnvironment())
33+
{
34+
}
35+
36+
public NamedPipeClient(string name, IEnvironment environment)
3137
{
3238
Guard.NotNull(name);
3339
_namedPipeClientStream = new(".", name, PipeDirection.InOut);
3440
PipeName = name;
41+
_environment = environment;
3542
}
3643

3744
public string PipeName { get; }
@@ -144,6 +151,16 @@ public async Task<TResponse> RequestReplyAsync<TRequest, TResponse>(TRequest req
144151
int currentReadBytes = await _namedPipeClientStream.ReadAsync(_readBuffer, currentReadIndex, _readBuffer.Length, cancellationToken).ConfigureAwait(false);
145152
#endif
146153

154+
if (currentReadBytes == 0)
155+
{
156+
// We are reading a message response.
157+
// If we cannot get a response, there is no way we can recover and continue executing.
158+
// This can happen if the other processes gets killed or crashes while while it's sending the response.
159+
// This is especially important for 'dotnet test', where the user can simply kill the dotnet.exe process themselves.
160+
// In that case, we want the MTP process to also die.
161+
_environment.FailFast("[NamedPipeClient] Connection lost with the other side.");
162+
}
163+
147164
// Reset the current chunk size
148165
int missingBytesToReadOfCurrentChunk = currentReadBytes;
149166

src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public async Task AfterCommonServiceSetupAsync()
5656
_environment.SetEnvironmentVariable(EnvironmentVariableConstants.TESTINGPLATFORM_DOTNETTEST_EXECUTIONID, Guid.NewGuid().ToString("N"));
5757
}
5858

59-
_dotnetTestPipeClient = new(arguments[0]);
59+
_dotnetTestPipeClient = new(arguments[0], _environment);
6060
_dotnetTestPipeClient.RegisterAllSerializers();
6161

6262
await _dotnetTestPipeClient.ConnectAsync(_cancellationTokenSource.CancellationToken).ConfigureAwait(false);

0 commit comments

Comments
 (0)