1 #region Copyright notice and license
3 // Copyright 2015 gRPC authors.
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
20 using System.Collections.Generic;
21 using System.Threading.Tasks;
23 using Grpc.Core.Internal;
24 using Grpc.Core.Utils;
25 using NUnit.Framework;
27 namespace Grpc.Core.Internal.Tests
30 /// Uses fake native call to test interaction of <c>AsyncCall</c> wrapping code with C core in different situations.
32 public class AsyncCallTest
35 FakeNativeCall fakeCall;
36 AsyncCall<string, string> asyncCall;
37 FakeBufferReaderManager fakeBufferReaderManager;
42 channel = new Channel("localhost", ChannelCredentials.Insecure);
44 fakeCall = new FakeNativeCall();
46 var callDetails = new CallInvocationDetails<string, string>(channel, "someMethod", null, Marshallers.StringMarshaller, Marshallers.StringMarshaller, new CallOptions());
47 asyncCall = new AsyncCall<string, string>(callDetails, fakeCall);
48 fakeBufferReaderManager = new FakeBufferReaderManager();
54 channel.ShutdownAsync().Wait();
55 fakeBufferReaderManager.Dispose();
59 public void AsyncUnary_CanBeStartedOnlyOnce()
61 asyncCall.UnaryCallAsync("request1");
62 Assert.Throws(typeof(InvalidOperationException),
63 () => asyncCall.UnaryCallAsync("abc"));
67 public void AsyncUnary_StreamingOperationsNotAllowed()
69 asyncCall.UnaryCallAsync("request1");
70 Assert.ThrowsAsync(typeof(InvalidOperationException),
71 async () => await asyncCall.ReadMessageAsync());
72 Assert.Throws(typeof(InvalidOperationException),
73 () => asyncCall.SendMessageAsync("abc", new WriteFlags()));
77 public void AsyncUnary_Success()
79 var resultTask = asyncCall.UnaryCallAsync("request1");
80 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
81 new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
82 CreateResponsePayload(),
85 AssertUnaryResponseSuccess(asyncCall, fakeCall, resultTask);
89 public void AsyncUnary_NonSuccessStatusCode()
91 var resultTask = asyncCall.UnaryCallAsync("request1");
92 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
93 CreateClientSideStatus(StatusCode.InvalidArgument),
97 AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument);
101 public void AsyncUnary_NullResponsePayload()
103 var resultTask = asyncCall.UnaryCallAsync("request1");
104 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
105 new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
109 // failure to deserialize will result in InvalidArgument status.
110 AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Internal);
114 public void AsyncUnary_RequestSerializationExceptionDoesntLeakResources()
116 string nullRequest = null; // will throw when serializing
117 Assert.Throws(typeof(ArgumentNullException), () => asyncCall.UnaryCallAsync(nullRequest));
118 Assert.AreEqual(0, channel.GetCallReferenceCount());
119 Assert.IsTrue(fakeCall.IsDisposed);
123 public void AsyncUnary_StartCallFailureDoesntLeakResources()
125 fakeCall.MakeStartCallFail();
126 Assert.Throws(typeof(InvalidOperationException), () => asyncCall.UnaryCallAsync("request1"));
127 Assert.AreEqual(0, channel.GetCallReferenceCount());
128 Assert.IsTrue(fakeCall.IsDisposed);
132 public void SyncUnary_RequestSerializationExceptionDoesntLeakResources()
134 string nullRequest = null; // will throw when serializing
135 Assert.Throws(typeof(ArgumentNullException), () => asyncCall.UnaryCall(nullRequest));
136 Assert.AreEqual(0, channel.GetCallReferenceCount());
137 Assert.IsTrue(fakeCall.IsDisposed);
141 public void SyncUnary_StartCallFailureDoesntLeakResources()
143 fakeCall.MakeStartCallFail();
144 Assert.Throws(typeof(InvalidOperationException), () => asyncCall.UnaryCall("request1"));
145 Assert.AreEqual(0, channel.GetCallReferenceCount());
146 Assert.IsTrue(fakeCall.IsDisposed);
150 public void ClientStreaming_StreamingReadNotAllowed()
152 asyncCall.ClientStreamingCallAsync();
153 Assert.ThrowsAsync(typeof(InvalidOperationException),
154 async () => await asyncCall.ReadMessageAsync());
158 public void ClientStreaming_NoRequest_Success()
160 var resultTask = asyncCall.ClientStreamingCallAsync();
161 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
162 new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
163 CreateResponsePayload(),
166 AssertUnaryResponseSuccess(asyncCall, fakeCall, resultTask);
170 public void ClientStreaming_NoRequest_NonSuccessStatusCode()
172 var resultTask = asyncCall.ClientStreamingCallAsync();
173 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
174 CreateClientSideStatus(StatusCode.InvalidArgument),
175 CreateNullResponse(),
178 AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument);
182 public void ClientStreaming_MoreRequests_Success()
184 var resultTask = asyncCall.ClientStreamingCallAsync();
185 var requestStream = new ClientRequestStream<string, string>(asyncCall);
187 var writeTask = requestStream.WriteAsync("request1");
188 fakeCall.SendCompletionCallback.OnSendCompletion(true);
191 var writeTask2 = requestStream.WriteAsync("request2");
192 fakeCall.SendCompletionCallback.OnSendCompletion(true);
195 var completeTask = requestStream.CompleteAsync();
196 fakeCall.SendCompletionCallback.OnSendCompletion(true);
199 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
200 new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
201 CreateResponsePayload(),
204 AssertUnaryResponseSuccess(asyncCall, fakeCall, resultTask);
208 public void ClientStreaming_WriteFailureThrowsRpcException()
210 var resultTask = asyncCall.ClientStreamingCallAsync();
211 var requestStream = new ClientRequestStream<string, string>(asyncCall);
213 var writeTask = requestStream.WriteAsync("request1");
214 fakeCall.SendCompletionCallback.OnSendCompletion(false);
216 // The write will wait for call to finish to receive the status code.
217 Assert.IsFalse(writeTask.IsCompleted);
219 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
220 CreateClientSideStatus(StatusCode.Internal),
221 CreateNullResponse(),
224 var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
225 Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode);
227 AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Internal);
231 public void ClientStreaming_WriteFailureThrowsRpcException2()
233 var resultTask = asyncCall.ClientStreamingCallAsync();
234 var requestStream = new ClientRequestStream<string, string>(asyncCall);
236 var writeTask = requestStream.WriteAsync("request1");
238 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
239 CreateClientSideStatus(StatusCode.Internal),
240 CreateNullResponse(),
243 fakeCall.SendCompletionCallback.OnSendCompletion(false);
245 var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
246 Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode);
248 AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Internal);
252 public void ClientStreaming_WriteFailureThrowsRpcException3()
254 var resultTask = asyncCall.ClientStreamingCallAsync();
255 var requestStream = new ClientRequestStream<string, string>(asyncCall);
257 var writeTask = requestStream.WriteAsync("request1");
258 fakeCall.SendCompletionCallback.OnSendCompletion(false);
260 // Until the delayed write completion has been triggered,
261 // we still act as if there was an active write.
262 Assert.Throws(typeof(InvalidOperationException), () => requestStream.WriteAsync("request2"));
264 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
265 CreateClientSideStatus(StatusCode.Internal),
266 CreateNullResponse(),
269 var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
270 Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode);
272 // Following attempts to write keep delivering the same status
273 var ex2 = Assert.ThrowsAsync<RpcException>(async () => await requestStream.WriteAsync("after call has finished"));
274 Assert.AreEqual(StatusCode.Internal, ex2.Status.StatusCode);
276 AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Internal);
280 public void ClientStreaming_WriteAfterReceivingStatusThrowsRpcException()
282 var resultTask = asyncCall.ClientStreamingCallAsync();
283 var requestStream = new ClientRequestStream<string, string>(asyncCall);
285 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
286 new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
287 CreateResponsePayload(),
290 AssertUnaryResponseSuccess(asyncCall, fakeCall, resultTask);
292 var writeTask = requestStream.WriteAsync("request1");
293 var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
294 Assert.AreEqual(Status.DefaultSuccess, ex.Status);
298 public void ClientStreaming_WriteAfterReceivingStatusThrowsRpcException2()
300 var resultTask = asyncCall.ClientStreamingCallAsync();
301 var requestStream = new ClientRequestStream<string, string>(asyncCall);
303 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
304 new ClientSideStatus(new Status(StatusCode.OutOfRange, ""), new Metadata()),
305 CreateResponsePayload(),
308 AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.OutOfRange);
310 var writeTask = requestStream.WriteAsync("request1");
311 var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
312 Assert.AreEqual(StatusCode.OutOfRange, ex.Status.StatusCode);
316 public void ClientStreaming_WriteAfterCompleteThrowsInvalidOperationException()
318 var resultTask = asyncCall.ClientStreamingCallAsync();
319 var requestStream = new ClientRequestStream<string, string>(asyncCall);
321 requestStream.CompleteAsync();
323 Assert.Throws(typeof(InvalidOperationException), () => requestStream.WriteAsync("request1"));
325 fakeCall.SendCompletionCallback.OnSendCompletion(true);
327 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
328 new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
329 CreateResponsePayload(),
332 AssertUnaryResponseSuccess(asyncCall, fakeCall, resultTask);
336 public void ClientStreaming_CompleteAfterReceivingStatusSucceeds()
338 var resultTask = asyncCall.ClientStreamingCallAsync();
339 var requestStream = new ClientRequestStream<string, string>(asyncCall);
341 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
342 new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
343 CreateResponsePayload(),
346 AssertUnaryResponseSuccess(asyncCall, fakeCall, resultTask);
347 Assert.DoesNotThrowAsync(async () => await requestStream.CompleteAsync());
351 public void ClientStreaming_WriteAfterCancellationRequestThrowsTaskCanceledException()
353 var resultTask = asyncCall.ClientStreamingCallAsync();
354 var requestStream = new ClientRequestStream<string, string>(asyncCall);
357 Assert.IsTrue(fakeCall.IsCancelled);
359 var writeTask = requestStream.WriteAsync("request1");
360 Assert.ThrowsAsync(typeof(TaskCanceledException), async () => await writeTask);
362 fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
363 CreateClientSideStatus(StatusCode.Cancelled),
364 CreateNullResponse(),
367 AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Cancelled);
371 public void ClientStreaming_StartCallFailureDoesntLeakResources()
373 fakeCall.MakeStartCallFail();
374 Assert.Throws(typeof(InvalidOperationException), () => asyncCall.ClientStreamingCallAsync());
375 Assert.AreEqual(0, channel.GetCallReferenceCount());
376 Assert.IsTrue(fakeCall.IsDisposed);
380 public void ServerStreaming_StreamingSendNotAllowed()
382 asyncCall.StartServerStreamingCall("request1");
383 Assert.Throws(typeof(InvalidOperationException),
384 () => asyncCall.SendMessageAsync("abc", new WriteFlags()));
388 public void ServerStreaming_NoResponse_Success1()
390 asyncCall.StartServerStreamingCall("request1");
391 var responseStream = new ClientResponseStream<string, string>(asyncCall);
392 var readTask = responseStream.MoveNext();
394 fakeCall.ReceivedResponseHeadersCallback.OnReceivedResponseHeaders(true, new Metadata());
395 Assert.AreEqual(0, asyncCall.ResponseHeadersAsync.Result.Count);
397 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse());
398 fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
400 AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask);
404 public void ServerStreaming_NoResponse_Success2()
406 asyncCall.StartServerStreamingCall("request1");
407 var responseStream = new ClientResponseStream<string, string>(asyncCall);
408 var readTask = responseStream.MoveNext();
410 // try alternative order of completions
411 fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
412 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse());
414 AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask);
418 public void ServerStreaming_NoResponse_ReadFailure()
420 asyncCall.StartServerStreamingCall("request1");
421 var responseStream = new ClientResponseStream<string, string>(asyncCall);
422 var readTask = responseStream.MoveNext();
424 fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, CreateNullResponse()); // after a failed read, we rely on C core to deliver appropriate status code.
425 fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Internal));
427 AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.Internal);
431 public void ServerStreaming_MoreResponses_Success()
433 asyncCall.StartServerStreamingCall("request1");
434 var responseStream = new ClientResponseStream<string, string>(asyncCall);
436 var readTask1 = responseStream.MoveNext();
437 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateResponsePayload());
438 Assert.IsTrue(readTask1.Result);
439 Assert.AreEqual("response1", responseStream.Current);
441 var readTask2 = responseStream.MoveNext();
442 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateResponsePayload());
443 Assert.IsTrue(readTask2.Result);
444 Assert.AreEqual("response1", responseStream.Current);
446 var readTask3 = responseStream.MoveNext();
447 fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
448 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse());
450 AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask3);
454 public void ServerStreaming_RequestSerializationExceptionDoesntLeakResources()
456 string nullRequest = null; // will throw when serializing
457 Assert.Throws(typeof(ArgumentNullException), () => asyncCall.StartServerStreamingCall(nullRequest));
458 Assert.AreEqual(0, channel.GetCallReferenceCount());
459 Assert.IsTrue(fakeCall.IsDisposed);
461 var responseStream = new ClientResponseStream<string, string>(asyncCall);
462 var readTask = responseStream.MoveNext();
466 public void ServerStreaming_StartCallFailureDoesntLeakResources()
468 fakeCall.MakeStartCallFail();
469 Assert.Throws(typeof(InvalidOperationException), () => asyncCall.StartServerStreamingCall("request1"));
470 Assert.AreEqual(0, channel.GetCallReferenceCount());
471 Assert.IsTrue(fakeCall.IsDisposed);
475 public void DuplexStreaming_NoRequestNoResponse_Success()
477 asyncCall.StartDuplexStreamingCall();
478 var requestStream = new ClientRequestStream<string, string>(asyncCall);
479 var responseStream = new ClientResponseStream<string, string>(asyncCall);
481 var writeTask1 = requestStream.CompleteAsync();
482 fakeCall.SendCompletionCallback.OnSendCompletion(true);
483 Assert.DoesNotThrowAsync(async () => await writeTask1);
485 var readTask = responseStream.MoveNext();
486 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse());
487 fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
489 AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask);
493 public void DuplexStreaming_WriteAfterReceivingStatusThrowsRpcException()
495 asyncCall.StartDuplexStreamingCall();
496 var requestStream = new ClientRequestStream<string, string>(asyncCall);
497 var responseStream = new ClientResponseStream<string, string>(asyncCall);
499 var readTask = responseStream.MoveNext();
500 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse());
501 fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
503 AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask);
505 var writeTask = requestStream.WriteAsync("request1");
506 var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
507 Assert.AreEqual(Status.DefaultSuccess, ex.Status);
511 public void DuplexStreaming_CompleteAfterReceivingStatusSuceeds()
513 asyncCall.StartDuplexStreamingCall();
514 var requestStream = new ClientRequestStream<string, string>(asyncCall);
515 var responseStream = new ClientResponseStream<string, string>(asyncCall);
517 var readTask = responseStream.MoveNext();
518 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse());
519 fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
521 AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask);
523 Assert.DoesNotThrowAsync(async () => await requestStream.CompleteAsync());
527 public void DuplexStreaming_WriteFailureThrowsRpcException()
529 asyncCall.StartDuplexStreamingCall();
530 var requestStream = new ClientRequestStream<string, string>(asyncCall);
531 var responseStream = new ClientResponseStream<string, string>(asyncCall);
533 var writeTask = requestStream.WriteAsync("request1");
534 fakeCall.SendCompletionCallback.OnSendCompletion(false);
536 // The write will wait for call to finish to receive the status code.
537 Assert.IsFalse(writeTask.IsCompleted);
539 var readTask = responseStream.MoveNext();
540 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse());
541 fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.PermissionDenied));
543 var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
544 Assert.AreEqual(StatusCode.PermissionDenied, ex.Status.StatusCode);
546 AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.PermissionDenied);
550 public void DuplexStreaming_WriteFailureThrowsRpcException2()
552 asyncCall.StartDuplexStreamingCall();
553 var requestStream = new ClientRequestStream<string, string>(asyncCall);
554 var responseStream = new ClientResponseStream<string, string>(asyncCall);
556 var writeTask = requestStream.WriteAsync("request1");
558 var readTask = responseStream.MoveNext();
559 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse());
560 fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.PermissionDenied));
561 fakeCall.SendCompletionCallback.OnSendCompletion(false);
563 var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
564 Assert.AreEqual(StatusCode.PermissionDenied, ex.Status.StatusCode);
566 AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.PermissionDenied);
570 public void DuplexStreaming_WriteAfterCancellationRequestThrowsTaskCanceledException()
572 asyncCall.StartDuplexStreamingCall();
573 var requestStream = new ClientRequestStream<string, string>(asyncCall);
574 var responseStream = new ClientResponseStream<string, string>(asyncCall);
577 Assert.IsTrue(fakeCall.IsCancelled);
579 var writeTask = requestStream.WriteAsync("request1");
580 Assert.ThrowsAsync(typeof(TaskCanceledException), async () => await writeTask);
582 var readTask = responseStream.MoveNext();
583 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse());
584 fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled));
586 AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.Cancelled);
590 public void DuplexStreaming_ReadAfterCancellationRequestCanSucceed()
592 asyncCall.StartDuplexStreamingCall();
593 var responseStream = new ClientResponseStream<string, string>(asyncCall);
596 Assert.IsTrue(fakeCall.IsCancelled);
598 var readTask1 = responseStream.MoveNext();
599 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateResponsePayload());
600 Assert.IsTrue(readTask1.Result);
601 Assert.AreEqual("response1", responseStream.Current);
603 var readTask2 = responseStream.MoveNext();
604 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse());
605 fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled));
607 AssertStreamingResponseError(asyncCall, fakeCall, readTask2, StatusCode.Cancelled);
611 public void DuplexStreaming_ReadStartedBeforeCancellationRequestCanSucceed()
613 asyncCall.StartDuplexStreamingCall();
614 var responseStream = new ClientResponseStream<string, string>(asyncCall);
616 var readTask1 = responseStream.MoveNext(); // initiate the read before cancel request
618 Assert.IsTrue(fakeCall.IsCancelled);
620 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateResponsePayload());
621 Assert.IsTrue(readTask1.Result);
622 Assert.AreEqual("response1", responseStream.Current);
624 var readTask2 = responseStream.MoveNext();
625 fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse());
626 fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled));
628 AssertStreamingResponseError(asyncCall, fakeCall, readTask2, StatusCode.Cancelled);
632 public void DuplexStreaming_StartCallFailureDoesntLeakResources()
634 fakeCall.MakeStartCallFail();
635 Assert.Throws(typeof(InvalidOperationException), () => asyncCall.StartDuplexStreamingCall());
636 Assert.AreEqual(0, channel.GetCallReferenceCount());
637 Assert.IsTrue(fakeCall.IsDisposed);
640 ClientSideStatus CreateClientSideStatus(StatusCode statusCode)
642 return new ClientSideStatus(new Status(statusCode, ""), new Metadata());
645 IBufferReader CreateResponsePayload()
647 return fakeBufferReaderManager.CreateSingleSegmentBufferReader(Marshallers.StringMarshaller.Serializer("response1"));
650 IBufferReader CreateNullResponse()
652 return fakeBufferReaderManager.CreateNullPayloadBufferReader();
655 static void AssertUnaryResponseSuccess(AsyncCall<string, string> asyncCall, FakeNativeCall fakeCall, Task<string> resultTask)
657 Assert.IsTrue(resultTask.IsCompleted);
658 Assert.IsTrue(fakeCall.IsDisposed);
660 Assert.AreEqual(Status.DefaultSuccess, asyncCall.GetStatus());
661 Assert.AreEqual(0, asyncCall.ResponseHeadersAsync.Result.Count);
662 Assert.AreEqual(0, asyncCall.GetTrailers().Count);
663 Assert.AreEqual("response1", resultTask.Result);
666 static void AssertStreamingResponseSuccess(AsyncCall<string, string> asyncCall, FakeNativeCall fakeCall, Task<bool> moveNextTask)
668 Assert.IsTrue(moveNextTask.IsCompleted);
669 Assert.IsTrue(fakeCall.IsDisposed);
671 Assert.IsFalse(moveNextTask.Result);
672 Assert.AreEqual(Status.DefaultSuccess, asyncCall.GetStatus());
673 Assert.AreEqual(0, asyncCall.GetTrailers().Count);
676 static void AssertUnaryResponseError(AsyncCall<string, string> asyncCall, FakeNativeCall fakeCall, Task<string> resultTask, StatusCode expectedStatusCode)
678 Assert.IsTrue(resultTask.IsCompleted);
679 Assert.IsTrue(fakeCall.IsDisposed);
681 Assert.AreEqual(expectedStatusCode, asyncCall.GetStatus().StatusCode);
682 var ex = Assert.ThrowsAsync<RpcException>(async () => await resultTask);
683 Assert.AreEqual(expectedStatusCode, ex.Status.StatusCode);
684 Assert.AreEqual(0, asyncCall.ResponseHeadersAsync.Result.Count);
685 Assert.AreEqual(0, asyncCall.GetTrailers().Count);
688 static void AssertStreamingResponseError(AsyncCall<string, string> asyncCall, FakeNativeCall fakeCall, Task<bool> moveNextTask, StatusCode expectedStatusCode)
690 Assert.IsTrue(moveNextTask.IsCompleted);
691 Assert.IsTrue(fakeCall.IsDisposed);
693 var ex = Assert.ThrowsAsync<RpcException>(async () => await moveNextTask);
694 Assert.AreEqual(expectedStatusCode, ex.Status.StatusCode);
695 Assert.AreEqual(expectedStatusCode, asyncCall.GetStatus().StatusCode);
696 Assert.AreEqual(0, asyncCall.GetTrailers().Count);