blob: 70a21e1724b49038269d7cd159c9efb629cc1a0a [file] [log] [blame]
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001// Licensed to the Apache Software Foundation(ASF) under one
2// or more contributor license agreements.See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18using System;
19using System.Collections.Generic;
20using System.Diagnostics;
21using System.IO;
22using System.Linq;
23using System.Net;
24using System.Reflection;
25using System.Security.Authentication;
26using System.Security.Cryptography.X509Certificates;
27using System.ServiceModel;
28using System.Text;
29using System.Threading;
30using System.Threading.Tasks;
Jens Geyereacd1d42019-11-20 19:03:14 +010031using Thrift;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010032using Thrift.Collections;
33using Thrift.Protocol;
34using Thrift.Transport;
35using Thrift.Transport.Client;
36
37namespace ThriftTest
38{
Jens Geyeradde44b2019-02-05 01:00:02 +010039 internal enum ProtocolChoice
40 {
41 Binary,
42 Compact,
43 Json
44 }
45
46 // it does not make much sense to use buffered when we already use framed
47 internal enum LayeredChoice
48 {
49 None,
50 Buffered,
51 Framed
52 }
53
Jens Geyeradde44b2019-02-05 01:00:02 +010054 internal enum TransportChoice
55 {
56 Socket,
57 TlsSocket,
Jens Geyer96c61132019-06-14 22:39:56 +020058 Http,
Jens Geyeradde44b2019-02-05 01:00:02 +010059 NamedPipe
60 }
61
Jens Geyeraa0c8b32019-01-28 23:27:45 +010062 public class TestClient
63 {
64 private class TestParams
65 {
66 public int numIterations = 1;
Jens Geyer22c412e2019-03-12 01:06:25 +010067 public string host = "localhost";
Jens Geyeraa0c8b32019-01-28 23:27:45 +010068 public int port = 9090;
69 public int numThreads = 1;
70 public string url;
71 public string pipe;
Jens Geyeradde44b2019-02-05 01:00:02 +010072 public LayeredChoice layered = LayeredChoice.None;
73 public ProtocolChoice protocol = ProtocolChoice.Binary;
74 public TransportChoice transport = TransportChoice.Socket;
Jens Geyereacd1d42019-11-20 19:03:14 +010075 private readonly TConfiguration Configuration = null; // or new TConfiguration() if needed
Jens Geyeraa0c8b32019-01-28 23:27:45 +010076
Jens Geyerbd1a2732019-06-26 22:52:44 +020077 internal void Parse(List<string> args)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010078 {
79 for (var i = 0; i < args.Count; ++i)
80 {
81 if (args[i] == "-u")
82 {
83 url = args[++i];
Jens Geyer96c61132019-06-14 22:39:56 +020084 transport = TransportChoice.Http;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010085 }
86 else if (args[i] == "-n")
87 {
88 numIterations = Convert.ToInt32(args[++i]);
89 }
90 else if (args[i].StartsWith("--pipe="))
91 {
92 pipe = args[i].Substring(args[i].IndexOf("=") + 1);
Jens Geyeradde44b2019-02-05 01:00:02 +010093 transport = TransportChoice.NamedPipe;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010094 }
95 else if (args[i].StartsWith("--host="))
96 {
97 // check there for ipaddress
Jens Geyer22c412e2019-03-12 01:06:25 +010098 host = args[i].Substring(args[i].IndexOf("=") + 1);
Jens Geyeradde44b2019-02-05 01:00:02 +010099 if (transport != TransportChoice.TlsSocket)
100 transport = TransportChoice.Socket;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100101 }
102 else if (args[i].StartsWith("--port="))
103 {
104 port = int.Parse(args[i].Substring(args[i].IndexOf("=") + 1));
Jens Geyeradde44b2019-02-05 01:00:02 +0100105 if (transport != TransportChoice.TlsSocket)
106 transport = TransportChoice.Socket;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100107 }
108 else if (args[i] == "-b" || args[i] == "--buffered" || args[i] == "--transport=buffered")
109 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100110 layered = LayeredChoice.Buffered;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100111 }
112 else if (args[i] == "-f" || args[i] == "--framed" || args[i] == "--transport=framed")
113 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100114 layered = LayeredChoice.Framed;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100115 }
116 else if (args[i] == "-t")
117 {
118 numThreads = Convert.ToInt32(args[++i]);
119 }
120 else if (args[i] == "--binary" || args[i] == "--protocol=binary")
121 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100122 protocol = ProtocolChoice.Binary;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100123 }
124 else if (args[i] == "--compact" || args[i] == "--protocol=compact")
125 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100126 protocol = ProtocolChoice.Compact;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100127 }
128 else if (args[i] == "--json" || args[i] == "--protocol=json")
129 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100130 protocol = ProtocolChoice.Json;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100131 }
132 else if (args[i] == "--ssl")
133 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100134 transport = TransportChoice.TlsSocket;
135 }
136 else if (args[i] == "--help")
137 {
138 PrintOptionsHelp();
139 return;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100140 }
141 else
142 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100143 Console.WriteLine("Invalid argument: {0}", args[i]);
144 PrintOptionsHelp();
145 return;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100146 }
147 }
Jens Geyeradde44b2019-02-05 01:00:02 +0100148
149 switch (transport)
150 {
151 case TransportChoice.Socket:
152 Console.WriteLine("Using socket transport");
153 break;
154 case TransportChoice.TlsSocket:
155 Console.WriteLine("Using encrypted transport");
156 break;
Jens Geyer96c61132019-06-14 22:39:56 +0200157 case TransportChoice.Http:
158 Console.WriteLine("Using HTTP transport");
159 break;
Jens Geyeradde44b2019-02-05 01:00:02 +0100160 case TransportChoice.NamedPipe:
161 Console.WriteLine("Using named pipes transport");
162 break;
163 default: // unhandled case
164 Debug.Assert(false);
165 break;
166 }
167
168 switch (layered)
169 {
170 case LayeredChoice.Framed:
171 Console.WriteLine("Using framed transport");
172 break;
173 case LayeredChoice.Buffered:
174 Console.WriteLine("Using buffered transport");
175 break;
176 default: // unhandled case?
177 Debug.Assert(layered == LayeredChoice.None);
178 break;
179 }
180
181 switch (protocol)
182 {
183 case ProtocolChoice.Binary:
184 Console.WriteLine("Using binary protocol");
185 break;
186 case ProtocolChoice.Compact:
187 Console.WriteLine("Using compact protocol");
188 break;
189 case ProtocolChoice.Json:
190 Console.WriteLine("Using JSON protocol");
191 break;
192 default: // unhandled case?
193 Debug.Assert(false);
194 break;
195 }
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100196 }
197
198 private static X509Certificate2 GetClientCert()
199 {
200 var clientCertName = "client.p12";
201 var possiblePaths = new List<string>
202 {
203 "../../../keys/",
204 "../../keys/",
205 "../keys/",
206 "keys/",
207 };
208
209 string existingPath = null;
210 foreach (var possiblePath in possiblePaths)
211 {
212 var path = Path.GetFullPath(possiblePath + clientCertName);
213 if (File.Exists(path))
214 {
215 existingPath = path;
216 break;
217 }
218 }
219
220 if (string.IsNullOrEmpty(existingPath))
221 {
222 throw new FileNotFoundException($"Cannot find file: {clientCertName}");
223 }
Jens Geyerbd1a2732019-06-26 22:52:44 +0200224
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100225 var cert = new X509Certificate2(existingPath, "thrift");
226
227 return cert;
228 }
Jens Geyerbd1a2732019-06-26 22:52:44 +0200229
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100230 public TTransport CreateTransport()
231 {
Jens Geyer96c61132019-06-14 22:39:56 +0200232 // endpoint transport
233 TTransport trans = null;
234
Jens Geyerbd1a2732019-06-26 22:52:44 +0200235 switch (transport)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100236 {
Jens Geyer96c61132019-06-14 22:39:56 +0200237 case TransportChoice.Http:
238 Debug.Assert(url != null);
Jens Geyereacd1d42019-11-20 19:03:14 +0100239 trans = new THttpTransport(new Uri(url), Configuration);
Jens Geyer96c61132019-06-14 22:39:56 +0200240 break;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100241
Jens Geyer96c61132019-06-14 22:39:56 +0200242 case TransportChoice.NamedPipe:
243 Debug.Assert(pipe != null);
Jens Geyereacd1d42019-11-20 19:03:14 +0100244 trans = new TNamedPipeTransport(pipe,Configuration);
Jens Geyer96c61132019-06-14 22:39:56 +0200245 break;
Jens Geyeradde44b2019-02-05 01:00:02 +0100246
Jens Geyer96c61132019-06-14 22:39:56 +0200247 case TransportChoice.TlsSocket:
248 var cert = GetClientCert();
249 if (cert == null || !cert.HasPrivateKey)
250 {
251 throw new InvalidOperationException("Certificate doesn't contain private key");
252 }
Jens Geyerbd1a2732019-06-26 22:52:44 +0200253
Jens Geyereacd1d42019-11-20 19:03:14 +0100254 trans = new TTlsSocketTransport(host, port, Configuration, 0,
255 cert,
Jens Geyer96c61132019-06-14 22:39:56 +0200256 (sender, certificate, chain, errors) => true,
257 null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12);
258 break;
Jens Geyeradde44b2019-02-05 01:00:02 +0100259
Jens Geyer96c61132019-06-14 22:39:56 +0200260 case TransportChoice.Socket:
261 default:
Jens Geyereacd1d42019-11-20 19:03:14 +0100262 trans = new TSocketTransport(host, port, Configuration);
Jens Geyer96c61132019-06-14 22:39:56 +0200263 break;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100264 }
265
Jens Geyer96c61132019-06-14 22:39:56 +0200266
267 // layered transport
Jens Geyerbd1a2732019-06-26 22:52:44 +0200268 switch (layered)
Jens Geyer96c61132019-06-14 22:39:56 +0200269 {
270 case LayeredChoice.Buffered:
271 trans = new TBufferedTransport(trans);
272 break;
273 case LayeredChoice.Framed:
274 trans = new TFramedTransport(trans);
275 break;
276 default:
277 Debug.Assert(layered == LayeredChoice.None);
278 break;
279 }
280
281 return trans;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100282 }
283
284 public TProtocol CreateProtocol(TTransport transport)
285 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100286 switch (protocol)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100287 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100288 case ProtocolChoice.Compact:
289 return new TCompactProtocol(transport);
290 case ProtocolChoice.Json:
291 return new TJsonProtocol(transport);
292 case ProtocolChoice.Binary:
293 default:
294 return new TBinaryProtocol(transport);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100295 }
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100296 }
297 }
298
299
300 private const int ErrorBaseTypes = 1;
301 private const int ErrorStructs = 2;
302 private const int ErrorContainers = 4;
303 private const int ErrorExceptions = 8;
304 private const int ErrorUnknown = 64;
305
306 private class ClientTest
307 {
308 private readonly TTransport transport;
309 private readonly ThriftTest.Client client;
310 private readonly int numIterations;
311 private bool done;
312
313 public int ReturnCode { get; set; }
314
315 public ClientTest(TestParams param)
316 {
317 transport = param.CreateTransport();
318 client = new ThriftTest.Client(param.CreateProtocol(transport));
319 numIterations = param.numIterations;
320 }
321
322 public void Execute()
323 {
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100324 if (done)
325 {
326 Console.WriteLine("Execute called more than once");
327 throw new InvalidOperationException();
328 }
329
330 for (var i = 0; i < numIterations; i++)
331 {
332 try
333 {
334 if (!transport.IsOpen)
Jens Geyer1b770f22019-03-12 01:19:43 +0100335 transport.OpenAsync(MakeTimeoutToken()).GetAwaiter().GetResult();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100336 }
337 catch (TTransportException ex)
338 {
339 Console.WriteLine("*** FAILED ***");
340 Console.WriteLine("Connect failed: " + ex.Message);
341 ReturnCode |= ErrorUnknown;
Mario Emmenlauer47e49232020-04-07 18:43:46 +0200342 Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100343 continue;
344 }
345 catch (Exception ex)
346 {
347 Console.WriteLine("*** FAILED ***");
348 Console.WriteLine("Connect failed: " + ex.Message);
349 ReturnCode |= ErrorUnknown;
Mario Emmenlauer47e49232020-04-07 18:43:46 +0200350 Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100351 continue;
352 }
353
354 try
355 {
Jens Geyer2b2ea622021-04-09 22:55:11 +0200356 ReturnCode |= ExecuteClientTest(client).GetAwaiter().GetResult(); ;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100357 }
358 catch (Exception ex)
359 {
360 Console.WriteLine("*** FAILED ***");
Mario Emmenlauer47e49232020-04-07 18:43:46 +0200361 Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100362 ReturnCode |= ErrorUnknown;
363 }
364 }
365 try
366 {
367 transport.Close();
368 }
369 catch (Exception ex)
370 {
371 Console.WriteLine("Error while closing transport");
Mario Emmenlauer47e49232020-04-07 18:43:46 +0200372 Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100373 }
374 done = true;
375 }
376 }
377
378 internal static void PrintOptionsHelp()
379 {
380 Console.WriteLine("Client options:");
381 Console.WriteLine(" -u <URL>");
382 Console.WriteLine(" -t <# of threads to run> default = 1");
383 Console.WriteLine(" -n <# of iterations> per thread");
384 Console.WriteLine(" --pipe=<pipe name>");
385 Console.WriteLine(" --host=<IP address>");
386 Console.WriteLine(" --port=<port number>");
387 Console.WriteLine(" --transport=<transport name> one of buffered,framed (defaults to none)");
388 Console.WriteLine(" --protocol=<protocol name> one of compact,json (defaults to binary)");
389 Console.WriteLine(" --ssl");
390 Console.WriteLine();
391 }
392
393 public static int Execute(List<string> args)
394 {
395 try
396 {
397 var param = new TestParams();
398
399 try
400 {
401 param.Parse(args);
402 }
403 catch (Exception ex)
404 {
405 Console.WriteLine("*** FAILED ***");
Mario Emmenlauer47e49232020-04-07 18:43:46 +0200406 Console.WriteLine("Error while parsing arguments");
407 Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100408 return ErrorUnknown;
409 }
410
411 var tests = Enumerable.Range(0, param.numThreads).Select(_ => new ClientTest(param)).ToArray();
412
413 //issue tests on separate threads simultaneously
414 var threads = tests.Select(test => new Task(test.Execute)).ToArray();
415 var start = DateTime.Now;
416 foreach (var t in threads)
417 {
418 t.Start();
419 }
420
421 Task.WaitAll(threads);
422
423 Console.WriteLine("Total time: " + (DateTime.Now - start));
424 Console.WriteLine();
425 return tests.Select(t => t.ReturnCode).Aggregate((r1, r2) => r1 | r2);
426 }
427 catch (Exception outerEx)
428 {
429 Console.WriteLine("*** FAILED ***");
430 Console.WriteLine("Unexpected error");
Mario Emmenlauer47e49232020-04-07 18:43:46 +0200431 Console.WriteLine(outerEx.Message + "\n" + outerEx.StackTrace);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100432 return ErrorUnknown;
433 }
434 }
435
436 public static string BytesToHex(byte[] data)
437 {
438 return BitConverter.ToString(data).Replace("-", string.Empty);
439 }
440
Jens Geyerbd1a2732019-06-26 22:52:44 +0200441
442 public enum BinaryTestSize
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100443 {
Jens Geyerbd1a2732019-06-26 22:52:44 +0200444 Empty, // Edge case: the zero-length empty binary
445 Normal, // Fairly small array of usual size (256 bytes)
446 Large, // Large writes/reads may cause range check errors
447 PipeWriteLimit, // Windows Limit: Pipe write operations across a network are limited to 65,535 bytes per write.
Jens Geyer50806452019-11-23 01:55:58 +0100448 FifteenMB // that's quite a bit of data
Jens Geyerbd1a2732019-06-26 22:52:44 +0200449 };
450
451 public static byte[] PrepareTestData(bool randomDist, BinaryTestSize testcase)
452 {
Jens Geyer261cad32019-11-20 19:03:14 +0100453 int amount;
Jens Geyerbd1a2732019-06-26 22:52:44 +0200454 switch (testcase)
455 {
456 case BinaryTestSize.Empty:
457 amount = 0;
458 break;
459 case BinaryTestSize.Normal:
460 amount = 0x100;
461 break;
462 case BinaryTestSize.Large:
463 amount = 0x8000 + 128;
464 break;
465 case BinaryTestSize.PipeWriteLimit:
466 amount = 0xFFFF + 128;
467 break;
Jens Geyer50806452019-11-23 01:55:58 +0100468 case BinaryTestSize.FifteenMB:
469 amount = 15 * 1024 * 1024;
Jens Geyerbd1a2732019-06-26 22:52:44 +0200470 break;
471 default:
Jens Geyer2b2ea622021-04-09 22:55:11 +0200472 throw new ArgumentException("invalid argument",nameof(testcase));
Jens Geyerbd1a2732019-06-26 22:52:44 +0200473 }
474
475 var retval = new byte[amount];
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100476
477 // linear distribution, unless random is requested
478 if (!randomDist)
479 {
Jens Geyerbd1a2732019-06-26 22:52:44 +0200480 for (var i = 0; i < retval.Length; ++i)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100481 {
482 retval[i] = (byte)i;
483 }
484 return retval;
485 }
486
487 // random distribution
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100488 var rnd = new Random();
Jens Geyerbd1a2732019-06-26 22:52:44 +0200489 for (var i = 1; i < retval.Length; ++i)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100490 {
Jens Geyerbd1a2732019-06-26 22:52:44 +0200491 retval[i] = (byte)rnd.Next(0x100);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100492 }
493 return retval;
494 }
495
Jens Geyer1b770f22019-03-12 01:19:43 +0100496 private static CancellationToken MakeTimeoutToken(int msec = 5000)
497 {
498 var token = new CancellationTokenSource(msec);
499 return token.Token;
500 }
501
Jens Geyer2b2ea622021-04-09 22:55:11 +0200502 public static async Task<int> ExecuteClientTest(ThriftTest.Client client)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100503 {
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100504 var returnCode = 0;
505
506 Console.Write("testVoid()");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200507 await client.testVoid(MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100508 Console.WriteLine(" = void");
509
510 Console.Write("testString(\"Test\")");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200511 var s = await client.testString("Test", MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100512 Console.WriteLine(" = \"" + s + "\"");
513 if ("Test" != s)
514 {
515 Console.WriteLine("*** FAILED ***");
516 returnCode |= ErrorBaseTypes;
517 }
518
519 Console.Write("testBool(true)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200520 var t = await client.testBool((bool)true, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100521 Console.WriteLine(" = " + t);
522 if (!t)
523 {
524 Console.WriteLine("*** FAILED ***");
525 returnCode |= ErrorBaseTypes;
526 }
527 Console.Write("testBool(false)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200528 var f = await client.testBool((bool)false, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100529 Console.WriteLine(" = " + f);
530 if (f)
531 {
532 Console.WriteLine("*** FAILED ***");
533 returnCode |= ErrorBaseTypes;
534 }
535
536 Console.Write("testByte(1)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200537 var i8 = await client.testByte((sbyte)1, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100538 Console.WriteLine(" = " + i8);
539 if (1 != i8)
540 {
541 Console.WriteLine("*** FAILED ***");
542 returnCode |= ErrorBaseTypes;
543 }
544
545 Console.Write("testI32(-1)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200546 var i32 = await client.testI32(-1, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100547 Console.WriteLine(" = " + i32);
548 if (-1 != i32)
549 {
550 Console.WriteLine("*** FAILED ***");
551 returnCode |= ErrorBaseTypes;
552 }
553
554 Console.Write("testI64(-34359738368)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200555 var i64 = await client.testI64(-34359738368, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100556 Console.WriteLine(" = " + i64);
557 if (-34359738368 != i64)
558 {
559 Console.WriteLine("*** FAILED ***");
560 returnCode |= ErrorBaseTypes;
561 }
562
563 // TODO: Validate received message
564 Console.Write("testDouble(5.325098235)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200565 var dub = await client.testDouble(5.325098235, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100566 Console.WriteLine(" = " + dub);
567 if (5.325098235 != dub)
568 {
569 Console.WriteLine("*** FAILED ***");
570 returnCode |= ErrorBaseTypes;
571 }
572 Console.Write("testDouble(-0.000341012439638598279)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200573 dub = await client.testDouble(-0.000341012439638598279, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100574 Console.WriteLine(" = " + dub);
575 if (-0.000341012439638598279 != dub)
576 {
577 Console.WriteLine("*** FAILED ***");
578 returnCode |= ErrorBaseTypes;
579 }
580
Jens Geyerbd1a2732019-06-26 22:52:44 +0200581 // testBinary()
582 foreach(BinaryTestSize binTestCase in Enum.GetValues(typeof(BinaryTestSize)))
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100583 {
Jens Geyerbd1a2732019-06-26 22:52:44 +0200584 var binOut = PrepareTestData(true, binTestCase);
585
586 Console.Write("testBinary({0} bytes)", binOut.Length);
587 try
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100588 {
Jens Geyer2b2ea622021-04-09 22:55:11 +0200589 var binIn = await client.testBinary(binOut, MakeTimeoutToken());
Jens Geyerbd1a2732019-06-26 22:52:44 +0200590 Console.WriteLine(" = {0} bytes", binIn.Length);
591 if (binIn.Length != binOut.Length)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100592 {
593 Console.WriteLine("*** FAILED ***");
594 returnCode |= ErrorBaseTypes;
595 }
Jens Geyerbd1a2732019-06-26 22:52:44 +0200596 for (var ofs = 0; ofs < Math.Min(binIn.Length, binOut.Length); ++ofs)
597 {
598 if (binIn[ofs] != binOut[ofs])
599 {
600 Console.WriteLine("*** FAILED ***");
601 returnCode |= ErrorBaseTypes;
602 }
603 }
604 }
605 catch (Thrift.TApplicationException ex)
606 {
607 Console.WriteLine("*** FAILED ***");
608 returnCode |= ErrorBaseTypes;
Mario Emmenlauer47e49232020-04-07 18:43:46 +0200609 Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Jens Geyerbd1a2732019-06-26 22:52:44 +0200610 }
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100611 }
612
Mario Emmenlauer47e49232020-04-07 18:43:46 +0200613 // CrazyNesting
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100614 Console.WriteLine("Test CrazyNesting");
615 var one = new CrazyNesting();
616 var two = new CrazyNesting();
617 one.String_field = "crazy";
618 two.String_field = "crazy";
619 one.Binary_field = new byte[] { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF };
620 two.Binary_field = new byte[10] { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF };
621 if (typeof(CrazyNesting).GetMethod("Equals")?.DeclaringType == typeof(CrazyNesting))
622 {
623 if (!one.Equals(two))
624 {
625 Console.WriteLine("*** FAILED ***");
626 returnCode |= ErrorContainers;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100627 }
628 }
629
630 // TODO: Validate received message
631 Console.Write("testStruct({\"Zero\", 1, -3, -5})");
Jens Geyer261cad32019-11-20 19:03:14 +0100632 var o = new Xtruct
633 {
634 String_thing = "Zero",
635 Byte_thing = (sbyte)1,
636 I32_thing = -3,
637 I64_thing = -5
638 };
Jens Geyer2b2ea622021-04-09 22:55:11 +0200639 var i = await client.testStruct(o, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100640 Console.WriteLine(" = {\"" + i.String_thing + "\", " + i.Byte_thing + ", " + i.I32_thing + ", " + i.I64_thing + "}");
641
642 // TODO: Validate received message
643 Console.Write("testNest({1, {\"Zero\", 1, -3, -5}, 5})");
Jens Geyer261cad32019-11-20 19:03:14 +0100644 var o2 = new Xtruct2
645 {
646 Byte_thing = (sbyte)1,
647 Struct_thing = o,
648 I32_thing = 5
649 };
Jens Geyer2b2ea622021-04-09 22:55:11 +0200650 var i2 = await client.testNest(o2, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100651 i = i2.Struct_thing;
652 Console.WriteLine(" = {" + i2.Byte_thing + ", {\"" + i.String_thing + "\", " + i.Byte_thing + ", " + i.I32_thing + ", " + i.I64_thing + "}, " + i2.I32_thing + "}");
653
654 var mapout = new Dictionary<int, int>();
655 for (var j = 0; j < 5; j++)
656 {
657 mapout[j] = j - 10;
658 }
659 Console.Write("testMap({");
660 var first = true;
661 foreach (var key in mapout.Keys)
662 {
663 if (first)
664 {
665 first = false;
666 }
667 else
668 {
669 Console.Write(", ");
670 }
671 Console.Write(key + " => " + mapout[key]);
672 }
673 Console.Write("})");
674
Jens Geyer2b2ea622021-04-09 22:55:11 +0200675 var mapin = await client.testMap(mapout, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100676
677 Console.Write(" = {");
678 first = true;
679 foreach (var key in mapin.Keys)
680 {
681 if (first)
682 {
683 first = false;
684 }
685 else
686 {
687 Console.Write(", ");
688 }
689 Console.Write(key + " => " + mapin[key]);
690 }
691 Console.WriteLine("}");
692
693 // TODO: Validate received message
694 var listout = new List<int>();
695 for (var j = -2; j < 3; j++)
696 {
697 listout.Add(j);
698 }
699 Console.Write("testList({");
700 first = true;
701 foreach (var j in listout)
702 {
703 if (first)
704 {
705 first = false;
706 }
707 else
708 {
709 Console.Write(", ");
710 }
711 Console.Write(j);
712 }
713 Console.Write("})");
714
Jens Geyer2b2ea622021-04-09 22:55:11 +0200715 var listin = await client.testList(listout, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100716
717 Console.Write(" = {");
718 first = true;
719 foreach (var j in listin)
720 {
721 if (first)
722 {
723 first = false;
724 }
725 else
726 {
727 Console.Write(", ");
728 }
729 Console.Write(j);
730 }
731 Console.WriteLine("}");
732
733 //set
734 // TODO: Validate received message
735 var setout = new THashSet<int>();
736 for (var j = -2; j < 3; j++)
737 {
738 setout.Add(j);
739 }
740 Console.Write("testSet({");
741 first = true;
742 foreach (int j in setout)
743 {
744 if (first)
745 {
746 first = false;
747 }
748 else
749 {
750 Console.Write(", ");
751 }
752 Console.Write(j);
753 }
754 Console.Write("})");
755
Jens Geyer2b2ea622021-04-09 22:55:11 +0200756 var setin = await client.testSet(setout, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100757
758 Console.Write(" = {");
759 first = true;
760 foreach (int j in setin)
761 {
762 if (first)
763 {
764 first = false;
765 }
766 else
767 {
768 Console.Write(", ");
769 }
770 Console.Write(j);
771 }
772 Console.WriteLine("}");
773
774
775 Console.Write("testEnum(ONE)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200776 var ret = await client.testEnum(Numberz.ONE, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100777 Console.WriteLine(" = " + ret);
778 if (Numberz.ONE != ret)
779 {
780 Console.WriteLine("*** FAILED ***");
781 returnCode |= ErrorStructs;
782 }
783
784 Console.Write("testEnum(TWO)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200785 ret = await client.testEnum(Numberz.TWO, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100786 Console.WriteLine(" = " + ret);
787 if (Numberz.TWO != ret)
788 {
789 Console.WriteLine("*** FAILED ***");
790 returnCode |= ErrorStructs;
791 }
792
793 Console.Write("testEnum(THREE)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200794 ret = await client.testEnum(Numberz.THREE, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100795 Console.WriteLine(" = " + ret);
796 if (Numberz.THREE != ret)
797 {
798 Console.WriteLine("*** FAILED ***");
799 returnCode |= ErrorStructs;
800 }
801
802 Console.Write("testEnum(FIVE)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200803 ret = await client.testEnum(Numberz.FIVE, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100804 Console.WriteLine(" = " + ret);
805 if (Numberz.FIVE != ret)
806 {
807 Console.WriteLine("*** FAILED ***");
808 returnCode |= ErrorStructs;
809 }
810
811 Console.Write("testEnum(EIGHT)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200812 ret = await client.testEnum(Numberz.EIGHT, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100813 Console.WriteLine(" = " + ret);
814 if (Numberz.EIGHT != ret)
815 {
816 Console.WriteLine("*** FAILED ***");
817 returnCode |= ErrorStructs;
818 }
819
820 Console.Write("testTypedef(309858235082523)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200821 var uid = await client.testTypedef(309858235082523L, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100822 Console.WriteLine(" = " + uid);
823 if (309858235082523L != uid)
824 {
825 Console.WriteLine("*** FAILED ***");
826 returnCode |= ErrorStructs;
827 }
828
829 // TODO: Validate received message
830 Console.Write("testMapMap(1)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200831 var mm = await client.testMapMap(1, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100832 Console.Write(" = {");
833 foreach (var key in mm.Keys)
834 {
835 Console.Write(key + " => {");
836 var m2 = mm[key];
837 foreach (var k2 in m2.Keys)
838 {
839 Console.Write(k2 + " => " + m2[k2] + ", ");
840 }
841 Console.Write("}, ");
842 }
843 Console.WriteLine("}");
844
845 // TODO: Validate received message
Jens Geyer261cad32019-11-20 19:03:14 +0100846 var insane = new Insanity
847 {
848 UserMap = new Dictionary<Numberz, long>
849 {
850 [Numberz.FIVE] = 5000L
851 }
852 };
853 var truck = new Xtruct
854 {
855 String_thing = "Truck",
856 Byte_thing = (sbyte)8,
857 I32_thing = 8,
858 I64_thing = 8
859 };
860 insane.Xtructs = new List<Xtruct>
861 {
862 truck
863 };
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100864 Console.Write("testInsanity()");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200865 var whoa = await client.testInsanity(insane, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100866 Console.Write(" = {");
867 foreach (var key in whoa.Keys)
868 {
869 var val = whoa[key];
870 Console.Write(key + " => {");
871
872 foreach (var k2 in val.Keys)
873 {
874 var v2 = val[k2];
875
876 Console.Write(k2 + " => {");
877 var userMap = v2.UserMap;
878
879 Console.Write("{");
880 if (userMap != null)
881 {
882 foreach (var k3 in userMap.Keys)
883 {
884 Console.Write(k3 + " => " + userMap[k3] + ", ");
885 }
886 }
887 else
888 {
889 Console.Write("null");
890 }
891 Console.Write("}, ");
892
893 var xtructs = v2.Xtructs;
894
895 Console.Write("{");
896 if (xtructs != null)
897 {
898 foreach (var x in xtructs)
899 {
900 Console.Write("{\"" + x.String_thing + "\", " + x.Byte_thing + ", " + x.I32_thing + ", " + x.I32_thing + "}, ");
901 }
902 }
903 else
904 {
905 Console.Write("null");
906 }
907 Console.Write("}");
908
909 Console.Write("}, ");
910 }
911 Console.Write("}, ");
912 }
913 Console.WriteLine("}");
914
915 sbyte arg0 = 1;
916 var arg1 = 2;
917 var arg2 = long.MaxValue;
Jens Geyer261cad32019-11-20 19:03:14 +0100918 var multiDict = new Dictionary<short, string>
919 {
920 [1] = "one"
921 };
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100922
923 var tmpMultiDict = new List<string>();
924 foreach (var pair in multiDict)
925 tmpMultiDict.Add(pair.Key +" => "+ pair.Value);
926
927 var arg4 = Numberz.FIVE;
928 long arg5 = 5000000;
929 Console.Write("Test Multi(" + arg0 + "," + arg1 + "," + arg2 + ",{" + string.Join(",", tmpMultiDict) + "}," + arg4 + "," + arg5 + ")");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200930 var multiResponse = await client.testMulti(arg0, arg1, arg2, multiDict, arg4, arg5, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100931 Console.Write(" = Xtruct(byte_thing:" + multiResponse.Byte_thing + ",String_thing:" + multiResponse.String_thing
932 + ",i32_thing:" + multiResponse.I32_thing + ",i64_thing:" + multiResponse.I64_thing + ")\n");
933
934 try
935 {
936 Console.WriteLine("testException(\"Xception\")");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200937 await client.testException("Xception", MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100938 Console.WriteLine("*** FAILED ***");
939 returnCode |= ErrorExceptions;
940 }
941 catch (Xception ex)
942 {
943 if (ex.ErrorCode != 1001 || ex.Message != "Xception")
944 {
945 Console.WriteLine("*** FAILED ***");
946 returnCode |= ErrorExceptions;
947 }
948 }
949 catch (Exception ex)
950 {
951 Console.WriteLine("*** FAILED ***");
952 returnCode |= ErrorExceptions;
Mario Emmenlauer47e49232020-04-07 18:43:46 +0200953 Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100954 }
955 try
956 {
957 Console.WriteLine("testException(\"TException\")");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200958 await client.testException("TException", MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100959 Console.WriteLine("*** FAILED ***");
960 returnCode |= ErrorExceptions;
961 }
962 catch (Thrift.TException)
963 {
964 // OK
965 }
966 catch (Exception ex)
967 {
968 Console.WriteLine("*** FAILED ***");
969 returnCode |= ErrorExceptions;
Mario Emmenlauer47e49232020-04-07 18:43:46 +0200970 Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100971 }
972 try
973 {
974 Console.WriteLine("testException(\"ok\")");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200975 await client.testException("ok", MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100976 // OK
977 }
978 catch (Exception ex)
979 {
980 Console.WriteLine("*** FAILED ***");
981 returnCode |= ErrorExceptions;
Mario Emmenlauer47e49232020-04-07 18:43:46 +0200982 Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100983 }
984
985 try
986 {
987 Console.WriteLine("testMultiException(\"Xception\", ...)");
Jens Geyer2b2ea622021-04-09 22:55:11 +0200988 await client.testMultiException("Xception", "ignore", MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100989 Console.WriteLine("*** FAILED ***");
990 returnCode |= ErrorExceptions;
991 }
992 catch (Xception ex)
993 {
994 if (ex.ErrorCode != 1001 || ex.Message != "This is an Xception")
995 {
996 Console.WriteLine("*** FAILED ***");
997 returnCode |= ErrorExceptions;
998 }
999 }
1000 catch (Exception ex)
1001 {
1002 Console.WriteLine("*** FAILED ***");
1003 returnCode |= ErrorExceptions;
Mario Emmenlauer47e49232020-04-07 18:43:46 +02001004 Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001005 }
1006 try
1007 {
1008 Console.WriteLine("testMultiException(\"Xception2\", ...)");
Jens Geyer2b2ea622021-04-09 22:55:11 +02001009 await client.testMultiException("Xception2", "ignore", MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001010 Console.WriteLine("*** FAILED ***");
1011 returnCode |= ErrorExceptions;
1012 }
1013 catch (Xception2 ex)
1014 {
1015 if (ex.ErrorCode != 2002 || ex.Struct_thing.String_thing != "This is an Xception2")
1016 {
1017 Console.WriteLine("*** FAILED ***");
1018 returnCode |= ErrorExceptions;
1019 }
1020 }
1021 catch (Exception ex)
1022 {
1023 Console.WriteLine("*** FAILED ***");
1024 returnCode |= ErrorExceptions;
Mario Emmenlauer47e49232020-04-07 18:43:46 +02001025 Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001026 }
1027 try
1028 {
1029 Console.WriteLine("testMultiException(\"success\", \"OK\")");
Jens Geyer2b2ea622021-04-09 22:55:11 +02001030 if ("OK" != (await client.testMultiException("success", "OK", MakeTimeoutToken())).String_thing)
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001031 {
1032 Console.WriteLine("*** FAILED ***");
1033 returnCode |= ErrorExceptions;
1034 }
1035 }
1036 catch (Exception ex)
1037 {
1038 Console.WriteLine("*** FAILED ***");
1039 returnCode |= ErrorExceptions;
Mario Emmenlauer47e49232020-04-07 18:43:46 +02001040 Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001041 }
1042
Jens Geyerb11f63c2019-03-14 21:12:38 +01001043 Console.WriteLine("Test Oneway(1)");
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001044 var sw = new Stopwatch();
1045 sw.Start();
Jens Geyer2b2ea622021-04-09 22:55:11 +02001046 await client.testOneway(1, MakeTimeoutToken());
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001047 sw.Stop();
1048 if (sw.ElapsedMilliseconds > 1000)
1049 {
1050 Console.WriteLine("*** FAILED ***");
1051 returnCode |= ErrorBaseTypes;
1052 }
1053
1054 Console.Write("Test Calltime()");
1055 var times = 50;
1056 sw.Reset();
1057 sw.Start();
Jens Geyer1b770f22019-03-12 01:19:43 +01001058 var token = MakeTimeoutToken(20000);
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001059 for (var k = 0; k < times; ++k)
Jens Geyer2b2ea622021-04-09 22:55:11 +02001060 await client.testVoid(token);
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001061 sw.Stop();
1062 Console.WriteLine(" = {0} ms a testVoid() call", sw.ElapsedMilliseconds / times);
1063 return returnCode;
1064 }
1065 }
1066}