@@ -23,6 +23,7 @@ internal sealed class TestApplication(TestModule module, BuildOptions buildOptio
23
23
24
24
private Task _testAppPipeConnectionLoop ;
25
25
private readonly List < NamedPipeServer > _testAppPipeConnections = [ ] ;
26
+ private readonly Dictionary < NamedPipeServer , HandshakeMessage > _handshakes = new ( ) ;
26
27
27
28
public event EventHandler < HandshakeArgs > HandshakeReceived ;
28
29
public event EventHandler < HelpEventArgs > HelpRequested ;
@@ -35,6 +36,8 @@ internal sealed class TestApplication(TestModule module, BuildOptions buildOptio
35
36
36
37
public TestModule Module { get ; } = module ;
37
38
39
+ public bool HasFailureDuringDispose { get ; private set ; }
40
+
38
41
public async Task < int > RunAsync ( TestOptions testOptions )
39
42
{
40
43
if ( testOptions . HasFilterMode && ! ModulePathExists ( ) )
@@ -146,7 +149,7 @@ private async Task WaitConnectionAsync(CancellationToken token)
146
149
{
147
150
while ( ! token . IsCancellationRequested )
148
151
{
149
- NamedPipeServer pipeConnection = new ( _pipeNameDescription , OnRequest , NamedPipeServerStream . MaxAllowedServerInstances , token , skipUnknownMessages : true ) ;
152
+ var pipeConnection = new NamedPipeServer ( _pipeNameDescription , OnRequest , NamedPipeServerStream . MaxAllowedServerInstances , token , skipUnknownMessages : true ) ;
150
153
pipeConnection . RegisterAllSerializers ( ) ;
151
154
152
155
await pipeConnection . WaitConnectionAsync ( token ) ;
@@ -173,20 +176,17 @@ private async Task WaitConnectionAsync(CancellationToken token)
173
176
}
174
177
}
175
178
176
- private Task < IResponse > OnRequest ( IRequest request )
179
+ private Task < IResponse > OnRequest ( NamedPipeServer server , IRequest request )
177
180
{
178
181
try
179
182
{
180
183
switch ( request )
181
184
{
182
185
case HandshakeMessage handshakeMessage :
183
- if ( handshakeMessage . Properties . TryGetValue ( HandshakeMessagePropertyNames . ModulePath , out string value ) )
184
- {
185
- OnHandshakeMessage ( handshakeMessage ) ;
186
-
187
- return Task . FromResult ( ( IResponse ) CreateHandshakeMessage ( GetSupportedProtocolVersion ( handshakeMessage ) ) ) ;
188
- }
189
- break ;
186
+ _handshakes . Add ( server , handshakeMessage ) ;
187
+ string negotiatedVersion = GetSupportedProtocolVersion ( handshakeMessage ) ;
188
+ OnHandshakeMessage ( handshakeMessage , negotiatedVersion . Length > 0 ) ;
189
+ return Task . FromResult ( ( IResponse ) CreateHandshakeMessage ( negotiatedVersion ) ) ;
190
190
191
191
case CommandLineOptionMessages commandLineOptionMessages :
192
192
OnCommandLineOptionMessages ( commandLineOptionMessages ) ;
@@ -236,15 +236,26 @@ private Task<IResponse> OnRequest(IRequest request)
236
236
237
237
private static string GetSupportedProtocolVersion ( HandshakeMessage handshakeMessage )
238
238
{
239
- handshakeMessage . Properties . TryGetValue ( HandshakeMessagePropertyNames . SupportedProtocolVersions , out string protocolVersions ) ;
239
+ if ( ! handshakeMessage . Properties . TryGetValue ( HandshakeMessagePropertyNames . SupportedProtocolVersions , out string protocolVersions ) ||
240
+ protocolVersions is null )
241
+ {
242
+ // It's not expected we hit this.
243
+ // TODO: Maybe we should fail more hard?
244
+ return string . Empty ;
245
+ }
240
246
241
- string version = string . Empty ;
242
- if ( protocolVersions is not null && protocolVersions . Split ( ";" ) . Contains ( ProtocolConstants . Version ) )
247
+ // NOTE: Today, ProtocolConstants.Version is only 1.0.0 (i.e, SDK supports only a single version).
248
+ // Whenever we support multiple versions in SDK, we should do intersection
249
+ // between protocolVersions given by MTP, and the versions supported by SDK.
250
+ // Then we return the "highest" version from the intersection.
251
+ // The current logic **assumes** that ProtocolConstants.SupportedVersions is a single version.
252
+ if ( protocolVersions . Split ( ";" ) . Contains ( ProtocolConstants . SupportedVersions ) )
243
253
{
244
- version = ProtocolConstants . Version ;
254
+ return ProtocolConstants . SupportedVersions ;
245
255
}
246
256
247
- return version ;
257
+ // The version given by MTP is not supported by SDK.
258
+ return string . Empty ;
248
259
}
249
260
250
261
private static HandshakeMessage CreateHandshakeMessage ( string version ) =>
@@ -305,9 +316,9 @@ private bool ModulePathExists()
305
316
return true ;
306
317
}
307
318
308
- public void OnHandshakeMessage ( HandshakeMessage handshakeMessage )
319
+ public void OnHandshakeMessage ( HandshakeMessage handshakeMessage , bool gotSupportedVersion )
309
320
{
310
- HandshakeReceived ? . Invoke ( this , new HandshakeArgs { Handshake = new Handshake ( handshakeMessage . Properties ) } ) ;
321
+ HandshakeReceived ? . Invoke ( this , new HandshakeArgs { Handshake = new Handshake ( handshakeMessage . Properties ) , GotSupportedVersion = gotSupportedVersion } ) ;
311
322
}
312
323
313
324
public void OnCommandLineOptionMessages ( CommandLineOptionMessages commandLineOptionMessages )
@@ -387,7 +398,35 @@ public void Dispose()
387
398
{
388
399
foreach ( var namedPipeServer in _testAppPipeConnections )
389
400
{
390
- namedPipeServer . Dispose ( ) ;
401
+ try
402
+ {
403
+ namedPipeServer . Dispose ( ) ;
404
+ }
405
+ catch ( Exception ex )
406
+ {
407
+ StringBuilder messageBuilder ;
408
+ if ( _handshakes . TryGetValue ( namedPipeServer , out var handshake ) )
409
+ {
410
+ messageBuilder = new StringBuilder ( CliCommandStrings . DotnetTestPipeFailureHasHandshake ) ;
411
+ messageBuilder . AppendLine ( ) ;
412
+ foreach ( var kvp in handshake . Properties )
413
+ {
414
+ messageBuilder . AppendLine ( $ "{ kvp . Key } : { kvp . Value } ") ;
415
+ }
416
+ }
417
+ else
418
+ {
419
+ messageBuilder = new StringBuilder ( CliCommandStrings . DotnetTestPipeFailureWithoutHandshake ) ;
420
+ messageBuilder . AppendLine ( ) ;
421
+ }
422
+
423
+ messageBuilder . AppendLine ( $ "RunCommand: { Module . RunProperties . Command } ") ;
424
+ messageBuilder . AppendLine ( $ "RunArguments: { Module . RunProperties . Arguments } ") ;
425
+ messageBuilder . AppendLine ( ex . ToString ( ) ) ;
426
+
427
+ HasFailureDuringDispose = true ;
428
+ Reporter . Error . WriteLine ( messageBuilder . ToString ( ) ) ;
429
+ }
391
430
}
392
431
393
432
WaitOnTestApplicationPipeConnectionLoop ( ) ;
0 commit comments