blob: 030a098cad364e73a47ae88013cd0a595c97f3ae [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 Tattermusch74f39e12015-09-23 20:14:56 -070036using System.IO;
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080037using System.Text.RegularExpressions;
Jan Tattermusche5c44602015-05-01 11:12:34 -070038using System.Threading;
Jan Tattermuscha5272b62015-04-30 11:56:46 -070039using System.Threading.Tasks;
Jan Tattermusch1ca56b92015-04-27 11:03:06 -070040
Jan Tattermuschb26972f2015-09-03 17:47:14 -070041using CommandLine;
Jan Tattermusch74f39e12015-09-23 20:14:56 -070042using CommandLine.Text;
Jan Tattermusch67c45872015-08-27 18:12:39 -070043using Google.Apis.Auth.OAuth2;
44using Google.Protobuf;
Jan Tattermuschdca6e882015-04-22 16:56:27 -070045using Grpc.Auth;
Jan Tattermusch30868622015-02-19 09:22:33 -080046using Grpc.Core;
47using Grpc.Core.Utils;
Jan Tattermusch8644aea2015-08-03 10:21:18 -070048using Grpc.Testing;
Jan Tattermusch64d7c242015-10-08 08:02:27 -070049using Newtonsoft.Json.Linq;
Jan Tattermusch30868622015-02-19 09:22:33 -080050using NUnit.Framework;
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080051
Jan Tattermusch8b86b152015-02-19 21:01:05 -080052namespace Grpc.IntegrationTesting
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080053{
Jan Tattermusch503bbac2015-02-26 18:19:47 -080054 public class InteropClient
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080055 {
56 private class ClientOptions
57 {
Jan Tattermuschb26972f2015-09-03 17:47:14 -070058 [Option("server_host", DefaultValue = "127.0.0.1")]
59 public string ServerHost { get; set; }
60
61 [Option("server_host_override", DefaultValue = TestCredentials.DefaultHostOverride)]
62 public string ServerHostOverride { get; set; }
63
64 [Option("server_port", Required = true)]
65 public int ServerPort { get; set; }
66
67 [Option("test_case", DefaultValue = "large_unary")]
68 public string TestCase { get; set; }
69
Jan Tattermusch7828e812015-10-07 17:27:48 -070070 // Deliberately using nullable bool type to allow --use_tls=true syntax (as opposed to --use_tls)
71 [Option("use_tls", DefaultValue = false)]
72 public bool? UseTls { get; set; }
Jan Tattermuschb26972f2015-09-03 17:47:14 -070073
Jan Tattermusch7828e812015-10-07 17:27:48 -070074 // Deliberately using nullable bool type to allow --use_test_ca=true syntax (as opposed to --use_test_ca)
75 [Option("use_test_ca", DefaultValue = false)]
76 public bool? UseTestCa { get; set; }
Jan Tattermuschb26972f2015-09-03 17:47:14 -070077
78 [Option("default_service_account", Required = false)]
79 public string DefaultServiceAccount { get; set; }
80
81 [Option("oauth_scope", Required = false)]
82 public string OAuthScope { get; set; }
83
84 [Option("service_account_key_file", Required = false)]
85 public string ServiceAccountKeyFile { get; set; }
86
87 [HelpOption]
88 public string GetUsage()
89 {
90 var help = new HelpText
91 {
92 Heading = "gRPC C# interop testing client",
93 AddDashesToOption = true
94 };
95 help.AddPreOptionsLine("Usage:");
96 help.AddOptions(this);
97 return help;
98 }
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -080099 }
100
101 ClientOptions options;
102
Jan Tattermusch503bbac2015-02-26 18:19:47 -0800103 private InteropClient(ClientOptions options)
Jan Tattermusch392d1e02015-02-09 11:13:51 -0800104 {
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800105 this.options = options;
106 }
107
Jan Tattermusch503bbac2015-02-26 18:19:47 -0800108 public static void Run(string[] args)
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800109 {
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700110 var options = new ClientOptions();
111 if (!Parser.Default.ParseArguments(args, options))
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800112 {
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800113 Environment.Exit(1);
114 }
115
Jan Tattermusch503bbac2015-02-26 18:19:47 -0800116 var interopClient = new InteropClient(options);
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700117 interopClient.Run().Wait();
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800118 }
119
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700120 private async Task Run()
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800121 {
Jan Tattermusch9e5e7e92015-09-24 10:34:05 -0700122 var credentials = await CreateCredentialsAsync();
123
124 List<ChannelOption> channelOptions = null;
125 if (!string.IsNullOrEmpty(options.ServerHostOverride))
126 {
127 channelOptions = new List<ChannelOption>
128 {
129 new ChannelOption(ChannelOptions.SslTargetNameOverride, options.ServerHostOverride)
130 };
131 }
132 var channel = new Channel(options.ServerHost, options.ServerPort, credentials, channelOptions);
133 TestService.TestServiceClient client = new TestService.TestServiceClient(channel);
134 await RunTestCaseAsync(client, options);
135 await channel.ShutdownAsync();
136 }
137
Jan Tattermusch5bd70052015-10-06 16:47:49 -0700138 private async Task<ChannelCredentials> CreateCredentialsAsync()
Jan Tattermusch9e5e7e92015-09-24 10:34:05 -0700139 {
Jan Tattermusch7828e812015-10-07 17:27:48 -0700140 var credentials = options.UseTls.Value ? TestCredentials.CreateTestClientCredentials(options.UseTestCa.Value) : ChannelCredentials.Insecure;
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700141
142 if (options.TestCase == "jwt_token_creds")
143 {
144 var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
145 Assert.IsTrue(googleCredential.IsCreateScopedRequired);
Jan Tattermusch18729a02015-10-08 18:40:00 -0700146 credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials());
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700147 }
148
149 if (options.TestCase == "compute_engine_creds")
150 {
151 var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
152 Assert.IsFalse(googleCredential.IsCreateScopedRequired);
Jan Tattermusch18729a02015-10-08 18:40:00 -0700153 credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials());
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700154 }
Jan Tattermusch9e5e7e92015-09-24 10:34:05 -0700155 return credentials;
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800156 }
157
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700158 private async Task RunTestCaseAsync(TestService.TestServiceClient client, ClientOptions options)
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800159 {
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700160 switch (options.TestCase)
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800161 {
162 case "empty_unary":
163 RunEmptyUnary(client);
164 break;
165 case "large_unary":
166 RunLargeUnary(client);
167 break;
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800168 case "client_streaming":
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700169 await RunClientStreamingAsync(client);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800170 break;
171 case "server_streaming":
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700172 await RunServerStreamingAsync(client);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800173 break;
174 case "ping_pong":
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700175 await RunPingPongAsync(client);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800176 break;
177 case "empty_stream":
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700178 await RunEmptyStreamAsync(client);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800179 break;
Jan Tattermusch0bbfa382015-04-27 16:11:59 -0700180 case "compute_engine_creds":
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700181 RunComputeEngineCreds(client, options.DefaultServiceAccount, options.OAuthScope);
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700182 break;
183 case "jwt_token_creds":
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700184 RunJwtTokenCreds(client);
Jan Tattermusch0bbfa382015-04-27 16:11:59 -0700185 break;
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700186 case "oauth2_auth_token":
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700187 await RunOAuth2AuthTokenAsync(client, options.OAuthScope);
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700188 break;
189 case "per_rpc_creds":
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700190 await RunPerRpcCredsAsync(client, options.OAuthScope);
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700191 break;
Jan Tattermusche5c44602015-05-01 11:12:34 -0700192 case "cancel_after_begin":
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700193 await RunCancelAfterBeginAsync(client);
Jan Tattermusche5c44602015-05-01 11:12:34 -0700194 break;
195 case "cancel_after_first_response":
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700196 await RunCancelAfterFirstResponseAsync(client);
Jan Tattermusche5c44602015-05-01 11:12:34 -0700197 break;
Jan Tattermusche4134dd2015-08-12 14:54:40 -0700198 case "timeout_on_sleeping_server":
199 await RunTimeoutOnSleepingServerAsync(client);
200 break;
Jan Tattermusch50faa8f2015-02-21 17:51:52 -0800201 case "benchmark_empty_unary":
202 RunBenchmarkEmptyUnary(client);
203 break;
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800204 default:
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700205 throw new ArgumentException("Unknown test case " + options.TestCase);
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800206 }
207 }
208
Jan Tattermusch7eb3a762015-05-07 14:26:13 -0700209 public static void RunEmptyUnary(TestService.ITestServiceClient client)
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800210 {
211 Console.WriteLine("running empty_unary");
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700212 var response = client.EmptyCall(new Empty());
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800213 Assert.IsNotNull(response);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800214 Console.WriteLine("Passed!");
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800215 }
216
Jan Tattermusch7eb3a762015-05-07 14:26:13 -0700217 public static void RunLargeUnary(TestService.ITestServiceClient client)
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800218 {
219 Console.WriteLine("running large_unary");
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700220 var request = new SimpleRequest
221 {
222 ResponseType = PayloadType.COMPRESSABLE,
223 ResponseSize = 314159,
224 Payload = CreateZerosPayload(271828)
225 };
Craig Tiller190d3602015-02-18 09:23:38 -0800226
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800227 var response = client.UnaryCall(request);
228
229 Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
230 Assert.AreEqual(314159, response.Payload.Body.Length);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800231 Console.WriteLine("Passed!");
232 }
233
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700234 public static async Task RunClientStreamingAsync(TestService.ITestServiceClient client)
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800235 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700236 Console.WriteLine("running client_streaming");
237
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700238 var bodySizes = new List<int> { 27182, 8, 1828, 45904 }.ConvertAll((size) => new StreamingInputCallRequest { Payload = CreateZerosPayload(size) });
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700239
240 using (var call = client.StreamingInputCall())
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800241 {
Jan Tattermuschf22abfb2015-08-09 16:15:34 -0700242 await call.RequestStream.WriteAllAsync(bodySizes);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800243
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700244 var response = await call.ResponseAsync;
245 Assert.AreEqual(74922, response.AggregatedPayloadSize);
246 }
247 Console.WriteLine("Passed!");
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800248 }
249
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700250 public static async Task RunServerStreamingAsync(TestService.ITestServiceClient client)
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800251 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700252 Console.WriteLine("running server_streaming");
253
254 var bodySizes = new List<int> { 31415, 9, 2653, 58979 };
255
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700256 var request = new StreamingOutputCallRequest
257 {
258 ResponseType = PayloadType.COMPRESSABLE,
259 ResponseParameters = { bodySizes.ConvertAll((size) => new ResponseParameters { Size = size }) }
260 };
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700261
262 using (var call = client.StreamingOutputCall(request))
Jan Tattermuscha5272b62015-04-30 11:56:46 -0700263 {
Jan Tattermuschf22abfb2015-08-09 16:15:34 -0700264 var responseList = await call.ResponseStream.ToListAsync();
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700265 foreach (var res in responseList)
266 {
267 Assert.AreEqual(PayloadType.COMPRESSABLE, res.Payload.Type);
268 }
269 CollectionAssert.AreEqual(bodySizes, responseList.ConvertAll((item) => item.Payload.Body.Length));
270 }
271 Console.WriteLine("Passed!");
272 }
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800273
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700274 public static async Task RunPingPongAsync(TestService.ITestServiceClient client)
275 {
276 Console.WriteLine("running ping_pong");
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800277
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700278 using (var call = client.FullDuplexCall())
279 {
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700280 await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
281 {
282 ResponseType = PayloadType.COMPRESSABLE,
283 ResponseParameters = { new ResponseParameters { Size = 31415 } },
284 Payload = CreateZerosPayload(27182)
285 });
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800286
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700287 Assert.IsTrue(await call.ResponseStream.MoveNext());
288 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
289 Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
290
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700291 await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
292 {
293 ResponseType = PayloadType.COMPRESSABLE,
294 ResponseParameters = { new ResponseParameters { Size = 9 } },
295 Payload = CreateZerosPayload(8)
296 });
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700297
298 Assert.IsTrue(await call.ResponseStream.MoveNext());
299 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
300 Assert.AreEqual(9, call.ResponseStream.Current.Payload.Body.Length);
301
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700302 await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
303 {
304 ResponseType = PayloadType.COMPRESSABLE,
305 ResponseParameters = { new ResponseParameters { Size = 2653 } },
306 Payload = CreateZerosPayload(1828)
307 });
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700308
309 Assert.IsTrue(await call.ResponseStream.MoveNext());
310 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
311 Assert.AreEqual(2653, call.ResponseStream.Current.Payload.Body.Length);
312
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700313 await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
314 {
315 ResponseType = PayloadType.COMPRESSABLE,
316 ResponseParameters = { new ResponseParameters { Size = 58979 } },
317 Payload = CreateZerosPayload(45904)
318 });
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700319
320 Assert.IsTrue(await call.ResponseStream.MoveNext());
321 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
322 Assert.AreEqual(58979, call.ResponseStream.Current.Payload.Body.Length);
323
324 await call.RequestStream.CompleteAsync();
325
326 Assert.IsFalse(await call.ResponseStream.MoveNext());
327 }
328 Console.WriteLine("Passed!");
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800329 }
330
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700331 public static async Task RunEmptyStreamAsync(TestService.ITestServiceClient client)
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800332 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700333 Console.WriteLine("running empty_stream");
334 using (var call = client.FullDuplexCall())
Jan Tattermuscha5272b62015-04-30 11:56:46 -0700335 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700336 await call.RequestStream.CompleteAsync();
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800337
Jan Tattermuschf22abfb2015-08-09 16:15:34 -0700338 var responseList = await call.ResponseStream.ToListAsync();
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700339 Assert.AreEqual(0, responseList.Count);
340 }
341 Console.WriteLine("Passed!");
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800342 }
343
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700344 public static void RunComputeEngineCreds(TestService.TestServiceClient client, string defaultServiceAccount, string oauthScope)
Jan Tattermusch0bbfa382015-04-27 16:11:59 -0700345 {
346 Console.WriteLine("running compute_engine_creds");
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700347
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700348 var request = new SimpleRequest
349 {
350 ResponseType = PayloadType.COMPRESSABLE,
351 ResponseSize = 314159,
352 Payload = CreateZerosPayload(271828),
353 FillUsername = true,
354 FillOauthScope = true
355 };
Jan Tattermusch0bbfa382015-04-27 16:11:59 -0700356
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700357 // not setting credentials here because they were set on channel already
Jan Tattermusch0bbfa382015-04-27 16:11:59 -0700358 var response = client.UnaryCall(request);
359
360 Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
361 Assert.AreEqual(314159, response.Payload.Body.Length);
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700362 Assert.False(string.IsNullOrEmpty(response.OauthScope));
363 Assert.True(oauthScope.Contains(response.OauthScope));
364 Assert.AreEqual(defaultServiceAccount, response.Username);
Jan Tattermusch0bbfa382015-04-27 16:11:59 -0700365 Console.WriteLine("Passed!");
366 }
367
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700368 public static void RunJwtTokenCreds(TestService.TestServiceClient client)
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700369 {
370 Console.WriteLine("running jwt_token_creds");
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700371
Jan Tattermusch46e85b02015-08-13 10:31:05 -0700372 var request = new SimpleRequest
373 {
374 ResponseType = PayloadType.COMPRESSABLE,
375 ResponseSize = 314159,
376 Payload = CreateZerosPayload(271828),
377 FillUsername = true,
Jan Tattermusch46e85b02015-08-13 10:31:05 -0700378 };
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700379
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700380 // not setting credentials here because they were set on channel already
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700381 var response = client.UnaryCall(request);
382
383 Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
384 Assert.AreEqual(314159, response.Payload.Body.Length);
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700385 Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700386 Console.WriteLine("Passed!");
387 }
388
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700389 public static async Task RunOAuth2AuthTokenAsync(TestService.TestServiceClient client, string oauthScope)
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700390 {
391 Console.WriteLine("running oauth2_auth_token");
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700392 ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { oauthScope });
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700393 string oauth2Token = await credential.GetAccessTokenForRequestAsync();
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700394
Jan Tattermusch18729a02015-10-08 18:40:00 -0700395 var credentials = GoogleGrpcCredentials.FromAccessToken(oauth2Token);
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700396 var request = new SimpleRequest
397 {
398 FillUsername = true,
399 FillOauthScope = true
400 };
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700401
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700402 var response = client.UnaryCall(request, new CallOptions(credentials: credentials));
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700403
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700404 Assert.False(string.IsNullOrEmpty(response.OauthScope));
405 Assert.True(oauthScope.Contains(response.OauthScope));
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700406 Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700407 Console.WriteLine("Passed!");
408 }
409
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700410 public static async Task RunPerRpcCredsAsync(TestService.TestServiceClient client, string oauthScope)
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700411 {
412 Console.WriteLine("running per_rpc_creds");
Jan Tattermuschcf72a3a2015-10-08 08:44:20 -0700413 ITokenAccess googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700414
Jan Tattermusch18729a02015-10-08 18:40:00 -0700415 var credentials = googleCredential.ToCallCredentials();
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700416 var request = new SimpleRequest
417 {
418 FillUsername = true,
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700419 };
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700420
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700421 var response = client.UnaryCall(request, new CallOptions(credentials: credentials));
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700422
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700423 Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700424 Console.WriteLine("Passed!");
425 }
426
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700427 public static async Task RunCancelAfterBeginAsync(TestService.ITestServiceClient client)
Jan Tattermusche5c44602015-05-01 11:12:34 -0700428 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700429 Console.WriteLine("running cancel_after_begin");
430
431 var cts = new CancellationTokenSource();
432 using (var call = client.StreamingInputCall(cancellationToken: cts.Token))
Jan Tattermusche5c44602015-05-01 11:12:34 -0700433 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700434 // TODO(jtattermusch): we need this to ensure call has been initiated once we cancel it.
435 await Task.Delay(1000);
436 cts.Cancel();
Jan Tattermusche5c44602015-05-01 11:12:34 -0700437
Jan Tattermuschc8d7b842015-08-07 20:52:21 -0700438 var ex = Assert.Throws<RpcException>(async () => await call.ResponseAsync);
439 Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700440 }
441 Console.WriteLine("Passed!");
Jan Tattermusche5c44602015-05-01 11:12:34 -0700442 }
443
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700444 public static async Task RunCancelAfterFirstResponseAsync(TestService.ITestServiceClient client)
Jan Tattermusche5c44602015-05-01 11:12:34 -0700445 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700446 Console.WriteLine("running cancel_after_first_response");
447
448 var cts = new CancellationTokenSource();
449 using (var call = client.FullDuplexCall(cancellationToken: cts.Token))
Jan Tattermusche5c44602015-05-01 11:12:34 -0700450 {
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700451 await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
452 {
453 ResponseType = PayloadType.COMPRESSABLE,
454 ResponseParameters = { new ResponseParameters { Size = 31415 } },
455 Payload = CreateZerosPayload(27182)
456 });
Jan Tattermusche5c44602015-05-01 11:12:34 -0700457
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700458 Assert.IsTrue(await call.ResponseStream.MoveNext());
459 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
460 Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
461
462 cts.Cancel();
463
Jan Tattermuschc8d7b842015-08-07 20:52:21 -0700464 var ex = Assert.Throws<RpcException>(async () => await call.ResponseStream.MoveNext());
465 Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700466 }
467 Console.WriteLine("Passed!");
Jan Tattermusche5c44602015-05-01 11:12:34 -0700468 }
469
Jan Tattermusche4134dd2015-08-12 14:54:40 -0700470 public static async Task RunTimeoutOnSleepingServerAsync(TestService.ITestServiceClient client)
471 {
472 Console.WriteLine("running timeout_on_sleeping_server");
473
474 var deadline = DateTime.UtcNow.AddMilliseconds(1);
475 using (var call = client.FullDuplexCall(deadline: deadline))
476 {
477 try
478 {
Jan Tattermusch0608a002015-08-26 08:50:19 -0700479 await call.RequestStream.WriteAsync(new StreamingOutputCallRequest { Payload = CreateZerosPayload(27182) });
Jan Tattermusche4134dd2015-08-12 14:54:40 -0700480 }
481 catch (InvalidOperationException)
482 {
483 // Deadline was reached before write has started. Eat the exception and continue.
484 }
485
486 var ex = Assert.Throws<RpcException>(async () => await call.ResponseStream.MoveNext());
487 Assert.AreEqual(StatusCode.DeadlineExceeded, ex.Status.StatusCode);
488 }
489 Console.WriteLine("Passed!");
490 }
491
Jan Tattermusch50faa8f2015-02-21 17:51:52 -0800492 // This is not an official interop test, but it's useful.
Jan Tattermusch7eb3a762015-05-07 14:26:13 -0700493 public static void RunBenchmarkEmptyUnary(TestService.ITestServiceClient client)
Jan Tattermusch50faa8f2015-02-21 17:51:52 -0800494 {
495 BenchmarkUtil.RunBenchmark(10000, 10000,
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700496 () => { client.EmptyCall(new Empty()); });
Jan Tattermusch50faa8f2015-02-21 17:51:52 -0800497 }
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800498
Jan Tattermusch075dde42015-03-11 18:21:00 -0700499 private static Payload CreateZerosPayload(int size)
500 {
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700501 return new Payload { Body = ByteString.CopyFrom(new byte[size]) };
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800502 }
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700503
504 // extracts the client_email field from service account file used for auth test cases
505 private static string GetEmailFromServiceAccountFile()
506 {
507 string keyFile = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS");
508 Assert.IsNotNull(keyFile);
509
510 var jobject = JObject.Parse(File.ReadAllText(keyFile));
511 string email = jobject.GetValue("client_email").Value<string>();
512 Assert.IsTrue(email.Length > 0); // spec requires nonempty client email.
513 return email;
514 }
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800515 }
516}