blob: cd78505b3c182b2d56fcfe52425ca434ebd292d6 [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>
25#include <thrift/protocol/TJSONProtocol.h>
26#include <thrift/transport/THttpClient.h>
27#include <thrift/transport/TTransportUtils.h>
28#include <thrift/transport/TSocket.h>
29#include <thrift/transport/TSSLSocket.h>
30#include <thrift/async/TEvhttpClientChannel.h>
31#include <thrift/server/TNonblockingServer.h> // <event.h>
Mark Sleee8540632006-05-30 09:24:40 +000032
Marc Slemko6be374b2006-08-04 03:16:25 +000033#include <boost/shared_ptr.hpp>
Roger Meierca142b02011-06-07 17:59:07 +000034#include <boost/program_options.hpp>
Jake Farrell5d02b802014-01-07 21:42:01 -050035#include <thrift/cxxfunctional.h>
36#if _WIN32
37 #include <thrift/windows/TWinsockSingleton.h>
38#endif
Roger Meierca142b02011-06-07 17:59:07 +000039
Marc Slemko6be374b2006-08-04 03:16:25 +000040#include "ThriftTest.h"
41
Marc Slemko6be374b2006-08-04 03:16:25 +000042using namespace std;
T Jake Lucianib5e62212009-01-31 22:36:20 +000043using namespace apache::thrift;
44using namespace apache::thrift::protocol;
45using namespace apache::thrift::transport;
Marc Slemkobf4fd192006-08-15 21:29:39 +000046using namespace thrift::test;
Roger Meier7e056e72011-07-17 07:28:28 +000047using namespace apache::thrift::async;
48
Marc Slemko6be374b2006-08-04 03:16:25 +000049//extern uint32_t g_socket_syscalls;
Mark Slee95771002006-06-07 06:53:25 +000050
51// Current time, microseconds since the epoch
52uint64_t now()
53{
Roger Meier5f9614c2010-11-21 16:59:05 +000054 int64_t ret;
Mark Slee95771002006-06-07 06:53:25 +000055 struct timeval tv;
David Reiss0c90f6f2008-02-06 22:18:40 +000056
Jake Farrell5d02b802014-01-07 21:42:01 -050057 THRIFT_GETTIMEOFDAY(&tv, NULL);
Mark Slee95771002006-06-07 06:53:25 +000058 ret = tv.tv_sec;
59 ret = ret*1000*1000 + tv.tv_usec;
60 return ret;
61}
62
Roger Meier7e056e72011-07-17 07:28:28 +000063static void testString_clientReturn(const char* host, int port, event_base *base, TProtocolFactory* protocolFactory, ThriftTestCobClient* client) {
Roger Meiera8cef6e2011-07-17 18:55:59 +000064 (void) host;
65 (void) port;
66 (void) protocolFactory;
Roger Meier7e056e72011-07-17 07:28:28 +000067 try {
68 string s;
69 client->recv_testString(s);
70 cout << "testString: " << s << endl;
71 } catch (TException& exn) {
Jake Farrell5d02b802014-01-07 21:42:01 -050072 cout << "Error: " << exn.what() << endl;
Roger Meier7e056e72011-07-17 07:28:28 +000073 }
74
75 event_base_loopbreak(base); // end test
76}
77
78static void testVoid_clientReturn(const char* host, int port, event_base *base, TProtocolFactory* protocolFactory, ThriftTestCobClient* client) {
79 try {
80 client->recv_testVoid();
81 cout << "testVoid" << endl;
82
83 // next test
84 delete client;
Roger Meier611f90c2011-12-11 22:08:51 +000085 boost::shared_ptr<TAsyncChannel> channel(new TEvhttpClientChannel(host, "/", host, port, base));
Roger Meier7e056e72011-07-17 07:28:28 +000086 client = new ThriftTestCobClient(channel, protocolFactory);
Roger Meier3faaedf2011-10-02 10:51:45 +000087 client->testString(tr1::bind(testString_clientReturn, host, port, base, protocolFactory, std::tr1::placeholders::_1), "Test");
Roger Meier7e056e72011-07-17 07:28:28 +000088 } catch (TException& exn) {
Jake Farrell5d02b802014-01-07 21:42:01 -050089 cout << "Error: " << exn.what() << endl;
Roger Meier7e056e72011-07-17 07:28:28 +000090 }
91}
92
Mark Sleee8540632006-05-30 09:24:40 +000093int main(int argc, char** argv) {
Jake Farrell5d02b802014-01-07 21:42:01 -050094#if _WIN32
95 transport::TWinsockSingleton::create();
96#endif
Mark Sleee8540632006-05-30 09:24:40 +000097 string host = "localhost";
98 int port = 9090;
99 int numTests = 1;
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000100 bool ssl = false;
Roger Meierca142b02011-06-07 17:59:07 +0000101 string transport_type = "buffered";
102 string protocol_type = "binary";
103 string domain_socket = "";
Mark Sleee8540632006-05-30 09:24:40 +0000104
Jake Farrell5d02b802014-01-07 21:42:01 -0500105 boost::program_options::options_description desc("Allowed options");
Roger Meierca142b02011-06-07 17:59:07 +0000106 desc.add_options()
107 ("help,h", "produce help message")
Jake Farrell5d02b802014-01-07 21:42:01 -0500108 ("host", boost::program_options::value<string>(&host)->default_value(host), "Host to connect")
109 ("port", boost::program_options::value<int>(&port)->default_value(port), "Port number to connect")
110 ("domain-socket", boost::program_options::value<string>(&domain_socket)->default_value(domain_socket), "Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port")
111 ("transport", boost::program_options::value<string>(&transport_type)->default_value(transport_type), "Transport: buffered, framed, http, evhttp")
112 ("protocol", boost::program_options::value<string>(&protocol_type)->default_value(protocol_type), "Protocol: binary, json")
Roger Meierca142b02011-06-07 17:59:07 +0000113 ("ssl", "Encrypted Transport using SSL")
Jake Farrell5d02b802014-01-07 21:42:01 -0500114 ("testloops,n", boost::program_options::value<int>(&numTests)->default_value(numTests), "Number of Tests")
Roger Meierca142b02011-06-07 17:59:07 +0000115 ;
116
Jake Farrell5d02b802014-01-07 21:42:01 -0500117 boost::program_options::variables_map vm;
118 boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
119 boost::program_options::notify(vm);
Roger Meierca142b02011-06-07 17:59:07 +0000120
121 if (vm.count("help")) {
122 cout << desc << "\n";
123 return 1;
Mark Sleee8540632006-05-30 09:24:40 +0000124 }
Mark Sleea3302652006-10-25 19:03:32 +0000125
Jake Farrell5d02b802014-01-07 21:42:01 -0500126 try {
Roger Meierca142b02011-06-07 17:59:07 +0000127 if (!protocol_type.empty()) {
128 if (protocol_type == "binary") {
129 } else if (protocol_type == "json") {
130 } else {
131 throw invalid_argument("Unknown protocol type "+protocol_type);
132 }
133 }
134
135 if (!transport_type.empty()) {
136 if (transport_type == "buffered") {
137 } else if (transport_type == "framed") {
138 } else if (transport_type == "http") {
Roger Meier7e056e72011-07-17 07:28:28 +0000139 } else if (transport_type == "evhttp") {
Roger Meierca142b02011-06-07 17:59:07 +0000140 } else {
141 throw invalid_argument("Unknown transport type "+transport_type);
142 }
143 }
144
145 } catch (std::exception& e) {
146 cerr << e.what() << endl;
147 cout << desc << "\n";
148 return 1;
149 }
150
151 if (vm.count("ssl")) {
152 ssl = true;
153 }
154
Roger Meier611f90c2011-12-11 22:08:51 +0000155 boost::shared_ptr<TTransport> transport;
156 boost::shared_ptr<TProtocol> protocol;
Roger Meierca142b02011-06-07 17:59:07 +0000157
Roger Meier611f90c2011-12-11 22:08:51 +0000158 boost::shared_ptr<TSocket> socket;
159 boost::shared_ptr<TSSLSocketFactory> factory;
Roger Meierca142b02011-06-07 17:59:07 +0000160
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000161 if (ssl) {
Roger Meier611f90c2011-12-11 22:08:51 +0000162 factory = boost::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000163 factory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
164 factory->loadTrustedCertificates("./trusted-ca-certificate.pem");
165 factory->authenticate(true);
166 socket = factory->createSocket(host, port);
167 } else {
Roger Meierca142b02011-06-07 17:59:07 +0000168 if (domain_socket != "") {
Roger Meier611f90c2011-12-11 22:08:51 +0000169 socket = boost::shared_ptr<TSocket>(new TSocket(domain_socket));
Roger Meierca142b02011-06-07 17:59:07 +0000170 port = 0;
171 }
172 else {
Roger Meier611f90c2011-12-11 22:08:51 +0000173 socket = boost::shared_ptr<TSocket>(new TSocket(host, port));
Roger Meierca142b02011-06-07 17:59:07 +0000174 }
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000175 }
Mark Sleea3302652006-10-25 19:03:32 +0000176
Roger Meierca142b02011-06-07 17:59:07 +0000177 if (transport_type.compare("http") == 0) {
Roger Meier611f90c2011-12-11 22:08:51 +0000178 boost::shared_ptr<TTransport> httpSocket(new THttpClient(socket, host, "/service"));
Roger Meierca142b02011-06-07 17:59:07 +0000179 transport = httpSocket;
180 } else if (transport_type.compare("framed") == 0){
Roger Meier611f90c2011-12-11 22:08:51 +0000181 boost::shared_ptr<TFramedTransport> framedSocket(new TFramedTransport(socket));
Mark Sleea3302652006-10-25 19:03:32 +0000182 transport = framedSocket;
Roger Meierca142b02011-06-07 17:59:07 +0000183 } else{
Roger Meier611f90c2011-12-11 22:08:51 +0000184 boost::shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket));
Mark Sleea3302652006-10-25 19:03:32 +0000185 transport = bufferedSocket;
186 }
187
Roger Meierca142b02011-06-07 17:59:07 +0000188 if (protocol_type.compare("json") == 0) {
Roger Meier611f90c2011-12-11 22:08:51 +0000189 boost::shared_ptr<TProtocol> jsonProtocol(new TJSONProtocol(transport));
Roger Meierca142b02011-06-07 17:59:07 +0000190 protocol = jsonProtocol;
191 } else{
Roger Meier611f90c2011-12-11 22:08:51 +0000192 boost::shared_ptr<TBinaryProtocol> binaryProtocol(new TBinaryProtocol(transport));
Roger Meierca142b02011-06-07 17:59:07 +0000193 protocol = binaryProtocol;
194 }
195
196 // Connection info
197 cout << "Connecting (" << transport_type << "/" << protocol_type << ") to: " << domain_socket;
198 if (port != 0) {
199 cout << host << ":" << port;
200 }
201 cout << endl;
202
Roger Meier7e056e72011-07-17 07:28:28 +0000203 if (transport_type.compare("evhttp") == 0) {
204 event_base *base = event_base_new();
205 cout << "Libevent Version: " << event_get_version() << endl;
206 cout << "Libevent Method: " << event_base_get_method(base) << endl;
207#if LIBEVENT_VERSION_NUMBER >= 0x02000000
208 cout << "Libevent Features: 0x" << hex << event_base_get_features(base) << endl;
209#endif
210
Roger Meier611f90c2011-12-11 22:08:51 +0000211 boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Roger Meier7e056e72011-07-17 07:28:28 +0000212
Roger Meier611f90c2011-12-11 22:08:51 +0000213 boost::shared_ptr<TAsyncChannel> channel(new TEvhttpClientChannel(host.c_str(), "/", host.c_str(), port, base));
Roger Meier7e056e72011-07-17 07:28:28 +0000214 ThriftTestCobClient* client = new ThriftTestCobClient(channel, protocolFactory.get());
Roger Meier3faaedf2011-10-02 10:51:45 +0000215 client->testVoid(tr1::bind(testVoid_clientReturn, host.c_str(), port, base, protocolFactory.get(), std::tr1::placeholders::_1));
Jake Farrell5d02b802014-01-07 21:42:01 -0500216
Roger Meier7e056e72011-07-17 07:28:28 +0000217 event_base_loop(base, 0);
218 return 0;
219 }
220
221
Roger Meierca142b02011-06-07 17:59:07 +0000222 ThriftTestClient testClient(protocol);
Mark Sleed788b2e2006-09-07 01:26:35 +0000223
224 uint64_t time_min = 0;
225 uint64_t time_max = 0;
226 uint64_t time_tot = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000227
Roger Meier4fce9602012-05-04 06:22:09 +0000228 int failCount = 0;
Mark Sleee8540632006-05-30 09:24:40 +0000229 int test = 0;
230 for (test = 0; test < numTests; ++test) {
Mark Slee95771002006-06-07 06:53:25 +0000231
Mark Slee95771002006-06-07 06:53:25 +0000232 try {
Mark Sleea3302652006-10-25 19:03:32 +0000233 transport->open();
Mark Slee95771002006-06-07 06:53:25 +0000234 } catch (TTransportException& ttx) {
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000235 printf("Connect failed: %s\n", ttx.what());
Roger Meier5b1e3c72011-12-08 13:20:12 +0000236 return 1;
Mark Sleee8540632006-05-30 09:24:40 +0000237 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000238
Mark Sleed788b2e2006-09-07 01:26:35 +0000239 /**
240 * CONNECT TEST
241 */
242 printf("Test #%d, connect %s:%d\n", test+1, host.c_str(), port);
Mark Slee95771002006-06-07 06:53:25 +0000243
244 uint64_t start = now();
David Reiss0c90f6f2008-02-06 22:18:40 +0000245
Mark Sleee8540632006-05-30 09:24:40 +0000246 /**
247 * VOID TEST
248 */
Mark Sleee129a2d2007-02-21 05:17:48 +0000249 try {
250 printf("testVoid()");
251 testClient.testVoid();
252 printf(" = void\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000253 } catch (TApplicationException& tax) {
Mark Sleee129a2d2007-02-21 05:17:48 +0000254 printf("%s\n", tax.what());
Roger Meier4fce9602012-05-04 06:22:09 +0000255 failCount++;
Mark Sleee129a2d2007-02-21 05:17:48 +0000256 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000257
Mark Sleee8540632006-05-30 09:24:40 +0000258 /**
259 * STRING TEST
260 */
261 printf("testString(\"Test\")");
Mark Slee1921d202007-01-24 19:43:06 +0000262 string s;
263 testClient.testString(s, "Test");
Mark Sleee8540632006-05-30 09:24:40 +0000264 printf(" = \"%s\"\n", s.c_str());
Roger Meier4fce9602012-05-04 06:22:09 +0000265 if (s != "Test")
266 failCount++;
David Reiss0c90f6f2008-02-06 22:18:40 +0000267
Mark Sleee8540632006-05-30 09:24:40 +0000268 /**
269 * BYTE TEST
270 */
271 printf("testByte(1)");
272 uint8_t u8 = testClient.testByte(1);
273 printf(" = %d\n", (int)u8);
Roger Meier4fce9602012-05-04 06:22:09 +0000274 if (u8 != 1)
275 failCount++;
David Reiss0c90f6f2008-02-06 22:18:40 +0000276
Mark Sleee8540632006-05-30 09:24:40 +0000277 /**
278 * I32 TEST
279 */
280 printf("testI32(-1)");
281 int32_t i32 = testClient.testI32(-1);
282 printf(" = %d\n", i32);
Roger Meier4fce9602012-05-04 06:22:09 +0000283 if (i32 != -1)
284 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000285
286 /**
Mark Sleee8540632006-05-30 09:24:40 +0000287 * I64 TEST
288 */
289 printf("testI64(-34359738368)");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000290 int64_t i64 = testClient.testI64(-34359738368LL);
David Reissbc3dddb2007-08-22 23:20:24 +0000291 printf(" = %"PRId64"\n", i64);
Roger Meier4fce9602012-05-04 06:22:09 +0000292 if (i64 != -34359738368LL)
293 failCount++;
Mark Sleec98d0502006-09-06 02:42:25 +0000294 /**
295 * DOUBLE TEST
296 */
297 printf("testDouble(-5.2098523)");
298 double dub = testClient.testDouble(-5.2098523);
Roger Meiera8cef6e2011-07-17 18:55:59 +0000299 printf(" = %f\n", dub);
Roger Meier4fce9602012-05-04 06:22:09 +0000300 if ((dub - (-5.2098523)) > 0.001)
301 failCount++;
David Reiss0c90f6f2008-02-06 22:18:40 +0000302
Mark Sleee8540632006-05-30 09:24:40 +0000303 /**
304 * STRUCT TEST
305 */
Mark Slee6e536442006-06-30 18:28:50 +0000306 printf("testStruct({\"Zero\", 1, -3, -5})");
Mark Sleee8540632006-05-30 09:24:40 +0000307 Xtruct out;
308 out.string_thing = "Zero";
309 out.byte_thing = 1;
Mark Sleee8540632006-05-30 09:24:40 +0000310 out.i32_thing = -3;
Mark Sleee8540632006-05-30 09:24:40 +0000311 out.i64_thing = -5;
Mark Slee1921d202007-01-24 19:43:06 +0000312 Xtruct in;
313 testClient.testStruct(in, out);
David Reissbc3dddb2007-08-22 23:20:24 +0000314 printf(" = {\"%s\", %d, %d, %"PRId64"}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000315 in.string_thing.c_str(),
316 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000317 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000318 in.i64_thing);
Roger Meier4fce9602012-05-04 06:22:09 +0000319 if (in != out)
320 failCount++;
David Reiss0c90f6f2008-02-06 22:18:40 +0000321
Mark Sleee8540632006-05-30 09:24:40 +0000322 /**
323 * NESTED STRUCT TEST
324 */
Mark Slee6e536442006-06-30 18:28:50 +0000325 printf("testNest({1, {\"Zero\", 1, -3, -5}), 5}");
Mark Sleee8540632006-05-30 09:24:40 +0000326 Xtruct2 out2;
327 out2.byte_thing = 1;
328 out2.struct_thing = out;
329 out2.i32_thing = 5;
Mark Slee1921d202007-01-24 19:43:06 +0000330 Xtruct2 in2;
331 testClient.testNest(in2, out2);
Mark Sleee8540632006-05-30 09:24:40 +0000332 in = in2.struct_thing;
David Reissbc3dddb2007-08-22 23:20:24 +0000333 printf(" = {%d, {\"%s\", %d, %d, %"PRId64"}, %d}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000334 in2.byte_thing,
335 in.string_thing.c_str(),
336 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000337 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000338 in.i64_thing,
David Reiss0c90f6f2008-02-06 22:18:40 +0000339 in2.i32_thing);
Roger Meier4fce9602012-05-04 06:22:09 +0000340 if (in2 != out2)
341 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000342
343 /**
344 * MAP TEST
345 */
346 map<int32_t,int32_t> mapout;
347 for (int32_t i = 0; i < 5; ++i) {
348 mapout.insert(make_pair(i, i-10));
349 }
350 printf("testMap({");
351 map<int32_t, int32_t>::const_iterator m_iter;
352 bool first = true;
353 for (m_iter = mapout.begin(); m_iter != mapout.end(); ++m_iter) {
354 if (first) {
355 first = false;
356 } else {
357 printf(", ");
358 }
359 printf("%d => %d", m_iter->first, m_iter->second);
360 }
361 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000362 map<int32_t,int32_t> mapin;
363 testClient.testMap(mapin, mapout);
Mark Sleee8540632006-05-30 09:24:40 +0000364 printf(" = {");
365 first = true;
366 for (m_iter = mapin.begin(); m_iter != mapin.end(); ++m_iter) {
367 if (first) {
368 first = false;
369 } else {
370 printf(", ");
371 }
372 printf("%d => %d", m_iter->first, m_iter->second);
373 }
374 printf("}\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000375 if (mapin != mapout)
376 failCount++;
377
378 /**
379 * STRING MAP TEST
380 * missing
381 */
Mark Sleee8540632006-05-30 09:24:40 +0000382
383 /**
384 * SET TEST
385 */
386 set<int32_t> setout;
387 for (int32_t i = -2; i < 3; ++i) {
388 setout.insert(i);
389 }
390 printf("testSet({");
391 set<int32_t>::const_iterator s_iter;
392 first = true;
393 for (s_iter = setout.begin(); s_iter != setout.end(); ++s_iter) {
394 if (first) {
395 first = false;
396 } else {
397 printf(", ");
398 }
399 printf("%d", *s_iter);
400 }
401 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000402 set<int32_t> setin;
403 testClient.testSet(setin, setout);
Mark Sleee8540632006-05-30 09:24:40 +0000404 printf(" = {");
405 first = true;
406 for (s_iter = setin.begin(); s_iter != setin.end(); ++s_iter) {
407 if (first) {
408 first = false;
409 } else {
410 printf(", ");
411 }
412 printf("%d", *s_iter);
413 }
414 printf("}\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000415 if (setin != setout)
416 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000417
418 /**
419 * LIST TEST
420 */
Mark Sleeb9acf982006-10-10 01:57:32 +0000421 vector<int32_t> listout;
Mark Sleee8540632006-05-30 09:24:40 +0000422 for (int32_t i = -2; i < 3; ++i) {
423 listout.push_back(i);
424 }
425 printf("testList({");
Mark Sleeb9acf982006-10-10 01:57:32 +0000426 vector<int32_t>::const_iterator l_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000427 first = true;
428 for (l_iter = listout.begin(); l_iter != listout.end(); ++l_iter) {
429 if (first) {
430 first = false;
431 } else {
432 printf(", ");
433 }
434 printf("%d", *l_iter);
435 }
436 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000437 vector<int32_t> listin;
438 testClient.testList(listin, listout);
Mark Sleee8540632006-05-30 09:24:40 +0000439 printf(" = {");
440 first = true;
441 for (l_iter = listin.begin(); l_iter != listin.end(); ++l_iter) {
442 if (first) {
443 first = false;
444 } else {
445 printf(", ");
446 }
447 printf("%d", *l_iter);
448 }
449 printf("}\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000450 if (listin != listout)
451 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000452
453 /**
454 * ENUM TEST
455 */
456 printf("testEnum(ONE)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000457 Numberz::type ret = testClient.testEnum(Numberz::ONE);
Mark Sleee8540632006-05-30 09:24:40 +0000458 printf(" = %d\n", ret);
Roger Meier4fce9602012-05-04 06:22:09 +0000459 if (ret != Numberz::ONE)
460 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000461
462 printf("testEnum(TWO)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000463 ret = testClient.testEnum(Numberz::TWO);
Mark Sleee8540632006-05-30 09:24:40 +0000464 printf(" = %d\n", ret);
Roger Meier4fce9602012-05-04 06:22:09 +0000465 if (ret != Numberz::TWO)
466 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000467
468 printf("testEnum(THREE)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000469 ret = testClient.testEnum(Numberz::THREE);
Mark Sleee8540632006-05-30 09:24:40 +0000470 printf(" = %d\n", ret);
Roger Meier4fce9602012-05-04 06:22:09 +0000471 if (ret != Numberz::THREE)
472 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000473
474 printf("testEnum(FIVE)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000475 ret = testClient.testEnum(Numberz::FIVE);
Mark Sleee8540632006-05-30 09:24:40 +0000476 printf(" = %d\n", ret);
Roger Meier4fce9602012-05-04 06:22:09 +0000477 if (ret != Numberz::FIVE)
478 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000479
480 printf("testEnum(EIGHT)");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000481 ret = testClient.testEnum(Numberz::EIGHT);
Mark Sleee8540632006-05-30 09:24:40 +0000482 printf(" = %d\n", ret);
Roger Meier4fce9602012-05-04 06:22:09 +0000483 if (ret != Numberz::EIGHT)
484 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000485
486 /**
487 * TYPEDEF TEST
488 */
489 printf("testTypedef(309858235082523)");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000490 UserId uid = testClient.testTypedef(309858235082523LL);
David Reissbc3dddb2007-08-22 23:20:24 +0000491 printf(" = %"PRId64"\n", uid);
Roger Meier4fce9602012-05-04 06:22:09 +0000492 if (uid != 309858235082523LL)
493 failCount++;
Mark Sleee8540632006-05-30 09:24:40 +0000494
495 /**
496 * NESTED MAP TEST
497 */
498 printf("testMapMap(1)");
Mark Slee1921d202007-01-24 19:43:06 +0000499 map<int32_t, map<int32_t, int32_t> > mm;
500 testClient.testMapMap(mm, 1);
Mark Sleee8540632006-05-30 09:24:40 +0000501 printf(" = {");
502 map<int32_t, map<int32_t, int32_t> >::const_iterator mi;
503 for (mi = mm.begin(); mi != mm.end(); ++mi) {
504 printf("%d => {", mi->first);
505 map<int32_t, int32_t>::const_iterator mi2;
506 for (mi2 = mi->second.begin(); mi2 != mi->second.end(); ++mi2) {
507 printf("%d => %d, ", mi2->first, mi2->second);
508 }
509 printf("}, ");
510 }
511 printf("}\n");
512
513 /**
514 * INSANITY TEST
515 */
516 Insanity insane;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000517 insane.userMap.insert(make_pair(Numberz::FIVE, 5000));
Mark Sleee8540632006-05-30 09:24:40 +0000518 Xtruct truck;
519 truck.string_thing = "Truck";
520 truck.byte_thing = 8;
Mark Sleee8540632006-05-30 09:24:40 +0000521 truck.i32_thing = 8;
Mark Sleee8540632006-05-30 09:24:40 +0000522 truck.i64_thing = 8;
523 insane.xtructs.push_back(truck);
524 printf("testInsanity()");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000525 map<UserId, map<Numberz::type,Insanity> > whoa;
Mark Slee1921d202007-01-24 19:43:06 +0000526 testClient.testInsanity(whoa, insane);
Mark Sleee8540632006-05-30 09:24:40 +0000527 printf(" = {");
Bryan Duxbury833ae492010-09-27 17:26:02 +0000528 map<UserId, map<Numberz::type,Insanity> >::const_iterator i_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000529 for (i_iter = whoa.begin(); i_iter != whoa.end(); ++i_iter) {
David Reissbc3dddb2007-08-22 23:20:24 +0000530 printf("%"PRId64" => {", i_iter->first);
Bryan Duxbury833ae492010-09-27 17:26:02 +0000531 map<Numberz::type,Insanity>::const_iterator i2_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000532 for (i2_iter = i_iter->second.begin();
533 i2_iter != i_iter->second.end();
534 ++i2_iter) {
535 printf("%d => {", i2_iter->first);
Bryan Duxbury833ae492010-09-27 17:26:02 +0000536 map<Numberz::type, UserId> userMap = i2_iter->second.userMap;
537 map<Numberz::type, UserId>::const_iterator um;
Mark Sleee8540632006-05-30 09:24:40 +0000538 printf("{");
539 for (um = userMap.begin(); um != userMap.end(); ++um) {
David Reissbc3dddb2007-08-22 23:20:24 +0000540 printf("%d => %"PRId64", ", um->first, um->second);
Mark Sleee8540632006-05-30 09:24:40 +0000541 }
542 printf("}, ");
543
Mark Sleeb9acf982006-10-10 01:57:32 +0000544 vector<Xtruct> xtructs = i2_iter->second.xtructs;
545 vector<Xtruct>::const_iterator x;
Mark Sleee8540632006-05-30 09:24:40 +0000546 printf("{");
547 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
David Reissbc3dddb2007-08-22 23:20:24 +0000548 printf("{\"%s\", %d, %d, %"PRId64"}, ",
Mark Sleee8540632006-05-30 09:24:40 +0000549 x->string_thing.c_str(),
550 (int)x->byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000551 x->i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000552 x->i64_thing);
553 }
554 printf("}");
555
556 printf("}, ");
557 }
558 printf("}, ");
559 }
560 printf("}\n");
561
Marc Slemko71d4e472006-08-15 22:34:04 +0000562 /* test exception */
Mark Slee95771002006-06-07 06:53:25 +0000563
Marc Slemkobf4fd192006-08-15 21:29:39 +0000564 try {
Marc Slemko71d4e472006-08-15 22:34:04 +0000565 printf("testClient.testException(\"Xception\") =>");
566 testClient.testException("Xception");
567 printf(" void\nFAILURE\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000568 failCount++;
David Reiss0c90f6f2008-02-06 22:18:40 +0000569
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000570 } catch(Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000571 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000572 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000573
Marc Slemkobf4fd192006-08-15 21:29:39 +0000574 try {
Roger Meier99b36722012-05-03 21:21:43 +0000575 printf("testClient.testException(\"TException\") =>");
576 testClient.testException("TException");
Roger Meierf50df7f2012-05-02 22:49:55 +0000577 printf(" void\nFAILURE\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000578 failCount++;
Roger Meierf50df7f2012-05-02 22:49:55 +0000579
Jake Farrell5d02b802014-01-07 21:42:01 -0500580 } catch(const TException&) {
Roger Meierf50df7f2012-05-02 22:49:55 +0000581 printf(" Caught TException\n");
582 }
583
584 try {
Marc Slemko71d4e472006-08-15 22:34:04 +0000585 printf("testClient.testException(\"success\") =>");
586 testClient.testException("success");
587 printf(" void\n");
588 } catch(...) {
589 printf(" exception\nFAILURE\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000590 failCount++;
Marc Slemko71d4e472006-08-15 22:34:04 +0000591 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000592
Marc Slemko71d4e472006-08-15 22:34:04 +0000593 /* test multi exception */
David Reiss0c90f6f2008-02-06 22:18:40 +0000594
Marc Slemko71d4e472006-08-15 22:34:04 +0000595 try {
596 printf("testClient.testMultiException(\"Xception\", \"test 1\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000597 Xtruct result;
598 testClient.testMultiException(result, "Xception", "test 1");
Marc Slemko71d4e472006-08-15 22:34:04 +0000599 printf(" result\nFAILURE\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000600 failCount++;
Mark Sleed3d733a2006-09-01 22:19:06 +0000601 } catch(Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000602 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
603 }
604
605 try {
606 printf("testClient.testMultiException(\"Xception2\", \"test 2\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000607 Xtruct result;
608 testClient.testMultiException(result, "Xception2", "test 2");
Marc Slemko71d4e472006-08-15 22:34:04 +0000609 printf(" result\nFAILURE\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000610 failCount++;
David Reiss0c90f6f2008-02-06 22:18:40 +0000611
Mark Sleed3d733a2006-09-01 22:19:06 +0000612 } catch(Xception2& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000613 printf(" {%u, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000614 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000615
Marc Slemko71d4e472006-08-15 22:34:04 +0000616 try {
617 printf("testClient.testMultiException(\"success\", \"test 3\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000618 Xtruct result;
619 testClient.testMultiException(result, "success", "test 3");
Marc Slemko71d4e472006-08-15 22:34:04 +0000620 printf(" {{\"%s\"}}\n", result.string_thing.c_str());
621 } catch(...) {
622 printf(" exception\nFAILURE\n");
Roger Meier4fce9602012-05-04 06:22:09 +0000623 failCount++;
Marc Slemko71d4e472006-08-15 22:34:04 +0000624 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000625
David Reissc51986f2009-03-24 20:01:25 +0000626 /* test oneway void */
David Reiss2ab6fe82008-02-18 02:11:44 +0000627 {
Jake Farrell5d02b802014-01-07 21:42:01 -0500628 printf("testClient.testOneway(1) =>");
David Reiss6ce401d2009-03-24 20:01:58 +0000629 uint64_t startOneway = now();
Jake Farrell5d02b802014-01-07 21:42:01 -0500630 testClient.testOneway(1);
David Reiss6ce401d2009-03-24 20:01:58 +0000631 uint64_t elapsed = now() - startOneway;
David Reiss2ab6fe82008-02-18 02:11:44 +0000632 if (elapsed > 200 * 1000) { // 0.2 seconds
633 printf(" FAILURE - took %.2f ms\n", (double)elapsed/1000.0);
Roger Meier4fce9602012-05-04 06:22:09 +0000634 failCount++;
David Reiss2ab6fe82008-02-18 02:11:44 +0000635 } else {
636 printf(" success - took %.2f ms\n", (double)elapsed/1000.0);
637 }
638 }
639
David Reiss2845b522008-02-18 02:11:52 +0000640 /**
David Reissc51986f2009-03-24 20:01:25 +0000641 * redo a simple test after the oneway to make sure we aren't "off by one" --
642 * if the server treated oneway void like normal void, this next test will
David Reiss2845b522008-02-18 02:11:52 +0000643 * fail since it will get the void confirmation rather than the correct
644 * result. In this circumstance, the client will throw the exception:
645 *
646 * TApplicationException: Wrong method namea
647 */
648 /**
649 * I32 TEST
650 */
651 printf("re-test testI32(-1)");
652 i32 = testClient.testI32(-1);
653 printf(" = %d\n", i32);
Roger Meier4fce9602012-05-04 06:22:09 +0000654 if (i32 != -1)
655 failCount++;
David Reiss2845b522008-02-18 02:11:52 +0000656
657
Marc Slemkobf4fd192006-08-15 21:29:39 +0000658 uint64_t stop = now();
Mark Sleed788b2e2006-09-07 01:26:35 +0000659 uint64_t tot = stop-start;
660
David Reissbc3dddb2007-08-22 23:20:24 +0000661 printf("Total time: %"PRIu64" us\n", stop-start);
David Reiss0c90f6f2008-02-06 22:18:40 +0000662
Mark Sleed788b2e2006-09-07 01:26:35 +0000663 time_tot += tot;
664 if (time_min == 0 || tot < time_min) {
665 time_min = tot;
666 }
667 if (tot > time_max) {
668 time_max = tot;
669 }
670
Mark Sleea3302652006-10-25 19:03:32 +0000671 transport->close();
Mark Sleee8540632006-05-30 09:24:40 +0000672 }
673
Marc Slemko6be374b2006-08-04 03:16:25 +0000674 // printf("\nSocket syscalls: %u", g_socket_syscalls);
Mark Sleee8540632006-05-30 09:24:40 +0000675 printf("\nAll tests done.\n");
Mark Sleed788b2e2006-09-07 01:26:35 +0000676
677 uint64_t time_avg = time_tot / numTests;
678
David Reissbc3dddb2007-08-22 23:20:24 +0000679 printf("Min time: %"PRIu64" us\n", time_min);
680 printf("Max time: %"PRIu64" us\n", time_max);
681 printf("Avg time: %"PRIu64" us\n", time_avg);
Mark Sleed788b2e2006-09-07 01:26:35 +0000682
Roger Meier4fce9602012-05-04 06:22:09 +0000683 return failCount;
Mark Sleee8540632006-05-30 09:24:40 +0000684}