blob: c496bcba0c46d001628bbb48e6288950d264dc60 [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>
Roger Meier49ff8b12012-04-13 09:12:31 +000026#include <thrift/protocol/TJSONProtocol.h>
27#include <thrift/transport/THttpClient.h>
28#include <thrift/transport/TTransportUtils.h>
29#include <thrift/transport/TSocket.h>
30#include <thrift/transport/TSSLSocket.h>
31#include <thrift/async/TEvhttpClientChannel.h>
32#include <thrift/server/TNonblockingServer.h> // <event.h>
Mark Sleee8540632006-05-30 09:24:40 +000033
Marc Slemko6be374b2006-08-04 03:16:25 +000034#include <boost/shared_ptr.hpp>
Roger Meierca142b02011-06-07 17:59:07 +000035#include <boost/program_options.hpp>
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +053036#include <boost/filesystem.hpp>
Jake Farrell5d02b802014-01-07 21:42:01 -050037#include <thrift/cxxfunctional.h>
38#if _WIN32
Konrad Grochowski16a23a62014-11-13 15:33:38 +010039#include <thrift/windows/TWinsockSingleton.h>
Jake Farrell5d02b802014-01-07 21:42:01 -050040#endif
Roger Meierca142b02011-06-07 17:59:07 +000041
Marc Slemko6be374b2006-08-04 03:16:25 +000042#include "ThriftTest.h"
43
Marc Slemko6be374b2006-08-04 03:16:25 +000044using namespace std;
T Jake Lucianib5e62212009-01-31 22:36:20 +000045using namespace apache::thrift;
46using namespace apache::thrift::protocol;
47using namespace apache::thrift::transport;
Marc Slemkobf4fd192006-08-15 21:29:39 +000048using namespace thrift::test;
Roger Meier7e056e72011-07-17 07:28:28 +000049using namespace apache::thrift::async;
50
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +053051// Length of argv[0] - Length of script dir
52#define EXECUTABLE_FILE_NAME_LENGTH 19
53
Konrad Grochowski16a23a62014-11-13 15:33:38 +010054// extern uint32_t g_socket_syscalls;
Mark Slee95771002006-06-07 06:53:25 +000055
56// Current time, microseconds since the epoch
Konrad Grochowski16a23a62014-11-13 15:33:38 +010057uint64_t now() {
Roger Meier5f9614c2010-11-21 16:59:05 +000058 int64_t ret;
Mark Slee95771002006-06-07 06:53:25 +000059 struct timeval tv;
David Reiss0c90f6f2008-02-06 22:18:40 +000060
Jake Farrell5d02b802014-01-07 21:42:01 -050061 THRIFT_GETTIMEOFDAY(&tv, NULL);
Mark Slee95771002006-06-07 06:53:25 +000062 ret = tv.tv_sec;
Konrad Grochowski16a23a62014-11-13 15:33:38 +010063 ret = ret * 1000 * 1000 + tv.tv_usec;
Mark Slee95771002006-06-07 06:53:25 +000064 return ret;
65}
66
Konrad Grochowski16a23a62014-11-13 15:33:38 +010067static void testString_clientReturn(const char* host,
68 int port,
69 event_base* base,
70 TProtocolFactory* protocolFactory,
71 ThriftTestCobClient* client) {
72 (void)host;
73 (void)port;
74 (void)protocolFactory;
Roger Meier7e056e72011-07-17 07:28:28 +000075 try {
76 string s;
77 client->recv_testString(s);
78 cout << "testString: " << s << endl;
79 } catch (TException& exn) {
Jake Farrell5d02b802014-01-07 21:42:01 -050080 cout << "Error: " << exn.what() << endl;
Roger Meier7e056e72011-07-17 07:28:28 +000081 }
82
83 event_base_loopbreak(base); // end test
84}
85
Konrad Grochowski16a23a62014-11-13 15:33:38 +010086static void testVoid_clientReturn(const char* host,
87 int port,
88 event_base* base,
89 TProtocolFactory* protocolFactory,
90 ThriftTestCobClient* client) {
Roger Meier7e056e72011-07-17 07:28:28 +000091 try {
92 client->recv_testVoid();
93 cout << "testVoid" << endl;
94
95 // next test
96 delete client;
Roger Meier611f90c2011-12-11 22:08:51 +000097 boost::shared_ptr<TAsyncChannel> channel(new TEvhttpClientChannel(host, "/", host, port, base));
Roger Meier7e056e72011-07-17 07:28:28 +000098 client = new ThriftTestCobClient(channel, protocolFactory);
Konrad Grochowski16a23a62014-11-13 15:33:38 +010099 client->testString(tcxx::bind(testString_clientReturn,
100 host,
101 port,
102 base,
103 protocolFactory,
104 tcxx::placeholders::_1),
105 "Test");
Roger Meier7e056e72011-07-17 07:28:28 +0000106 } catch (TException& exn) {
Jake Farrell5d02b802014-01-07 21:42:01 -0500107 cout << "Error: " << exn.what() << endl;
Roger Meier7e056e72011-07-17 07:28:28 +0000108 }
109}
110
Mark Sleee8540632006-05-30 09:24:40 +0000111int main(int argc, char** argv) {
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +0530112 string file_path = boost::filesystem::system_complete(argv[0]).string();
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100113 string dir_path = file_path.substr(0, file_path.size() - EXECUTABLE_FILE_NAME_LENGTH);
Jake Farrell5d02b802014-01-07 21:42:01 -0500114#if _WIN32
115 transport::TWinsockSingleton::create();
116#endif
Mark Sleee8540632006-05-30 09:24:40 +0000117 string host = "localhost";
118 int port = 9090;
119 int numTests = 1;
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000120 bool ssl = false;
Roger Meierca142b02011-06-07 17:59:07 +0000121 string transport_type = "buffered";
122 string protocol_type = "binary";
123 string domain_socket = "";
Jens Geyerf4598682014-05-08 23:18:44 +0200124 bool noinsane = false;
Mark Sleee8540632006-05-30 09:24:40 +0000125
Jake Farrell5d02b802014-01-07 21:42:01 -0500126 boost::program_options::options_description desc("Allowed options");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100127 desc.add_options()("help,h",
128 "produce help message")("host",
129 boost::program_options::value<string>(&host)
130 ->default_value(host),
131 "Host to connect")("port",
132 boost::program_options::value<int>(
133 &port)->default_value(port),
134 "Port number to connect")(
135 "domain-socket",
136 boost::program_options::value<string>(&domain_socket)->default_value(domain_socket),
137 "Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port")(
138 "transport",
139 boost::program_options::value<string>(&transport_type)->default_value(transport_type),
140 "Transport: buffered, framed, http, evhttp")(
141 "protocol",
142 boost::program_options::value<string>(&protocol_type)->default_value(protocol_type),
143 "Protocol: binary, compact, json")("ssl", "Encrypted Transport using SSL")(
144 "testloops,n",
145 boost::program_options::value<int>(&numTests)->default_value(numTests),
146 "Number of Tests")("noinsane", "Do not run insanity test");
Roger Meierca142b02011-06-07 17:59:07 +0000147
Jake Farrell5d02b802014-01-07 21:42:01 -0500148 boost::program_options::variables_map vm;
149 boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
150 boost::program_options::notify(vm);
Roger Meierca142b02011-06-07 17:59:07 +0000151
152 if (vm.count("help")) {
153 cout << desc << "\n";
154 return 1;
Mark Sleee8540632006-05-30 09:24:40 +0000155 }
Mark Sleea3302652006-10-25 19:03:32 +0000156
Jake Farrell5d02b802014-01-07 21:42:01 -0500157 try {
Roger Meierca142b02011-06-07 17:59:07 +0000158 if (!protocol_type.empty()) {
159 if (protocol_type == "binary") {
Roger Meier284101c2014-03-11 21:20:35 +0100160 } else if (protocol_type == "compact") {
Roger Meierca142b02011-06-07 17:59:07 +0000161 } else if (protocol_type == "json") {
162 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100163 throw invalid_argument("Unknown protocol type " + protocol_type);
Roger Meierca142b02011-06-07 17:59:07 +0000164 }
165 }
166
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100167 if (!transport_type.empty()) {
Roger Meierca142b02011-06-07 17:59:07 +0000168 if (transport_type == "buffered") {
169 } else if (transport_type == "framed") {
170 } else if (transport_type == "http") {
Roger Meier7e056e72011-07-17 07:28:28 +0000171 } else if (transport_type == "evhttp") {
Roger Meierca142b02011-06-07 17:59:07 +0000172 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100173 throw invalid_argument("Unknown transport type " + transport_type);
Roger Meierca142b02011-06-07 17:59:07 +0000174 }
175 }
176
177 } catch (std::exception& e) {
178 cerr << e.what() << endl;
179 cout << desc << "\n";
180 return 1;
181 }
182
183 if (vm.count("ssl")) {
184 ssl = true;
185 }
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +0530186
Jens Geyerf4598682014-05-08 23:18:44 +0200187 if (vm.count("noinsane")) {
188 noinsane = true;
189 }
Roger Meierca142b02011-06-07 17:59:07 +0000190
Roger Meier611f90c2011-12-11 22:08:51 +0000191 boost::shared_ptr<TTransport> transport;
192 boost::shared_ptr<TProtocol> protocol;
Roger Meierca142b02011-06-07 17:59:07 +0000193
Roger Meier611f90c2011-12-11 22:08:51 +0000194 boost::shared_ptr<TSocket> socket;
195 boost::shared_ptr<TSSLSocketFactory> factory;
Roger Meierca142b02011-06-07 17:59:07 +0000196
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000197 if (ssl) {
Roger Meier611f90c2011-12-11 22:08:51 +0000198 factory = boost::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000199 factory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +0530200 factory->loadTrustedCertificates((dir_path + "../keys/CA.pem").c_str());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000201 factory->authenticate(true);
202 socket = factory->createSocket(host, port);
203 } else {
Roger Meierca142b02011-06-07 17:59:07 +0000204 if (domain_socket != "") {
Roger Meier611f90c2011-12-11 22:08:51 +0000205 socket = boost::shared_ptr<TSocket>(new TSocket(domain_socket));
Roger Meierca142b02011-06-07 17:59:07 +0000206 port = 0;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100207 } else {
Roger Meier611f90c2011-12-11 22:08:51 +0000208 socket = boost::shared_ptr<TSocket>(new TSocket(host, port));
Roger Meierca142b02011-06-07 17:59:07 +0000209 }
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000210 }
Mark Sleea3302652006-10-25 19:03:32 +0000211
Roger Meierca142b02011-06-07 17:59:07 +0000212 if (transport_type.compare("http") == 0) {
Roger Meier611f90c2011-12-11 22:08:51 +0000213 boost::shared_ptr<TTransport> httpSocket(new THttpClient(socket, host, "/service"));
Roger Meierca142b02011-06-07 17:59:07 +0000214 transport = httpSocket;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100215 } else if (transport_type.compare("framed") == 0) {
Roger Meier611f90c2011-12-11 22:08:51 +0000216 boost::shared_ptr<TFramedTransport> framedSocket(new TFramedTransport(socket));
Mark Sleea3302652006-10-25 19:03:32 +0000217 transport = framedSocket;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100218 } else {
Roger Meier611f90c2011-12-11 22:08:51 +0000219 boost::shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket));
Mark Sleea3302652006-10-25 19:03:32 +0000220 transport = bufferedSocket;
221 }
222
Roger Meierca142b02011-06-07 17:59:07 +0000223 if (protocol_type.compare("json") == 0) {
Roger Meier611f90c2011-12-11 22:08:51 +0000224 boost::shared_ptr<TProtocol> jsonProtocol(new TJSONProtocol(transport));
Roger Meierca142b02011-06-07 17:59:07 +0000225 protocol = jsonProtocol;
Roger Meier023192f2014-02-12 09:35:12 +0100226 } else if (protocol_type.compare("compact") == 0) {
227 boost::shared_ptr<TProtocol> compactProtocol(new TCompactProtocol(transport));
228 protocol = compactProtocol;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100229 } else {
Roger Meier611f90c2011-12-11 22:08:51 +0000230 boost::shared_ptr<TBinaryProtocol> binaryProtocol(new TBinaryProtocol(transport));
Roger Meierca142b02011-06-07 17:59:07 +0000231 protocol = binaryProtocol;
232 }
233
234 // Connection info
235 cout << "Connecting (" << transport_type << "/" << protocol_type << ") to: " << domain_socket;
236 if (port != 0) {
237 cout << host << ":" << port;
238 }
239 cout << endl;
240
Roger Meier7e056e72011-07-17 07:28:28 +0000241 if (transport_type.compare("evhttp") == 0) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100242 event_base* base = event_base_new();
Roger Meier7e056e72011-07-17 07:28:28 +0000243 cout << "Libevent Version: " << event_get_version() << endl;
244 cout << "Libevent Method: " << event_base_get_method(base) << endl;
245#if LIBEVENT_VERSION_NUMBER >= 0x02000000
246 cout << "Libevent Features: 0x" << hex << event_base_get_features(base) << endl;
247#endif
248
Roger Meier611f90c2011-12-11 22:08:51 +0000249 boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Roger Meier7e056e72011-07-17 07:28:28 +0000250
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100251 boost::shared_ptr<TAsyncChannel> channel(
252 new TEvhttpClientChannel(host.c_str(), "/", host.c_str(), port, base));
Roger Meier7e056e72011-07-17 07:28:28 +0000253 ThriftTestCobClient* client = new ThriftTestCobClient(channel, protocolFactory.get());
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100254 client->testVoid(tcxx::bind(testVoid_clientReturn,
255 host.c_str(),
256 port,
257 base,
258 protocolFactory.get(),
259 tcxx::placeholders::_1));
Jake Farrell5d02b802014-01-07 21:42:01 -0500260
Roger Meier7e056e72011-07-17 07:28:28 +0000261 event_base_loop(base, 0);
262 return 0;
263 }
264
Roger Meierca142b02011-06-07 17:59:07 +0000265 ThriftTestClient testClient(protocol);
Mark Sleed788b2e2006-09-07 01:26:35 +0000266
267 uint64_t time_min = 0;
268 uint64_t time_max = 0;
269 uint64_t time_tot = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000270
Roger Meier4fce9602012-05-04 06:22:09 +0000271 int failCount = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000272 int test = 0;
273 for (test = 0; test < numTests; ++test) {
Mark Slee95771002006-06-07 06:53:25 +0000274
Mark Slee95771002006-06-07 06:53:25 +0000275 try {
Mark Sleea3302652006-10-25 19:03:32 +0000276 transport->open();
Mark Slee95771002006-06-07 06:53:25 +0000277 } catch (TTransportException& ttx) {
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000278 printf("Connect failed: %s\n", ttx.what());
Roger Meier5b1e3c72011-12-08 13:20:12 +0000279 return 1;
Mark Sleee8540632006-05-30 09:24:40 +0000280 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000281
Mark Sleed788b2e2006-09-07 01:26:35 +0000282 /**
283 * CONNECT TEST
284 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100285 printf("Test #%d, connect %s:%d\n", test + 1, host.c_str(), port);
Mark Slee95771002006-06-07 06:53:25 +0000286
287 uint64_t start = now();
David Reiss0c90f6f2008-02-06 22:18:40 +0000288
Mark Sleee8540632006-05-30 09:24:40 +0000289 /**
290 * VOID TEST
291 */
Mark Sleee129a2d2007-02-21 05:17:48 +0000292 try {
293 printf("testVoid()");
294 testClient.testVoid();
295 printf(" = void\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000296 } catch (TApplicationException& tax) {
Mark Sleee129a2d2007-02-21 05:17:48 +0000297 printf("%s\n", tax.what());
Roger Meier4fce9602012-05-04 06:22:09 +0000298 failCount++;
Mark Sleee129a2d2007-02-21 05:17:48 +0000299 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000300
Mark Sleee8540632006-05-30 09:24:40 +0000301 /**
302 * STRING TEST
303 */
304 printf("testString(\"Test\")");
Mark Slee1921d202007-01-24 19:43:06 +0000305 string s;
306 testClient.testString(s, "Test");
Mark Sleee8540632006-05-30 09:24:40 +0000307 printf(" = \"%s\"\n", s.c_str());
Roger Meier4fce9602012-05-04 06:22:09 +0000308 if (s != "Test")
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100309 failCount++;
David Reiss0c90f6f2008-02-06 22:18:40 +0000310
Mark Sleee8540632006-05-30 09:24:40 +0000311 /**
312 * BYTE TEST
313 */
314 printf("testByte(1)");
315 uint8_t u8 = testClient.testByte(1);
316 printf(" = %d\n", (int)u8);
Roger Meier4fce9602012-05-04 06:22:09 +0000317 if (u8 != 1)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100318 failCount++;
David Reiss0c90f6f2008-02-06 22:18:40 +0000319
Mark Sleee8540632006-05-30 09:24:40 +0000320 /**
321 * I32 TEST
322 */
323 printf("testI32(-1)");
324 int32_t i32 = testClient.testI32(-1);
325 printf(" = %d\n", i32);
Roger Meier4fce9602012-05-04 06:22:09 +0000326 if (i32 != -1)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100327 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000328
329 /**
Mark Sleee8540632006-05-30 09:24:40 +0000330 * I64 TEST
331 */
332 printf("testI64(-34359738368)");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000333 int64_t i64 = testClient.testI64(-34359738368LL);
Roger Meier0e814802014-01-17 21:07:58 +0100334 printf(" = %" PRId64 "\n", i64);
Roger Meier4fce9602012-05-04 06:22:09 +0000335 if (i64 != -34359738368LL)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100336 failCount++;
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100337
Mark Sleec98d0502006-09-06 02:42:25 +0000338 /**
339 * DOUBLE TEST
340 */
341 printf("testDouble(-5.2098523)");
342 double dub = testClient.testDouble(-5.2098523);
Roger Meiera8cef6e2011-07-17 18:55:59 +0000343 printf(" = %f\n", dub);
Roger Meier4fce9602012-05-04 06:22:09 +0000344 if ((dub - (-5.2098523)) > 0.001)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100345 failCount++;
David Reiss0c90f6f2008-02-06 22:18:40 +0000346
Mark Sleee8540632006-05-30 09:24:40 +0000347 /**
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100348 * BINARY TEST
349 */
350 // TODO: add testBinary() call
351
352 /**
Mark Sleee8540632006-05-30 09:24:40 +0000353 * STRUCT TEST
354 */
Mark Slee6e536442006-06-30 18:28:50 +0000355 printf("testStruct({\"Zero\", 1, -3, -5})");
Mark Sleee8540632006-05-30 09:24:40 +0000356 Xtruct out;
357 out.string_thing = "Zero";
358 out.byte_thing = 1;
Mark Sleee8540632006-05-30 09:24:40 +0000359 out.i32_thing = -3;
Mark Sleee8540632006-05-30 09:24:40 +0000360 out.i64_thing = -5;
Mark Slee1921d202007-01-24 19:43:06 +0000361 Xtruct in;
362 testClient.testStruct(in, out);
Roger Meier0e814802014-01-17 21:07:58 +0100363 printf(" = {\"%s\", %d, %d, %" PRId64 "}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000364 in.string_thing.c_str(),
365 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000366 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000367 in.i64_thing);
Roger Meier4fce9602012-05-04 06:22:09 +0000368 if (in != out)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100369 failCount++;
David Reiss0c90f6f2008-02-06 22:18:40 +0000370
Mark Sleee8540632006-05-30 09:24:40 +0000371 /**
372 * NESTED STRUCT TEST
373 */
Mark Slee6e536442006-06-30 18:28:50 +0000374 printf("testNest({1, {\"Zero\", 1, -3, -5}), 5}");
Mark Sleee8540632006-05-30 09:24:40 +0000375 Xtruct2 out2;
376 out2.byte_thing = 1;
377 out2.struct_thing = out;
378 out2.i32_thing = 5;
Mark Slee1921d202007-01-24 19:43:06 +0000379 Xtruct2 in2;
380 testClient.testNest(in2, out2);
Mark Sleee8540632006-05-30 09:24:40 +0000381 in = in2.struct_thing;
Roger Meier0e814802014-01-17 21:07:58 +0100382 printf(" = {%d, {\"%s\", %d, %d, %" PRId64 "}, %d}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000383 in2.byte_thing,
384 in.string_thing.c_str(),
385 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000386 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000387 in.i64_thing,
David Reiss0c90f6f2008-02-06 22:18:40 +0000388 in2.i32_thing);
Roger Meier4fce9602012-05-04 06:22:09 +0000389 if (in2 != out2)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100390 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000391
392 /**
393 * MAP TEST
394 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100395 map<int32_t, int32_t> mapout;
Mark Sleee8540632006-05-30 09:24:40 +0000396 for (int32_t i = 0; i < 5; ++i) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100397 mapout.insert(make_pair(i, i - 10));
Mark Sleee8540632006-05-30 09:24:40 +0000398 }
399 printf("testMap({");
400 map<int32_t, int32_t>::const_iterator m_iter;
401 bool first = true;
402 for (m_iter = mapout.begin(); m_iter != mapout.end(); ++m_iter) {
403 if (first) {
404 first = false;
405 } else {
406 printf(", ");
407 }
408 printf("%d => %d", m_iter->first, m_iter->second);
409 }
410 printf("})");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100411 map<int32_t, int32_t> mapin;
Mark Slee1921d202007-01-24 19:43:06 +0000412 testClient.testMap(mapin, mapout);
Mark Sleee8540632006-05-30 09:24:40 +0000413 printf(" = {");
414 first = true;
415 for (m_iter = mapin.begin(); m_iter != mapin.end(); ++m_iter) {
416 if (first) {
417 first = false;
418 } else {
419 printf(", ");
420 }
421 printf("%d => %d", m_iter->first, m_iter->second);
422 }
423 printf("}\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000424 if (mapin != mapout)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100425 failCount++;
Roger Meier4fce9602012-05-04 06:22:09 +0000426
427 /**
428 * STRING MAP TEST
429 * missing
430 */
Mark Sleee8540632006-05-30 09:24:40 +0000431
432 /**
433 * SET TEST
434 */
435 set<int32_t> setout;
436 for (int32_t i = -2; i < 3; ++i) {
437 setout.insert(i);
438 }
439 printf("testSet({");
440 set<int32_t>::const_iterator s_iter;
441 first = true;
442 for (s_iter = setout.begin(); s_iter != setout.end(); ++s_iter) {
443 if (first) {
444 first = false;
445 } else {
446 printf(", ");
447 }
448 printf("%d", *s_iter);
449 }
450 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000451 set<int32_t> setin;
452 testClient.testSet(setin, setout);
Mark Sleee8540632006-05-30 09:24:40 +0000453 printf(" = {");
454 first = true;
455 for (s_iter = setin.begin(); s_iter != setin.end(); ++s_iter) {
456 if (first) {
457 first = false;
458 } else {
459 printf(", ");
460 }
461 printf("%d", *s_iter);
462 }
463 printf("}\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000464 if (setin != setout)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100465 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000466
467 /**
468 * LIST TEST
469 */
Mark Sleeb9acf982006-10-10 01:57:32 +0000470 vector<int32_t> listout;
Mark Sleee8540632006-05-30 09:24:40 +0000471 for (int32_t i = -2; i < 3; ++i) {
472 listout.push_back(i);
473 }
474 printf("testList({");
Mark Sleeb9acf982006-10-10 01:57:32 +0000475 vector<int32_t>::const_iterator l_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000476 first = true;
477 for (l_iter = listout.begin(); l_iter != listout.end(); ++l_iter) {
478 if (first) {
479 first = false;
480 } else {
481 printf(", ");
482 }
483 printf("%d", *l_iter);
484 }
485 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000486 vector<int32_t> listin;
487 testClient.testList(listin, listout);
Mark Sleee8540632006-05-30 09:24:40 +0000488 printf(" = {");
489 first = true;
490 for (l_iter = listin.begin(); l_iter != listin.end(); ++l_iter) {
491 if (first) {
492 first = false;
493 } else {
494 printf(", ");
495 }
496 printf("%d", *l_iter);
497 }
498 printf("}\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000499 if (listin != listout)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100500 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000501
502 /**
503 * ENUM TEST
504 */
505 printf("testEnum(ONE)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000506 Numberz::type ret = testClient.testEnum(Numberz::ONE);
Mark Sleee8540632006-05-30 09:24:40 +0000507 printf(" = %d\n", ret);
Roger Meier4fce9602012-05-04 06:22:09 +0000508 if (ret != Numberz::ONE)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100509 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000510
511 printf("testEnum(TWO)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000512 ret = testClient.testEnum(Numberz::TWO);
Mark Sleee8540632006-05-30 09:24:40 +0000513 printf(" = %d\n", ret);
Roger Meier4fce9602012-05-04 06:22:09 +0000514 if (ret != Numberz::TWO)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100515 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000516
517 printf("testEnum(THREE)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000518 ret = testClient.testEnum(Numberz::THREE);
Mark Sleee8540632006-05-30 09:24:40 +0000519 printf(" = %d\n", ret);
Roger Meier4fce9602012-05-04 06:22:09 +0000520 if (ret != Numberz::THREE)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100521 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000522
523 printf("testEnum(FIVE)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000524 ret = testClient.testEnum(Numberz::FIVE);
Mark Sleee8540632006-05-30 09:24:40 +0000525 printf(" = %d\n", ret);
Roger Meier4fce9602012-05-04 06:22:09 +0000526 if (ret != Numberz::FIVE)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100527 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000528
529 printf("testEnum(EIGHT)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000530 ret = testClient.testEnum(Numberz::EIGHT);
Mark Sleee8540632006-05-30 09:24:40 +0000531 printf(" = %d\n", ret);
Roger Meier4fce9602012-05-04 06:22:09 +0000532 if (ret != Numberz::EIGHT)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100533 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000534
535 /**
536 * TYPEDEF TEST
537 */
538 printf("testTypedef(309858235082523)");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000539 UserId uid = testClient.testTypedef(309858235082523LL);
Roger Meier0e814802014-01-17 21:07:58 +0100540 printf(" = %" PRId64 "\n", uid);
Roger Meier4fce9602012-05-04 06:22:09 +0000541 if (uid != 309858235082523LL)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100542 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000543
544 /**
545 * NESTED MAP TEST
546 */
547 printf("testMapMap(1)");
Mark Slee1921d202007-01-24 19:43:06 +0000548 map<int32_t, map<int32_t, int32_t> > mm;
549 testClient.testMapMap(mm, 1);
Mark Sleee8540632006-05-30 09:24:40 +0000550 printf(" = {");
551 map<int32_t, map<int32_t, int32_t> >::const_iterator mi;
552 for (mi = mm.begin(); mi != mm.end(); ++mi) {
553 printf("%d => {", mi->first);
554 map<int32_t, int32_t>::const_iterator mi2;
555 for (mi2 = mi->second.begin(); mi2 != mi->second.end(); ++mi2) {
556 printf("%d => %d, ", mi2->first, mi2->second);
557 }
558 printf("}, ");
559 }
560 printf("}\n");
561
562 /**
563 * INSANITY TEST
564 */
Jens Geyerf4598682014-05-08 23:18:44 +0200565 if (!noinsane) {
566 Insanity insane;
567 insane.userMap.insert(make_pair(Numberz::FIVE, 5000));
568 Xtruct truck;
569 truck.string_thing = "Truck";
570 truck.byte_thing = 8;
571 truck.i32_thing = 8;
572 truck.i64_thing = 8;
573 insane.xtructs.push_back(truck);
574 printf("testInsanity()");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100575 map<UserId, map<Numberz::type, Insanity> > whoa;
Jens Geyerf4598682014-05-08 23:18:44 +0200576 testClient.testInsanity(whoa, insane);
577 printf(" = {");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100578 map<UserId, map<Numberz::type, Insanity> >::const_iterator i_iter;
Jens Geyerf4598682014-05-08 23:18:44 +0200579 for (i_iter = whoa.begin(); i_iter != whoa.end(); ++i_iter) {
580 printf("%" PRId64 " => {", i_iter->first);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100581 map<Numberz::type, Insanity>::const_iterator i2_iter;
582 for (i2_iter = i_iter->second.begin(); i2_iter != i_iter->second.end(); ++i2_iter) {
Jens Geyerf4598682014-05-08 23:18:44 +0200583 printf("%d => {", i2_iter->first);
584 map<Numberz::type, UserId> userMap = i2_iter->second.userMap;
585 map<Numberz::type, UserId>::const_iterator um;
586 printf("{");
587 for (um = userMap.begin(); um != userMap.end(); ++um) {
588 printf("%d => %" PRId64 ", ", um->first, um->second);
589 }
590 printf("}, ");
Mark Sleee8540632006-05-30 09:24:40 +0000591
Jens Geyerf4598682014-05-08 23:18:44 +0200592 vector<Xtruct> xtructs = i2_iter->second.xtructs;
593 vector<Xtruct>::const_iterator x;
594 printf("{");
595 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
596 printf("{\"%s\", %d, %d, %" PRId64 "}, ",
597 x->string_thing.c_str(),
598 (int)x->byte_thing,
599 x->i32_thing,
600 x->i64_thing);
601 }
602 printf("}");
Mark Sleee8540632006-05-30 09:24:40 +0000603
Jens Geyerf4598682014-05-08 23:18:44 +0200604 printf("}, ");
605 }
Mark Sleee8540632006-05-30 09:24:40 +0000606 printf("}, ");
607 }
Jens Geyerf4598682014-05-08 23:18:44 +0200608 printf("}\n");
Mark Sleee8540632006-05-30 09:24:40 +0000609 }
Marc Slemko71d4e472006-08-15 22:34:04 +0000610 /* test exception */
Mark Slee95771002006-06-07 06:53:25 +0000611
Marc Slemkobf4fd192006-08-15 21:29:39 +0000612 try {
Marc Slemko71d4e472006-08-15 22:34:04 +0000613 printf("testClient.testException(\"Xception\") =>");
614 testClient.testException("Xception");
615 printf(" void\nFAILURE\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000616 failCount++;
David Reiss0c90f6f2008-02-06 22:18:40 +0000617
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100618 } catch (Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000619 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000620 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000621
Marc Slemkobf4fd192006-08-15 21:29:39 +0000622 try {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100623 printf("testClient.testException(\"TException\") =>");
624 testClient.testException("TException");
625 printf(" void\nFAILURE\n");
626 failCount++;
Roger Meierf50df7f2012-05-02 22:49:55 +0000627
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100628 } catch (const TException&) {
629 printf(" Caught TException\n");
630 }
Roger Meierf50df7f2012-05-02 22:49:55 +0000631
632 try {
Marc Slemko71d4e472006-08-15 22:34:04 +0000633 printf("testClient.testException(\"success\") =>");
634 testClient.testException("success");
635 printf(" void\n");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100636 } catch (...) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000637 printf(" exception\nFAILURE\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000638 failCount++;
Marc Slemko71d4e472006-08-15 22:34:04 +0000639 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000640
Marc Slemko71d4e472006-08-15 22:34:04 +0000641 /* test multi exception */
David Reiss0c90f6f2008-02-06 22:18:40 +0000642
Marc Slemko71d4e472006-08-15 22:34:04 +0000643 try {
644 printf("testClient.testMultiException(\"Xception\", \"test 1\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000645 Xtruct result;
646 testClient.testMultiException(result, "Xception", "test 1");
Marc Slemko71d4e472006-08-15 22:34:04 +0000647 printf(" result\nFAILURE\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000648 failCount++;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100649 } catch (Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000650 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
651 }
652
653 try {
654 printf("testClient.testMultiException(\"Xception2\", \"test 2\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000655 Xtruct result;
656 testClient.testMultiException(result, "Xception2", "test 2");
Marc Slemko71d4e472006-08-15 22:34:04 +0000657 printf(" result\nFAILURE\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000658 failCount++;
David Reiss0c90f6f2008-02-06 22:18:40 +0000659
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100660 } catch (Xception2& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000661 printf(" {%u, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000662 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000663
Marc Slemko71d4e472006-08-15 22:34:04 +0000664 try {
665 printf("testClient.testMultiException(\"success\", \"test 3\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000666 Xtruct result;
667 testClient.testMultiException(result, "success", "test 3");
Marc Slemko71d4e472006-08-15 22:34:04 +0000668 printf(" {{\"%s\"}}\n", result.string_thing.c_str());
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100669 } catch (...) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000670 printf(" exception\nFAILURE\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000671 failCount++;
Marc Slemko71d4e472006-08-15 22:34:04 +0000672 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000673
David Reissc51986f2009-03-24 20:01:25 +0000674 /* test oneway void */
David Reiss2ab6fe82008-02-18 02:11:44 +0000675 {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100676 printf("testClient.testOneway(1) =>");
677 uint64_t startOneway = now();
678 testClient.testOneway(1);
679 uint64_t elapsed = now() - startOneway;
680 if (elapsed > 200 * 1000) { // 0.2 seconds
681 printf(" FAILURE - took %.2f ms\n", (double)elapsed / 1000.0);
682 failCount++;
683 } else {
684 printf(" success - took %.2f ms\n", (double)elapsed / 1000.0);
685 }
David Reiss2ab6fe82008-02-18 02:11:44 +0000686 }
687
David Reiss2845b522008-02-18 02:11:52 +0000688 /**
David Reissc51986f2009-03-24 20:01:25 +0000689 * redo a simple test after the oneway to make sure we aren't "off by one" --
690 * if the server treated oneway void like normal void, this next test will
David Reiss2845b522008-02-18 02:11:52 +0000691 * fail since it will get the void confirmation rather than the correct
692 * result. In this circumstance, the client will throw the exception:
693 *
694 * TApplicationException: Wrong method namea
695 */
696 /**
697 * I32 TEST
698 */
699 printf("re-test testI32(-1)");
700 i32 = testClient.testI32(-1);
701 printf(" = %d\n", i32);
Roger Meier4fce9602012-05-04 06:22:09 +0000702 if (i32 != -1)
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100703 failCount++;
David Reiss2845b522008-02-18 02:11:52 +0000704
Marc Slemkobf4fd192006-08-15 21:29:39 +0000705 uint64_t stop = now();
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100706 uint64_t tot = stop - start;
Mark Sleed788b2e2006-09-07 01:26:35 +0000707
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100708 printf("Total time: %" PRIu64 " us\n", stop - start);
David Reiss0c90f6f2008-02-06 22:18:40 +0000709
Mark Sleed788b2e2006-09-07 01:26:35 +0000710 time_tot += tot;
711 if (time_min == 0 || tot < time_min) {
712 time_min = tot;
713 }
714 if (tot > time_max) {
715 time_max = tot;
716 }
717
Mark Sleea3302652006-10-25 19:03:32 +0000718 transport->close();
Mark Sleee8540632006-05-30 09:24:40 +0000719 }
720
Marc Slemko6be374b2006-08-04 03:16:25 +0000721 // printf("\nSocket syscalls: %u", g_socket_syscalls);
Mark Sleee8540632006-05-30 09:24:40 +0000722 printf("\nAll tests done.\n");
Mark Sleed788b2e2006-09-07 01:26:35 +0000723
724 uint64_t time_avg = time_tot / numTests;
725
Roger Meier0e814802014-01-17 21:07:58 +0100726 printf("Min time: %" PRIu64 " us\n", time_min);
727 printf("Max time: %" PRIu64 " us\n", time_max);
728 printf("Avg time: %" PRIu64 " us\n", time_avg);
Mark Sleed788b2e2006-09-07 01:26:35 +0000729
Roger Meier4fce9602012-05-04 06:22:09 +0000730 return failCount;
Mark Sleee8540632006-05-30 09:24:40 +0000731}