blob: fdec6efd2ef2a3b26aad5a1afef7da2a6e5ec56d [file] [log] [blame]
Jan Tattermuscha7fff862015-02-13 11:08:08 -08001#region Copyright notice and license
2
Jan Tattermuschaf77b3d2015-02-13 11:22:21 -08003// Copyright 2015, Google Inc.
Jan Tattermuscha7fff862015-02-13 11:08:08 -08004// All rights reserved.
Craig Tiller190d3602015-02-18 09:23:38 -08005//
Jan Tattermuscha7fff862015-02-13 11:08:08 -08006// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
Craig Tiller190d3602015-02-18 09:23:38 -08009//
Jan Tattermuscha7fff862015-02-13 11:08:08 -080010// * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above
13// copyright notice, this list of conditions and the following disclaimer
14// in the documentation and/or other materials provided with the
15// distribution.
16// * Neither the name of Google Inc. nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
Craig Tiller190d3602015-02-18 09:23:38 -080019//
Jan Tattermuscha7fff862015-02-13 11:08:08 -080020// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32#endregion
33
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080034using System;
Jan Tattermuschd233d3a2015-02-06 14:15:00 -080035using System.Collections.Generic;
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080036using System.Text.RegularExpressions;
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080037using Google.ProtocolBuffers;
Jan Tattermusch30868622015-02-19 09:22:33 -080038using Grpc.Core;
39using Grpc.Core.Utils;
40using NUnit.Framework;
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080041using grpc.testing;
42
Jan Tattermusch30868622015-02-19 09:22:33 -080043namespace Grpc.Interop
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080044{
Jan Tattermusch392d1e02015-02-09 11:13:51 -080045 class Client
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080046 {
47 private class ClientOptions
48 {
49 public bool help;
50 public string serverHost;
51 public string serverHostOverride;
52 public int? serverPort;
53 public string testCase;
54 public bool useTls;
55 public bool useTestCa;
56 }
57
58 ClientOptions options;
59
Jan Tattermusch392d1e02015-02-09 11:13:51 -080060 private Client(ClientOptions options)
61 {
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080062 this.options = options;
63 }
64
65 public static void Main(string[] args)
66 {
67 Console.WriteLine("gRPC C# interop testing client");
68 ClientOptions options = ParseArguments(args);
69
70 if (options.serverHost == null || !options.serverPort.HasValue || options.testCase == null)
71 {
72 Console.WriteLine("Missing required argument.");
73 Console.WriteLine();
74 options.help = true;
75 }
76
77 if (options.help)
78 {
79 Console.WriteLine("Usage:");
80 Console.WriteLine(" --server_host=HOSTNAME");
81 Console.WriteLine(" --server_host_override=HOSTNAME");
82 Console.WriteLine(" --server_port=PORT");
83 Console.WriteLine(" --test_case=TESTCASE");
84 Console.WriteLine(" --use_tls=BOOLEAN");
85 Console.WriteLine(" --use_test_ca=BOOLEAN");
Craig Tiller190d3602015-02-18 09:23:38 -080086 Console.WriteLine();
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080087 Environment.Exit(1);
88 }
89
Jan Tattermusch392d1e02015-02-09 11:13:51 -080090 var interopClient = new Client(options);
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080091 interopClient.Run();
92 }
93
94 private void Run()
95 {
Jan Tattermusch23821ce2015-02-13 10:46:02 -080096 GrpcEnvironment.Initialize();
97
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080098 string addr = string.Format("{0}:{1}", options.serverHost, options.serverPort);
99 using (Channel channel = new Channel(addr))
100 {
101 TestServiceGrpc.ITestServiceClient client = new TestServiceGrpc.TestServiceClientStub(channel);
102
103 RunTestCase(options.testCase, client);
104 }
105
106 GrpcEnvironment.Shutdown();
107 }
108
109 private void RunTestCase(string testCase, TestServiceGrpc.ITestServiceClient client)
110 {
111 switch (testCase)
112 {
113 case "empty_unary":
114 RunEmptyUnary(client);
115 break;
116 case "large_unary":
117 RunLargeUnary(client);
118 break;
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800119 case "client_streaming":
120 RunClientStreaming(client);
121 break;
122 case "server_streaming":
123 RunServerStreaming(client);
124 break;
125 case "ping_pong":
126 RunPingPong(client);
127 break;
128 case "empty_stream":
129 RunEmptyStream(client);
130 break;
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800131 default:
132 throw new ArgumentException("Unknown test case " + testCase);
133 }
134 }
135
136 private void RunEmptyUnary(TestServiceGrpc.ITestServiceClient client)
137 {
138 Console.WriteLine("running empty_unary");
139 var response = client.EmptyCall(Empty.DefaultInstance);
140 Assert.IsNotNull(response);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800141 Console.WriteLine("Passed!");
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800142 }
143
144 private void RunLargeUnary(TestServiceGrpc.ITestServiceClient client)
145 {
146 Console.WriteLine("running large_unary");
147 var request = SimpleRequest.CreateBuilder()
148 .SetResponseType(PayloadType.COMPRESSABLE)
149 .SetResponseSize(314159)
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800150 .SetPayload(CreateZerosPayload(271828))
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800151 .Build();
Craig Tiller190d3602015-02-18 09:23:38 -0800152
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800153 var response = client.UnaryCall(request);
154
155 Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
156 Assert.AreEqual(314159, response.Payload.Body.Length);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800157 Console.WriteLine("Passed!");
158 }
159
160 private void RunClientStreaming(TestServiceGrpc.ITestServiceClient client)
161 {
162 Console.WriteLine("running client_streaming");
163
164 var bodySizes = new List<int>{27182, 8, 1828, 45904};
165
166 var context = client.StreamingInputCall();
167 foreach (var size in bodySizes)
168 {
169 context.Inputs.OnNext(
170 StreamingInputCallRequest.CreateBuilder().SetPayload(CreateZerosPayload(size)).Build());
171 }
172 context.Inputs.OnCompleted();
173
174 var response = context.Task.Result;
175 Assert.AreEqual(74922, response.AggregatedPayloadSize);
176 Console.WriteLine("Passed!");
177 }
178
179 private void RunServerStreaming(TestServiceGrpc.ITestServiceClient client)
180 {
181 Console.WriteLine("running server_streaming");
182
183 var bodySizes = new List<int>{31415, 9, 2653, 58979};
184
185 var request = StreamingOutputCallRequest.CreateBuilder()
186 .SetResponseType(PayloadType.COMPRESSABLE)
187 .AddRangeResponseParameters(bodySizes.ConvertAll(
188 (size) => ResponseParameters.CreateBuilder().SetSize(size).Build()))
189 .Build();
190
191 var recorder = new RecordingObserver<StreamingOutputCallResponse>();
192 client.StreamingOutputCall(request, recorder);
193
194 var responseList = recorder.ToList().Result;
195
196 foreach (var res in responseList)
197 {
198 Assert.AreEqual(PayloadType.COMPRESSABLE, res.Payload.Type);
199 }
200 CollectionAssert.AreEqual(bodySizes, responseList.ConvertAll((item) => item.Payload.Body.Length));
201 Console.WriteLine("Passed!");
202 }
203
204 private void RunPingPong(TestServiceGrpc.ITestServiceClient client)
205 {
206 Console.WriteLine("running ping_pong");
207
208 var recorder = new RecordingQueue<StreamingOutputCallResponse>();
209 var inputs = client.FullDuplexCall(recorder);
210
211 StreamingOutputCallResponse response;
212
213 inputs.OnNext(StreamingOutputCallRequest.CreateBuilder()
214 .SetResponseType(PayloadType.COMPRESSABLE)
215 .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415))
216 .SetPayload(CreateZerosPayload(27182)).Build());
Craig Tiller190d3602015-02-18 09:23:38 -0800217
218 response = recorder.Queue.Take();
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800219 Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
220 Assert.AreEqual(31415, response.Payload.Body.Length);
221
222 inputs.OnNext(StreamingOutputCallRequest.CreateBuilder()
223 .SetResponseType(PayloadType.COMPRESSABLE)
224 .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(9))
225 .SetPayload(CreateZerosPayload(8)).Build());
226
Craig Tiller190d3602015-02-18 09:23:38 -0800227 response = recorder.Queue.Take();
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800228 Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
229 Assert.AreEqual(9, response.Payload.Body.Length);
230
231 inputs.OnNext(StreamingOutputCallRequest.CreateBuilder()
232 .SetResponseType(PayloadType.COMPRESSABLE)
233 .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(2635))
234 .SetPayload(CreateZerosPayload(1828)).Build());
235
Craig Tiller190d3602015-02-18 09:23:38 -0800236 response = recorder.Queue.Take();
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800237 Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
238 Assert.AreEqual(2653, response.Payload.Body.Length);
239
240
241 inputs.OnNext(StreamingOutputCallRequest.CreateBuilder()
242 .SetResponseType(PayloadType.COMPRESSABLE)
243 .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(58979))
244 .SetPayload(CreateZerosPayload(45904)).Build());
245
Craig Tiller190d3602015-02-18 09:23:38 -0800246 response = recorder.Queue.Take();
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800247 Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
248 Assert.AreEqual(58979, response.Payload.Body.Length);
249
250 recorder.Finished.Wait();
251 Assert.AreEqual(0, recorder.Queue.Count);
252
253 Console.WriteLine("Passed!");
254 }
255
256 private void RunEmptyStream(TestServiceGrpc.ITestServiceClient client)
257 {
258 Console.WriteLine("running empty_stream");
259
260 var recorder = new RecordingObserver<StreamingOutputCallResponse>();
261 var inputs = client.FullDuplexCall(recorder);
262 inputs.OnCompleted();
263
264 var responseList = recorder.ToList().Result;
265 Assert.AreEqual(0, responseList.Count);
266
267 Console.WriteLine("Passed!");
268 }
269
270
271 private Payload CreateZerosPayload(int size) {
272 return Payload.CreateBuilder().SetBody(ByteString.CopyFrom(new byte[size])).Build();
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800273 }
274
275 private static ClientOptions ParseArguments(string[] args)
276 {
277 var options = new ClientOptions();
278 foreach(string arg in args)
279 {
280 ParseArgument(arg, options);
281 if (options.help)
282 {
283 break;
284 }
285 }
286 return options;
287 }
288
289 private static void ParseArgument(string arg, ClientOptions options)
290 {
291 Match match;
292 match = Regex.Match(arg, "--server_host=(.*)");
293 if (match.Success)
294 {
295 options.serverHost = match.Groups[1].Value.Trim();
296 return;
297 }
298
299 match = Regex.Match(arg, "--server_host_override=(.*)");
300 if (match.Success)
301 {
302 options.serverHostOverride = match.Groups[1].Value.Trim();
303 return;
304 }
305
306 match = Regex.Match(arg, "--server_port=(.*)");
307 if (match.Success)
308 {
309 options.serverPort = int.Parse(match.Groups[1].Value.Trim());
310 return;
311 }
312
313 match = Regex.Match(arg, "--test_case=(.*)");
314 if (match.Success)
315 {
316 options.testCase = match.Groups[1].Value.Trim();
317 return;
318 }
319
320 match = Regex.Match(arg, "--use_tls=(.*)");
321 if (match.Success)
322 {
323 options.useTls = bool.Parse(match.Groups[1].Value.Trim());
324 return;
325 }
326
327 match = Regex.Match(arg, "--use_test_ca=(.*)");
328 if (match.Success)
329 {
330 options.useTestCa = bool.Parse(match.Groups[1].Value.Trim());
331 return;
332 }
333
334 Console.WriteLine(string.Format("Unrecognized argument \"{0}\"", arg));
335 options.help = true;
336 }
337 }
338}