|
|
|
@ -180,21 +180,74 @@ namespace Grpc.Core.Internal.Tests |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
public void ClientStreaming_WriteCompletionFailure() |
|
|
|
|
public void ClientStreaming_WriteFailureThrowsRpcException() |
|
|
|
|
{ |
|
|
|
|
var resultTask = asyncCall.ClientStreamingCallAsync(); |
|
|
|
|
var requestStream = new ClientRequestStream<string, string>(asyncCall); |
|
|
|
|
|
|
|
|
|
var writeTask = requestStream.WriteAsync("request1"); |
|
|
|
|
fakeCall.SendCompletionHandler(false); |
|
|
|
|
// TODO: maybe IOException or waiting for RPCException is more appropriate here. |
|
|
|
|
Assert.ThrowsAsync(typeof(InvalidOperationException), async () => await writeTask); |
|
|
|
|
|
|
|
|
|
// The write will wait for call to finish to receive the status code. |
|
|
|
|
Assert.IsFalse(writeTask.IsCompleted); |
|
|
|
|
|
|
|
|
|
fakeCall.UnaryResponseClientHandler(true, |
|
|
|
|
CreateClientSideStatus(StatusCode.Internal), |
|
|
|
|
null, |
|
|
|
|
new Metadata()); |
|
|
|
|
|
|
|
|
|
var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask); |
|
|
|
|
Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode); |
|
|
|
|
|
|
|
|
|
AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Internal); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
public void ClientStreaming_WriteFailureThrowsRpcException2() |
|
|
|
|
{ |
|
|
|
|
var resultTask = asyncCall.ClientStreamingCallAsync(); |
|
|
|
|
var requestStream = new ClientRequestStream<string, string>(asyncCall); |
|
|
|
|
|
|
|
|
|
var writeTask = requestStream.WriteAsync("request1"); |
|
|
|
|
|
|
|
|
|
fakeCall.UnaryResponseClientHandler(true, |
|
|
|
|
CreateClientSideStatus(StatusCode.Internal), |
|
|
|
|
null, |
|
|
|
|
new Metadata()); |
|
|
|
|
|
|
|
|
|
fakeCall.SendCompletionHandler(false); |
|
|
|
|
|
|
|
|
|
var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask); |
|
|
|
|
Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode); |
|
|
|
|
|
|
|
|
|
AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Internal); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
public void ClientStreaming_WriteFailureThrowsRpcException3() |
|
|
|
|
{ |
|
|
|
|
var resultTask = asyncCall.ClientStreamingCallAsync(); |
|
|
|
|
var requestStream = new ClientRequestStream<string, string>(asyncCall); |
|
|
|
|
|
|
|
|
|
var writeTask = requestStream.WriteAsync("request1"); |
|
|
|
|
fakeCall.SendCompletionHandler(false); |
|
|
|
|
|
|
|
|
|
// Until the delayed write completion has been triggered, |
|
|
|
|
// we still act as if there was an active write. |
|
|
|
|
Assert.Throws(typeof(InvalidOperationException), () => requestStream.WriteAsync("request2")); |
|
|
|
|
|
|
|
|
|
fakeCall.UnaryResponseClientHandler(true, |
|
|
|
|
CreateClientSideStatus(StatusCode.Internal), |
|
|
|
|
null, |
|
|
|
|
new Metadata()); |
|
|
|
|
|
|
|
|
|
var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask); |
|
|
|
|
Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode); |
|
|
|
|
|
|
|
|
|
// Following attempts to write keep delivering the same status |
|
|
|
|
var ex2 = Assert.ThrowsAsync<RpcException>(async () => await requestStream.WriteAsync("after call has finished")); |
|
|
|
|
Assert.AreEqual(StatusCode.Internal, ex2.Status.StatusCode); |
|
|
|
|
|
|
|
|
|
AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Internal); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -415,6 +468,49 @@ namespace Grpc.Core.Internal.Tests |
|
|
|
|
Assert.DoesNotThrowAsync(async () => await requestStream.CompleteAsync()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
public void DuplexStreaming_WriteFailureThrowsRpcException() |
|
|
|
|
{ |
|
|
|
|
asyncCall.StartDuplexStreamingCall(); |
|
|
|
|
var requestStream = new ClientRequestStream<string, string>(asyncCall); |
|
|
|
|
var responseStream = new ClientResponseStream<string, string>(asyncCall); |
|
|
|
|
|
|
|
|
|
var writeTask = requestStream.WriteAsync("request1"); |
|
|
|
|
fakeCall.SendCompletionHandler(false); |
|
|
|
|
|
|
|
|
|
// The write will wait for call to finish to receive the status code. |
|
|
|
|
Assert.IsFalse(writeTask.IsCompleted); |
|
|
|
|
|
|
|
|
|
var readTask = responseStream.MoveNext(); |
|
|
|
|
fakeCall.ReceivedMessageHandler(true, null); |
|
|
|
|
fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.PermissionDenied)); |
|
|
|
|
|
|
|
|
|
var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask); |
|
|
|
|
Assert.AreEqual(StatusCode.PermissionDenied, ex.Status.StatusCode); |
|
|
|
|
|
|
|
|
|
AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.PermissionDenied); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
public void DuplexStreaming_WriteFailureThrowsRpcException2() |
|
|
|
|
{ |
|
|
|
|
asyncCall.StartDuplexStreamingCall(); |
|
|
|
|
var requestStream = new ClientRequestStream<string, string>(asyncCall); |
|
|
|
|
var responseStream = new ClientResponseStream<string, string>(asyncCall); |
|
|
|
|
|
|
|
|
|
var writeTask = requestStream.WriteAsync("request1"); |
|
|
|
|
|
|
|
|
|
var readTask = responseStream.MoveNext(); |
|
|
|
|
fakeCall.ReceivedMessageHandler(true, null); |
|
|
|
|
fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.PermissionDenied)); |
|
|
|
|
fakeCall.SendCompletionHandler(false); |
|
|
|
|
|
|
|
|
|
var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask); |
|
|
|
|
Assert.AreEqual(StatusCode.PermissionDenied, ex.Status.StatusCode); |
|
|
|
|
|
|
|
|
|
AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.PermissionDenied); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
public void DuplexStreaming_WriteAfterCancellationRequestThrowsTaskCanceledException() |
|
|
|
|
{ |
|
|
|
|