blob: 8529938971805bf9deab3fbfef61ca70c7fd3409 [file] [log] [blame]
Mark Sleee8540632006-05-30 09:24:40 +00001#include <stdio.h>
2#include <unistd.h>
Mark Slee95771002006-06-07 06:53:25 +00003#include <sys/time.h>
Marc Slemko6be374b2006-08-04 03:16:25 +00004#include <protocol/TBinaryProtocol.h>
Mark Sleea3302652006-10-25 19:03:32 +00005#include <transport/TTransportUtils.h>
Marc Slemko6be374b2006-08-04 03:16:25 +00006#include <transport/TSocket.h>
Mark Sleee8540632006-05-30 09:24:40 +00007
Marc Slemko6be374b2006-08-04 03:16:25 +00008#include <boost/shared_ptr.hpp>
9#include "ThriftTest.h"
10
David Reissbc3dddb2007-08-22 23:20:24 +000011#define __STDC_FORMAT_MACROS
12#include <inttypes.h>
13
Marc Slemko6be374b2006-08-04 03:16:25 +000014using namespace boost;
15using namespace std;
16using namespace facebook::thrift;
17using namespace facebook::thrift::protocol;
18using namespace facebook::thrift::transport;
Marc Slemkobf4fd192006-08-15 21:29:39 +000019using namespace thrift::test;
Marc Slemko6be374b2006-08-04 03:16:25 +000020
21//extern uint32_t g_socket_syscalls;
Mark Slee95771002006-06-07 06:53:25 +000022
23// Current time, microseconds since the epoch
24uint64_t now()
25{
26 long long ret;
27 struct timeval tv;
David Reiss0c90f6f2008-02-06 22:18:40 +000028
Mark Slee95771002006-06-07 06:53:25 +000029 gettimeofday(&tv, NULL);
30 ret = tv.tv_sec;
31 ret = ret*1000*1000 + tv.tv_usec;
32 return ret;
33}
34
Mark Sleee8540632006-05-30 09:24:40 +000035int main(int argc, char** argv) {
36 string host = "localhost";
37 int port = 9090;
38 int numTests = 1;
Mark Sleea3302652006-10-25 19:03:32 +000039 bool framed = false;
Mark Sleee8540632006-05-30 09:24:40 +000040
Mark Sleea3302652006-10-25 19:03:32 +000041 for (int i = 0; i < argc; ++i) {
42 if (strcmp(argv[i], "-h") == 0) {
43 char* pch = strtok(argv[++i], ":");
44 if (pch != NULL) {
45 host = string(pch);
46 }
47 pch = strtok(NULL, ":");
48 if (pch != NULL) {
49 port = atoi(pch);
50 }
51 } else if (strcmp(argv[i], "-n") == 0) {
52 numTests = atoi(argv[++i]);
53 } else if (strcmp(argv[i], "-f") == 0) {
54 framed = true;
Mark Sleea3302652006-10-25 19:03:32 +000055 }
Mark Sleee8540632006-05-30 09:24:40 +000056 }
Mark Sleea3302652006-10-25 19:03:32 +000057
58
59 shared_ptr<TTransport> transport;
Mark Sleee8540632006-05-30 09:24:40 +000060
Marc Slemko6be374b2006-08-04 03:16:25 +000061 shared_ptr<TSocket> socket(new TSocket(host, port));
David Reiss0c90f6f2008-02-06 22:18:40 +000062
Mark Sleea3302652006-10-25 19:03:32 +000063 if (framed) {
64 shared_ptr<TFramedTransport> framedSocket(new TFramedTransport(socket));
Mark Sleea3302652006-10-25 19:03:32 +000065 transport = framedSocket;
Mark Sleea3302652006-10-25 19:03:32 +000066 } else {
67 shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket));
68 transport = bufferedSocket;
69 }
70
Mark Slee9e288d42007-01-24 23:42:12 +000071 shared_ptr<TBinaryProtocol> protocol(new TBinaryProtocol(transport));
Mark Sleea3302652006-10-25 19:03:32 +000072 ThriftTestClient testClient(protocol);
Mark Sleed788b2e2006-09-07 01:26:35 +000073
74 uint64_t time_min = 0;
75 uint64_t time_max = 0;
76 uint64_t time_tot = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +000077
Mark Sleee8540632006-05-30 09:24:40 +000078 int test = 0;
79 for (test = 0; test < numTests; ++test) {
Mark Slee95771002006-06-07 06:53:25 +000080
Mark Slee95771002006-06-07 06:53:25 +000081 try {
Mark Sleea3302652006-10-25 19:03:32 +000082 transport->open();
Mark Slee95771002006-06-07 06:53:25 +000083 } catch (TTransportException& ttx) {
Mark Sleeb9ff32a2006-11-16 01:00:24 +000084 printf("Connect failed: %s\n", ttx.what());
Mark Sleee8540632006-05-30 09:24:40 +000085 continue;
86 }
David Reiss0c90f6f2008-02-06 22:18:40 +000087
Mark Sleed788b2e2006-09-07 01:26:35 +000088 /**
89 * CONNECT TEST
90 */
91 printf("Test #%d, connect %s:%d\n", test+1, host.c_str(), port);
Mark Slee95771002006-06-07 06:53:25 +000092
93 uint64_t start = now();
David Reiss0c90f6f2008-02-06 22:18:40 +000094
Mark Sleee8540632006-05-30 09:24:40 +000095 /**
96 * VOID TEST
97 */
Mark Sleee129a2d2007-02-21 05:17:48 +000098 try {
99 printf("testVoid()");
100 testClient.testVoid();
101 printf(" = void\n");
102 } catch (TApplicationException tax) {
103 printf("%s\n", tax.what());
104 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000105
Mark Sleee8540632006-05-30 09:24:40 +0000106 /**
107 * STRING TEST
108 */
109 printf("testString(\"Test\")");
Mark Slee1921d202007-01-24 19:43:06 +0000110 string s;
111 testClient.testString(s, "Test");
Mark Sleee8540632006-05-30 09:24:40 +0000112 printf(" = \"%s\"\n", s.c_str());
David Reiss0c90f6f2008-02-06 22:18:40 +0000113
Mark Sleee8540632006-05-30 09:24:40 +0000114 /**
115 * BYTE TEST
116 */
117 printf("testByte(1)");
118 uint8_t u8 = testClient.testByte(1);
119 printf(" = %d\n", (int)u8);
David Reiss0c90f6f2008-02-06 22:18:40 +0000120
Mark Sleee8540632006-05-30 09:24:40 +0000121 /**
122 * I32 TEST
123 */
124 printf("testI32(-1)");
125 int32_t i32 = testClient.testI32(-1);
126 printf(" = %d\n", i32);
127
128 /**
Mark Sleee8540632006-05-30 09:24:40 +0000129 * I64 TEST
130 */
131 printf("testI64(-34359738368)");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000132 int64_t i64 = testClient.testI64(-34359738368LL);
David Reissbc3dddb2007-08-22 23:20:24 +0000133 printf(" = %"PRId64"\n", i64);
Mark Sleec98d0502006-09-06 02:42:25 +0000134
135 /**
136 * DOUBLE TEST
137 */
138 printf("testDouble(-5.2098523)");
139 double dub = testClient.testDouble(-5.2098523);
140 printf(" = %lf\n", dub);
David Reiss0c90f6f2008-02-06 22:18:40 +0000141
Mark Sleee8540632006-05-30 09:24:40 +0000142 /**
143 * STRUCT TEST
144 */
Mark Slee6e536442006-06-30 18:28:50 +0000145 printf("testStruct({\"Zero\", 1, -3, -5})");
Mark Sleee8540632006-05-30 09:24:40 +0000146 Xtruct out;
147 out.string_thing = "Zero";
148 out.byte_thing = 1;
Mark Sleee8540632006-05-30 09:24:40 +0000149 out.i32_thing = -3;
Mark Sleee8540632006-05-30 09:24:40 +0000150 out.i64_thing = -5;
Mark Slee1921d202007-01-24 19:43:06 +0000151 Xtruct in;
152 testClient.testStruct(in, out);
David Reissbc3dddb2007-08-22 23:20:24 +0000153 printf(" = {\"%s\", %d, %d, %"PRId64"}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000154 in.string_thing.c_str(),
155 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000156 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000157 in.i64_thing);
David Reiss0c90f6f2008-02-06 22:18:40 +0000158
Mark Sleee8540632006-05-30 09:24:40 +0000159 /**
160 * NESTED STRUCT TEST
161 */
Mark Slee6e536442006-06-30 18:28:50 +0000162 printf("testNest({1, {\"Zero\", 1, -3, -5}), 5}");
Mark Sleee8540632006-05-30 09:24:40 +0000163 Xtruct2 out2;
164 out2.byte_thing = 1;
165 out2.struct_thing = out;
166 out2.i32_thing = 5;
Mark Slee1921d202007-01-24 19:43:06 +0000167 Xtruct2 in2;
168 testClient.testNest(in2, out2);
Mark Sleee8540632006-05-30 09:24:40 +0000169 in = in2.struct_thing;
David Reissbc3dddb2007-08-22 23:20:24 +0000170 printf(" = {%d, {\"%s\", %d, %d, %"PRId64"}, %d}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000171 in2.byte_thing,
172 in.string_thing.c_str(),
173 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000174 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000175 in.i64_thing,
David Reiss0c90f6f2008-02-06 22:18:40 +0000176 in2.i32_thing);
Mark Sleee8540632006-05-30 09:24:40 +0000177
178 /**
179 * MAP TEST
180 */
181 map<int32_t,int32_t> mapout;
182 for (int32_t i = 0; i < 5; ++i) {
183 mapout.insert(make_pair(i, i-10));
184 }
185 printf("testMap({");
186 map<int32_t, int32_t>::const_iterator m_iter;
187 bool first = true;
188 for (m_iter = mapout.begin(); m_iter != mapout.end(); ++m_iter) {
189 if (first) {
190 first = false;
191 } else {
192 printf(", ");
193 }
194 printf("%d => %d", m_iter->first, m_iter->second);
195 }
196 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000197 map<int32_t,int32_t> mapin;
198 testClient.testMap(mapin, mapout);
Mark Sleee8540632006-05-30 09:24:40 +0000199 printf(" = {");
200 first = true;
201 for (m_iter = mapin.begin(); m_iter != mapin.end(); ++m_iter) {
202 if (first) {
203 first = false;
204 } else {
205 printf(", ");
206 }
207 printf("%d => %d", m_iter->first, m_iter->second);
208 }
209 printf("}\n");
210
211 /**
212 * SET TEST
213 */
214 set<int32_t> setout;
215 for (int32_t i = -2; i < 3; ++i) {
216 setout.insert(i);
217 }
218 printf("testSet({");
219 set<int32_t>::const_iterator s_iter;
220 first = true;
221 for (s_iter = setout.begin(); s_iter != setout.end(); ++s_iter) {
222 if (first) {
223 first = false;
224 } else {
225 printf(", ");
226 }
227 printf("%d", *s_iter);
228 }
229 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000230 set<int32_t> setin;
231 testClient.testSet(setin, setout);
Mark Sleee8540632006-05-30 09:24:40 +0000232 printf(" = {");
233 first = true;
234 for (s_iter = setin.begin(); s_iter != setin.end(); ++s_iter) {
235 if (first) {
236 first = false;
237 } else {
238 printf(", ");
239 }
240 printf("%d", *s_iter);
241 }
242 printf("}\n");
243
244 /**
245 * LIST TEST
246 */
Mark Sleeb9acf982006-10-10 01:57:32 +0000247 vector<int32_t> listout;
Mark Sleee8540632006-05-30 09:24:40 +0000248 for (int32_t i = -2; i < 3; ++i) {
249 listout.push_back(i);
250 }
251 printf("testList({");
Mark Sleeb9acf982006-10-10 01:57:32 +0000252 vector<int32_t>::const_iterator l_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000253 first = true;
254 for (l_iter = listout.begin(); l_iter != listout.end(); ++l_iter) {
255 if (first) {
256 first = false;
257 } else {
258 printf(", ");
259 }
260 printf("%d", *l_iter);
261 }
262 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000263 vector<int32_t> listin;
264 testClient.testList(listin, listout);
Mark Sleee8540632006-05-30 09:24:40 +0000265 printf(" = {");
266 first = true;
267 for (l_iter = listin.begin(); l_iter != listin.end(); ++l_iter) {
268 if (first) {
269 first = false;
270 } else {
271 printf(", ");
272 }
273 printf("%d", *l_iter);
274 }
275 printf("}\n");
276
277 /**
278 * ENUM TEST
279 */
280 printf("testEnum(ONE)");
281 Numberz ret = testClient.testEnum(ONE);
282 printf(" = %d\n", ret);
283
284 printf("testEnum(TWO)");
285 ret = testClient.testEnum(TWO);
286 printf(" = %d\n", ret);
287
288 printf("testEnum(THREE)");
289 ret = testClient.testEnum(THREE);
290 printf(" = %d\n", ret);
291
292 printf("testEnum(FIVE)");
293 ret = testClient.testEnum(FIVE);
294 printf(" = %d\n", ret);
295
296 printf("testEnum(EIGHT)");
297 ret = testClient.testEnum(EIGHT);
298 printf(" = %d\n", ret);
299
300 /**
301 * TYPEDEF TEST
302 */
303 printf("testTypedef(309858235082523)");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000304 UserId uid = testClient.testTypedef(309858235082523LL);
David Reissbc3dddb2007-08-22 23:20:24 +0000305 printf(" = %"PRId64"\n", uid);
Mark Sleee8540632006-05-30 09:24:40 +0000306
307 /**
308 * NESTED MAP TEST
309 */
310 printf("testMapMap(1)");
Mark Slee1921d202007-01-24 19:43:06 +0000311 map<int32_t, map<int32_t, int32_t> > mm;
312 testClient.testMapMap(mm, 1);
Mark Sleee8540632006-05-30 09:24:40 +0000313 printf(" = {");
314 map<int32_t, map<int32_t, int32_t> >::const_iterator mi;
315 for (mi = mm.begin(); mi != mm.end(); ++mi) {
316 printf("%d => {", mi->first);
317 map<int32_t, int32_t>::const_iterator mi2;
318 for (mi2 = mi->second.begin(); mi2 != mi->second.end(); ++mi2) {
319 printf("%d => %d, ", mi2->first, mi2->second);
320 }
321 printf("}, ");
322 }
323 printf("}\n");
324
325 /**
326 * INSANITY TEST
327 */
328 Insanity insane;
329 insane.userMap.insert(make_pair(FIVE, 5000));
330 Xtruct truck;
331 truck.string_thing = "Truck";
332 truck.byte_thing = 8;
Mark Sleee8540632006-05-30 09:24:40 +0000333 truck.i32_thing = 8;
Mark Sleee8540632006-05-30 09:24:40 +0000334 truck.i64_thing = 8;
335 insane.xtructs.push_back(truck);
336 printf("testInsanity()");
Mark Slee1921d202007-01-24 19:43:06 +0000337 map<UserId, map<Numberz,Insanity> > whoa;
338 testClient.testInsanity(whoa, insane);
Mark Sleee8540632006-05-30 09:24:40 +0000339 printf(" = {");
340 map<UserId, map<Numberz,Insanity> >::const_iterator i_iter;
341 for (i_iter = whoa.begin(); i_iter != whoa.end(); ++i_iter) {
David Reissbc3dddb2007-08-22 23:20:24 +0000342 printf("%"PRId64" => {", i_iter->first);
Mark Sleee8540632006-05-30 09:24:40 +0000343 map<Numberz,Insanity>::const_iterator i2_iter;
344 for (i2_iter = i_iter->second.begin();
345 i2_iter != i_iter->second.end();
346 ++i2_iter) {
347 printf("%d => {", i2_iter->first);
348 map<Numberz, UserId> userMap = i2_iter->second.userMap;
349 map<Numberz, UserId>::const_iterator um;
350 printf("{");
351 for (um = userMap.begin(); um != userMap.end(); ++um) {
David Reissbc3dddb2007-08-22 23:20:24 +0000352 printf("%d => %"PRId64", ", um->first, um->second);
Mark Sleee8540632006-05-30 09:24:40 +0000353 }
354 printf("}, ");
355
Mark Sleeb9acf982006-10-10 01:57:32 +0000356 vector<Xtruct> xtructs = i2_iter->second.xtructs;
357 vector<Xtruct>::const_iterator x;
Mark Sleee8540632006-05-30 09:24:40 +0000358 printf("{");
359 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
David Reissbc3dddb2007-08-22 23:20:24 +0000360 printf("{\"%s\", %d, %d, %"PRId64"}, ",
Mark Sleee8540632006-05-30 09:24:40 +0000361 x->string_thing.c_str(),
362 (int)x->byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000363 x->i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000364 x->i64_thing);
365 }
366 printf("}");
367
368 printf("}, ");
369 }
370 printf("}, ");
371 }
372 printf("}\n");
373
Marc Slemko71d4e472006-08-15 22:34:04 +0000374 /* test exception */
Mark Slee95771002006-06-07 06:53:25 +0000375
Marc Slemkobf4fd192006-08-15 21:29:39 +0000376 try {
Marc Slemko71d4e472006-08-15 22:34:04 +0000377 printf("testClient.testException(\"Xception\") =>");
378 testClient.testException("Xception");
379 printf(" void\nFAILURE\n");
David Reiss0c90f6f2008-02-06 22:18:40 +0000380
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000381 } catch(Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000382 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000383 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000384
Marc Slemkobf4fd192006-08-15 21:29:39 +0000385 try {
Marc Slemko71d4e472006-08-15 22:34:04 +0000386 printf("testClient.testException(\"success\") =>");
387 testClient.testException("success");
388 printf(" void\n");
389 } catch(...) {
390 printf(" exception\nFAILURE\n");
391 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000392
Marc Slemko71d4e472006-08-15 22:34:04 +0000393 /* test multi exception */
David Reiss0c90f6f2008-02-06 22:18:40 +0000394
Marc Slemko71d4e472006-08-15 22:34:04 +0000395 try {
396 printf("testClient.testMultiException(\"Xception\", \"test 1\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000397 Xtruct result;
398 testClient.testMultiException(result, "Xception", "test 1");
Marc Slemko71d4e472006-08-15 22:34:04 +0000399 printf(" result\nFAILURE\n");
Mark Sleed3d733a2006-09-01 22:19:06 +0000400 } catch(Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000401 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
402 }
403
404 try {
405 printf("testClient.testMultiException(\"Xception2\", \"test 2\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000406 Xtruct result;
407 testClient.testMultiException(result, "Xception2", "test 2");
Marc Slemko71d4e472006-08-15 22:34:04 +0000408 printf(" result\nFAILURE\n");
David Reiss0c90f6f2008-02-06 22:18:40 +0000409
Mark Sleed3d733a2006-09-01 22:19:06 +0000410 } catch(Xception2& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000411 printf(" {%u, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000412 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000413
Marc Slemko71d4e472006-08-15 22:34:04 +0000414 try {
415 printf("testClient.testMultiException(\"success\", \"test 3\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000416 Xtruct result;
417 testClient.testMultiException(result, "success", "test 3");
Marc Slemko71d4e472006-08-15 22:34:04 +0000418 printf(" {{\"%s\"}}\n", result.string_thing.c_str());
419 } catch(...) {
420 printf(" exception\nFAILURE\n");
421 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000422
David Reiss2ab6fe82008-02-18 02:11:44 +0000423 /* test async void */
424 {
425 printf("testClient.testAsync(3) =>");
426 uint64_t startAsync = now();
427 testClient.testAsync(3);
428 uint64_t elapsed = now() - startAsync;
429 if (elapsed > 200 * 1000) { // 0.2 seconds
430 printf(" FAILURE - took %.2f ms\n", (double)elapsed/1000.0);
431 } else {
432 printf(" success - took %.2f ms\n", (double)elapsed/1000.0);
433 }
434 }
435
David Reiss2845b522008-02-18 02:11:52 +0000436 /**
437 * redo a simple test after the async to make sure we aren't "off by one" --
438 * if the server treated async void like normal void, this next test will
439 * fail since it will get the void confirmation rather than the correct
440 * result. In this circumstance, the client will throw the exception:
441 *
442 * TApplicationException: Wrong method namea
443 */
444 /**
445 * I32 TEST
446 */
447 printf("re-test testI32(-1)");
448 i32 = testClient.testI32(-1);
449 printf(" = %d\n", i32);
450
451
Marc Slemkobf4fd192006-08-15 21:29:39 +0000452 uint64_t stop = now();
Mark Sleed788b2e2006-09-07 01:26:35 +0000453 uint64_t tot = stop-start;
454
David Reissbc3dddb2007-08-22 23:20:24 +0000455 printf("Total time: %"PRIu64" us\n", stop-start);
David Reiss0c90f6f2008-02-06 22:18:40 +0000456
Mark Sleed788b2e2006-09-07 01:26:35 +0000457 time_tot += tot;
458 if (time_min == 0 || tot < time_min) {
459 time_min = tot;
460 }
461 if (tot > time_max) {
462 time_max = tot;
463 }
464
Mark Sleea3302652006-10-25 19:03:32 +0000465 transport->close();
Mark Sleee8540632006-05-30 09:24:40 +0000466 }
467
Marc Slemko6be374b2006-08-04 03:16:25 +0000468 // printf("\nSocket syscalls: %u", g_socket_syscalls);
Mark Sleee8540632006-05-30 09:24:40 +0000469 printf("\nAll tests done.\n");
Mark Sleed788b2e2006-09-07 01:26:35 +0000470
471 uint64_t time_avg = time_tot / numTests;
472
David Reissbc3dddb2007-08-22 23:20:24 +0000473 printf("Min time: %"PRIu64" us\n", time_min);
474 printf("Max time: %"PRIu64" us\n", time_max);
475 printf("Avg time: %"PRIu64" us\n", time_avg);
Mark Sleed788b2e2006-09-07 01:26:35 +0000476
Mark Sleee8540632006-05-30 09:24:40 +0000477 return 0;
478}