@@ -1072,14 +1072,35 @@ public enum ResponseHandleAction
10721072 Nothing
10731073 }
10741074
1075- [ Test ]
1076- //[TestCase(0, false, ResponseHandleAction.ResponseAsync)]
1077- //[TestCase(0, true, ResponseHandleAction.ResponseAsync)]
1078- [ TestCase ( 0 , false , ResponseHandleAction . ResponseHeadersAsync ) ]
1079- //[TestCase(0, false, ResponseHandleAction.Dispose)]
1080- //[TestCase(1, false, ResponseHandleAction.Nothing)]
1081- public async Task AsyncUnaryCall_CallFailed_NoUnobservedExceptions ( int expectedUnobservedExceptions , bool addClientInterceptor , ResponseHandleAction action )
1075+ public static object [ ] NoUnobservedExceptionsCases
1076+ {
1077+ get
1078+ {
1079+ var cases = new List < object [ ] > ( ) ;
1080+ AddCases ( 0 , addClientInterceptor : false , throwCancellationError : false , ResponseHandleAction . ResponseAsync ) ;
1081+ AddCases ( 0 , addClientInterceptor : true , throwCancellationError : false , ResponseHandleAction . ResponseAsync ) ;
1082+ AddCases ( 0 , addClientInterceptor : false , throwCancellationError : false , ResponseHandleAction . ResponseHeadersAsync ) ;
1083+ AddCases ( 0 , addClientInterceptor : false , throwCancellationError : false , ResponseHandleAction . Dispose ) ;
1084+ AddCases ( 1 , addClientInterceptor : false , throwCancellationError : false , ResponseHandleAction . Nothing ) ;
1085+ AddCases ( 0 , addClientInterceptor : false , throwCancellationError : true , ResponseHandleAction . Nothing ) ;
1086+ return cases . ToArray ( ) ;
1087+
1088+ void AddCases ( int expectedUnobservedExceptions , bool addClientInterceptor , bool throwCancellationError , ResponseHandleAction action )
1089+ {
1090+ cases . Add ( new object [ ] { expectedUnobservedExceptions , true , addClientInterceptor , throwCancellationError , action } ) ;
1091+ cases . Add ( new object [ ] { expectedUnobservedExceptions , false , addClientInterceptor , throwCancellationError , action } ) ;
1092+ }
1093+ }
1094+ }
1095+
1096+ [ TestCaseSource ( nameof ( NoUnobservedExceptionsCases ) ) ]
1097+ public async Task AsyncUnaryCall_CallFailed_NoUnobservedExceptions ( int expectedUnobservedExceptions , bool isAsync , bool addClientInterceptor , bool throwCancellationError , ResponseHandleAction action )
10821098 {
1099+ // Provoke the garbage collector to find the unobserved exception.
1100+ GC . Collect ( ) ;
1101+ // Wait for any failed tasks to be garbage collected
1102+ GC . WaitForPendingFinalizers ( ) ;
1103+
10831104 // Arrange
10841105 var services = new ServiceCollection ( ) ;
10851106 services . AddNUnitLogger ( ) ;
@@ -1099,9 +1120,20 @@ public async Task AsyncUnaryCall_CallFailed_NoUnobservedExceptions(int expectedU
10991120
11001121 try
11011122 {
1102- var httpClient = ClientTestHelpers . CreateTestClient ( request =>
1123+ var httpClient = ClientTestHelpers . CreateTestClient ( async request =>
11031124 {
1104- throw new Exception ( "Test error" ) ;
1125+ if ( isAsync )
1126+ {
1127+ await Task . Delay ( 50 ) ;
1128+ }
1129+ if ( throwCancellationError )
1130+ {
1131+ throw new OperationCanceledException ( ) ;
1132+ }
1133+ else
1134+ {
1135+ throw new Exception ( "Test error" ) ;
1136+ }
11051137 } ) ;
11061138 var serviceConfig = ServiceConfigHelpers . CreateRetryServiceConfig ( ) ;
11071139 CallInvoker invoker = HttpClientCallInvokerFactory . Create ( httpClient , loggerFactory : loggerFactory , serviceConfig : serviceConfig ) ;
@@ -1112,32 +1144,28 @@ public async Task AsyncUnaryCall_CallFailed_NoUnobservedExceptions(int expectedU
11121144
11131145 // Act
11141146 logger . LogDebug ( "Starting call" ) ;
1115- var awaitedException = await MakeGrpcCallAsync ( logger , invoker , action ) ;
1147+ await MakeGrpcCallAsync ( logger , invoker , action ) ;
11161148
11171149 logger . LogDebug ( "Waiting for finalizers" ) ;
1118- // Provoke the garbage collector to find the unobserved exception.
1119- GC . Collect ( ) ;
1120- // Wait for any failed tasks to be garbage collected
1121- GC . WaitForPendingFinalizers ( ) ;
1150+ for ( var i = 0 ; i < 5 ; i ++ )
1151+ {
1152+ // Provoke the garbage collector to find the unobserved exception.
1153+ GC . Collect ( ) ;
1154+ // Wait for any failed tasks to be garbage collected
1155+ GC . WaitForPendingFinalizers ( ) ;
1156+
1157+ await Task . Delay ( 10 ) ;
1158+ }
11221159
11231160 foreach ( var exception in unobservedExceptions )
11241161 {
11251162 logger . LogCritical ( exception , "Unobserved task exception" ) ;
11261163 }
11271164
11281165 // Assert
1129- try
1130- {
1131- Assert . AreEqual ( expectedUnobservedExceptions , unobservedExceptions . Count ) ;
1132- logger . LogDebug ( "Expected number of observed exceptions" ) ;
1133- }
1134- catch
1135- {
1136- Assert . AreSame ( unobservedExceptions . Single ( ) . InnerException , awaitedException ) ;
1137- logger . LogDebug ( "Observed exception was awaited by the test" ) ;
1138- }
1166+ Assert . AreEqual ( expectedUnobservedExceptions , unobservedExceptions . Count ) ;
11391167
1140- static async Task < Exception ? > MakeGrpcCallAsync ( ILogger logger , CallInvoker invoker , ResponseHandleAction action )
1168+ static async Task MakeGrpcCallAsync ( ILogger logger , CallInvoker invoker , ResponseHandleAction action )
11411169 {
11421170 var runTask = Task . Run ( async ( ) =>
11431171 {
@@ -1146,21 +1174,23 @@ public async Task AsyncUnaryCall_CallFailed_NoUnobservedExceptions(int expectedU
11461174 switch ( action )
11471175 {
11481176 case ResponseHandleAction . ResponseAsync :
1149- return await ExceptionAssert . ThrowsAsync < RpcException > ( ( ) => call . ResponseAsync ) ;
1177+ await ExceptionAssert . ThrowsAsync < RpcException > ( ( ) => call . ResponseAsync ) ;
1178+ break ;
11501179 case ResponseHandleAction . ResponseHeadersAsync :
1151- return await ExceptionAssert . ThrowsAsync < RpcException > ( ( ) => call . ResponseHeadersAsync ) ;
1180+ await ExceptionAssert . ThrowsAsync < RpcException > ( ( ) => call . ResponseHeadersAsync ) ;
1181+ break ;
11521182 case ResponseHandleAction . Dispose :
11531183 await WaitForCallCompleteAsync ( logger , call ) ;
11541184 call . Dispose ( ) ;
1155- return null ;
1185+ break ;
11561186 default :
11571187 // Do nothing (but wait until call is finished)
11581188 await WaitForCallCompleteAsync ( logger , call ) ;
1159- return null ;
1189+ break ;
11601190 }
11611191 } ) ;
11621192
1163- return await runTask ;
1193+ await runTask ;
11641194 }
11651195 }
11661196 finally
0 commit comments