• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 
3 // Copyright 2015 gRPC authors.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 
17 #endregion
18 
19 using System;
20 using System.Collections.Generic;
21 using System.Diagnostics;
22 using System.IO;
23 using System.Linq;
24 using System.Threading;
25 using System.Threading.Tasks;
26 
27 using Grpc.Core;
28 using Grpc.Core.Internal;
29 using Grpc.Core.Utils;
30 using NUnit.Framework;
31 
32 namespace Grpc.Core.Tests
33 {
34     public class MarshallingErrorsTest
35     {
36         const string Host = "127.0.0.1";
37 
38         MockServiceHelper helper;
39         Server server;
40         Channel channel;
41 
42         [SetUp]
Init()43         public void Init()
44         {
45             var marshaller = new Marshaller<string>(
46                 (str) =>
47                 {
48                     if (str == "UNSERIALIZABLE_VALUE")
49                     {
50                         // Google.Protobuf throws exception inherited from IOException
51                         throw new IOException("Error serializing the message.");
52                     }
53                     return System.Text.Encoding.UTF8.GetBytes(str);
54                 },
55                 (payload) =>
56                 {
57                     var s = System.Text.Encoding.UTF8.GetString(payload);
58                     if (s == "UNPARSEABLE_VALUE")
59                     {
60                         // Google.Protobuf throws exception inherited from IOException
61                         throw new IOException("Error parsing the message.");
62                     }
63                     return s;
64                 });
65             helper = new MockServiceHelper(Host, marshaller);
66             server = helper.GetServer();
67             server.Start();
68             channel = helper.GetChannel();
69         }
70 
71         [TearDown]
Cleanup()72         public void Cleanup()
73         {
74             channel.ShutdownAsync().Wait();
75             server.ShutdownAsync().Wait();
76         }
77 
78         [Test]
ResponseParsingError_UnaryResponse()79         public void ResponseParsingError_UnaryResponse()
80         {
81             helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
82             {
83                 return Task.FromResult("UNPARSEABLE_VALUE");
84             });
85 
86             var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "REQUEST"));
87             Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode);
88         }
89 
90         [Test]
ResponseParsingError_StreamingResponse()91         public void ResponseParsingError_StreamingResponse()
92         {
93             helper.ServerStreamingHandler = new ServerStreamingServerMethod<string, string>(async (request, responseStream, context) =>
94             {
95                 await responseStream.WriteAsync("UNPARSEABLE_VALUE");
96                 await Task.Delay(10000);
97             });
98 
99             var call = Calls.AsyncServerStreamingCall(helper.CreateServerStreamingCall(), "REQUEST");
100             var ex = Assert.ThrowsAsync<RpcException>(async () => await call.ResponseStream.MoveNext());
101             Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode);
102         }
103 
104         [Test]
RequestParsingError_UnaryRequest()105         public void RequestParsingError_UnaryRequest()
106         {
107             helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
108             {
109                 return Task.FromResult("RESPONSE");
110             });
111 
112             var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "UNPARSEABLE_VALUE"));
113             // Spec doesn't define the behavior. With the current implementation server handler throws exception which results in StatusCode.Unknown.
114             Assert.AreEqual(StatusCode.Unknown, ex.Status.StatusCode);
115         }
116 
117         [Test]
RequestParsingError_StreamingRequest()118         public async Task RequestParsingError_StreamingRequest()
119         {
120             helper.ClientStreamingHandler = new ClientStreamingServerMethod<string, string>(async (requestStream, context) =>
121             {
122                 try
123                 {
124                     // cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock.
125                     await requestStream.MoveNext();
126                     Assert.Fail();
127                 }
128                 catch (IOException)
129                 {
130                 }
131                 return "RESPONSE";
132             });
133 
134             var call = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall());
135             await call.RequestStream.WriteAsync("UNPARSEABLE_VALUE");
136 
137             Assert.AreEqual("RESPONSE", await call);
138         }
139 
140         [Test]
RequestSerializationError_BlockingUnary()141         public void RequestSerializationError_BlockingUnary()
142         {
143             Assert.Throws<IOException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "UNSERIALIZABLE_VALUE"));
144         }
145 
146         [Test]
RequestSerializationError_AsyncUnary()147         public void RequestSerializationError_AsyncUnary()
148         {
149             Assert.ThrowsAsync<IOException>(async () => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "UNSERIALIZABLE_VALUE"));
150         }
151 
152         [Test]
RequestSerializationError_ClientStreaming()153         public async Task RequestSerializationError_ClientStreaming()
154         {
155             helper.ClientStreamingHandler = new ClientStreamingServerMethod<string, string>(async (requestStream, context) =>
156             {
157                 CollectionAssert.AreEqual(new[] { "A", "B" }, await requestStream.ToListAsync());
158                 return "RESPONSE";
159             });
160             var call = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall());
161             await call.RequestStream.WriteAsync("A");
162             Assert.ThrowsAsync<IOException>(async () => await call.RequestStream.WriteAsync("UNSERIALIZABLE_VALUE"));
163             await call.RequestStream.WriteAsync("B");
164             await call.RequestStream.CompleteAsync();
165 
166             Assert.AreEqual("RESPONSE", await call);
167         }
168     }
169 }
170