blob: e1110b4dfcf37fa89da22027fc0f20618e38c96f [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
11using namespace boost;
12using namespace std;
13using namespace facebook::thrift;
14using namespace facebook::thrift::protocol;
15using namespace facebook::thrift::transport;
Marc Slemkobf4fd192006-08-15 21:29:39 +000016using namespace thrift::test;
Marc Slemko6be374b2006-08-04 03:16:25 +000017
18//extern uint32_t g_socket_syscalls;
Mark Slee95771002006-06-07 06:53:25 +000019
20// Current time, microseconds since the epoch
21uint64_t now()
22{
23 long long ret;
24 struct timeval tv;
25
26 gettimeofday(&tv, NULL);
27 ret = tv.tv_sec;
28 ret = ret*1000*1000 + tv.tv_usec;
29 return ret;
30}
31
Mark Sleee8540632006-05-30 09:24:40 +000032int main(int argc, char** argv) {
33 string host = "localhost";
34 int port = 9090;
35 int numTests = 1;
Mark Sleea3302652006-10-25 19:03:32 +000036 bool framed = false;
37 bool frameInput = true;
Mark Sleee8540632006-05-30 09:24:40 +000038
Mark Sleea3302652006-10-25 19:03:32 +000039 for (int i = 0; i < argc; ++i) {
40 if (strcmp(argv[i], "-h") == 0) {
41 char* pch = strtok(argv[++i], ":");
42 if (pch != NULL) {
43 host = string(pch);
44 }
45 pch = strtok(NULL, ":");
46 if (pch != NULL) {
47 port = atoi(pch);
48 }
49 } else if (strcmp(argv[i], "-n") == 0) {
50 numTests = atoi(argv[++i]);
51 } else if (strcmp(argv[i], "-f") == 0) {
52 framed = true;
53 } else if (strcmp(argv[i], "-fo") == 0) {
54 framed = true;
55 frameInput = false;
56 }
Mark Sleee8540632006-05-30 09:24:40 +000057 }
Mark Sleea3302652006-10-25 19:03:32 +000058
59
60 shared_ptr<TTransport> transport;
Mark Sleee8540632006-05-30 09:24:40 +000061
Marc Slemko6be374b2006-08-04 03:16:25 +000062 shared_ptr<TSocket> socket(new TSocket(host, port));
Mark Sleea3302652006-10-25 19:03:32 +000063
64 if (framed) {
65 shared_ptr<TFramedTransport> framedSocket(new TFramedTransport(socket));
66 framedSocket->setRead(frameInput);
67 transport = framedSocket;
68 if (frameInput) {
69 printf("Using bi-directional framed transport mode\n");
70 } else {
71 printf("Using framed output only mode\n");
72 }
73 } else {
74 shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket));
75 transport = bufferedSocket;
76 }
77
Mark Slee9e288d42007-01-24 23:42:12 +000078 shared_ptr<TBinaryProtocol> protocol(new TBinaryProtocol(transport));
Mark Sleea3302652006-10-25 19:03:32 +000079 ThriftTestClient testClient(protocol);
Mark Sleed788b2e2006-09-07 01:26:35 +000080
81 uint64_t time_min = 0;
82 uint64_t time_max = 0;
83 uint64_t time_tot = 0;
84
Mark Sleee8540632006-05-30 09:24:40 +000085 int test = 0;
86 for (test = 0; test < numTests; ++test) {
Mark Slee95771002006-06-07 06:53:25 +000087
Mark Slee95771002006-06-07 06:53:25 +000088 try {
Mark Sleea3302652006-10-25 19:03:32 +000089 transport->open();
Mark Slee95771002006-06-07 06:53:25 +000090 } catch (TTransportException& ttx) {
Mark Sleeb9ff32a2006-11-16 01:00:24 +000091 printf("Connect failed: %s\n", ttx.what());
Mark Sleee8540632006-05-30 09:24:40 +000092 continue;
93 }
Mark Sleed788b2e2006-09-07 01:26:35 +000094
95 /**
96 * CONNECT TEST
97 */
98 printf("Test #%d, connect %s:%d\n", test+1, host.c_str(), port);
Mark Slee95771002006-06-07 06:53:25 +000099
100 uint64_t start = now();
Mark Sleee8540632006-05-30 09:24:40 +0000101
102 /**
103 * VOID TEST
104 */
Mark Sleee129a2d2007-02-21 05:17:48 +0000105 try {
106 printf("testVoid()");
107 testClient.testVoid();
108 printf(" = void\n");
109 } catch (TApplicationException tax) {
110 printf("%s\n", tax.what());
111 }
Mark Sleee8540632006-05-30 09:24:40 +0000112
113 /**
114 * STRING TEST
115 */
116 printf("testString(\"Test\")");
Mark Slee1921d202007-01-24 19:43:06 +0000117 string s;
118 testClient.testString(s, "Test");
Mark Sleee8540632006-05-30 09:24:40 +0000119 printf(" = \"%s\"\n", s.c_str());
120
121 /**
122 * BYTE TEST
123 */
124 printf("testByte(1)");
125 uint8_t u8 = testClient.testByte(1);
126 printf(" = %d\n", (int)u8);
Mark Slee6e536442006-06-30 18:28:50 +0000127
Mark Sleee8540632006-05-30 09:24:40 +0000128 /**
129 * I32 TEST
130 */
131 printf("testI32(-1)");
132 int32_t i32 = testClient.testI32(-1);
133 printf(" = %d\n", i32);
134
135 /**
Mark Sleee8540632006-05-30 09:24:40 +0000136 * I64 TEST
137 */
138 printf("testI64(-34359738368)");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000139 int64_t i64 = testClient.testI64(-34359738368LL);
Mark Sleed3d733a2006-09-01 22:19:06 +0000140 printf(" = %ld\n", i64);
Mark Sleec98d0502006-09-06 02:42:25 +0000141
142 /**
143 * DOUBLE TEST
144 */
145 printf("testDouble(-5.2098523)");
146 double dub = testClient.testDouble(-5.2098523);
147 printf(" = %lf\n", dub);
Mark Sleee8540632006-05-30 09:24:40 +0000148
149 /**
150 * STRUCT TEST
151 */
Mark Slee6e536442006-06-30 18:28:50 +0000152 printf("testStruct({\"Zero\", 1, -3, -5})");
Mark Sleee8540632006-05-30 09:24:40 +0000153 Xtruct out;
154 out.string_thing = "Zero";
155 out.byte_thing = 1;
Mark Sleee8540632006-05-30 09:24:40 +0000156 out.i32_thing = -3;
Mark Sleee8540632006-05-30 09:24:40 +0000157 out.i64_thing = -5;
Mark Slee1921d202007-01-24 19:43:06 +0000158 Xtruct in;
159 testClient.testStruct(in, out);
Mark Sleed3d733a2006-09-01 22:19:06 +0000160 printf(" = {\"%s\", %d, %d, %ld}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000161 in.string_thing.c_str(),
162 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000163 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000164 in.i64_thing);
165
166 /**
167 * NESTED STRUCT TEST
168 */
Mark Slee6e536442006-06-30 18:28:50 +0000169 printf("testNest({1, {\"Zero\", 1, -3, -5}), 5}");
Mark Sleee8540632006-05-30 09:24:40 +0000170 Xtruct2 out2;
171 out2.byte_thing = 1;
172 out2.struct_thing = out;
173 out2.i32_thing = 5;
Mark Slee1921d202007-01-24 19:43:06 +0000174 Xtruct2 in2;
175 testClient.testNest(in2, out2);
Mark Sleee8540632006-05-30 09:24:40 +0000176 in = in2.struct_thing;
Mark Sleed3d733a2006-09-01 22:19:06 +0000177 printf(" = {%d, {\"%s\", %d, %d, %ld}, %d}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000178 in2.byte_thing,
179 in.string_thing.c_str(),
180 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000181 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000182 in.i64_thing,
183 in2.i32_thing);
184
185 /**
186 * MAP TEST
187 */
188 map<int32_t,int32_t> mapout;
189 for (int32_t i = 0; i < 5; ++i) {
190 mapout.insert(make_pair(i, i-10));
191 }
192 printf("testMap({");
193 map<int32_t, int32_t>::const_iterator m_iter;
194 bool first = true;
195 for (m_iter = mapout.begin(); m_iter != mapout.end(); ++m_iter) {
196 if (first) {
197 first = false;
198 } else {
199 printf(", ");
200 }
201 printf("%d => %d", m_iter->first, m_iter->second);
202 }
203 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000204 map<int32_t,int32_t> mapin;
205 testClient.testMap(mapin, mapout);
Mark Sleee8540632006-05-30 09:24:40 +0000206 printf(" = {");
207 first = true;
208 for (m_iter = mapin.begin(); m_iter != mapin.end(); ++m_iter) {
209 if (first) {
210 first = false;
211 } else {
212 printf(", ");
213 }
214 printf("%d => %d", m_iter->first, m_iter->second);
215 }
216 printf("}\n");
217
218 /**
219 * SET TEST
220 */
221 set<int32_t> setout;
222 for (int32_t i = -2; i < 3; ++i) {
223 setout.insert(i);
224 }
225 printf("testSet({");
226 set<int32_t>::const_iterator s_iter;
227 first = true;
228 for (s_iter = setout.begin(); s_iter != setout.end(); ++s_iter) {
229 if (first) {
230 first = false;
231 } else {
232 printf(", ");
233 }
234 printf("%d", *s_iter);
235 }
236 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000237 set<int32_t> setin;
238 testClient.testSet(setin, setout);
Mark Sleee8540632006-05-30 09:24:40 +0000239 printf(" = {");
240 first = true;
241 for (s_iter = setin.begin(); s_iter != setin.end(); ++s_iter) {
242 if (first) {
243 first = false;
244 } else {
245 printf(", ");
246 }
247 printf("%d", *s_iter);
248 }
249 printf("}\n");
250
251 /**
252 * LIST TEST
253 */
Mark Sleeb9acf982006-10-10 01:57:32 +0000254 vector<int32_t> listout;
Mark Sleee8540632006-05-30 09:24:40 +0000255 for (int32_t i = -2; i < 3; ++i) {
256 listout.push_back(i);
257 }
258 printf("testList({");
Mark Sleeb9acf982006-10-10 01:57:32 +0000259 vector<int32_t>::const_iterator l_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000260 first = true;
261 for (l_iter = listout.begin(); l_iter != listout.end(); ++l_iter) {
262 if (first) {
263 first = false;
264 } else {
265 printf(", ");
266 }
267 printf("%d", *l_iter);
268 }
269 printf("})");
Mark Slee1921d202007-01-24 19:43:06 +0000270 vector<int32_t> listin;
271 testClient.testList(listin, listout);
Mark Sleee8540632006-05-30 09:24:40 +0000272 printf(" = {");
273 first = true;
274 for (l_iter = listin.begin(); l_iter != listin.end(); ++l_iter) {
275 if (first) {
276 first = false;
277 } else {
278 printf(", ");
279 }
280 printf("%d", *l_iter);
281 }
282 printf("}\n");
283
284 /**
285 * ENUM TEST
286 */
287 printf("testEnum(ONE)");
288 Numberz ret = testClient.testEnum(ONE);
289 printf(" = %d\n", ret);
290
291 printf("testEnum(TWO)");
292 ret = testClient.testEnum(TWO);
293 printf(" = %d\n", ret);
294
295 printf("testEnum(THREE)");
296 ret = testClient.testEnum(THREE);
297 printf(" = %d\n", ret);
298
299 printf("testEnum(FIVE)");
300 ret = testClient.testEnum(FIVE);
301 printf(" = %d\n", ret);
302
303 printf("testEnum(EIGHT)");
304 ret = testClient.testEnum(EIGHT);
305 printf(" = %d\n", ret);
306
307 /**
308 * TYPEDEF TEST
309 */
310 printf("testTypedef(309858235082523)");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000311 UserId uid = testClient.testTypedef(309858235082523LL);
Mark Sleed3d733a2006-09-01 22:19:06 +0000312 printf(" = %ld\n", uid);
Mark Sleee8540632006-05-30 09:24:40 +0000313
314 /**
315 * NESTED MAP TEST
316 */
317 printf("testMapMap(1)");
Mark Slee1921d202007-01-24 19:43:06 +0000318 map<int32_t, map<int32_t, int32_t> > mm;
319 testClient.testMapMap(mm, 1);
Mark Sleee8540632006-05-30 09:24:40 +0000320 printf(" = {");
321 map<int32_t, map<int32_t, int32_t> >::const_iterator mi;
322 for (mi = mm.begin(); mi != mm.end(); ++mi) {
323 printf("%d => {", mi->first);
324 map<int32_t, int32_t>::const_iterator mi2;
325 for (mi2 = mi->second.begin(); mi2 != mi->second.end(); ++mi2) {
326 printf("%d => %d, ", mi2->first, mi2->second);
327 }
328 printf("}, ");
329 }
330 printf("}\n");
331
332 /**
333 * INSANITY TEST
334 */
335 Insanity insane;
336 insane.userMap.insert(make_pair(FIVE, 5000));
337 Xtruct truck;
338 truck.string_thing = "Truck";
339 truck.byte_thing = 8;
Mark Sleee8540632006-05-30 09:24:40 +0000340 truck.i32_thing = 8;
Mark Sleee8540632006-05-30 09:24:40 +0000341 truck.i64_thing = 8;
342 insane.xtructs.push_back(truck);
343 printf("testInsanity()");
Mark Slee1921d202007-01-24 19:43:06 +0000344 map<UserId, map<Numberz,Insanity> > whoa;
345 testClient.testInsanity(whoa, insane);
Mark Sleee8540632006-05-30 09:24:40 +0000346 printf(" = {");
347 map<UserId, map<Numberz,Insanity> >::const_iterator i_iter;
348 for (i_iter = whoa.begin(); i_iter != whoa.end(); ++i_iter) {
Mark Sleed3d733a2006-09-01 22:19:06 +0000349 printf("%ld => {", i_iter->first);
Mark Sleee8540632006-05-30 09:24:40 +0000350 map<Numberz,Insanity>::const_iterator i2_iter;
351 for (i2_iter = i_iter->second.begin();
352 i2_iter != i_iter->second.end();
353 ++i2_iter) {
354 printf("%d => {", i2_iter->first);
355 map<Numberz, UserId> userMap = i2_iter->second.userMap;
356 map<Numberz, UserId>::const_iterator um;
357 printf("{");
358 for (um = userMap.begin(); um != userMap.end(); ++um) {
Mark Sleed3d733a2006-09-01 22:19:06 +0000359 printf("%d => %ld, ", um->first, um->second);
Mark Sleee8540632006-05-30 09:24:40 +0000360 }
361 printf("}, ");
362
Mark Sleeb9acf982006-10-10 01:57:32 +0000363 vector<Xtruct> xtructs = i2_iter->second.xtructs;
364 vector<Xtruct>::const_iterator x;
Mark Sleee8540632006-05-30 09:24:40 +0000365 printf("{");
366 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
Mark Sleed3d733a2006-09-01 22:19:06 +0000367 printf("{\"%s\", %d, %d, %ld}, ",
Mark Sleee8540632006-05-30 09:24:40 +0000368 x->string_thing.c_str(),
369 (int)x->byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000370 x->i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000371 x->i64_thing);
372 }
373 printf("}");
374
375 printf("}, ");
376 }
377 printf("}, ");
378 }
379 printf("}\n");
380
Marc Slemko71d4e472006-08-15 22:34:04 +0000381 /* test exception */
Mark Slee95771002006-06-07 06:53:25 +0000382
Marc Slemkobf4fd192006-08-15 21:29:39 +0000383 try {
Marc Slemko71d4e472006-08-15 22:34:04 +0000384 printf("testClient.testException(\"Xception\") =>");
385 testClient.testException("Xception");
386 printf(" void\nFAILURE\n");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000387
Mark Sleeb9ff32a2006-11-16 01:00:24 +0000388 } catch(Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000389 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000390 }
Marc Slemko71d4e472006-08-15 22:34:04 +0000391
Marc Slemkobf4fd192006-08-15 21:29:39 +0000392 try {
Marc Slemko71d4e472006-08-15 22:34:04 +0000393 printf("testClient.testException(\"success\") =>");
394 testClient.testException("success");
395 printf(" void\n");
396 } catch(...) {
397 printf(" exception\nFAILURE\n");
398 }
399
400 /* test multi exception */
401
402 try {
403 printf("testClient.testMultiException(\"Xception\", \"test 1\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000404 Xtruct result;
405 testClient.testMultiException(result, "Xception", "test 1");
Marc Slemko71d4e472006-08-15 22:34:04 +0000406 printf(" result\nFAILURE\n");
Mark Sleed3d733a2006-09-01 22:19:06 +0000407 } catch(Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000408 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
409 }
410
411 try {
412 printf("testClient.testMultiException(\"Xception2\", \"test 2\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000413 Xtruct result;
414 testClient.testMultiException(result, "Xception2", "test 2");
Marc Slemko71d4e472006-08-15 22:34:04 +0000415 printf(" result\nFAILURE\n");
Marc Slemkobf4fd192006-08-15 21:29:39 +0000416
Mark Sleed3d733a2006-09-01 22:19:06 +0000417 } catch(Xception2& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +0000418 printf(" {%u, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +0000419 }
420
Marc Slemko71d4e472006-08-15 22:34:04 +0000421 try {
422 printf("testClient.testMultiException(\"success\", \"test 3\") =>");
Mark Slee1921d202007-01-24 19:43:06 +0000423 Xtruct result;
424 testClient.testMultiException(result, "success", "test 3");
Marc Slemko71d4e472006-08-15 22:34:04 +0000425 printf(" {{\"%s\"}}\n", result.string_thing.c_str());
426 } catch(...) {
427 printf(" exception\nFAILURE\n");
428 }
Marc Slemkobf4fd192006-08-15 21:29:39 +0000429
Marc Slemkobf4fd192006-08-15 21:29:39 +0000430 uint64_t stop = now();
Mark Sleed788b2e2006-09-07 01:26:35 +0000431 uint64_t tot = stop-start;
432
Mark Sleed3d733a2006-09-01 22:19:06 +0000433 printf("Total time: %lu us\n", stop-start);
Marc Slemkobf4fd192006-08-15 21:29:39 +0000434
Mark Sleed788b2e2006-09-07 01:26:35 +0000435 time_tot += tot;
436 if (time_min == 0 || tot < time_min) {
437 time_min = tot;
438 }
439 if (tot > time_max) {
440 time_max = tot;
441 }
442
Mark Sleea3302652006-10-25 19:03:32 +0000443 transport->close();
Mark Sleee8540632006-05-30 09:24:40 +0000444 }
445
Marc Slemko6be374b2006-08-04 03:16:25 +0000446 // printf("\nSocket syscalls: %u", g_socket_syscalls);
Mark Sleee8540632006-05-30 09:24:40 +0000447 printf("\nAll tests done.\n");
Mark Sleed788b2e2006-09-07 01:26:35 +0000448
449 uint64_t time_avg = time_tot / numTests;
450
451 printf("Min time: %lu us\n", time_min);
452 printf("Max time: %lu us\n", time_max);
453 printf("Avg time: %lu us\n", time_avg);
454
Mark Sleee8540632006-05-30 09:24:40 +0000455 return 0;
456}