Skip to content

Commit 0d5a300

Browse files
authored
Add interceptor with GetStatus tests (#1502)
1 parent 868adfe commit 0d5a300

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

test/Grpc.Net.Client.Tests/InterceptorTests.cs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,115 @@ public async Task Intercept_WrapClientStream_ClientStreamWrapperExecuted()
143143
Assert.IsNotNull(call.GetTrailers());
144144
}
145145

146+
[TestCase(StatusCode.OK)]
147+
[TestCase(StatusCode.Internal)]
148+
public async Task Intercept_OnCompleted_StatusReturned(StatusCode statusCode)
149+
{
150+
await StatusReturnedCore(new OnCompletedInterceptor(), statusCode);
151+
}
152+
153+
[TestCase(StatusCode.OK)]
154+
[TestCase(StatusCode.Internal)]
155+
public async Task Intercept_Await_StatusReturned(StatusCode statusCode)
156+
{
157+
await StatusReturnedCore(new AwaitInterceptor(), statusCode);
158+
}
159+
160+
private static async Task StatusReturnedCore(StatusInterceptor interceptor, StatusCode statusCode)
161+
{
162+
// Arrange
163+
var httpClient = ClientTestHelpers.CreateTestClient(async request =>
164+
{
165+
if (statusCode == StatusCode.OK)
166+
{
167+
var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply { Message = "PASS" }).DefaultTimeout();
168+
return ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent);
169+
}
170+
else
171+
{
172+
return ResponseUtils.CreateHeadersOnlyResponse(HttpStatusCode.OK, statusCode);
173+
}
174+
});
175+
176+
var invoker = HttpClientCallInvokerFactory.Create(httpClient);
177+
178+
// Act
179+
var callInvoker = invoker.Intercept(interceptor);
180+
181+
var call = callInvoker.AsyncUnaryCall(ClientTestHelpers.ServiceMethod, Host, new CallOptions(), new HelloRequest());
182+
183+
// Assert
184+
if (statusCode == StatusCode.OK)
185+
{
186+
var result = await call.ResponseAsync.DefaultTimeout();
187+
Assert.AreEqual("PASS", result.Message);
188+
}
189+
else
190+
{
191+
var ex = await ExceptionAssert.ThrowsAsync<RpcException>(() => call.ResponseAsync).DefaultTimeout();
192+
Assert.AreEqual(statusCode, ex.StatusCode);
193+
}
194+
195+
var interceptorStatusCode = await interceptor.GetStatusCodeAsync().DefaultTimeout();
196+
Assert.AreEqual(statusCode, interceptorStatusCode);
197+
}
198+
199+
private abstract class StatusInterceptor : Interceptor
200+
{
201+
protected readonly TaskCompletionSource<StatusCode> StatusTcs = new TaskCompletionSource<StatusCode>(TaskCreationOptions.RunContinuationsAsynchronously);
202+
203+
public Task<StatusCode> GetStatusCodeAsync() => StatusTcs.Task;
204+
}
205+
206+
private class OnCompletedInterceptor : StatusInterceptor
207+
{
208+
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
209+
{
210+
var result = continuation(request, context);
211+
result.GetAwaiter().OnCompleted(() =>
212+
{
213+
try
214+
{
215+
StatusTcs.SetResult(result.GetStatus().StatusCode);
216+
}
217+
catch (Exception ex)
218+
{
219+
StatusTcs.SetException(ex);
220+
}
221+
});
222+
return result;
223+
}
224+
}
225+
226+
private class AwaitInterceptor : StatusInterceptor
227+
{
228+
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
229+
{
230+
var call = continuation(request, context);
231+
232+
return new AsyncUnaryCall<TResponse>(HandleResponse(call), call.ResponseHeadersAsync, call.GetStatus, call.GetTrailers, call.Dispose);
233+
234+
async Task<TResponse> HandleResponse(AsyncUnaryCall<TResponse> call)
235+
{
236+
try
237+
{
238+
return await call.ResponseAsync;
239+
}
240+
finally
241+
{
242+
try
243+
{
244+
StatusTcs.SetResult(call.GetStatus().StatusCode);
245+
}
246+
catch (Exception ex)
247+
{
248+
StatusTcs.SetException(ex);
249+
}
250+
}
251+
}
252+
}
253+
}
254+
146255
private class ClientStreamingCountingInterceptor : Interceptor
147256
{
148257
public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, AsyncClientStreamingCallContinuation<TRequest, TResponse> continuation)

0 commit comments

Comments
 (0)