blob: 0ad789d0dd3c1c93255f2d0288788fd4bedd9393 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
Roger Meierd3b9dca2011-06-24 14:01:10 +000020#define __STDC_FORMAT_MACROS
21#include <inttypes.h>
22
Roger Meierca142b02011-06-07 17:59:07 +000023#include <iostream>
Roger Meier49ff8b12012-04-13 09:12:31 +000024#include <thrift/protocol/TBinaryProtocol.h>
Roger Meier023192f2014-02-12 09:35:12 +010025#include <thrift/protocol/TCompactProtocol.h>
Dave Watson792db4e2015-01-16 11:22:01 -080026#include <thrift/protocol/THeaderProtocol.h>
Roger Meier49ff8b12012-04-13 09:12:31 +000027#include <thrift/protocol/TJSONProtocol.h>
28#include <thrift/transport/THttpClient.h>
29#include <thrift/transport/TTransportUtils.h>
30#include <thrift/transport/TSocket.h>
31#include <thrift/transport/TSSLSocket.h>
32#include <thrift/async/TEvhttpClientChannel.h>
33#include <thrift/server/TNonblockingServer.h> // <event.h>
Mark Sleee8540632006-05-30 09:24:40 +000034
Marc Slemko6be374b2006-08-04 03:16:25 +000035#include <boost/shared_ptr.hpp>
Roger Meierca142b02011-06-07 17:59:07 +000036#include <boost/program_options.hpp>
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +053037#include <boost/filesystem.hpp>
Jake Farrell5d02b802014-01-07 21:42:01 -050038#include <thrift/cxxfunctional.h>
39#if _WIN32
Konrad Grochowski16a23a62014-11-13 15:33:38 +010040#include <thrift/windows/TWinsockSingleton.h>
Jake Farrell5d02b802014-01-07 21:42:01 -050041#endif
Roger Meierca142b02011-06-07 17:59:07 +000042
Marc Slemko6be374b2006-08-04 03:16:25 +000043#include "ThriftTest.h"
44
Marc Slemko6be374b2006-08-04 03:16:25 +000045using namespace std;
T Jake Lucianib5e62212009-01-31 22:36:20 +000046using namespace apache::thrift;
47using namespace apache::thrift::protocol;
48using namespace apache::thrift::transport;
Marc Slemkobf4fd192006-08-15 21:29:39 +000049using namespace thrift::test;
Roger Meier7e056e72011-07-17 07:28:28 +000050using namespace apache::thrift::async;
51
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +053052// Length of argv[0] - Length of script dir
53#define EXECUTABLE_FILE_NAME_LENGTH 19
54
Mark Slee95771002006-06-07 06:53:25 +000055// Current time, microseconds since the epoch
Konrad Grochowski16a23a62014-11-13 15:33:38 +010056uint64_t now() {
Roger Meier5f9614c2010-11-21 16:59:05 +000057 int64_t ret;
Mark Slee95771002006-06-07 06:53:25 +000058 struct timeval tv;
David Reiss0c90f6f2008-02-06 22:18:40 +000059
Jake Farrell5d02b802014-01-07 21:42:01 -050060 THRIFT_GETTIMEOFDAY(&tv, NULL);
Mark Slee95771002006-06-07 06:53:25 +000061 ret = tv.tv_sec;
Konrad Grochowski16a23a62014-11-13 15:33:38 +010062 ret = ret * 1000 * 1000 + tv.tv_usec;
Mark Slee95771002006-06-07 06:53:25 +000063 return ret;
64}
65
Konrad Grochowski16a23a62014-11-13 15:33:38 +010066static void testString_clientReturn(const char* host,
67 int port,
68 event_base* base,
69 TProtocolFactory* protocolFactory,
70 ThriftTestCobClient* client) {
71 (void)host;
72 (void)port;
73 (void)protocolFactory;
Roger Meier7e056e72011-07-17 07:28:28 +000074 try {
75 string s;
76 client->recv_testString(s);
77 cout << "testString: " << s << endl;
78 } catch (TException& exn) {
Jake Farrell5d02b802014-01-07 21:42:01 -050079 cout << "Error: " << exn.what() << endl;
Roger Meier7e056e72011-07-17 07:28:28 +000080 }
81
82 event_base_loopbreak(base); // end test
83}
84
Konrad Grochowski16a23a62014-11-13 15:33:38 +010085static void testVoid_clientReturn(const char* host,
86 int port,
87 event_base* base,
88 TProtocolFactory* protocolFactory,
89 ThriftTestCobClient* client) {
Roger Meier7e056e72011-07-17 07:28:28 +000090 try {
91 client->recv_testVoid();
92 cout << "testVoid" << endl;
93
94 // next test
95 delete client;
Roger Meier611f90c2011-12-11 22:08:51 +000096 boost::shared_ptr<TAsyncChannel> channel(new TEvhttpClientChannel(host, "/", host, port, base));
Roger Meier7e056e72011-07-17 07:28:28 +000097 client = new ThriftTestCobClient(channel, protocolFactory);
Konrad Grochowski16a23a62014-11-13 15:33:38 +010098 client->testString(tcxx::bind(testString_clientReturn,
99 host,
100 port,
101 base,
102 protocolFactory,
103 tcxx::placeholders::_1),
104 "Test");
Roger Meier7e056e72011-07-17 07:28:28 +0000105 } catch (TException& exn) {
Jake Farrell5d02b802014-01-07 21:42:01 -0500106 cout << "Error: " << exn.what() << endl;
Roger Meier7e056e72011-07-17 07:28:28 +0000107 }
108}
109
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900110// Workaround for absense of C++11 "auto" keyword.
111template <typename T>
112bool print_eq(T expected, T actual) {
113 cout << "(" << actual << ")" << endl;
114 if (expected != actual) {
115 cout << "*** FAILED ***" << endl << "Expected: " << expected << " but got: " << actual << endl;
116 return false;
117 }
118 return true;
119}
120
121#define BASETYPE_IDENTITY_TEST(func, value) \
122 cout << #func "(" << value << ") = "; \
123 try { \
124 if (!print_eq(value, testClient.func(value))) \
125 return_code |= ERR_BASETYPES; \
126 } catch (TTransportException&) { \
127 throw; \
128 } catch (exception & ex) { \
129 cout << "*** FAILED ***" << endl << ex.what() << endl; \
130 return_code |= ERR_BASETYPES; \
131 }
132
Mark Sleee8540632006-05-30 09:24:40 +0000133int main(int argc, char** argv) {
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900134 int ERR_BASETYPES = 1;
135 int ERR_STRUCTS = 2;
136 int ERR_CONTAINERS = 4;
137 int ERR_EXCEPTIONS = 8;
138 int ERR_UNKNOWN = 64;
139
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +0530140 string file_path = boost::filesystem::system_complete(argv[0]).string();
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100141 string dir_path = file_path.substr(0, file_path.size() - EXECUTABLE_FILE_NAME_LENGTH);
Jake Farrell5d02b802014-01-07 21:42:01 -0500142#if _WIN32
143 transport::TWinsockSingleton::create();
144#endif
Mark Sleee8540632006-05-30 09:24:40 +0000145 string host = "localhost";
146 int port = 9090;
147 int numTests = 1;
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000148 bool ssl = false;
Roger Meierca142b02011-06-07 17:59:07 +0000149 string transport_type = "buffered";
150 string protocol_type = "binary";
151 string domain_socket = "";
pavlodd08f6e2015-10-08 16:43:56 -0400152 bool abstract_namespace = false;
Jens Geyerf4598682014-05-08 23:18:44 +0200153 bool noinsane = false;
Mark Sleee8540632006-05-30 09:24:40 +0000154
Jake Farrell5d02b802014-01-07 21:42:01 -0500155 boost::program_options::options_description desc("Allowed options");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100156 desc.add_options()("help,h",
157 "produce help message")("host",
158 boost::program_options::value<string>(&host)
159 ->default_value(host),
160 "Host to connect")("port",
161 boost::program_options::value<int>(
162 &port)->default_value(port),
163 "Port number to connect")(
164 "domain-socket",
165 boost::program_options::value<string>(&domain_socket)->default_value(domain_socket),
166 "Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port")(
pavlodd08f6e2015-10-08 16:43:56 -0400167 "abstract-namespace",
168 "Look for the domain socket in the Abstract Namespace (no connection with filesystem pathnames)")(
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100169 "transport",
170 boost::program_options::value<string>(&transport_type)->default_value(transport_type),
171 "Transport: buffered, framed, http, evhttp")(
172 "protocol",
173 boost::program_options::value<string>(&protocol_type)->default_value(protocol_type),
Dave Watson792db4e2015-01-16 11:22:01 -0800174 "Protocol: binary, header, compact, json")("ssl", "Encrypted Transport using SSL")(
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100175 "testloops,n",
176 boost::program_options::value<int>(&numTests)->default_value(numTests),
177 "Number of Tests")("noinsane", "Do not run insanity test");
Roger Meierca142b02011-06-07 17:59:07 +0000178
Jake Farrell5d02b802014-01-07 21:42:01 -0500179 boost::program_options::variables_map vm;
180 boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
181 boost::program_options::notify(vm);
Roger Meierca142b02011-06-07 17:59:07 +0000182
183 if (vm.count("help")) {
184 cout << desc << "\n";
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900185 return ERR_UNKNOWN;
Mark Sleee8540632006-05-30 09:24:40 +0000186 }
Mark Sleea3302652006-10-25 19:03:32 +0000187
Jake Farrell5d02b802014-01-07 21:42:01 -0500188 try {
Roger Meierca142b02011-06-07 17:59:07 +0000189 if (!protocol_type.empty()) {
190 if (protocol_type == "binary") {
Roger Meier284101c2014-03-11 21:20:35 +0100191 } else if (protocol_type == "compact") {
Dave Watson792db4e2015-01-16 11:22:01 -0800192 } else if (protocol_type == "header") {
Roger Meierca142b02011-06-07 17:59:07 +0000193 } else if (protocol_type == "json") {
194 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100195 throw invalid_argument("Unknown protocol type " + protocol_type);
Roger Meierca142b02011-06-07 17:59:07 +0000196 }
197 }
198
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100199 if (!transport_type.empty()) {
Roger Meierca142b02011-06-07 17:59:07 +0000200 if (transport_type == "buffered") {
201 } else if (transport_type == "framed") {
202 } else if (transport_type == "http") {
Roger Meier7e056e72011-07-17 07:28:28 +0000203 } else if (transport_type == "evhttp") {
Roger Meierca142b02011-06-07 17:59:07 +0000204 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100205 throw invalid_argument("Unknown transport type " + transport_type);
Roger Meierca142b02011-06-07 17:59:07 +0000206 }
207 }
208
209 } catch (std::exception& e) {
210 cerr << e.what() << endl;
211 cout << desc << "\n";
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900212 return ERR_UNKNOWN;
Roger Meierca142b02011-06-07 17:59:07 +0000213 }
214
215 if (vm.count("ssl")) {
216 ssl = true;
217 }
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +0530218
pavlodd08f6e2015-10-08 16:43:56 -0400219 if (vm.count("abstract-namespace")) {
220 abstract_namespace = true;
221 }
222
Jens Geyerf4598682014-05-08 23:18:44 +0200223 if (vm.count("noinsane")) {
224 noinsane = true;
225 }
Roger Meierca142b02011-06-07 17:59:07 +0000226
Roger Meier611f90c2011-12-11 22:08:51 +0000227 boost::shared_ptr<TTransport> transport;
228 boost::shared_ptr<TProtocol> protocol;
Roger Meierca142b02011-06-07 17:59:07 +0000229
Roger Meier611f90c2011-12-11 22:08:51 +0000230 boost::shared_ptr<TSocket> socket;
231 boost::shared_ptr<TSSLSocketFactory> factory;
Roger Meierca142b02011-06-07 17:59:07 +0000232
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000233 if (ssl) {
Roger Meier611f90c2011-12-11 22:08:51 +0000234 factory = boost::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000235 factory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +0530236 factory->loadTrustedCertificates((dir_path + "../keys/CA.pem").c_str());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000237 factory->authenticate(true);
238 socket = factory->createSocket(host, port);
239 } else {
Roger Meierca142b02011-06-07 17:59:07 +0000240 if (domain_socket != "") {
pavlodd08f6e2015-10-08 16:43:56 -0400241 if (abstract_namespace) {
242 std::string abstract_socket("\0", 1);
243 abstract_socket += domain_socket;
244 socket = boost::shared_ptr<TSocket>(new TSocket(abstract_socket));
245 } else {
246 socket = boost::shared_ptr<TSocket>(new TSocket(domain_socket));
247 }
Roger Meierca142b02011-06-07 17:59:07 +0000248 port = 0;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100249 } else {
Roger Meier611f90c2011-12-11 22:08:51 +0000250 socket = boost::shared_ptr<TSocket>(new TSocket(host, port));
Roger Meierca142b02011-06-07 17:59:07 +0000251 }
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000252 }
Mark Sleea3302652006-10-25 19:03:32 +0000253
Roger Meierca142b02011-06-07 17:59:07 +0000254 if (transport_type.compare("http") == 0) {
Roger Meier611f90c2011-12-11 22:08:51 +0000255 boost::shared_ptr<TTransport> httpSocket(new THttpClient(socket, host, "/service"));
Roger Meierca142b02011-06-07 17:59:07 +0000256 transport = httpSocket;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100257 } else if (transport_type.compare("framed") == 0) {
Roger Meier611f90c2011-12-11 22:08:51 +0000258 boost::shared_ptr<TFramedTransport> framedSocket(new TFramedTransport(socket));
Mark Sleea3302652006-10-25 19:03:32 +0000259 transport = framedSocket;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100260 } else {
Roger Meier611f90c2011-12-11 22:08:51 +0000261 boost::shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket));
Mark Sleea3302652006-10-25 19:03:32 +0000262 transport = bufferedSocket;
263 }
264
Roger Meierca142b02011-06-07 17:59:07 +0000265 if (protocol_type.compare("json") == 0) {
Roger Meier611f90c2011-12-11 22:08:51 +0000266 boost::shared_ptr<TProtocol> jsonProtocol(new TJSONProtocol(transport));
Roger Meierca142b02011-06-07 17:59:07 +0000267 protocol = jsonProtocol;
Roger Meier023192f2014-02-12 09:35:12 +0100268 } else if (protocol_type.compare("compact") == 0) {
269 boost::shared_ptr<TProtocol> compactProtocol(new TCompactProtocol(transport));
270 protocol = compactProtocol;
Dave Watson792db4e2015-01-16 11:22:01 -0800271 } else if (protocol_type == "header") {
272 boost::shared_ptr<TProtocol> headerProtocol(new THeaderProtocol(transport));
273 protocol = headerProtocol;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100274 } else {
Roger Meier611f90c2011-12-11 22:08:51 +0000275 boost::shared_ptr<TBinaryProtocol> binaryProtocol(new TBinaryProtocol(transport));
Roger Meierca142b02011-06-07 17:59:07 +0000276 protocol = binaryProtocol;
277 }
278
279 // Connection info
pavlodd08f6e2015-10-08 16:43:56 -0400280 cout << "Connecting (" << transport_type << "/" << protocol_type << ") to: ";
281 if (abstract_namespace) {
282 cout << '@';
283 }
284 cout << domain_socket;
Roger Meierca142b02011-06-07 17:59:07 +0000285 if (port != 0) {
286 cout << host << ":" << port;
287 }
288 cout << endl;
289
Roger Meier7e056e72011-07-17 07:28:28 +0000290 if (transport_type.compare("evhttp") == 0) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100291 event_base* base = event_base_new();
Roger Meier7e056e72011-07-17 07:28:28 +0000292 cout << "Libevent Version: " << event_get_version() << endl;
293 cout << "Libevent Method: " << event_base_get_method(base) << endl;
294#if LIBEVENT_VERSION_NUMBER >= 0x02000000
295 cout << "Libevent Features: 0x" << hex << event_base_get_features(base) << endl;
296#endif
297
Roger Meier611f90c2011-12-11 22:08:51 +0000298 boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Roger Meier7e056e72011-07-17 07:28:28 +0000299
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100300 boost::shared_ptr<TAsyncChannel> channel(
301 new TEvhttpClientChannel(host.c_str(), "/", host.c_str(), port, base));
Roger Meier7e056e72011-07-17 07:28:28 +0000302 ThriftTestCobClient* client = new ThriftTestCobClient(channel, protocolFactory.get());
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100303 client->testVoid(tcxx::bind(testVoid_clientReturn,
304 host.c_str(),
305 port,
306 base,
307 protocolFactory.get(),
308 tcxx::placeholders::_1));
Jake Farrell5d02b802014-01-07 21:42:01 -0500309
Roger Meier7e056e72011-07-17 07:28:28 +0000310 event_base_loop(base, 0);
311 return 0;
312 }
313
Roger Meierca142b02011-06-07 17:59:07 +0000314 ThriftTestClient testClient(protocol);
Mark Sleed788b2e2006-09-07 01:26:35 +0000315
316 uint64_t time_min = 0;
317 uint64_t time_max = 0;
318 uint64_t time_tot = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000319
Jens Geyerd629ea02015-09-23 21:16:50 +0200320 int return_code = 0;
Jens Geyerd629ea02015-09-23 21:16:50 +0200321
Mark Sleee8540632006-05-30 09:24:40 +0000322 int test = 0;
323 for (test = 0; test < numTests; ++test) {
Mark Slee95771002006-06-07 06:53:25 +0000324
Mark Slee95771002006-06-07 06:53:25 +0000325 try {
Mark Sleea3302652006-10-25 19:03:32 +0000326 transport->open();
Mark Slee95771002006-06-07 06:53:25 +0000327 } catch (TTransportException& ttx) {
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000328 printf("Connect failed: %s\n", ttx.what());
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900329 return ERR_UNKNOWN;
Mark Sleee8540632006-05-30 09:24:40 +0000330 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000331
Mark Sleed788b2e2006-09-07 01:26:35 +0000332 /**
333 * CONNECT TEST
334 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100335 printf("Test #%d, connect %s:%d\n", test + 1, host.c_str(), port);
Mark Slee95771002006-06-07 06:53:25 +0000336
337 uint64_t start = now();
David Reiss0c90f6f2008-02-06 22:18:40 +0000338
Mark Sleee8540632006-05-30 09:24:40 +0000339 /**
340 * VOID TEST
341 */
Mark Sleee129a2d2007-02-21 05:17:48 +0000342 try {
343 printf("testVoid()");
344 testClient.testVoid();
345 printf(" = void\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000346 } catch (TApplicationException& tax) {
Jens Geyerd629ea02015-09-23 21:16:50 +0200347 printf("*** FAILED ***\n");
Mark Sleee129a2d2007-02-21 05:17:48 +0000348 printf("%s\n", tax.what());
Jens Geyerd629ea02015-09-23 21:16:50 +0200349 return_code |= ERR_BASETYPES;
Mark Sleee129a2d2007-02-21 05:17:48 +0000350 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000351
Mark Sleee8540632006-05-30 09:24:40 +0000352 /**
353 * STRING TEST
354 */
355 printf("testString(\"Test\")");
Mark Slee1921d202007-01-24 19:43:06 +0000356 string s;
357 testClient.testString(s, "Test");
Mark Sleee8540632006-05-30 09:24:40 +0000358 printf(" = \"%s\"\n", s.c_str());
Jens Geyerd629ea02015-09-23 21:16:50 +0200359 if (s != "Test") {
360 printf("*** FAILED ***\n");
361 return_code |= ERR_BASETYPES;
362 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000363
Mark Sleee8540632006-05-30 09:24:40 +0000364 /**
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900365 * BOOL TEST
366 */
367 printf("testBool(true)");
368 bool bl = testClient.testBool(true);
369 printf(" = %s\n", bl ? "true" : "false");
Jens Geyerd629ea02015-09-23 21:16:50 +0200370 if (bl != true) {
371 printf("*** FAILED ***\n");
372 return_code |= ERR_BASETYPES;
373 }
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900374
375 printf("testBool(false)");
376 bl = testClient.testBool(false);
377 printf(" = %s\n", bl ? "true" : "false");
Jens Geyerd629ea02015-09-23 21:16:50 +0200378 if (bl != false) {
379 printf("*** FAILED ***\n");
380 return_code |= ERR_BASETYPES;
381 }
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900382
383 /**
Mark Sleee8540632006-05-30 09:24:40 +0000384 * BYTE TEST
385 */
386 printf("testByte(1)");
387 uint8_t u8 = testClient.testByte(1);
388 printf(" = %d\n", (int)u8);
Jens Geyerd629ea02015-09-23 21:16:50 +0200389 if (u8 != 1) {
390 printf("*** FAILED ***\n");
391 return_code |= ERR_BASETYPES;
392 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000393
Mark Sleee8540632006-05-30 09:24:40 +0000394 /**
395 * I32 TEST
396 */
397 printf("testI32(-1)");
398 int32_t i32 = testClient.testI32(-1);
399 printf(" = %d\n", i32);
Jens Geyerd629ea02015-09-23 21:16:50 +0200400 if (i32 != -1) {
401 printf("*** FAILED ***\n");
402 return_code |= ERR_BASETYPES;
403 }
Mark Sleee8540632006-05-30 09:24:40 +0000404
405 /**
Mark Sleee8540632006-05-30 09:24:40 +0000406 * I64 TEST
407 */
408 printf("testI64(-34359738368)");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000409 int64_t i64 = testClient.testI64(-34359738368LL);
Roger Meier0e814802014-01-17 21:07:58 +0100410 printf(" = %" PRId64 "\n", i64);
Jens Geyerd629ea02015-09-23 21:16:50 +0200411 if (i64 != -34359738368LL) {
412 printf("*** FAILED ***\n");
413 return_code |= ERR_BASETYPES;
414 }
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100415
Mark Sleec98d0502006-09-06 02:42:25 +0000416 /**
417 * DOUBLE TEST
418 */
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900419 // Comparing double values with plain equality because Thrift handles full precision of double
420 BASETYPE_IDENTITY_TEST(testDouble, 0.0);
421 BASETYPE_IDENTITY_TEST(testDouble, -1.0);
422 BASETYPE_IDENTITY_TEST(testDouble, -5.2098523);
423 BASETYPE_IDENTITY_TEST(testDouble, -0.000341012439638598279);
424 BASETYPE_IDENTITY_TEST(testDouble, pow(2, 32));
425 BASETYPE_IDENTITY_TEST(testDouble, pow(2, 32) + 1);
426 BASETYPE_IDENTITY_TEST(testDouble, pow(2, 53) - 1);
427 BASETYPE_IDENTITY_TEST(testDouble, -pow(2, 32));
428 BASETYPE_IDENTITY_TEST(testDouble, -pow(2, 32) - 1);
429 BASETYPE_IDENTITY_TEST(testDouble, -pow(2, 53) + 1);
430
431 try {
432 double expected = pow(10, 307);
433 cout << "testDouble(" << expected << ") = ";
434 double actual = testClient.testDouble(expected);
435 cout << "(" << actual << ")" << endl;
436 if (expected - actual > pow(10, 292)) {
437 cout << "*** FAILED ***" << endl
438 << "Expected: " << expected << " but got: " << actual << endl;
439 }
440 } catch (TTransportException&) {
441 throw;
442 } catch (exception& ex) {
443 cout << "*** FAILED ***" << endl << ex.what() << endl;
444 return_code |= ERR_BASETYPES;
445 }
446
447 try {
448 double expected = pow(10, -292);
449 cout << "testDouble(" << expected << ") = ";
450 double actual = testClient.testDouble(expected);
451 cout << "(" << actual << ")" << endl;
452 if (expected - actual > pow(10, -307)) {
453 cout << "*** FAILED ***" << endl
454 << "Expected: " << expected << " but got: " << actual << endl;
455 }
456 } catch (TTransportException&) {
457 throw;
458 } catch (exception& ex) {
459 cout << "*** FAILED ***" << endl << ex.what() << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200460 return_code |= ERR_BASETYPES;
461 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000462
Mark Sleee8540632006-05-30 09:24:40 +0000463 /**
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100464 * BINARY TEST
465 */
Nobuaki Sukegawadfb68962015-12-09 22:09:26 +0900466 printf("testBinary(empty)\n");
467 try {
468 string bin_result;
469 testClient.testBinary(bin_result, string());
470 if (!bin_result.empty()) {
471 printf("*** FAILED ***\n");
472 printf("invalid length: %lu\n", static_cast<long unsigned int>(bin_result.size()));
473 return_code |= ERR_BASETYPES;
474 }
475 } catch (exception& ex) {
476 printf("}\n*** FAILED ***\n");
477 printf("%s\n", ex.what());
478 return_code |= ERR_BASETYPES;
479 }
Jens Geyerd629ea02015-09-23 21:16:50 +0200480 printf("testBinary([-128..127]) = {");
481 const char bin_data[256]
482 = {-128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114,
483 -113, -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99,
484 -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84,
485 -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, -69,
486 -68, -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54,
487 -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39,
488 -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24,
489 -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9,
490 -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6,
491 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
492 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
493 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
494 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
495 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
496 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
497 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
498 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
499 127};
500 try {
501 string bin_result;
502 testClient.testBinary(bin_result, string(bin_data, 256));
503 if (bin_result.size() != 256) {
504 printf("}\n*** FAILED ***\n");
Jens Geyer2faac5a2015-11-17 23:00:52 +0100505 printf("invalid length: %lu\n", static_cast<long unsigned int>(bin_result.size()));
Jens Geyerd629ea02015-09-23 21:16:50 +0200506 return_code |= ERR_BASETYPES;
507 } else {
508 bool first = true;
509 bool failed = false;
510 for (int i = 0; i < 256; ++i) {
511 if (!first)
512 printf(" ,");
513 else
514 first = false;
515 printf("%d", bin_result[i]);
516 if (!failed && bin_result[i] != i - 128) {
517 failed = true;
518 }
519 }
520 printf("}\n");
521 if (failed) {
522 printf("*** FAILED ***\n");
523 return_code |= ERR_BASETYPES;
524 }
525 }
526 } catch (exception& ex) {
527 printf("}\n*** FAILED ***\n");
528 printf("%s\n", ex.what());
529 return_code |= ERR_BASETYPES;
530 }
531
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100532
533 /**
Mark Sleee8540632006-05-30 09:24:40 +0000534 * STRUCT TEST
535 */
Mark Slee6e536442006-06-30 18:28:50 +0000536 printf("testStruct({\"Zero\", 1, -3, -5})");
Mark Sleee8540632006-05-30 09:24:40 +0000537 Xtruct out;
538 out.string_thing = "Zero";
539 out.byte_thing = 1;
Mark Sleee8540632006-05-30 09:24:40 +0000540 out.i32_thing = -3;
Mark Sleee8540632006-05-30 09:24:40 +0000541 out.i64_thing = -5;
Mark Slee1921d202007-01-24 19:43:06 +0000542 Xtruct in;
543 testClient.testStruct(in, out);
Roger Meier0e814802014-01-17 21:07:58 +0100544 printf(" = {\"%s\", %d, %d, %" PRId64 "}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000545 in.string_thing.c_str(),
546 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000547 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000548 in.i64_thing);
Jens Geyerd629ea02015-09-23 21:16:50 +0200549 if (in != out) {
550 printf("*** FAILED ***\n");
551 return_code |= ERR_STRUCTS;
552 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000553
Mark Sleee8540632006-05-30 09:24:40 +0000554 /**
555 * NESTED STRUCT TEST
556 */
Mark Slee6e536442006-06-30 18:28:50 +0000557 printf("testNest({1, {\"Zero\", 1, -3, -5}), 5}");
Mark Sleee8540632006-05-30 09:24:40 +0000558 Xtruct2 out2;
559 out2.byte_thing = 1;
560 out2.struct_thing = out;
561 out2.i32_thing = 5;
Mark Slee1921d202007-01-24 19:43:06 +0000562 Xtruct2 in2;
563 testClient.testNest(in2, out2);
Mark Sleee8540632006-05-30 09:24:40 +0000564 in = in2.struct_thing;
Roger Meier0e814802014-01-17 21:07:58 +0100565 printf(" = {%d, {\"%s\", %d, %d, %" PRId64 "}, %d}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000566 in2.byte_thing,
567 in.string_thing.c_str(),
568 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000569 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000570 in.i64_thing,
David Reiss0c90f6f2008-02-06 22:18:40 +0000571 in2.i32_thing);
Jens Geyerd629ea02015-09-23 21:16:50 +0200572 if (in2 != out2) {
573 printf("*** FAILED ***\n");
574 return_code |= ERR_STRUCTS;
575 }
Mark Sleee8540632006-05-30 09:24:40 +0000576
577 /**
578 * MAP TEST
579 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100580 map<int32_t, int32_t> mapout;
Mark Sleee8540632006-05-30 09:24:40 +0000581 for (int32_t i = 0; i < 5; ++i) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100582 mapout.insert(make_pair(i, i - 10));
Mark Sleee8540632006-05-30 09:24:40 +0000583 }
584 printf("testMap({");
585 map<int32_t, int32_t>::const_iterator m_iter;
586 bool first = true;
587 for (m_iter = mapout.begin(); m_iter != mapout.end(); ++m_iter) {
588 if (first) {
589 first = false;
590 } else {
591 printf(", ");
592 }
593 printf("%d => %d", m_iter->first, m_iter->second);
594 }
595 printf("})");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100596 map<int32_t, int32_t> mapin;
Mark Slee1921d202007-01-24 19:43:06 +0000597 testClient.testMap(mapin, mapout);
Mark Sleee8540632006-05-30 09:24:40 +0000598 printf(" = {");
599 first = true;
600 for (m_iter = mapin.begin(); m_iter != mapin.end(); ++m_iter) {
601 if (first) {
602 first = false;
603 } else {
604 printf(", ");
605 }
606 printf("%d => %d", m_iter->first, m_iter->second);
607 }
608 printf("}\n");
Jens Geyerd629ea02015-09-23 21:16:50 +0200609 if (mapin != mapout) {
610 printf("*** FAILED ***\n");
611 return_code |= ERR_CONTAINERS;
612 }
Roger Meier4fce9602012-05-04 06:22:09 +0000613
614 /**
615 * STRING MAP TEST
Roger Meier4fce9602012-05-04 06:22:09 +0000616 */
Jens Geyerd629ea02015-09-23 21:16:50 +0200617 printf("testStringMap({a => 2, b => blah, some => thing}) = {");
618 map<string, string> smapin;
619 map<string, string> smapout;
620 smapin["a"] = "2";
621 smapin["b"] = "blah";
622 smapin["some"] = "thing";
623 try {
624 testClient.testStringMap(smapout, smapin);
625 first = true;
626 for (map<string, string>::const_iterator it = smapout.begin(); it != smapout.end(); ++it) {
627 if (first)
628 printf(",");
629 else
630 first = false;
631 printf("%s => %s", it->first.c_str(), it->second.c_str());
632 }
633 printf("}\n");
634 if (smapin != smapout) {
635 printf("*** FAILED ***\n");
636 return_code |= ERR_CONTAINERS;
637 }
638 } catch (exception& ex) {
639 printf("}\n*** FAILED ***\n");
640 printf("%s\n", ex.what());
641 return_code |= ERR_CONTAINERS;
642 }
Mark Sleee8540632006-05-30 09:24:40 +0000643
644 /**
645 * SET TEST
646 */
647 set<int32_t> setout;
648 for (int32_t i = -2; i < 3; ++i) {
649 setout.insert(i);
650 }
651 printf("testSet({");
652 set<int32_t>::const_iterator s_iter;
653 first = true;
654 for (s_iter = setout.begin(); s_iter != setout.end(); ++s_iter) {
655 if (first) {
656 first = false;
657 } else {
658 printf(", ");
659 }
660 printf("%d", *s_iter);
661 }
662 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000663 set<int32_t> setin;
664 testClient.testSet(setin, setout);
Mark Sleee8540632006-05-30 09:24:40 +0000665 printf(" = {");
666 first = true;
667 for (s_iter = setin.begin(); s_iter != setin.end(); ++s_iter) {
668 if (first) {
669 first = false;
670 } else {
671 printf(", ");
672 }
673 printf("%d", *s_iter);
674 }
675 printf("}\n");
Jens Geyerd629ea02015-09-23 21:16:50 +0200676 if (setin != setout) {
677 printf("*** FAILED ***\n");
678 return_code |= ERR_CONTAINERS;
679 }
Mark Sleee8540632006-05-30 09:24:40 +0000680
681 /**
682 * LIST TEST
683 */
Mark Sleeb9acf982006-10-10 01:57:32 +0000684 vector<int32_t> listout;
Mark Sleee8540632006-05-30 09:24:40 +0000685 for (int32_t i = -2; i < 3; ++i) {
686 listout.push_back(i);
687 }
688 printf("testList({");
Mark Sleeb9acf982006-10-10 01:57:32 +0000689 vector<int32_t>::const_iterator l_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000690 first = true;
691 for (l_iter = listout.begin(); l_iter != listout.end(); ++l_iter) {
692 if (first) {
693 first = false;
694 } else {
695 printf(", ");
696 }
697 printf("%d", *l_iter);
698 }
699 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000700 vector<int32_t> listin;
701 testClient.testList(listin, listout);
Mark Sleee8540632006-05-30 09:24:40 +0000702 printf(" = {");
703 first = true;
704 for (l_iter = listin.begin(); l_iter != listin.end(); ++l_iter) {
705 if (first) {
706 first = false;
707 } else {
708 printf(", ");
709 }
710 printf("%d", *l_iter);
711 }
712 printf("}\n");
Jens Geyerd629ea02015-09-23 21:16:50 +0200713 if (listin != listout) {
714 printf("*** FAILED ***\n");
715 return_code |= ERR_CONTAINERS;
716 }
Mark Sleee8540632006-05-30 09:24:40 +0000717
718 /**
719 * ENUM TEST
720 */
721 printf("testEnum(ONE)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000722 Numberz::type ret = testClient.testEnum(Numberz::ONE);
Mark Sleee8540632006-05-30 09:24:40 +0000723 printf(" = %d\n", ret);
Jens Geyerd629ea02015-09-23 21:16:50 +0200724 if (ret != Numberz::ONE) {
725 printf("*** FAILED ***\n");
726 return_code |= ERR_STRUCTS;
727 }
Mark Sleee8540632006-05-30 09:24:40 +0000728
729 printf("testEnum(TWO)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000730 ret = testClient.testEnum(Numberz::TWO);
Mark Sleee8540632006-05-30 09:24:40 +0000731 printf(" = %d\n", ret);
Jens Geyerd629ea02015-09-23 21:16:50 +0200732 if (ret != Numberz::TWO) {
733 printf("*** FAILED ***\n");
734 return_code |= ERR_STRUCTS;
735 }
Mark Sleee8540632006-05-30 09:24:40 +0000736
737 printf("testEnum(THREE)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000738 ret = testClient.testEnum(Numberz::THREE);
Mark Sleee8540632006-05-30 09:24:40 +0000739 printf(" = %d\n", ret);
Jens Geyerd629ea02015-09-23 21:16:50 +0200740 if (ret != Numberz::THREE) {
741 printf("*** FAILED ***\n");
742 return_code |= ERR_STRUCTS;
743 }
Mark Sleee8540632006-05-30 09:24:40 +0000744
745 printf("testEnum(FIVE)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000746 ret = testClient.testEnum(Numberz::FIVE);
Mark Sleee8540632006-05-30 09:24:40 +0000747 printf(" = %d\n", ret);
Jens Geyerd629ea02015-09-23 21:16:50 +0200748 if (ret != Numberz::FIVE) {
749 printf("*** FAILED ***\n");
750 return_code |= ERR_STRUCTS;
751 }
Mark Sleee8540632006-05-30 09:24:40 +0000752
753 printf("testEnum(EIGHT)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000754 ret = testClient.testEnum(Numberz::EIGHT);
Mark Sleee8540632006-05-30 09:24:40 +0000755 printf(" = %d\n", ret);
Jens Geyerd629ea02015-09-23 21:16:50 +0200756 if (ret != Numberz::EIGHT) {
757 printf("*** FAILED ***\n");
758 return_code |= ERR_STRUCTS;
759 }
Mark Sleee8540632006-05-30 09:24:40 +0000760
761 /**
762 * TYPEDEF TEST
763 */
764 printf("testTypedef(309858235082523)");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000765 UserId uid = testClient.testTypedef(309858235082523LL);
Roger Meier0e814802014-01-17 21:07:58 +0100766 printf(" = %" PRId64 "\n", uid);
Jens Geyerd629ea02015-09-23 21:16:50 +0200767 if (uid != 309858235082523LL) {
768 printf("*** FAILED ***\n");
769 return_code |= ERR_STRUCTS;
770 }
Mark Sleee8540632006-05-30 09:24:40 +0000771
772 /**
773 * NESTED MAP TEST
774 */
775 printf("testMapMap(1)");
Mark Slee1921d202007-01-24 19:43:06 +0000776 map<int32_t, map<int32_t, int32_t> > mm;
777 testClient.testMapMap(mm, 1);
Mark Sleee8540632006-05-30 09:24:40 +0000778 printf(" = {");
779 map<int32_t, map<int32_t, int32_t> >::const_iterator mi;
780 for (mi = mm.begin(); mi != mm.end(); ++mi) {
781 printf("%d => {", mi->first);
782 map<int32_t, int32_t>::const_iterator mi2;
783 for (mi2 = mi->second.begin(); mi2 != mi->second.end(); ++mi2) {
784 printf("%d => %d, ", mi2->first, mi2->second);
785 }
786 printf("}, ");
787 }
788 printf("}\n");
Jens Geyerd629ea02015-09-23 21:16:50 +0200789 if (mm.size() != 2 ||
790 mm[-4][-4] != -4 ||
791 mm[-4][-3] != -3 ||
792 mm[-4][-2] != -2 ||
793 mm[-4][-1] != -1 ||
794 mm[4][4] != 4 ||
795 mm[4][3] != 3 ||
796 mm[4][2] != 2 ||
797 mm[4][1] != 1) {
798 printf("*** FAILED ***\n");
799 return_code |= ERR_CONTAINERS;
800 }
Mark Sleee8540632006-05-30 09:24:40 +0000801
802 /**
803 * INSANITY TEST
804 */
Jens Geyerf4598682014-05-08 23:18:44 +0200805 if (!noinsane) {
806 Insanity insane;
Jens Geyerd629ea02015-09-23 21:16:50 +0200807 insane.userMap.insert(make_pair(Numberz::FIVE, 5));
808 insane.userMap.insert(make_pair(Numberz::EIGHT, 8));
Jens Geyerf4598682014-05-08 23:18:44 +0200809 Xtruct truck;
Jens Geyerd629ea02015-09-23 21:16:50 +0200810 truck.string_thing = "Goodbye4";
811 truck.byte_thing = 4;
812 truck.i32_thing = 4;
813 truck.i64_thing = 4;
814 Xtruct truck2;
815 truck2.string_thing = "Hello2";
816 truck2.byte_thing = 2;
817 truck2.i32_thing = 2;
818 truck2.i64_thing = 2;
Jens Geyerf4598682014-05-08 23:18:44 +0200819 insane.xtructs.push_back(truck);
Jens Geyerd629ea02015-09-23 21:16:50 +0200820 insane.xtructs.push_back(truck2);
Jens Geyerf4598682014-05-08 23:18:44 +0200821 printf("testInsanity()");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100822 map<UserId, map<Numberz::type, Insanity> > whoa;
Jens Geyerf4598682014-05-08 23:18:44 +0200823 testClient.testInsanity(whoa, insane);
824 printf(" = {");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100825 map<UserId, map<Numberz::type, Insanity> >::const_iterator i_iter;
Jens Geyerf4598682014-05-08 23:18:44 +0200826 for (i_iter = whoa.begin(); i_iter != whoa.end(); ++i_iter) {
827 printf("%" PRId64 " => {", i_iter->first);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100828 map<Numberz::type, Insanity>::const_iterator i2_iter;
829 for (i2_iter = i_iter->second.begin(); i2_iter != i_iter->second.end(); ++i2_iter) {
Jens Geyerf4598682014-05-08 23:18:44 +0200830 printf("%d => {", i2_iter->first);
831 map<Numberz::type, UserId> userMap = i2_iter->second.userMap;
832 map<Numberz::type, UserId>::const_iterator um;
833 printf("{");
834 for (um = userMap.begin(); um != userMap.end(); ++um) {
835 printf("%d => %" PRId64 ", ", um->first, um->second);
836 }
837 printf("}, ");
Mark Sleee8540632006-05-30 09:24:40 +0000838
Jens Geyerf4598682014-05-08 23:18:44 +0200839 vector<Xtruct> xtructs = i2_iter->second.xtructs;
840 vector<Xtruct>::const_iterator x;
841 printf("{");
842 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
843 printf("{\"%s\", %d, %d, %" PRId64 "}, ",
844 x->string_thing.c_str(),
845 (int)x->byte_thing,
846 x->i32_thing,
847 x->i64_thing);
848 }
849 printf("}");
Mark Sleee8540632006-05-30 09:24:40 +0000850
Jens Geyerf4598682014-05-08 23:18:44 +0200851 printf("}, ");
852 }
Mark Sleee8540632006-05-30 09:24:40 +0000853 printf("}, ");
854 }
Jens Geyerf4598682014-05-08 23:18:44 +0200855 printf("}\n");
Jens Geyerd629ea02015-09-23 21:16:50 +0200856 bool failed = false;
857 map<UserId, map<Numberz::type, Insanity> >::const_iterator it1 = whoa.find(UserId(1));
858 if (whoa.size() != 2) {
859 failed = true;
860 }
861 if (it1 == whoa.end()) {
862 failed = true;
863 } else {
864 map<Numberz::type, Insanity>::const_iterator it12 = it1->second.find(Numberz::TWO);
865 if (it12 == it1->second.end() || it12->second != insane) {
866 failed = true;
867 }
868 map<Numberz::type, Insanity>::const_iterator it13 = it1->second.find(Numberz::THREE);
869 if (it13 == it1->second.end() || it13->second != insane) {
870 failed = true;
871 }
872 }
873 map<UserId, map<Numberz::type, Insanity> >::const_iterator it2 = whoa.find(UserId(2));
874 if (it2 == whoa.end()) {
875 failed = true;
876 } else {
877 map<Numberz::type, Insanity>::const_iterator it26 = it2->second.find(Numberz::SIX);
878 if (it26 == it1->second.end() || it26->second != Insanity()) {
879 failed = true;
880 }
881 }
882 if (failed) {
883 printf("*** FAILED ***\n");
884 return_code |= ERR_STRUCTS;
885 }
Mark Sleee8540632006-05-30 09:24:40 +0000886 }
Jens Geyerd629ea02015-09-23 21:16:50 +0200887
888 /**
889 * MULTI TEST
890 */
891 printf("testMulti()\n");
892 try {
893 map<int16_t, string> mul_map;
894 Xtruct mul_result;
895 mul_map[1] = "blah";
896 mul_map[2] = "thing";
897 testClient.testMulti(mul_result, 42, 4242, 424242, mul_map, Numberz::EIGHT, UserId(24));
898 Xtruct xxs;
899 xxs.string_thing = "Hello2";
900 xxs.byte_thing = 42;
901 xxs.i32_thing = 4242;
902 xxs.i64_thing = 424242;
903 if (mul_result != xxs) {
904 printf("*** FAILED ***\n");
905 return_code |= ERR_STRUCTS;
906 }
907 } catch (exception& ex) {
908 printf("*** FAILED ***\n");
909 return_code |= ERR_STRUCTS;
910 }
911
Marc Slemko71d4e472006-08-15 22:34:04 +0000912 /* test exception */
Mark Slee95771002006-06-07 06:53:25 +0000913
Marc Slemkobf4fd192006-08-15 21:29:39 +0000914 try {
Marc Slemko71d4e472006-08-15 22:34:04 +0000915 printf("testClient.testException(\"Xception\") =>");
916 testClient.testException("Xception");
Jens Geyerd629ea02015-09-23 21:16:50 +0200917 printf(" void\n*** FAILED ***\n");
918 return_code |= ERR_EXCEPTIONS;
David Reiss0c90f6f2008-02-06 22:18:40 +0000919
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100920 } catch (Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000921 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000922 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000923
Marc Slemkobf4fd192006-08-15 21:29:39 +0000924 try {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100925 printf("testClient.testException(\"TException\") =>");
926 testClient.testException("TException");
Jens Geyerd629ea02015-09-23 21:16:50 +0200927 printf(" void\n*** FAILED ***\n");
928 return_code |= ERR_EXCEPTIONS;
Roger Meierf50df7f2012-05-02 22:49:55 +0000929
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100930 } catch (const TException&) {
931 printf(" Caught TException\n");
932 }
Roger Meierf50df7f2012-05-02 22:49:55 +0000933
934 try {
Marc Slemko71d4e472006-08-15 22:34:04 +0000935 printf("testClient.testException(\"success\") =>");
936 testClient.testException("success");
937 printf(" void\n");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100938 } catch (...) {
Jens Geyerd629ea02015-09-23 21:16:50 +0200939 printf(" exception\n*** FAILED ***\n");
940 return_code |= ERR_EXCEPTIONS;
Marc Slemko71d4e472006-08-15 22:34:04 +0000941 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000942
Marc Slemko71d4e472006-08-15 22:34:04 +0000943 /* test multi exception */
David Reiss0c90f6f2008-02-06 22:18:40 +0000944
Marc Slemko71d4e472006-08-15 22:34:04 +0000945 try {
946 printf("testClient.testMultiException(\"Xception\", \"test 1\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000947 Xtruct result;
948 testClient.testMultiException(result, "Xception", "test 1");
Jens Geyerd629ea02015-09-23 21:16:50 +0200949 printf(" result\n*** FAILED ***\n");
950 return_code |= ERR_EXCEPTIONS;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100951 } catch (Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000952 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
953 }
954
955 try {
956 printf("testClient.testMultiException(\"Xception2\", \"test 2\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000957 Xtruct result;
958 testClient.testMultiException(result, "Xception2", "test 2");
Jens Geyerd629ea02015-09-23 21:16:50 +0200959 printf(" result\n*** FAILED ***\n");
960 return_code |= ERR_EXCEPTIONS;
David Reiss0c90f6f2008-02-06 22:18:40 +0000961
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100962 } catch (Xception2& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000963 printf(" {%u, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000964 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000965
Marc Slemko71d4e472006-08-15 22:34:04 +0000966 try {
967 printf("testClient.testMultiException(\"success\", \"test 3\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000968 Xtruct result;
969 testClient.testMultiException(result, "success", "test 3");
Marc Slemko71d4e472006-08-15 22:34:04 +0000970 printf(" {{\"%s\"}}\n", result.string_thing.c_str());
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100971 } catch (...) {
Jens Geyerd629ea02015-09-23 21:16:50 +0200972 printf(" exception\n*** FAILED ***\n");
973 return_code |= ERR_EXCEPTIONS;
Marc Slemko71d4e472006-08-15 22:34:04 +0000974 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000975
David Reissc51986f2009-03-24 20:01:25 +0000976 /* test oneway void */
David Reiss2ab6fe82008-02-18 02:11:44 +0000977 {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100978 printf("testClient.testOneway(1) =>");
979 uint64_t startOneway = now();
980 testClient.testOneway(1);
981 uint64_t elapsed = now() - startOneway;
982 if (elapsed > 200 * 1000) { // 0.2 seconds
Jens Geyerd629ea02015-09-23 21:16:50 +0200983 printf("*** FAILED *** - took %.2f ms\n", (double)elapsed / 1000.0);
984 return_code |= ERR_BASETYPES;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100985 } else {
986 printf(" success - took %.2f ms\n", (double)elapsed / 1000.0);
987 }
David Reiss2ab6fe82008-02-18 02:11:44 +0000988 }
989
David Reiss2845b522008-02-18 02:11:52 +0000990 /**
David Reissc51986f2009-03-24 20:01:25 +0000991 * redo a simple test after the oneway to make sure we aren't "off by one" --
992 * if the server treated oneway void like normal void, this next test will
David Reiss2845b522008-02-18 02:11:52 +0000993 * fail since it will get the void confirmation rather than the correct
994 * result. In this circumstance, the client will throw the exception:
995 *
996 * TApplicationException: Wrong method namea
997 */
998 /**
999 * I32 TEST
1000 */
1001 printf("re-test testI32(-1)");
1002 i32 = testClient.testI32(-1);
1003 printf(" = %d\n", i32);
Roger Meier4fce9602012-05-04 06:22:09 +00001004 if (i32 != -1)
Jens Geyerd629ea02015-09-23 21:16:50 +02001005 return_code |= ERR_BASETYPES;
David Reiss2845b522008-02-18 02:11:52 +00001006
Marc Slemkobf4fd192006-08-15 21:29:39 +00001007 uint64_t stop = now();
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001008 uint64_t tot = stop - start;
Mark Sleed788b2e2006-09-07 01:26:35 +00001009
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001010 printf("Total time: %" PRIu64 " us\n", stop - start);
David Reiss0c90f6f2008-02-06 22:18:40 +00001011
Mark Sleed788b2e2006-09-07 01:26:35 +00001012 time_tot += tot;
1013 if (time_min == 0 || tot < time_min) {
1014 time_min = tot;
1015 }
1016 if (tot > time_max) {
1017 time_max = tot;
1018 }
1019
Mark Sleea3302652006-10-25 19:03:32 +00001020 transport->close();
Mark Sleee8540632006-05-30 09:24:40 +00001021 }
1022
Mark Sleee8540632006-05-30 09:24:40 +00001023 printf("\nAll tests done.\n");
Mark Sleed788b2e2006-09-07 01:26:35 +00001024
1025 uint64_t time_avg = time_tot / numTests;
1026
Roger Meier0e814802014-01-17 21:07:58 +01001027 printf("Min time: %" PRIu64 " us\n", time_min);
1028 printf("Max time: %" PRIu64 " us\n", time_max);
1029 printf("Avg time: %" PRIu64 " us\n", time_avg);
Mark Sleed788b2e2006-09-07 01:26:35 +00001030
Jens Geyerd629ea02015-09-23 21:16:50 +02001031 return return_code;
Mark Sleee8540632006-05-30 09:24:40 +00001032}