blob: 5eec11abf7f71b6a948f5dc29916bf06716c3f96 [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 Tattermuschbeffc772015-10-22 13:28:22 -0700140 var credentials = ChannelCredentials.Insecure;
141 if (options.UseTls.Value)
142 {
143 credentials = options.UseTestCa.Value ? TestCredentials.CreateSslCredentials() : new SslCredentials();
144 }
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700145
146 if (options.TestCase == "jwt_token_creds")
147 {
148 var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
149 Assert.IsTrue(googleCredential.IsCreateScopedRequired);
Jan Tattermusch18729a02015-10-08 18:40:00 -0700150 credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials());
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700151 }
152
153 if (options.TestCase == "compute_engine_creds")
154 {
155 var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
156 Assert.IsFalse(googleCredential.IsCreateScopedRequired);
Jan Tattermusch18729a02015-10-08 18:40:00 -0700157 credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials());
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700158 }
Jan Tattermusch9e5e7e92015-09-24 10:34:05 -0700159 return credentials;
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800160 }
161
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700162 private async Task RunTestCaseAsync(TestService.TestServiceClient client, ClientOptions options)
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800163 {
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700164 switch (options.TestCase)
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800165 {
166 case "empty_unary":
167 RunEmptyUnary(client);
168 break;
169 case "large_unary":
170 RunLargeUnary(client);
171 break;
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800172 case "client_streaming":
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700173 await RunClientStreamingAsync(client);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800174 break;
175 case "server_streaming":
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700176 await RunServerStreamingAsync(client);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800177 break;
178 case "ping_pong":
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700179 await RunPingPongAsync(client);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800180 break;
181 case "empty_stream":
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700182 await RunEmptyStreamAsync(client);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800183 break;
Jan Tattermusch0bbfa382015-04-27 16:11:59 -0700184 case "compute_engine_creds":
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700185 RunComputeEngineCreds(client, options.DefaultServiceAccount, options.OAuthScope);
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700186 break;
187 case "jwt_token_creds":
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700188 RunJwtTokenCreds(client);
Jan Tattermusch0bbfa382015-04-27 16:11:59 -0700189 break;
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700190 case "oauth2_auth_token":
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700191 await RunOAuth2AuthTokenAsync(client, options.OAuthScope);
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700192 break;
193 case "per_rpc_creds":
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700194 await RunPerRpcCredsAsync(client, options.OAuthScope);
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700195 break;
Jan Tattermusche5c44602015-05-01 11:12:34 -0700196 case "cancel_after_begin":
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700197 await RunCancelAfterBeginAsync(client);
Jan Tattermusche5c44602015-05-01 11:12:34 -0700198 break;
199 case "cancel_after_first_response":
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700200 await RunCancelAfterFirstResponseAsync(client);
Jan Tattermusche5c44602015-05-01 11:12:34 -0700201 break;
Jan Tattermusche4134dd2015-08-12 14:54:40 -0700202 case "timeout_on_sleeping_server":
203 await RunTimeoutOnSleepingServerAsync(client);
204 break;
Jan Tattermusch50faa8f2015-02-21 17:51:52 -0800205 case "benchmark_empty_unary":
206 RunBenchmarkEmptyUnary(client);
207 break;
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800208 default:
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700209 throw new ArgumentException("Unknown test case " + options.TestCase);
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800210 }
211 }
212
Jan Tattermusch7eb3a762015-05-07 14:26:13 -0700213 public static void RunEmptyUnary(TestService.ITestServiceClient client)
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800214 {
215 Console.WriteLine("running empty_unary");
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700216 var response = client.EmptyCall(new Empty());
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800217 Assert.IsNotNull(response);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800218 Console.WriteLine("Passed!");
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800219 }
220
Jan Tattermusch7eb3a762015-05-07 14:26:13 -0700221 public static void RunLargeUnary(TestService.ITestServiceClient client)
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800222 {
223 Console.WriteLine("running large_unary");
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700224 var request = new SimpleRequest
225 {
226 ResponseType = PayloadType.COMPRESSABLE,
227 ResponseSize = 314159,
228 Payload = CreateZerosPayload(271828)
229 };
Craig Tiller190d3602015-02-18 09:23:38 -0800230
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800231 var response = client.UnaryCall(request);
232
233 Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
234 Assert.AreEqual(314159, response.Payload.Body.Length);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800235 Console.WriteLine("Passed!");
236 }
237
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700238 public static async Task RunClientStreamingAsync(TestService.ITestServiceClient client)
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800239 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700240 Console.WriteLine("running client_streaming");
241
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700242 var bodySizes = new List<int> { 27182, 8, 1828, 45904 }.ConvertAll((size) => new StreamingInputCallRequest { Payload = CreateZerosPayload(size) });
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700243
244 using (var call = client.StreamingInputCall())
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800245 {
Jan Tattermuschf22abfb2015-08-09 16:15:34 -0700246 await call.RequestStream.WriteAllAsync(bodySizes);
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800247
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700248 var response = await call.ResponseAsync;
249 Assert.AreEqual(74922, response.AggregatedPayloadSize);
250 }
251 Console.WriteLine("Passed!");
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800252 }
253
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700254 public static async Task RunServerStreamingAsync(TestService.ITestServiceClient client)
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800255 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700256 Console.WriteLine("running server_streaming");
257
258 var bodySizes = new List<int> { 31415, 9, 2653, 58979 };
259
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700260 var request = new StreamingOutputCallRequest
261 {
262 ResponseType = PayloadType.COMPRESSABLE,
263 ResponseParameters = { bodySizes.ConvertAll((size) => new ResponseParameters { Size = size }) }
264 };
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700265
266 using (var call = client.StreamingOutputCall(request))
Jan Tattermuscha5272b62015-04-30 11:56:46 -0700267 {
Jan Tattermuschf22abfb2015-08-09 16:15:34 -0700268 var responseList = await call.ResponseStream.ToListAsync();
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700269 foreach (var res in responseList)
270 {
271 Assert.AreEqual(PayloadType.COMPRESSABLE, res.Payload.Type);
272 }
273 CollectionAssert.AreEqual(bodySizes, responseList.ConvertAll((item) => item.Payload.Body.Length));
274 }
275 Console.WriteLine("Passed!");
276 }
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800277
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700278 public static async Task RunPingPongAsync(TestService.ITestServiceClient client)
279 {
280 Console.WriteLine("running ping_pong");
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800281
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700282 using (var call = client.FullDuplexCall())
283 {
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700284 await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
285 {
286 ResponseType = PayloadType.COMPRESSABLE,
287 ResponseParameters = { new ResponseParameters { Size = 31415 } },
288 Payload = CreateZerosPayload(27182)
289 });
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800290
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700291 Assert.IsTrue(await call.ResponseStream.MoveNext());
292 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
293 Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
294
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700295 await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
296 {
297 ResponseType = PayloadType.COMPRESSABLE,
298 ResponseParameters = { new ResponseParameters { Size = 9 } },
299 Payload = CreateZerosPayload(8)
300 });
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700301
302 Assert.IsTrue(await call.ResponseStream.MoveNext());
303 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
304 Assert.AreEqual(9, call.ResponseStream.Current.Payload.Body.Length);
305
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700306 await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
307 {
308 ResponseType = PayloadType.COMPRESSABLE,
309 ResponseParameters = { new ResponseParameters { Size = 2653 } },
310 Payload = CreateZerosPayload(1828)
311 });
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700312
313 Assert.IsTrue(await call.ResponseStream.MoveNext());
314 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
315 Assert.AreEqual(2653, call.ResponseStream.Current.Payload.Body.Length);
316
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700317 await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
318 {
319 ResponseType = PayloadType.COMPRESSABLE,
320 ResponseParameters = { new ResponseParameters { Size = 58979 } },
321 Payload = CreateZerosPayload(45904)
322 });
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700323
324 Assert.IsTrue(await call.ResponseStream.MoveNext());
325 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
326 Assert.AreEqual(58979, call.ResponseStream.Current.Payload.Body.Length);
327
328 await call.RequestStream.CompleteAsync();
329
330 Assert.IsFalse(await call.ResponseStream.MoveNext());
331 }
332 Console.WriteLine("Passed!");
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800333 }
334
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700335 public static async Task RunEmptyStreamAsync(TestService.ITestServiceClient client)
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800336 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700337 Console.WriteLine("running empty_stream");
338 using (var call = client.FullDuplexCall())
Jan Tattermuscha5272b62015-04-30 11:56:46 -0700339 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700340 await call.RequestStream.CompleteAsync();
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800341
Jan Tattermuschf22abfb2015-08-09 16:15:34 -0700342 var responseList = await call.ResponseStream.ToListAsync();
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700343 Assert.AreEqual(0, responseList.Count);
344 }
345 Console.WriteLine("Passed!");
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800346 }
347
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700348 public static void RunComputeEngineCreds(TestService.TestServiceClient client, string defaultServiceAccount, string oauthScope)
Jan Tattermusch0bbfa382015-04-27 16:11:59 -0700349 {
350 Console.WriteLine("running compute_engine_creds");
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700351
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700352 var request = new SimpleRequest
353 {
354 ResponseType = PayloadType.COMPRESSABLE,
355 ResponseSize = 314159,
356 Payload = CreateZerosPayload(271828),
357 FillUsername = true,
358 FillOauthScope = true
359 };
Jan Tattermusch0bbfa382015-04-27 16:11:59 -0700360
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700361 // not setting credentials here because they were set on channel already
Jan Tattermusch0bbfa382015-04-27 16:11:59 -0700362 var response = client.UnaryCall(request);
363
364 Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
365 Assert.AreEqual(314159, response.Payload.Body.Length);
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700366 Assert.False(string.IsNullOrEmpty(response.OauthScope));
367 Assert.True(oauthScope.Contains(response.OauthScope));
368 Assert.AreEqual(defaultServiceAccount, response.Username);
Jan Tattermusch0bbfa382015-04-27 16:11:59 -0700369 Console.WriteLine("Passed!");
370 }
371
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700372 public static void RunJwtTokenCreds(TestService.TestServiceClient client)
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700373 {
374 Console.WriteLine("running jwt_token_creds");
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700375
Jan Tattermusch46e85b02015-08-13 10:31:05 -0700376 var request = new SimpleRequest
377 {
378 ResponseType = PayloadType.COMPRESSABLE,
379 ResponseSize = 314159,
380 Payload = CreateZerosPayload(271828),
381 FillUsername = true,
Jan Tattermusch46e85b02015-08-13 10:31:05 -0700382 };
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700383
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700384 // not setting credentials here because they were set on channel already
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700385 var response = client.UnaryCall(request);
386
387 Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
388 Assert.AreEqual(314159, response.Payload.Body.Length);
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700389 Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700390 Console.WriteLine("Passed!");
391 }
392
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700393 public static async Task RunOAuth2AuthTokenAsync(TestService.TestServiceClient client, string oauthScope)
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700394 {
395 Console.WriteLine("running oauth2_auth_token");
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700396 ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { oauthScope });
Jan Tattermusch0c140a82015-08-02 00:54:02 -0700397 string oauth2Token = await credential.GetAccessTokenForRequestAsync();
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700398
Jan Tattermusch18729a02015-10-08 18:40:00 -0700399 var credentials = GoogleGrpcCredentials.FromAccessToken(oauth2Token);
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700400 var request = new SimpleRequest
401 {
402 FillUsername = true,
403 FillOauthScope = true
404 };
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700405
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700406 var response = client.UnaryCall(request, new CallOptions(credentials: credentials));
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700407
Jan Tattermuschb26972f2015-09-03 17:47:14 -0700408 Assert.False(string.IsNullOrEmpty(response.OauthScope));
409 Assert.True(oauthScope.Contains(response.OauthScope));
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700410 Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700411 Console.WriteLine("Passed!");
412 }
413
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700414 public static async Task RunPerRpcCredsAsync(TestService.TestServiceClient client, string oauthScope)
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700415 {
416 Console.WriteLine("running per_rpc_creds");
Jan Tattermuschcf72a3a2015-10-08 08:44:20 -0700417 ITokenAccess googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700418
Jan Tattermusch18729a02015-10-08 18:40:00 -0700419 var credentials = googleCredential.ToCallCredentials();
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700420 var request = new SimpleRequest
421 {
422 FillUsername = true,
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700423 };
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700424
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700425 var response = client.UnaryCall(request, new CallOptions(credentials: credentials));
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700426
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700427 Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
Jan Tattermusch7b4a31f2015-07-20 17:08:13 -0700428 Console.WriteLine("Passed!");
429 }
430
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700431 public static async Task RunCancelAfterBeginAsync(TestService.ITestServiceClient client)
Jan Tattermusche5c44602015-05-01 11:12:34 -0700432 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700433 Console.WriteLine("running cancel_after_begin");
434
435 var cts = new CancellationTokenSource();
436 using (var call = client.StreamingInputCall(cancellationToken: cts.Token))
Jan Tattermusche5c44602015-05-01 11:12:34 -0700437 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700438 // TODO(jtattermusch): we need this to ensure call has been initiated once we cancel it.
439 await Task.Delay(1000);
440 cts.Cancel();
Jan Tattermusche5c44602015-05-01 11:12:34 -0700441
Jan Tattermuschc8d7b842015-08-07 20:52:21 -0700442 var ex = Assert.Throws<RpcException>(async () => await call.ResponseAsync);
443 Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700444 }
445 Console.WriteLine("Passed!");
Jan Tattermusche5c44602015-05-01 11:12:34 -0700446 }
447
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700448 public static async Task RunCancelAfterFirstResponseAsync(TestService.ITestServiceClient client)
Jan Tattermusche5c44602015-05-01 11:12:34 -0700449 {
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700450 Console.WriteLine("running cancel_after_first_response");
451
452 var cts = new CancellationTokenSource();
453 using (var call = client.FullDuplexCall(cancellationToken: cts.Token))
Jan Tattermusche5c44602015-05-01 11:12:34 -0700454 {
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700455 await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
456 {
457 ResponseType = PayloadType.COMPRESSABLE,
458 ResponseParameters = { new ResponseParameters { Size = 31415 } },
459 Payload = CreateZerosPayload(27182)
460 });
Jan Tattermusche5c44602015-05-01 11:12:34 -0700461
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700462 Assert.IsTrue(await call.ResponseStream.MoveNext());
463 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
464 Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
465
466 cts.Cancel();
467
Jan Tattermuschc8d7b842015-08-07 20:52:21 -0700468 var ex = Assert.Throws<RpcException>(async () => await call.ResponseStream.MoveNext());
469 Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
Jan Tattermuschb98e1dd2015-07-24 21:30:14 -0700470 }
471 Console.WriteLine("Passed!");
Jan Tattermusche5c44602015-05-01 11:12:34 -0700472 }
473
Jan Tattermusche4134dd2015-08-12 14:54:40 -0700474 public static async Task RunTimeoutOnSleepingServerAsync(TestService.ITestServiceClient client)
475 {
476 Console.WriteLine("running timeout_on_sleeping_server");
477
478 var deadline = DateTime.UtcNow.AddMilliseconds(1);
479 using (var call = client.FullDuplexCall(deadline: deadline))
480 {
481 try
482 {
Jan Tattermusch0608a002015-08-26 08:50:19 -0700483 await call.RequestStream.WriteAsync(new StreamingOutputCallRequest { Payload = CreateZerosPayload(27182) });
Jan Tattermusche4134dd2015-08-12 14:54:40 -0700484 }
485 catch (InvalidOperationException)
486 {
487 // Deadline was reached before write has started. Eat the exception and continue.
488 }
489
490 var ex = Assert.Throws<RpcException>(async () => await call.ResponseStream.MoveNext());
491 Assert.AreEqual(StatusCode.DeadlineExceeded, ex.Status.StatusCode);
492 }
493 Console.WriteLine("Passed!");
494 }
495
Jan Tattermusch50faa8f2015-02-21 17:51:52 -0800496 // This is not an official interop test, but it's useful.
Jan Tattermusch7eb3a762015-05-07 14:26:13 -0700497 public static void RunBenchmarkEmptyUnary(TestService.ITestServiceClient client)
Jan Tattermusch50faa8f2015-02-21 17:51:52 -0800498 {
499 BenchmarkUtil.RunBenchmark(10000, 10000,
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700500 () => { client.EmptyCall(new Empty()); });
Jan Tattermusch50faa8f2015-02-21 17:51:52 -0800501 }
Jan Tattermuschd233d3a2015-02-06 14:15:00 -0800502
Jan Tattermusch075dde42015-03-11 18:21:00 -0700503 private static Payload CreateZerosPayload(int size)
504 {
Jan Tattermusch8644aea2015-08-03 10:21:18 -0700505 return new Payload { Body = ByteString.CopyFrom(new byte[size]) };
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800506 }
Jan Tattermusch64d7c242015-10-08 08:02:27 -0700507
508 // extracts the client_email field from service account file used for auth test cases
509 private static string GetEmailFromServiceAccountFile()
510 {
511 string keyFile = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS");
512 Assert.IsNotNull(keyFile);
513
514 var jobject = JObject.Parse(File.ReadAllText(keyFile));
515 string email = jobject.GetValue("client_email").Value<string>();
516 Assert.IsTrue(email.Length > 0); // spec requires nonempty client email.
517 return email;
518 }
Jan Tattermuscheb3e76e2015-02-06 11:43:13 -0800519 }
520}