Jan Tattermusch | a7fff86 | 2015-02-13 11:08:08 -0800 | [diff] [blame] | 1 | #region Copyright notice and license |
| 2 | |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 3 | // Copyright 2015 gRPC authors. |
Craig Tiller | 190d360 | 2015-02-18 09:23:38 -0800 | [diff] [blame] | 4 | // |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 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 |
Craig Tiller | 190d360 | 2015-02-18 09:23:38 -0800 | [diff] [blame] | 8 | // |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 9 | // http://www.apache.org/licenses/LICENSE-2.0 |
Craig Tiller | 190d360 | 2015-02-18 09:23:38 -0800 | [diff] [blame] | 10 | // |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 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. |
Jan Tattermusch | a7fff86 | 2015-02-13 11:08:08 -0800 | [diff] [blame] | 16 | |
| 17 | #endregion |
| 18 | |
Jan Tattermusch | a7608b0 | 2015-02-03 17:54:38 -0800 | [diff] [blame] | 19 | using System; |
Jan Tattermusch | a1e6097 | 2015-12-10 19:54:10 -0800 | [diff] [blame] | 20 | using System.Collections.Generic; |
Jan Tattermusch | 337a2dd | 2015-02-13 15:41:41 -0800 | [diff] [blame] | 21 | using System.Diagnostics; |
Jan Tattermusch | 766d72b | 2015-07-21 20:09:25 -0700 | [diff] [blame] | 22 | using System.Linq; |
Jan Tattermusch | 3086862 | 2015-02-19 09:22:33 -0800 | [diff] [blame] | 23 | using System.Threading; |
Jan Tattermusch | a7608b0 | 2015-02-03 17:54:38 -0800 | [diff] [blame] | 24 | using System.Threading.Tasks; |
Jan Tattermusch | 3086862 | 2015-02-19 09:22:33 -0800 | [diff] [blame] | 25 | using Grpc.Core; |
| 26 | using Grpc.Core.Internal; |
Jan Tattermusch | 452ca9b | 2015-10-29 10:38:03 -0700 | [diff] [blame] | 27 | using Grpc.Core.Profiling; |
Jan Tattermusch | 3086862 | 2015-02-19 09:22:33 -0800 | [diff] [blame] | 28 | using Grpc.Core.Utils; |
| 29 | using NUnit.Framework; |
Jan Tattermusch | a7608b0 | 2015-02-03 17:54:38 -0800 | [diff] [blame] | 30 | |
Jan Tattermusch | 3086862 | 2015-02-19 09:22:33 -0800 | [diff] [blame] | 31 | namespace Grpc.Core.Tests |
Jan Tattermusch | a7608b0 | 2015-02-03 17:54:38 -0800 | [diff] [blame] | 32 | { |
| 33 | public class ClientServerTest |
| 34 | { |
Jan Tattermusch | 062c329 | 2015-07-23 20:28:42 -0700 | [diff] [blame] | 35 | const string Host = "127.0.0.1"; |
Jan Tattermusch | a7608b0 | 2015-02-03 17:54:38 -0800 | [diff] [blame] | 36 | |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 37 | MockServiceHelper helper; |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 38 | Server server; |
| 39 | Channel channel; |
Jan Tattermusch | a5272b6 | 2015-04-30 11:56:46 -0700 | [diff] [blame] | 40 | |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 41 | [SetUp] |
| 42 | public void Init() |
| 43 | { |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 44 | helper = new MockServiceHelper(Host); |
| 45 | server = helper.GetServer(); |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 46 | server.Start(); |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 47 | channel = helper.GetChannel(); |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 48 | } |
| 49 | |
| 50 | [TearDown] |
Jan Tattermusch | 607307d | 2015-02-18 11:05:45 -0800 | [diff] [blame] | 51 | public void Cleanup() |
| 52 | { |
Jan Tattermusch | 2b35795 | 2015-08-20 14:54:33 -0700 | [diff] [blame] | 53 | channel.ShutdownAsync().Wait(); |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 54 | server.ShutdownAsync().Wait(); |
| 55 | } |
| 56 | |
Jan Tattermusch | a7608b0 | 2015-02-03 17:54:38 -0800 | [diff] [blame] | 57 | [Test] |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 58 | public async Task UnaryCall() |
Jan Tattermusch | a7608b0 | 2015-02-03 17:54:38 -0800 | [diff] [blame] | 59 | { |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 60 | helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 61 | { |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 62 | return Task.FromResult(request); |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 63 | }); |
| 64 | |
| 65 | Assert.AreEqual("ABC", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "ABC")); |
| 66 | |
| 67 | Assert.AreEqual("ABC", await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "ABC")); |
Jan Tattermusch | a5272b6 | 2015-04-30 11:56:46 -0700 | [diff] [blame] | 68 | } |
| 69 | |
| 70 | [Test] |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 71 | public void UnaryCall_ServerHandlerThrows() |
Jan Tattermusch | a5272b6 | 2015-04-30 11:56:46 -0700 | [diff] [blame] | 72 | { |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 73 | helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => |
Jan Tattermusch | a5272b6 | 2015-04-30 11:56:46 -0700 | [diff] [blame] | 74 | { |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 75 | throw new Exception("This was thrown on purpose by a test"); |
| 76 | }); |
| 77 | |
| 78 | var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); |
| 79 | Assert.AreEqual(StatusCode.Unknown, ex.Status.StatusCode); |
| 80 | |
Jan Tattermusch | e331da2 | 2016-04-08 11:05:39 -0700 | [diff] [blame] | 81 | var ex2 = Assert.ThrowsAsync<RpcException>(async () => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 82 | Assert.AreEqual(StatusCode.Unknown, ex2.Status.StatusCode); |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 83 | } |
Craig Tiller | 190d360 | 2015-02-18 09:23:38 -0800 | [diff] [blame] | 84 | |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 85 | [Test] |
Jan Tattermusch | 1cf8d42 | 2015-07-21 10:37:55 -0700 | [diff] [blame] | 86 | public void UnaryCall_ServerHandlerThrowsRpcException() |
| 87 | { |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 88 | helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => |
Jan Tattermusch | 1cf8d42 | 2015-07-21 10:37:55 -0700 | [diff] [blame] | 89 | { |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 90 | throw new RpcException(new Status(StatusCode.Unauthenticated, "")); |
| 91 | }); |
| 92 | |
| 93 | var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); |
| 94 | Assert.AreEqual(StatusCode.Unauthenticated, ex.Status.StatusCode); |
Jan Tattermusch | a87f6d8 | 2017-08-08 16:35:51 +0200 | [diff] [blame] | 95 | Assert.AreEqual(0, ex.Trailers.Count); |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 96 | |
Jan Tattermusch | e331da2 | 2016-04-08 11:05:39 -0700 | [diff] [blame] | 97 | var ex2 = Assert.ThrowsAsync<RpcException>(async () => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 98 | Assert.AreEqual(StatusCode.Unauthenticated, ex2.Status.StatusCode); |
Jan Tattermusch | a87f6d8 | 2017-08-08 16:35:51 +0200 | [diff] [blame] | 99 | Assert.AreEqual(0, ex.Trailers.Count); |
| 100 | } |
| 101 | |
| 102 | [Test] |
| 103 | public void UnaryCall_ServerHandlerThrowsRpcExceptionWithTrailers() |
| 104 | { |
| 105 | helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => |
| 106 | { |
| 107 | var trailers = new Metadata { {"xyz", "xyz-value"} }; |
| 108 | throw new RpcException(new Status(StatusCode.Unauthenticated, ""), trailers); |
| 109 | }); |
| 110 | |
| 111 | var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); |
| 112 | Assert.AreEqual(StatusCode.Unauthenticated, ex.Status.StatusCode); |
| 113 | Assert.AreEqual(1, ex.Trailers.Count); |
| 114 | Assert.AreEqual("xyz", ex.Trailers[0].Key); |
| 115 | Assert.AreEqual("xyz-value", ex.Trailers[0].Value); |
| 116 | |
| 117 | var ex2 = Assert.ThrowsAsync<RpcException>(async () => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); |
| 118 | Assert.AreEqual(StatusCode.Unauthenticated, ex2.Status.StatusCode); |
| 119 | Assert.AreEqual(1, ex2.Trailers.Count); |
| 120 | Assert.AreEqual("xyz", ex2.Trailers[0].Key); |
| 121 | Assert.AreEqual("xyz-value", ex2.Trailers[0].Value); |
Jan Tattermusch | 1cf8d42 | 2015-07-21 10:37:55 -0700 | [diff] [blame] | 122 | } |
| 123 | |
| 124 | [Test] |
| 125 | public void UnaryCall_ServerHandlerSetsStatus() |
| 126 | { |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 127 | helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => |
Jan Tattermusch | 1cf8d42 | 2015-07-21 10:37:55 -0700 | [diff] [blame] | 128 | { |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 129 | context.Status = new Status(StatusCode.Unauthenticated, ""); |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 130 | return Task.FromResult(""); |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 131 | }); |
Jan Tattermusch | 1cf8d42 | 2015-07-21 10:37:55 -0700 | [diff] [blame] | 132 | |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 133 | var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); |
| 134 | Assert.AreEqual(StatusCode.Unauthenticated, ex.Status.StatusCode); |
Jan Tattermusch | a87f6d8 | 2017-08-08 16:35:51 +0200 | [diff] [blame] | 135 | Assert.AreEqual(0, ex.Trailers.Count); |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 136 | |
Jan Tattermusch | e331da2 | 2016-04-08 11:05:39 -0700 | [diff] [blame] | 137 | var ex2 = Assert.ThrowsAsync<RpcException>(async () => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 138 | Assert.AreEqual(StatusCode.Unauthenticated, ex2.Status.StatusCode); |
Jan Tattermusch | a87f6d8 | 2017-08-08 16:35:51 +0200 | [diff] [blame] | 139 | Assert.AreEqual(0, ex2.Trailers.Count); |
| 140 | } |
| 141 | |
| 142 | [Test] |
| 143 | public void UnaryCall_ServerHandlerSetsStatusAndTrailers() |
| 144 | { |
Jan Tattermusch | 2312634 | 2017-08-11 18:21:05 +0200 | [diff] [blame] | 145 | helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => |
Jan Tattermusch | a87f6d8 | 2017-08-08 16:35:51 +0200 | [diff] [blame] | 146 | { |
| 147 | context.Status = new Status(StatusCode.Unauthenticated, ""); |
| 148 | context.ResponseTrailers.Add("xyz", "xyz-value"); |
Jan Tattermusch | 2312634 | 2017-08-11 18:21:05 +0200 | [diff] [blame] | 149 | return Task.FromResult(""); |
Jan Tattermusch | a87f6d8 | 2017-08-08 16:35:51 +0200 | [diff] [blame] | 150 | }); |
| 151 | |
| 152 | var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); |
| 153 | Assert.AreEqual(StatusCode.Unauthenticated, ex.Status.StatusCode); |
| 154 | Assert.AreEqual(1, ex.Trailers.Count); |
| 155 | Assert.AreEqual("xyz", ex.Trailers[0].Key); |
| 156 | Assert.AreEqual("xyz-value", ex.Trailers[0].Value); |
| 157 | |
| 158 | var ex2 = Assert.ThrowsAsync<RpcException>(async () => await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc")); |
| 159 | Assert.AreEqual(StatusCode.Unauthenticated, ex2.Status.StatusCode); |
| 160 | Assert.AreEqual(1, ex2.Trailers.Count); |
| 161 | Assert.AreEqual("xyz", ex2.Trailers[0].Key); |
| 162 | Assert.AreEqual("xyz-value", ex2.Trailers[0].Value); |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 163 | } |
| 164 | |
| 165 | [Test] |
Jan Tattermusch | 9b048e5 | 2015-07-24 21:20:24 -0700 | [diff] [blame] | 166 | public async Task ClientStreamingCall() |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 167 | { |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 168 | helper.ClientStreamingHandler = new ClientStreamingServerMethod<string, string>(async (requestStream, context) => |
| 169 | { |
| 170 | string result = ""; |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 171 | await requestStream.ForEachAsync((request) => |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 172 | { |
| 173 | result += request; |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 174 | return TaskUtils.CompletedTask; |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 175 | }); |
| 176 | await Task.Delay(100); |
| 177 | return result; |
| 178 | }); |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 179 | |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 180 | var call = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall()); |
Jan Tattermusch | f22abfb | 2015-08-09 16:15:34 -0700 | [diff] [blame] | 181 | await call.RequestStream.WriteAllAsync(new string[] { "A", "B", "C" }); |
Jan Tattermusch | 9b048e5 | 2015-07-24 21:20:24 -0700 | [diff] [blame] | 182 | Assert.AreEqual("ABC", await call.ResponseAsync); |
Jan Tattermusch | a1e6097 | 2015-12-10 19:54:10 -0800 | [diff] [blame] | 183 | |
| 184 | Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode); |
| 185 | Assert.IsNotNull(call.GetTrailers()); |
| 186 | } |
| 187 | |
| 188 | [Test] |
| 189 | public async Task ServerStreamingCall() |
| 190 | { |
| 191 | helper.ServerStreamingHandler = new ServerStreamingServerMethod<string, string>(async (request, responseStream, context) => |
| 192 | { |
Jan Tattermusch | 8fe3f64 | 2015-12-10 20:30:46 -0800 | [diff] [blame] | 193 | await responseStream.WriteAllAsync(request.Split(new []{' '})); |
Jan Tattermusch | a1e6097 | 2015-12-10 19:54:10 -0800 | [diff] [blame] | 194 | context.ResponseTrailers.Add("xyz", ""); |
| 195 | }); |
| 196 | |
| 197 | var call = Calls.AsyncServerStreamingCall(helper.CreateServerStreamingCall(), "A B C"); |
| 198 | CollectionAssert.AreEqual(new string[] { "A", "B", "C" }, await call.ResponseStream.ToListAsync()); |
| 199 | |
| 200 | Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode); |
Jan Tattermusch | a87f6d8 | 2017-08-08 16:35:51 +0200 | [diff] [blame] | 201 | Assert.AreEqual("xyz", call.GetTrailers()[0].Key); |
Jan Tattermusch | a1e6097 | 2015-12-10 19:54:10 -0800 | [diff] [blame] | 202 | } |
| 203 | |
| 204 | [Test] |
Jan Tattermusch | a83ad2a | 2016-05-02 17:13:00 -0700 | [diff] [blame] | 205 | public async Task ServerStreamingCall_EndOfStreamIsIdempotent() |
| 206 | { |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 207 | helper.ServerStreamingHandler = new ServerStreamingServerMethod<string, string>((request, responseStream, context) => TaskUtils.CompletedTask); |
Jan Tattermusch | a83ad2a | 2016-05-02 17:13:00 -0700 | [diff] [blame] | 208 | |
| 209 | var call = Calls.AsyncServerStreamingCall(helper.CreateServerStreamingCall(), ""); |
| 210 | |
| 211 | Assert.IsFalse(await call.ResponseStream.MoveNext()); |
| 212 | Assert.IsFalse(await call.ResponseStream.MoveNext()); |
| 213 | } |
| 214 | |
| 215 | [Test] |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 216 | public void ServerStreamingCall_ErrorCanBeAwaitedTwice() |
Jan Tattermusch | a83ad2a | 2016-05-02 17:13:00 -0700 | [diff] [blame] | 217 | { |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 218 | helper.ServerStreamingHandler = new ServerStreamingServerMethod<string, string>((request, responseStream, context) => |
Jan Tattermusch | a83ad2a | 2016-05-02 17:13:00 -0700 | [diff] [blame] | 219 | { |
| 220 | context.Status = new Status(StatusCode.InvalidArgument, ""); |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 221 | return TaskUtils.CompletedTask; |
Jan Tattermusch | a83ad2a | 2016-05-02 17:13:00 -0700 | [diff] [blame] | 222 | }); |
| 223 | |
| 224 | var call = Calls.AsyncServerStreamingCall(helper.CreateServerStreamingCall(), ""); |
| 225 | |
| 226 | var ex = Assert.ThrowsAsync<RpcException>(async () => await call.ResponseStream.MoveNext()); |
| 227 | Assert.AreEqual(StatusCode.InvalidArgument, ex.Status.StatusCode); |
| 228 | |
| 229 | // attempting MoveNext again should result in throwing the same exception. |
| 230 | var ex2 = Assert.ThrowsAsync<RpcException>(async () => await call.ResponseStream.MoveNext()); |
| 231 | Assert.AreEqual(StatusCode.InvalidArgument, ex2.Status.StatusCode); |
| 232 | } |
| 233 | |
| 234 | [Test] |
Jan Tattermusch | 2312634 | 2017-08-11 18:21:05 +0200 | [diff] [blame] | 235 | public void ServerStreamingCall_TrailersFromMultipleSourcesGetConcatenated() |
Jan Tattermusch | a87f6d8 | 2017-08-08 16:35:51 +0200 | [diff] [blame] | 236 | { |
Jan Tattermusch | 2312634 | 2017-08-11 18:21:05 +0200 | [diff] [blame] | 237 | helper.ServerStreamingHandler = new ServerStreamingServerMethod<string, string>((request, responseStream, context) => |
Jan Tattermusch | a87f6d8 | 2017-08-08 16:35:51 +0200 | [diff] [blame] | 238 | { |
| 239 | context.ResponseTrailers.Add("xyz", "xyz-value"); |
| 240 | throw new RpcException(new Status(StatusCode.InvalidArgument, ""), new Metadata { {"abc", "abc-value"} }); |
| 241 | }); |
| 242 | |
| 243 | var call = Calls.AsyncServerStreamingCall(helper.CreateServerStreamingCall(), ""); |
| 244 | |
| 245 | var ex = Assert.ThrowsAsync<RpcException>(async () => await call.ResponseStream.MoveNext()); |
| 246 | Assert.AreEqual(StatusCode.InvalidArgument, ex.Status.StatusCode); |
| 247 | Assert.AreEqual(2, call.GetTrailers().Count); |
| 248 | Assert.AreEqual(2, ex.Trailers.Count); |
| 249 | Assert.AreEqual("xyz", ex.Trailers[0].Key); |
| 250 | Assert.AreEqual("xyz-value", ex.Trailers[0].Value); |
| 251 | Assert.AreEqual("abc", ex.Trailers[1].Key); |
| 252 | Assert.AreEqual("abc-value", ex.Trailers[1].Value); |
| 253 | } |
| 254 | |
| 255 | [Test] |
Jan Tattermusch | a1e6097 | 2015-12-10 19:54:10 -0800 | [diff] [blame] | 256 | public async Task DuplexStreamingCall() |
| 257 | { |
| 258 | helper.DuplexStreamingHandler = new DuplexStreamingServerMethod<string, string>(async (requestStream, responseStream, context) => |
| 259 | { |
| 260 | while (await requestStream.MoveNext()) |
| 261 | { |
| 262 | await responseStream.WriteAsync(requestStream.Current); |
| 263 | } |
| 264 | context.ResponseTrailers.Add("xyz", "xyz-value"); |
| 265 | }); |
| 266 | |
| 267 | var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall()); |
| 268 | await call.RequestStream.WriteAllAsync(new string[] { "A", "B", "C" }); |
| 269 | CollectionAssert.AreEqual(new string[] { "A", "B", "C" }, await call.ResponseStream.ToListAsync()); |
| 270 | |
| 271 | Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode); |
Jan Tattermusch | a87f6d8 | 2017-08-08 16:35:51 +0200 | [diff] [blame] | 272 | Assert.AreEqual("xyz-value", call.GetTrailers()[0].Value); |
Jan Tattermusch | e5c4460 | 2015-05-01 11:12:34 -0700 | [diff] [blame] | 273 | } |
| 274 | |
| 275 | [Test] |
Jan Tattermusch | 2615f39 | 2015-08-07 20:41:26 -0700 | [diff] [blame] | 276 | public async Task AsyncUnaryCall_EchoMetadata() |
Jan Tattermusch | 998eb9b | 2015-07-20 22:12:53 -0700 | [diff] [blame] | 277 | { |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 278 | helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 279 | { |
| 280 | foreach (Metadata.Entry metadataEntry in context.RequestHeaders) |
| 281 | { |
| 282 | if (metadataEntry.Key != "user-agent") |
| 283 | { |
| 284 | context.ResponseTrailers.Add(metadataEntry); |
| 285 | } |
| 286 | } |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 287 | return Task.FromResult(""); |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 288 | }); |
| 289 | |
Jan Tattermusch | 7d219cf | 2015-07-21 12:23:31 -0700 | [diff] [blame] | 290 | var headers = new Metadata |
Jan Tattermusch | 998eb9b | 2015-07-20 22:12:53 -0700 | [diff] [blame] | 291 | { |
Jan Tattermusch | 410c473 | 2015-08-08 00:02:07 -0700 | [diff] [blame] | 292 | { "ascii-header", "abcdefg" }, |
| 293 | { "binary-header-bin", new byte[] { 1, 2, 3, 0, 0xff } } |
Jan Tattermusch | 998eb9b | 2015-07-20 22:12:53 -0700 | [diff] [blame] | 294 | }; |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 295 | var call = Calls.AsyncUnaryCall(helper.CreateUnaryCall(new CallOptions(headers: headers)), "ABC"); |
Jan Tattermusch | 2615f39 | 2015-08-07 20:41:26 -0700 | [diff] [blame] | 296 | await call; |
Jan Tattermusch | 1cf8d42 | 2015-07-21 10:37:55 -0700 | [diff] [blame] | 297 | |
Jan Tattermusch | e7e1c82 | 2015-07-21 12:38:07 -0700 | [diff] [blame] | 298 | Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode); |
Jan Tattermusch | 7d219cf | 2015-07-21 12:23:31 -0700 | [diff] [blame] | 299 | |
Jan Tattermusch | e7e1c82 | 2015-07-21 12:38:07 -0700 | [diff] [blame] | 300 | var trailers = call.GetTrailers(); |
Jan Tattermusch | 7d219cf | 2015-07-21 12:23:31 -0700 | [diff] [blame] | 301 | Assert.AreEqual(2, trailers.Count); |
| 302 | Assert.AreEqual(headers[0].Key, trailers[0].Key); |
| 303 | Assert.AreEqual(headers[0].Value, trailers[0].Value); |
| 304 | |
| 305 | Assert.AreEqual(headers[1].Key, trailers[1].Key); |
| 306 | CollectionAssert.AreEqual(headers[1].ValueBytes, trailers[1].ValueBytes); |
Jan Tattermusch | 998eb9b | 2015-07-20 22:12:53 -0700 | [diff] [blame] | 307 | } |
Jan Tattermusch | 7ebbc47 | 2015-12-08 22:39:02 -0800 | [diff] [blame] | 308 | |
Jan Tattermusch | 797b875 | 2015-06-17 10:53:59 -0700 | [diff] [blame] | 309 | [Test] |
| 310 | public void UnknownMethodHandler() |
| 311 | { |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 312 | var nonexistentMethod = new Method<string, string>( |
| 313 | MethodType.Unary, |
| 314 | MockServiceHelper.ServiceName, |
| 315 | "NonExistentMethod", |
| 316 | Marshallers.StringMarshaller, |
| 317 | Marshallers.StringMarshaller); |
| 318 | |
| 319 | var callDetails = new CallInvocationDetails<string, string>(channel, nonexistentMethod, new CallOptions()); |
| 320 | |
| 321 | var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(callDetails, "abc")); |
| 322 | Assert.AreEqual(StatusCode.Unimplemented, ex.Status.StatusCode); |
Jan Tattermusch | 797b875 | 2015-06-17 10:53:59 -0700 | [diff] [blame] | 323 | } |
Jan Tattermusch | 337a2dd | 2015-02-13 15:41:41 -0800 | [diff] [blame] | 324 | |
Jan Tattermusch | 766d72b | 2015-07-21 20:09:25 -0700 | [diff] [blame] | 325 | [Test] |
Jan Tattermusch | 2e5e5f6 | 2017-01-18 21:31:06 +0100 | [diff] [blame] | 326 | public void StatusDetailIsUtf8() |
| 327 | { |
| 328 | // some japanese and chinese characters |
| 329 | var nonAsciiString = "\u30a1\u30a2\u30a3 \u62b5\u6297\u662f\u5f92\u52b3\u7684"; |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 330 | helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => |
Jan Tattermusch | 2e5e5f6 | 2017-01-18 21:31:06 +0100 | [diff] [blame] | 331 | { |
| 332 | context.Status = new Status(StatusCode.Unknown, nonAsciiString); |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 333 | return Task.FromResult(""); |
Jan Tattermusch | 2e5e5f6 | 2017-01-18 21:31:06 +0100 | [diff] [blame] | 334 | }); |
| 335 | |
| 336 | var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); |
| 337 | Assert.AreEqual(StatusCode.Unknown, ex.Status.StatusCode); |
| 338 | Assert.AreEqual(nonAsciiString, ex.Status.Detail); |
| 339 | } |
| 340 | |
| 341 | [Test] |
Jan Tattermusch | 00c144a | 2015-12-10 20:04:01 -0800 | [diff] [blame] | 342 | public void ServerCallContext_PeerInfoPresent() |
Jan Tattermusch | 062c329 | 2015-07-23 20:28:42 -0700 | [diff] [blame] | 343 | { |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 344 | helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 345 | { |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 346 | return Task.FromResult(context.Peer); |
Jan Tattermusch | 0abb847 | 2015-08-07 20:28:44 -0700 | [diff] [blame] | 347 | }); |
| 348 | |
| 349 | string peer = Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc"); |
Jan Tattermusch | 062c329 | 2015-07-23 20:28:42 -0700 | [diff] [blame] | 350 | Assert.IsTrue(peer.Contains(Host)); |
| 351 | } |
| 352 | |
Jan Tattermusch | d8bbdea | 2015-07-22 12:51:06 -0700 | [diff] [blame] | 353 | [Test] |
Jan Tattermusch | 00c144a | 2015-12-10 20:04:01 -0800 | [diff] [blame] | 354 | public void ServerCallContext_HostAndMethodPresent() |
| 355 | { |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 356 | helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => |
Jan Tattermusch | 00c144a | 2015-12-10 20:04:01 -0800 | [diff] [blame] | 357 | { |
| 358 | Assert.IsTrue(context.Host.Contains(Host)); |
| 359 | Assert.AreEqual("/tests.Test/Unary", context.Method); |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 360 | return Task.FromResult("PASS"); |
Jan Tattermusch | 00c144a | 2015-12-10 20:04:01 -0800 | [diff] [blame] | 361 | }); |
| 362 | Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); |
| 363 | } |
| 364 | |
| 365 | [Test] |
Jan Tattermusch | c9b03fe | 2017-02-06 08:45:00 -0800 | [diff] [blame] | 366 | public void ServerCallContext_AuthContextNotPopulated() |
| 367 | { |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 368 | helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => |
Jan Tattermusch | c9b03fe | 2017-02-06 08:45:00 -0800 | [diff] [blame] | 369 | { |
| 370 | Assert.IsFalse(context.AuthContext.IsPeerAuthenticated); |
| 371 | Assert.AreEqual(0, context.AuthContext.Properties.Count()); |
Jan Tattermusch | 2fb313c | 2017-08-09 09:41:25 +0200 | [diff] [blame] | 372 | return Task.FromResult("PASS"); |
Jan Tattermusch | c9b03fe | 2017-02-06 08:45:00 -0800 | [diff] [blame] | 373 | }); |
| 374 | Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); |
| 375 | } |
Jan Tattermusch | a7608b0 | 2015-02-03 17:54:38 -0800 | [diff] [blame] | 376 | } |
| 377 | } |