blob: 9b350b0bbd671b7b8f2ff399ec3c74252d9eebe7 [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;
40 bool frameInput = true;
Mark Sleee8540632006-05-30 09:24:40 +000041
Mark Sleea3302652006-10-25 19:03:32 +000042 for (int i = 0; i < argc; ++i) {
43 if (strcmp(argv[i], "-h") == 0) {
44 char* pch = strtok(argv[++i], ":");
45 if (pch != NULL) {
46 host = string(pch);
47 }
48 pch = strtok(NULL, ":");
49 if (pch != NULL) {
50 port = atoi(pch);
51 }
52 } else if (strcmp(argv[i], "-n") == 0) {
53 numTests = atoi(argv[++i]);
54 } else if (strcmp(argv[i], "-f") == 0) {
55 framed = true;
56 } else if (strcmp(argv[i], "-fo") == 0) {
57 framed = true;
58 frameInput = false;
59 }
Mark Sleee8540632006-05-30 09:24:40 +000060 }
Mark Sleea3302652006-10-25 19:03:32 +000061
62
63 shared_ptr<TTransport> transport;
Mark Sleee8540632006-05-30 09:24:40 +000064
Marc Slemko6be374b2006-08-04 03:16:25 +000065 shared_ptr<TSocket> socket(new TSocket(host, port));
David Reiss0c90f6f2008-02-06 22:18:40 +000066
Mark Sleea3302652006-10-25 19:03:32 +000067 if (framed) {
68 shared_ptr<TFramedTransport> framedSocket(new TFramedTransport(socket));
69 framedSocket->setRead(frameInput);
70 transport = framedSocket;
71 if (frameInput) {
72 printf("Using bi-directional framed transport mode\n");
73 } else {
74 printf("Using framed output only mode\n");
75 }
76 } else {
77 shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket));
78 transport = bufferedSocket;
79 }
80
Mark Slee9e288d42007-01-24 23:42:12 +000081 shared_ptr<TBinaryProtocol> protocol(new TBinaryProtocol(transport));
Mark Sleea3302652006-10-25 19:03:32 +000082 ThriftTestClient testClient(protocol);
Mark Sleed788b2e2006-09-07 01:26:35 +000083
84 uint64_t time_min = 0;
85 uint64_t time_max = 0;
86 uint64_t time_tot = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +000087
Mark Sleee8540632006-05-30 09:24:40 +000088 int test = 0;
89 for (test = 0; test < numTests; ++test) {
Mark Slee95771002006-06-07 06:53:25 +000090
Mark Slee95771002006-06-07 06:53:25 +000091 try {
Mark Sleea3302652006-10-25 19:03:32 +000092 transport->open();
Mark Slee95771002006-06-07 06:53:25 +000093 } catch (TTransportException& ttx) {
Mark Sleeb9ff32a2006-11-16 01:00:24 +000094 printf("Connect failed: %s\n", ttx.what());
Mark Sleee8540632006-05-30 09:24:40 +000095 continue;
96 }
David Reiss0c90f6f2008-02-06 22:18:40 +000097
Mark Sleed788b2e2006-09-07 01:26:35 +000098 /**
99 * CONNECT TEST
100 */
101 printf("Test #%d, connect %s:%d\n", test+1, host.c_str(), port);
Mark Slee95771002006-06-07 06:53:25 +0000102
103 uint64_t start = now();
David Reiss0c90f6f2008-02-06 22:18:40 +0000104
Mark Sleee8540632006-05-30 09:24:40 +0000105 /**
106 * VOID TEST
107 */
Mark Sleee129a2d2007-02-21 05:17:48 +0000108 try {
109 printf("testVoid()");
110 testClient.testVoid();
111 printf(" = void\n");
112 } catch (TApplicationException tax) {
113 printf("%s\n", tax.what());
114 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000115
Mark Sleee8540632006-05-30 09:24:40 +0000116 /**
117 * STRING TEST
118 */
119 printf("testString(\"Test\")");
Mark Slee1921d202007-01-24 19:43:06 +0000120 string s;
121 testClient.testString(s, "Test");
Mark Sleee8540632006-05-30 09:24:40 +0000122 printf(" = \"%s\"\n", s.c_str());
David Reiss0c90f6f2008-02-06 22:18:40 +0000123
Mark Sleee8540632006-05-30 09:24:40 +0000124 /**
125 * BYTE TEST
126 */
127 printf("testByte(1)");
128 uint8_t u8 = testClient.testByte(1);
129 printf(" = %d\n", (int)u8);
David Reiss0c90f6f2008-02-06 22:18:40 +0000130
Mark Sleee8540632006-05-30 09:24:40 +0000131 /**
132 * I32 TEST
133 */
134 printf("testI32(-1)");
135 int32_t i32 = testClient.testI32(-1);
136 printf(" = %d\n", i32);
137
138 /**
Mark Sleee8540632006-05-30 09:24:40 +0000139 * I64 TEST
140 */
141 printf("testI64(-34359738368)");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000142 int64_t i64 = testClient.testI64(-34359738368LL);
David Reissbc3dddb2007-08-22 23:20:24 +0000143 printf(" = %"PRId64"\n", i64);
Mark Sleec98d0502006-09-06 02:42:25 +0000144
145 /**
146 * DOUBLE TEST
147 */
148 printf("testDouble(-5.2098523)");
149 double dub = testClient.testDouble(-5.2098523);
150 printf(" = %lf\n", dub);
David Reiss0c90f6f2008-02-06 22:18:40 +0000151
Mark Sleee8540632006-05-30 09:24:40 +0000152 /**
153 * STRUCT TEST
154 */
Mark Slee6e536442006-06-30 18:28:50 +0000155 printf("testStruct({\"Zero\", 1, -3, -5})");
Mark Sleee8540632006-05-30 09:24:40 +0000156 Xtruct out;
157 out.string_thing = "Zero";
158 out.byte_thing = 1;
Mark Sleee8540632006-05-30 09:24:40 +0000159 out.i32_thing = -3;
Mark Sleee8540632006-05-30 09:24:40 +0000160 out.i64_thing = -5;
Mark Slee1921d202007-01-24 19:43:06 +0000161 Xtruct in;
162 testClient.testStruct(in, out);
David Reissbc3dddb2007-08-22 23:20:24 +0000163 printf(" = {\"%s\", %d, %d, %"PRId64"}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000164 in.string_thing.c_str(),
165 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000166 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000167 in.i64_thing);
David Reiss0c90f6f2008-02-06 22:18:40 +0000168
Mark Sleee8540632006-05-30 09:24:40 +0000169 /**
170 * NESTED STRUCT TEST
171 */
Mark Slee6e536442006-06-30 18:28:50 +0000172 printf("testNest({1, {\"Zero\", 1, -3, -5}), 5}");
Mark Sleee8540632006-05-30 09:24:40 +0000173 Xtruct2 out2;
174 out2.byte_thing = 1;
175 out2.struct_thing = out;
176 out2.i32_thing = 5;
Mark Slee1921d202007-01-24 19:43:06 +0000177 Xtruct2 in2;
178 testClient.testNest(in2, out2);
Mark Sleee8540632006-05-30 09:24:40 +0000179 in = in2.struct_thing;
David Reissbc3dddb2007-08-22 23:20:24 +0000180 printf(" = {%d, {\"%s\", %d, %d, %"PRId64"}, %d}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000181 in2.byte_thing,
182 in.string_thing.c_str(),
183 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000184 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000185 in.i64_thing,
David Reiss0c90f6f2008-02-06 22:18:40 +0000186 in2.i32_thing);
Mark Sleee8540632006-05-30 09:24:40 +0000187
188 /**
189 * MAP TEST
190 */
191 map<int32_t,int32_t> mapout;
192 for (int32_t i = 0; i < 5; ++i) {
193 mapout.insert(make_pair(i, i-10));
194 }
195 printf("testMap({");
196 map<int32_t, int32_t>::const_iterator m_iter;
197 bool first = true;
198 for (m_iter = mapout.begin(); m_iter != mapout.end(); ++m_iter) {
199 if (first) {
200 first = false;
201 } else {
202 printf(", ");
203 }
204 printf("%d => %d", m_iter->first, m_iter->second);
205 }
206 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000207 map<int32_t,int32_t> mapin;
208 testClient.testMap(mapin, mapout);
Mark Sleee8540632006-05-30 09:24:40 +0000209 printf(" = {");
210 first = true;
211 for (m_iter = mapin.begin(); m_iter != mapin.end(); ++m_iter) {
212 if (first) {
213 first = false;
214 } else {
215 printf(", ");
216 }
217 printf("%d => %d", m_iter->first, m_iter->second);
218 }
219 printf("}\n");
220
221 /**
222 * SET TEST
223 */
224 set<int32_t> setout;
225 for (int32_t i = -2; i < 3; ++i) {
226 setout.insert(i);
227 }
228 printf("testSet({");
229 set<int32_t>::const_iterator s_iter;
230 first = true;
231 for (s_iter = setout.begin(); s_iter != setout.end(); ++s_iter) {
232 if (first) {
233 first = false;
234 } else {
235 printf(", ");
236 }
237 printf("%d", *s_iter);
238 }
239 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000240 set<int32_t> setin;
241 testClient.testSet(setin, setout);
Mark Sleee8540632006-05-30 09:24:40 +0000242 printf(" = {");
243 first = true;
244 for (s_iter = setin.begin(); s_iter != setin.end(); ++s_iter) {
245 if (first) {
246 first = false;
247 } else {
248 printf(", ");
249 }
250 printf("%d", *s_iter);
251 }
252 printf("}\n");
253
254 /**
255 * LIST TEST
256 */
Mark Sleeb9acf982006-10-10 01:57:32 +0000257 vector<int32_t> listout;
Mark Sleee8540632006-05-30 09:24:40 +0000258 for (int32_t i = -2; i < 3; ++i) {
259 listout.push_back(i);
260 }
261 printf("testList({");
Mark Sleeb9acf982006-10-10 01:57:32 +0000262 vector<int32_t>::const_iterator l_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000263 first = true;
264 for (l_iter = listout.begin(); l_iter != listout.end(); ++l_iter) {
265 if (first) {
266 first = false;
267 } else {
268 printf(", ");
269 }
270 printf("%d", *l_iter);
271 }
272 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000273 vector<int32_t> listin;
274 testClient.testList(listin, listout);
Mark Sleee8540632006-05-30 09:24:40 +0000275 printf(" = {");
276 first = true;
277 for (l_iter = listin.begin(); l_iter != listin.end(); ++l_iter) {
278 if (first) {
279 first = false;
280 } else {
281 printf(", ");
282 }
283 printf("%d", *l_iter);
284 }
285 printf("}\n");
286
287 /**
288 * ENUM TEST
289 */
290 printf("testEnum(ONE)");
291 Numberz ret = testClient.testEnum(ONE);
292 printf(" = %d\n", ret);
293
294 printf("testEnum(TWO)");
295 ret = testClient.testEnum(TWO);
296 printf(" = %d\n", ret);
297
298 printf("testEnum(THREE)");
299 ret = testClient.testEnum(THREE);
300 printf(" = %d\n", ret);
301
302 printf("testEnum(FIVE)");
303 ret = testClient.testEnum(FIVE);
304 printf(" = %d\n", ret);
305
306 printf("testEnum(EIGHT)");
307 ret = testClient.testEnum(EIGHT);
308 printf(" = %d\n", ret);
309
310 /**
311 * TYPEDEF TEST
312 */
313 printf("testTypedef(309858235082523)");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000314 UserId uid = testClient.testTypedef(309858235082523LL);
David Reissbc3dddb2007-08-22 23:20:24 +0000315 printf(" = %"PRId64"\n", uid);
Mark Sleee8540632006-05-30 09:24:40 +0000316
317 /**
318 * NESTED MAP TEST
319 */
320 printf("testMapMap(1)");
Mark Slee1921d202007-01-24 19:43:06 +0000321 map<int32_t, map<int32_t, int32_t> > mm;
322 testClient.testMapMap(mm, 1);
Mark Sleee8540632006-05-30 09:24:40 +0000323 printf(" = {");
324 map<int32_t, map<int32_t, int32_t> >::const_iterator mi;
325 for (mi = mm.begin(); mi != mm.end(); ++mi) {
326 printf("%d => {", mi->first);
327 map<int32_t, int32_t>::const_iterator mi2;
328 for (mi2 = mi->second.begin(); mi2 != mi->second.end(); ++mi2) {
329 printf("%d => %d, ", mi2->first, mi2->second);
330 }
331 printf("}, ");
332 }
333 printf("}\n");
334
335 /**
336 * INSANITY TEST
337 */
338 Insanity insane;
339 insane.userMap.insert(make_pair(FIVE, 5000));
340 Xtruct truck;
341 truck.string_thing = "Truck";
342 truck.byte_thing = 8;
Mark Sleee8540632006-05-30 09:24:40 +0000343 truck.i32_thing = 8;
Mark Sleee8540632006-05-30 09:24:40 +0000344 truck.i64_thing = 8;
345 insane.xtructs.push_back(truck);
346 printf("testInsanity()");
Mark Slee1921d202007-01-24 19:43:06 +0000347 map<UserId, map<Numberz,Insanity> > whoa;
348 testClient.testInsanity(whoa, insane);
Mark Sleee8540632006-05-30 09:24:40 +0000349 printf(" = {");
350 map<UserId, map<Numberz,Insanity> >::const_iterator i_iter;
351 for (i_iter = whoa.begin(); i_iter != whoa.end(); ++i_iter) {
David Reissbc3dddb2007-08-22 23:20:24 +0000352 printf("%"PRId64" => {", i_iter->first);
Mark Sleee8540632006-05-30 09:24:40 +0000353 map<Numberz,Insanity>::const_iterator i2_iter;
354 for (i2_iter = i_iter->second.begin();
355 i2_iter != i_iter->second.end();
356 ++i2_iter) {
357 printf("%d => {", i2_iter->first);
358 map<Numberz, UserId> userMap = i2_iter->second.userMap;
359 map<Numberz, UserId>::const_iterator um;
360 printf("{");
361 for (um = userMap.begin(); um != userMap.end(); ++um) {
David Reissbc3dddb2007-08-22 23:20:24 +0000362 printf("%d => %"PRId64", ", um->first, um->second);
Mark Sleee8540632006-05-30 09:24:40 +0000363 }
364 printf("}, ");
365
Mark Sleeb9acf982006-10-10 01:57:32 +0000366 vector<Xtruct> xtructs = i2_iter->second.xtructs;
367 vector<Xtruct>::const_iterator x;
Mark Sleee8540632006-05-30 09:24:40 +0000368 printf("{");
369 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
David Reissbc3dddb2007-08-22 23:20:24 +0000370 printf("{\"%s\", %d, %d, %"PRId64"}, ",
Mark Sleee8540632006-05-30 09:24:40 +0000371 x->string_thing.c_str(),
372 (int)x->byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000373 x->i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000374 x->i64_thing);
375 }
376 printf("}");
377
378 printf("}, ");
379 }
380 printf("}, ");
381 }
382 printf("}\n");
383
Marc Slemko71d4e472006-08-15 22:34:04 +0000384 /* test exception */
Mark Slee95771002006-06-07 06:53:25 +0000385
Marc Slemkobf4fd192006-08-15 21:29:39 +0000386 try {
Marc Slemko71d4e472006-08-15 22:34:04 +0000387 printf("testClient.testException(\"Xception\") =>");
388 testClient.testException("Xception");
389 printf(" void\nFAILURE\n");
David Reiss0c90f6f2008-02-06 22:18:40 +0000390
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000391 } catch(Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000392 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000393 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000394
Marc Slemkobf4fd192006-08-15 21:29:39 +0000395 try {
Marc Slemko71d4e472006-08-15 22:34:04 +0000396 printf("testClient.testException(\"success\") =>");
397 testClient.testException("success");
398 printf(" void\n");
399 } catch(...) {
400 printf(" exception\nFAILURE\n");
401 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000402
Marc Slemko71d4e472006-08-15 22:34:04 +0000403 /* test multi exception */
David Reiss0c90f6f2008-02-06 22:18:40 +0000404
Marc Slemko71d4e472006-08-15 22:34:04 +0000405 try {
406 printf("testClient.testMultiException(\"Xception\", \"test 1\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000407 Xtruct result;
408 testClient.testMultiException(result, "Xception", "test 1");
Marc Slemko71d4e472006-08-15 22:34:04 +0000409 printf(" result\nFAILURE\n");
Mark Sleed3d733a2006-09-01 22:19:06 +0000410 } catch(Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000411 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
412 }
413
414 try {
415 printf("testClient.testMultiException(\"Xception2\", \"test 2\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000416 Xtruct result;
417 testClient.testMultiException(result, "Xception2", "test 2");
Marc Slemko71d4e472006-08-15 22:34:04 +0000418 printf(" result\nFAILURE\n");
David Reiss0c90f6f2008-02-06 22:18:40 +0000419
Mark Sleed3d733a2006-09-01 22:19:06 +0000420 } catch(Xception2& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000421 printf(" {%u, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000422 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000423
Marc Slemko71d4e472006-08-15 22:34:04 +0000424 try {
425 printf("testClient.testMultiException(\"success\", \"test 3\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000426 Xtruct result;
427 testClient.testMultiException(result, "success", "test 3");
Marc Slemko71d4e472006-08-15 22:34:04 +0000428 printf(" {{\"%s\"}}\n", result.string_thing.c_str());
429 } catch(...) {
430 printf(" exception\nFAILURE\n");
431 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000432
Marc Slemkobf4fd192006-08-15 21:29:39 +0000433 uint64_t stop = now();
Mark Sleed788b2e2006-09-07 01:26:35 +0000434 uint64_t tot = stop-start;
435
David Reissbc3dddb2007-08-22 23:20:24 +0000436 printf("Total time: %"PRIu64" us\n", stop-start);
David Reiss0c90f6f2008-02-06 22:18:40 +0000437
Mark Sleed788b2e2006-09-07 01:26:35 +0000438 time_tot += tot;
439 if (time_min == 0 || tot < time_min) {
440 time_min = tot;
441 }
442 if (tot > time_max) {
443 time_max = tot;
444 }
445
Mark Sleea3302652006-10-25 19:03:32 +0000446 transport->close();
Mark Sleee8540632006-05-30 09:24:40 +0000447 }
448
Marc Slemko6be374b2006-08-04 03:16:25 +0000449 // printf("\nSocket syscalls: %u", g_socket_syscalls);
Mark Sleee8540632006-05-30 09:24:40 +0000450 printf("\nAll tests done.\n");
Mark Sleed788b2e2006-09-07 01:26:35 +0000451
452 uint64_t time_avg = time_tot / numTests;
453
David Reissbc3dddb2007-08-22 23:20:24 +0000454 printf("Min time: %"PRIu64" us\n", time_min);
455 printf("Max time: %"PRIu64" us\n", time_max);
456 printf("Avg time: %"PRIu64" us\n", time_avg);
Mark Sleed788b2e2006-09-07 01:26:35 +0000457
Mark Sleee8540632006-05-30 09:24:40 +0000458 return 0;
459}