blob: c4146cc5cf57b9a7a6140a6cf681dbd40a8f5f11 [file] [log] [blame]
James E. King, III7edc8fa2017-01-20 10:11:41 -05001/*
David Reissea2cba82009-03-30 21:35:00 +00002 * 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
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +090020#include <limits>
21#include <locale>
22#include <ios>
Roger Meierca142b02011-06-07 17:59:07 +000023#include <iostream>
Sebastian Zenker39e505c2015-12-18 16:15:08 +010024#include <sstream>
Roger Meier49ff8b12012-04-13 09:12:31 +000025#include <thrift/protocol/TBinaryProtocol.h>
Roger Meier023192f2014-02-12 09:35:12 +010026#include <thrift/protocol/TCompactProtocol.h>
Dave Watson792db4e2015-01-16 11:22:01 -080027#include <thrift/protocol/THeaderProtocol.h>
Roger Meier49ff8b12012-04-13 09:12:31 +000028#include <thrift/protocol/TJSONProtocol.h>
James E. King, III58402ff2017-11-17 14:41:46 -050029#include <thrift/protocol/TMultiplexedProtocol.h>
Roger Meier49ff8b12012-04-13 09:12:31 +000030#include <thrift/transport/THttpClient.h>
31#include <thrift/transport/TTransportUtils.h>
32#include <thrift/transport/TSocket.h>
33#include <thrift/transport/TSSLSocket.h>
James E. King IIIb2b767e2018-09-15 20:32:04 +000034#include <thrift/transport/TZlibTransport.h>
Roger Meier49ff8b12012-04-13 09:12:31 +000035#include <thrift/async/TEvhttpClientChannel.h>
36#include <thrift/server/TNonblockingServer.h> // <event.h>
Mark Sleee8540632006-05-30 09:24:40 +000037
James E. King, III7edc8fa2017-01-20 10:11:41 -050038#ifdef HAVE_STDINT_H
39#include <stdint.h>
40#endif
41#ifdef HAVE_INTTYPES_H
42#include <inttypes.h>
43#endif
44
James E. King, III58402ff2017-11-17 14:41:46 -050045#include <boost/algorithm/string.hpp>
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +053046#include <boost/filesystem.hpp>
James E. King, III58402ff2017-11-17 14:41:46 -050047#include <boost/program_options.hpp>
James E. King, III39eaae62017-11-19 20:17:33 -050048#include <boost/random/random_device.hpp>
Jake Farrell5d02b802014-01-07 21:42:01 -050049#if _WIN32
Konrad Grochowski16a23a62014-11-13 15:33:38 +010050#include <thrift/windows/TWinsockSingleton.h>
Jake Farrell5d02b802014-01-07 21:42:01 -050051#endif
Roger Meierca142b02011-06-07 17:59:07 +000052
James E. King, III58402ff2017-11-17 14:41:46 -050053#include "SecondService.h"
Marc Slemko6be374b2006-08-04 03:16:25 +000054#include "ThriftTest.h"
55
Marc Slemko6be374b2006-08-04 03:16:25 +000056using namespace std;
T Jake Lucianib5e62212009-01-31 22:36:20 +000057using namespace apache::thrift;
James E. King, III82ae9572017-08-05 12:23:54 -040058using namespace apache::thrift::async;
T Jake Lucianib5e62212009-01-31 22:36:20 +000059using namespace apache::thrift::protocol;
60using namespace apache::thrift::transport;
Marc Slemkobf4fd192006-08-15 21:29:39 +000061using namespace thrift::test;
Roger Meier7e056e72011-07-17 07:28:28 +000062
James E. King IIIf95620d2019-01-28 18:15:13 -050063//
64// A pedantic protocol that checks to make sure the response sequence ID
65// is the same as the sent sequence ID. lib/cpp always sends zero for
66// synchronous clients, so this bumps the number to make sure it gets
67// returned properly from the remote server. Any server that does not
68// respond with the same sequence number is violating the sequence ID
69// agreement between client and server.
70//
71
James E. King III3ec40312019-01-31 18:35:51 -050072template<typename Proto>
73class TPedanticProtocol : public Proto
James E. King IIIf95620d2019-01-28 18:15:13 -050074{
75 public:
76 TPedanticProtocol(std::shared_ptr<TTransport>& transport)
James E. King III3ec40312019-01-31 18:35:51 -050077 : Proto(transport), m_last_seqid((std::numeric_limits<int32_t>::max)() - 10) { }
James E. King IIIf95620d2019-01-28 18:15:13 -050078
79 virtual uint32_t writeMessageBegin_virt(const std::string& name,
80 const TMessageType messageType,
81 const int32_t in_seqid) override
82 {
83 int32_t seqid = in_seqid;
84 if (!seqid) { // this is typical for normal cpp generated code
85 seqid = ++m_last_seqid;
86 }
87
James E. King III3ec40312019-01-31 18:35:51 -050088 return Proto::writeMessageBegin_virt(name, messageType, seqid);
James E. King IIIf95620d2019-01-28 18:15:13 -050089 }
90
91 virtual uint32_t readMessageBegin_virt(std::string& name,
92 TMessageType& messageType,
93 int32_t& seqid) override
94 {
James E. King III3ec40312019-01-31 18:35:51 -050095 uint32_t result = Proto::readMessageBegin_virt(name, messageType, seqid);
James E. King IIIf95620d2019-01-28 18:15:13 -050096 if (seqid != m_last_seqid) {
97 std::stringstream ss;
98 ss << "ERROR: send request with seqid " << m_last_seqid << " and got reply with seqid " << seqid;
99 throw std::logic_error(ss.str());
100 } /* else {
101 std::cout << "verified seqid " << m_last_seqid << " round trip OK" << std::endl;
102 } */
103 return result;
104 }
105
106 private:
107 int32_t m_last_seqid;
108};
109
Mark Slee95771002006-06-07 06:53:25 +0000110// Current time, microseconds since the epoch
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100111uint64_t now() {
Roger Meier5f9614c2010-11-21 16:59:05 +0000112 int64_t ret;
Mark Slee95771002006-06-07 06:53:25 +0000113 struct timeval tv;
David Reiss0c90f6f2008-02-06 22:18:40 +0000114
Sebastian Zenker042580f2019-01-29 15:48:12 +0100115 THRIFT_GETTIMEOFDAY(&tv, nullptr);
Mark Slee95771002006-06-07 06:53:25 +0000116 ret = tv.tv_sec;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100117 ret = ret * 1000 * 1000 + tv.tv_usec;
Mark Slee95771002006-06-07 06:53:25 +0000118 return ret;
119}
120
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100121static void testString_clientReturn(event_base* base,
122 int testNr,
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100123 ThriftTestCobClient* client) {
Roger Meier7e056e72011-07-17 07:28:28 +0000124 try {
125 string s;
126 client->recv_testString(s);
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100127 std::ostringstream os;
128 os << "test" << testNr;
129 const bool ok = (s == os.str());
130 cout << "testString: " << s << " " << ((ok) ? "ok" : "failed") << endl;
Roger Meier7e056e72011-07-17 07:28:28 +0000131 } catch (TException& exn) {
Jake Farrell5d02b802014-01-07 21:42:01 -0500132 cout << "Error: " << exn.what() << endl;
Roger Meier7e056e72011-07-17 07:28:28 +0000133 }
134
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100135 if (testNr == 9)
136 event_base_loopbreak(base); // end test
Roger Meier7e056e72011-07-17 07:28:28 +0000137}
138
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100139static void testVoid_clientReturn(event_base* base, ThriftTestCobClient* client) {
Roger Meier7e056e72011-07-17 07:28:28 +0000140 try {
141 client->recv_testVoid();
142 cout << "testVoid" << endl;
143
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100144 for (int testNr = 0; testNr < 10; ++testNr) {
145 std::ostringstream os;
146 os << "test" << testNr;
cyy316723a2019-01-05 16:35:14 +0800147 client->testString(std::bind(testString_clientReturn,
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100148 base,
149 testNr,
cyy316723a2019-01-05 16:35:14 +0800150 std::placeholders::_1),
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100151 os.str());
152 }
Roger Meier7e056e72011-07-17 07:28:28 +0000153 } catch (TException& exn) {
Jake Farrell5d02b802014-01-07 21:42:01 -0500154 cout << "Error: " << exn.what() << endl;
Roger Meier7e056e72011-07-17 07:28:28 +0000155 }
156}
157
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900158// Workaround for absense of C++11 "auto" keyword.
159template <typename T>
160bool print_eq(T expected, T actual) {
161 cout << "(" << actual << ")" << endl;
162 if (expected != actual) {
163 cout << "*** FAILED ***" << endl << "Expected: " << expected << " but got: " << actual << endl;
164 return false;
165 }
166 return true;
167}
168
169#define BASETYPE_IDENTITY_TEST(func, value) \
170 cout << #func "(" << value << ") = "; \
171 try { \
172 if (!print_eq(value, testClient.func(value))) \
173 return_code |= ERR_BASETYPES; \
174 } catch (TTransportException&) { \
175 throw; \
176 } catch (exception & ex) { \
177 cout << "*** FAILED ***" << endl << ex.what() << endl; \
178 return_code |= ERR_BASETYPES; \
179 }
180
James E. King, III39eaae62017-11-19 20:17:33 -0500181int binary_test(ThriftTestClient& testClient, string::size_type siz);
182
183BOOST_CONSTEXPR_OR_CONST int ERR_BASETYPES = 1;
184BOOST_CONSTEXPR_OR_CONST int ERR_STRUCTS = 2;
185BOOST_CONSTEXPR_OR_CONST int ERR_CONTAINERS = 4;
186BOOST_CONSTEXPR_OR_CONST int ERR_EXCEPTIONS = 8;
187BOOST_CONSTEXPR_OR_CONST int ERR_UNKNOWN = 64;
188
Mark Sleee8540632006-05-30 09:24:40 +0000189int main(int argc, char** argv) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900190 cout.precision(19);
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900191
James E. King, III06190872017-02-20 08:52:11 -0500192 string testDir = boost::filesystem::system_complete(argv[0]).parent_path().parent_path().parent_path().string();
193 string caPath = testDir + "/keys/CA.pem";
194 string certPath = testDir + "/keys/client.crt";
195 string keyPath = testDir + "/keys/client.key";
196
Jake Farrell5d02b802014-01-07 21:42:01 -0500197#if _WIN32
198 transport::TWinsockSingleton::create();
199#endif
Mark Sleee8540632006-05-30 09:24:40 +0000200 string host = "localhost";
201 int port = 9090;
202 int numTests = 1;
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000203 bool ssl = false;
James E. King IIIb2b767e2018-09-15 20:32:04 +0000204 bool zlib = false;
Roger Meierca142b02011-06-07 17:59:07 +0000205 string transport_type = "buffered";
206 string protocol_type = "binary";
207 string domain_socket = "";
pavlodd08f6e2015-10-08 16:43:56 -0400208 bool abstract_namespace = false;
Jens Geyerf4598682014-05-08 23:18:44 +0200209 bool noinsane = false;
Mark Sleee8540632006-05-30 09:24:40 +0000210
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900211 int return_code = 0;
212
Jake Farrell5d02b802014-01-07 21:42:01 -0500213 boost::program_options::options_description desc("Allowed options");
James E. King, III58402ff2017-11-17 14:41:46 -0500214 desc.add_options()
215 ("help,h", "produce help message")
James E. King, III39eaae62017-11-19 20:17:33 -0500216 ("host",
217 boost::program_options::value<string>(&host)->default_value(host),
James E. King, III58402ff2017-11-17 14:41:46 -0500218 "Host to connect")
James E. King, III39eaae62017-11-19 20:17:33 -0500219 ("port",
220 boost::program_options::value<int>(&port)->default_value(port),
James E. King, III58402ff2017-11-17 14:41:46 -0500221 "Port number to connect")
James E. King, III39eaae62017-11-19 20:17:33 -0500222 ("domain-socket",
James E. King, III58402ff2017-11-17 14:41:46 -0500223 boost::program_options::value<string>(&domain_socket)->default_value(domain_socket),
224 "Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port")
225 ("abstract-namespace",
226 "Look for the domain socket in the Abstract Namespace"
227 " (no connection with filesystem pathnames)")
228 ("transport",
229 boost::program_options::value<string>(&transport_type)->default_value(transport_type),
James E. King IIIb2b767e2018-09-15 20:32:04 +0000230 "Transport: buffered, framed, http, evhttp, zlib")
James E. King, III58402ff2017-11-17 14:41:46 -0500231 ("protocol",
232 boost::program_options::value<string>(&protocol_type)->default_value(protocol_type),
233 "Protocol: binary, compact, header, json, multi, multic, multih, multij")
James E. King, III39eaae62017-11-19 20:17:33 -0500234 ("ssl",
James E. King, III58402ff2017-11-17 14:41:46 -0500235 "Encrypted Transport using SSL")
James E. King IIIb2b767e2018-09-15 20:32:04 +0000236 ("zlib",
237 "Wrap Transport with Zlib")
James E. King, III58402ff2017-11-17 14:41:46 -0500238 ("testloops,n",
239 boost::program_options::value<int>(&numTests)->default_value(numTests),
240 "Number of Tests")
241 ("noinsane",
242 "Do not run insanity test");
Roger Meierca142b02011-06-07 17:59:07 +0000243
Jake Farrell5d02b802014-01-07 21:42:01 -0500244 boost::program_options::variables_map vm;
245 boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
246 boost::program_options::notify(vm);
Roger Meierca142b02011-06-07 17:59:07 +0000247
248 if (vm.count("help")) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900249 cout << desc << endl;
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900250 return ERR_UNKNOWN;
Mark Sleee8540632006-05-30 09:24:40 +0000251 }
Mark Sleea3302652006-10-25 19:03:32 +0000252
Jake Farrell5d02b802014-01-07 21:42:01 -0500253 try {
Roger Meierca142b02011-06-07 17:59:07 +0000254 if (!protocol_type.empty()) {
255 if (protocol_type == "binary") {
Roger Meier284101c2014-03-11 21:20:35 +0100256 } else if (protocol_type == "compact") {
Dave Watson792db4e2015-01-16 11:22:01 -0800257 } else if (protocol_type == "header") {
Roger Meierca142b02011-06-07 17:59:07 +0000258 } else if (protocol_type == "json") {
James E. King, III58402ff2017-11-17 14:41:46 -0500259 } else if (protocol_type == "multi") {
260 } else if (protocol_type == "multic") {
261 } else if (protocol_type == "multih") {
262 } else if (protocol_type == "multij") {
Roger Meierca142b02011-06-07 17:59:07 +0000263 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100264 throw invalid_argument("Unknown protocol type " + protocol_type);
Roger Meierca142b02011-06-07 17:59:07 +0000265 }
266 }
267
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100268 if (!transport_type.empty()) {
Roger Meierca142b02011-06-07 17:59:07 +0000269 if (transport_type == "buffered") {
270 } else if (transport_type == "framed") {
271 } else if (transport_type == "http") {
Roger Meier7e056e72011-07-17 07:28:28 +0000272 } else if (transport_type == "evhttp") {
James E. King IIIb2b767e2018-09-15 20:32:04 +0000273 } else if (transport_type == "zlib") {
274 // crosstest will pass zlib as a transport and as a flag right now..
Roger Meierca142b02011-06-07 17:59:07 +0000275 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100276 throw invalid_argument("Unknown transport type " + transport_type);
Roger Meierca142b02011-06-07 17:59:07 +0000277 }
278 }
279
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900280 } catch (exception& e) {
Roger Meierca142b02011-06-07 17:59:07 +0000281 cerr << e.what() << endl;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900282 cout << desc << endl;
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900283 return ERR_UNKNOWN;
Roger Meierca142b02011-06-07 17:59:07 +0000284 }
285
286 if (vm.count("ssl")) {
287 ssl = true;
288 }
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +0530289
James E. King IIIb2b767e2018-09-15 20:32:04 +0000290 if (vm.count("zlib")) {
291 zlib = true;
292 }
293
pavlodd08f6e2015-10-08 16:43:56 -0400294 if (vm.count("abstract-namespace")) {
295 abstract_namespace = true;
296 }
297
Jens Geyerf4598682014-05-08 23:18:44 +0200298 if (vm.count("noinsane")) {
299 noinsane = true;
300 }
Roger Meierca142b02011-06-07 17:59:07 +0000301
James E. King, III7f5a8c22017-04-04 09:36:38 -0400302 // THRIFT-4164: The factory MUST outlive any sockets it creates for correct behavior!
cyy316723a2019-01-05 16:35:14 +0800303 std::shared_ptr<TSSLSocketFactory> factory;
304 std::shared_ptr<TSocket> socket;
305 std::shared_ptr<TTransport> transport;
306 std::shared_ptr<TProtocol> protocol;
307 std::shared_ptr<TProtocol> protocol2; // SecondService for multiplexed
Roger Meierca142b02011-06-07 17:59:07 +0000308
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000309 if (ssl) {
James E. King, III06190872017-02-20 08:52:11 -0500310 cout << "Client Certificate File: " << certPath << endl;
311 cout << "Client Key File: " << keyPath << endl;
312 cout << "CA File: " << caPath << endl;
313
cyy316723a2019-01-05 16:35:14 +0800314 factory = std::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000315 factory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
James E. King, III06190872017-02-20 08:52:11 -0500316 factory->loadTrustedCertificates(caPath.c_str());
317 factory->loadCertificate(certPath.c_str());
318 factory->loadPrivateKey(keyPath.c_str());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000319 factory->authenticate(true);
320 socket = factory->createSocket(host, port);
321 } else {
Roger Meierca142b02011-06-07 17:59:07 +0000322 if (domain_socket != "") {
pavlodd08f6e2015-10-08 16:43:56 -0400323 if (abstract_namespace) {
324 std::string abstract_socket("\0", 1);
325 abstract_socket += domain_socket;
cyy316723a2019-01-05 16:35:14 +0800326 socket = std::shared_ptr<TSocket>(new TSocket(abstract_socket));
pavlodd08f6e2015-10-08 16:43:56 -0400327 } else {
cyy316723a2019-01-05 16:35:14 +0800328 socket = std::shared_ptr<TSocket>(new TSocket(domain_socket));
pavlodd08f6e2015-10-08 16:43:56 -0400329 }
Roger Meierca142b02011-06-07 17:59:07 +0000330 port = 0;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100331 } else {
cyy316723a2019-01-05 16:35:14 +0800332 socket = std::shared_ptr<TSocket>(new TSocket(host, port));
Roger Meierca142b02011-06-07 17:59:07 +0000333 }
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000334 }
Mark Sleea3302652006-10-25 19:03:32 +0000335
Roger Meierca142b02011-06-07 17:59:07 +0000336 if (transport_type.compare("http") == 0) {
cyy316723a2019-01-05 16:35:14 +0800337 transport = std::make_shared<THttpClient>(socket, host, "/service");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100338 } else if (transport_type.compare("framed") == 0) {
cyy316723a2019-01-05 16:35:14 +0800339 transport = std::make_shared<TFramedTransport>(socket);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100340 } else {
cyy316723a2019-01-05 16:35:14 +0800341 transport = std::make_shared<TBufferedTransport>(socket);
James E. King IIIb2b767e2018-09-15 20:32:04 +0000342 }
343
344 if (zlib) {
cyy316723a2019-01-05 16:35:14 +0800345 transport = std::make_shared<TZlibTransport>(transport);
Mark Sleea3302652006-10-25 19:03:32 +0000346 }
347
James E. King, III58402ff2017-11-17 14:41:46 -0500348 if (protocol_type == "json" || protocol_type == "multij") {
James E. King IIIf95620d2019-01-28 18:15:13 -0500349 typedef TPedanticProtocol<TJSONProtocol> TPedanticJSONProtocol;
350 protocol = std::make_shared<TPedanticJSONProtocol>(transport);
James E. King, III58402ff2017-11-17 14:41:46 -0500351 } else if (protocol_type == "compact" || protocol_type == "multic") {
James E. King IIIf95620d2019-01-28 18:15:13 -0500352 typedef TPedanticProtocol<TCompactProtocol> TPedanticCompactProtocol;
353 protocol = std::make_shared<TPedanticCompactProtocol>(transport);
James E. King, III58402ff2017-11-17 14:41:46 -0500354 } else if (protocol_type == "header" || protocol_type == "multih") {
James E. King IIIf95620d2019-01-28 18:15:13 -0500355 typedef TPedanticProtocol<THeaderProtocol> TPedanticHeaderProtocol;
356 protocol = std::make_shared<TPedanticHeaderProtocol>(transport);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100357 } else {
James E. King IIIf95620d2019-01-28 18:15:13 -0500358 typedef TPedanticProtocol<TBinaryProtocol> TPedanticBinaryProtocol;
359 protocol = std::make_shared<TPedanticBinaryProtocol>(transport);
James E. King, III58402ff2017-11-17 14:41:46 -0500360 }
361
362 if (boost::starts_with(protocol_type, "multi")) {
James E. King IIIf95620d2019-01-28 18:15:13 -0500363 protocol2 = std::make_shared<TMultiplexedProtocol>(protocol, "SecondService");
364 // we don't need access to the original protocol any more, so...
365 protocol = std::make_shared<TMultiplexedProtocol>(protocol, "ThriftTest");
Roger Meierca142b02011-06-07 17:59:07 +0000366 }
367
368 // Connection info
pavlodd08f6e2015-10-08 16:43:56 -0400369 cout << "Connecting (" << transport_type << "/" << protocol_type << ") to: ";
370 if (abstract_namespace) {
371 cout << '@';
372 }
373 cout << domain_socket;
Roger Meierca142b02011-06-07 17:59:07 +0000374 if (port != 0) {
375 cout << host << ":" << port;
376 }
377 cout << endl;
378
Roger Meier7e056e72011-07-17 07:28:28 +0000379 if (transport_type.compare("evhttp") == 0) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100380 event_base* base = event_base_new();
Roger Meier7e056e72011-07-17 07:28:28 +0000381 cout << "Libevent Version: " << event_get_version() << endl;
382 cout << "Libevent Method: " << event_base_get_method(base) << endl;
383#if LIBEVENT_VERSION_NUMBER >= 0x02000000
384 cout << "Libevent Features: 0x" << hex << event_base_get_features(base) << endl;
385#endif
386
cyy316723a2019-01-05 16:35:14 +0800387 std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Roger Meier7e056e72011-07-17 07:28:28 +0000388
cyy316723a2019-01-05 16:35:14 +0800389 std::shared_ptr<TAsyncChannel> channel(
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100390 new TEvhttpClientChannel(host.c_str(), "/", host.c_str(), port, base));
Roger Meier7e056e72011-07-17 07:28:28 +0000391 ThriftTestCobClient* client = new ThriftTestCobClient(channel, protocolFactory.get());
cyy316723a2019-01-05 16:35:14 +0800392 client->testVoid(std::bind(testVoid_clientReturn,
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100393 base,
cyy316723a2019-01-05 16:35:14 +0800394 std::placeholders::_1));
Jake Farrell5d02b802014-01-07 21:42:01 -0500395
Roger Meier7e056e72011-07-17 07:28:28 +0000396 event_base_loop(base, 0);
397 return 0;
398 }
399
Roger Meierca142b02011-06-07 17:59:07 +0000400 ThriftTestClient testClient(protocol);
Mark Sleed788b2e2006-09-07 01:26:35 +0000401
402 uint64_t time_min = 0;
403 uint64_t time_max = 0;
404 uint64_t time_tot = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000405
Mark Sleee8540632006-05-30 09:24:40 +0000406 int test = 0;
407 for (test = 0; test < numTests; ++test) {
Mark Slee95771002006-06-07 06:53:25 +0000408
Mark Slee95771002006-06-07 06:53:25 +0000409 try {
Mark Sleea3302652006-10-25 19:03:32 +0000410 transport->open();
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900411 } catch (TTransportException& ex) {
412 cout << "Connect failed: " << ex.what() << endl;
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900413 return ERR_UNKNOWN;
Mark Sleee8540632006-05-30 09:24:40 +0000414 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000415
Mark Sleed788b2e2006-09-07 01:26:35 +0000416 /**
417 * CONNECT TEST
418 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100419 printf("Test #%d, connect %s:%d\n", test + 1, host.c_str(), port);
Mark Slee95771002006-06-07 06:53:25 +0000420
421 uint64_t start = now();
David Reiss0c90f6f2008-02-06 22:18:40 +0000422
Mark Sleee8540632006-05-30 09:24:40 +0000423 /**
424 * VOID TEST
425 */
Mark Sleee129a2d2007-02-21 05:17:48 +0000426 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900427 cout << "testVoid()" << flush;
Mark Sleee129a2d2007-02-21 05:17:48 +0000428 testClient.testVoid();
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900429 cout << " = void" << endl;
430 } catch (TTransportException&) {
431 // Stop here if transport got broken
432 throw;
433 } catch (exception& ex) {
434 cout << "*** FAILED ***" << endl << ex.what() << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200435 return_code |= ERR_BASETYPES;
Mark Sleee129a2d2007-02-21 05:17:48 +0000436 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000437
Mark Sleee8540632006-05-30 09:24:40 +0000438 /**
439 * STRING TEST
440 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900441 cout << "testString(\"Test\")" << flush;
Mark Slee1921d202007-01-24 19:43:06 +0000442 string s;
443 testClient.testString(s, "Test");
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900444 cout << " = " << s << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200445 if (s != "Test") {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900446 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200447 return_code |= ERR_BASETYPES;
448 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000449
James E. King, III58402ff2017-11-17 14:41:46 -0500450 //
451 // Multiplexed protocol - call another service method
452 // in the middle of the ThriftTest
453 //
454 if (boost::starts_with(protocol_type, "multi")) {
James E. King, III39eaae62017-11-19 20:17:33 -0500455 SecondServiceClient ssc(protocol2);
456 // transport is already open...
457
James E. King, III58402ff2017-11-17 14:41:46 -0500458 try {
459 cout << "secondService.secondTestString(\"foo\") => " << flush;
James E. King, III39eaae62017-11-19 20:17:33 -0500460 std::string result;
461 ssc.secondtestString(result, "foo");
462 cout << "{" << result << "}" << endl;
463 } catch (std::exception& e) {
464 cout << " *** FAILED *** " << e.what() << endl;
465 return_code |= ERR_EXCEPTIONS;
466 }
James E. King, III58402ff2017-11-17 14:41:46 -0500467 }
468
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900469 try {
James E. King, III7edc8fa2017-01-20 10:11:41 -0500470#ifdef _MSC_VER
471#pragma warning( push )
472#pragma warning( disable : 4566 )
473#endif
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900474 string str(
475 "}{Afrikaans, Alemannisch, Aragonés, العربية, مصرى, "
476 "Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, "
477 "Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, "
478 "বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, "
479 "Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, "
480 "Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, "
481 "Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, "
482 "Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, "
483 "Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski, "
484 "Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia, "
485 "Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa, "
486 "ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар, "
487 "Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, "
488 "Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa "
489 "Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, مازِرونی, Bahasa "
490 "Melayu, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, ‪"
491 "Norsk (nynorsk)‬, ‪Norsk (bokmål)‬, Nouormand, Diné bizaad, "
492 "Occitan, Иронау, Papiamentu, Deitsch, Polski, پنجابی, پښتو, "
493 "Norfuk / Pitkern, Português, Runa Simi, Rumantsch, Romani, Română, "
494 "Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple "
495 "English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk, "
496 "Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog, "
497 "Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük, "
498 "Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, "
499 "Bân-lâm-gú, 粵語");
James E. King, III7edc8fa2017-01-20 10:11:41 -0500500#ifdef _MSC_VER
501#pragma warning( pop )
502#endif
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900503 cout << "testString(" << str << ") = " << flush;
504 testClient.testString(s, str);
505 cout << s << endl;
506 if (s != str) {
507 cout.imbue(locale("en_US.UTF8"));
508 cout << "*** FAILED ***" << endl << "Expected string: " << str << " but got: " << s << endl << "CLEAR";
509 return_code |= ERR_BASETYPES;
510 }
511 } catch (TTransportException&) {
512 throw;
513 } catch (exception& ex) {
514 cout << "*** FAILED ***" << endl << ex.what() << endl;
515 return_code |= ERR_BASETYPES;
516 return return_code;
517 }
518 try {
519 string str(
520 "quote: \" backslash:"
521 " forwardslash-escaped: \\/ "
522 " backspace: \b formfeed: \f newline: \n return: \r tab: "
523 " now-all-of-them-together: \"\\\\/\b\n\r\t"
524 " now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><"
525 " char-to-test-json-parsing: ]] \"]] \\\" }}}{ [[[ ");
526 cout << "testString(" << str << ") = " << flush;
527 testClient.testString(s, str);
528 cout << s << endl;
529 if (s != str) {
530 cout.imbue(locale("en_US.UTF8"));
531 cout << "*** FAILED ***" << endl
532 << "Expected string: " << str << " but got: " << s << endl
533 << "CLEAR";
534 ;
535 return_code |= ERR_BASETYPES;
536 }
537 } catch (TTransportException&) {
538 throw;
539 } catch (exception& ex) {
540 cout << "*** FAILED ***" << endl << ex.what() << endl;
541 return_code |= ERR_BASETYPES;
542 return return_code;
543 }
544
Mark Sleee8540632006-05-30 09:24:40 +0000545 /**
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900546 * BOOL TEST
547 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900548 cout << boolalpha;
549 BASETYPE_IDENTITY_TEST(testBool, true);
550 BASETYPE_IDENTITY_TEST(testBool, false);
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900551
552 /**
Mark Sleee8540632006-05-30 09:24:40 +0000553 * BYTE TEST
554 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900555 BASETYPE_IDENTITY_TEST(testByte, (int8_t)0);
556 BASETYPE_IDENTITY_TEST(testByte, (int8_t)-1);
557 BASETYPE_IDENTITY_TEST(testByte, (int8_t)42);
558 BASETYPE_IDENTITY_TEST(testByte, (int8_t)-42);
559 BASETYPE_IDENTITY_TEST(testByte, (int8_t)127);
560 BASETYPE_IDENTITY_TEST(testByte, (int8_t)-128);
David Reiss0c90f6f2008-02-06 22:18:40 +0000561
Mark Sleee8540632006-05-30 09:24:40 +0000562 /**
563 * I32 TEST
564 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900565 BASETYPE_IDENTITY_TEST(testI32, 0);
566 BASETYPE_IDENTITY_TEST(testI32, -1);
567 BASETYPE_IDENTITY_TEST(testI32, 190000013);
568 BASETYPE_IDENTITY_TEST(testI32, -190000013);
James E. King III9b75e4f2018-12-17 16:21:14 -0500569 BASETYPE_IDENTITY_TEST(testI32, (numeric_limits<int32_t>::max)());
570 BASETYPE_IDENTITY_TEST(testI32, (numeric_limits<int32_t>::min)());
Mark Sleee8540632006-05-30 09:24:40 +0000571
572 /**
Mark Sleee8540632006-05-30 09:24:40 +0000573 * I64 TEST
574 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900575 BASETYPE_IDENTITY_TEST(testI64, (int64_t)0);
576 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-1);
577 BASETYPE_IDENTITY_TEST(testI64, (int64_t)7000000000000000123LL);
578 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-7000000000000000123LL);
James E. King, III7edc8fa2017-01-20 10:11:41 -0500579 BASETYPE_IDENTITY_TEST(testI64, (int64_t)pow(static_cast<double>(2LL), 32));
580 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-pow(static_cast<double>(2LL), 32));
581 BASETYPE_IDENTITY_TEST(testI64, (int64_t)pow(static_cast<double>(2LL), 32) + 1);
582 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-pow(static_cast<double>(2LL), 32) - 1);
James E. King III9b75e4f2018-12-17 16:21:14 -0500583 BASETYPE_IDENTITY_TEST(testI64, (numeric_limits<int64_t>::max)());
584 BASETYPE_IDENTITY_TEST(testI64, (numeric_limits<int64_t>::min)());
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100585
Mark Sleec98d0502006-09-06 02:42:25 +0000586 /**
587 * DOUBLE TEST
588 */
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900589 // Comparing double values with plain equality because Thrift handles full precision of double
590 BASETYPE_IDENTITY_TEST(testDouble, 0.0);
591 BASETYPE_IDENTITY_TEST(testDouble, -1.0);
592 BASETYPE_IDENTITY_TEST(testDouble, -5.2098523);
593 BASETYPE_IDENTITY_TEST(testDouble, -0.000341012439638598279);
James E. King, III7edc8fa2017-01-20 10:11:41 -0500594 BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast<double>(2), 32));
595 BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast<double>(2), 32) + 1);
596 BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast<double>(2), 53) - 1);
597 BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast<double>(2), 32));
598 BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast<double>(2), 32) - 1);
599 BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast<double>(2), 53) + 1);
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900600
601 try {
James E. King, III7edc8fa2017-01-20 10:11:41 -0500602 double expected = pow(static_cast<double>(10), 307);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900603 cout << "testDouble(" << expected << ") = " << flush;
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900604 double actual = testClient.testDouble(expected);
605 cout << "(" << actual << ")" << endl;
James E. King, III7edc8fa2017-01-20 10:11:41 -0500606 if (expected - actual > pow(static_cast<double>(10), 292)) {
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900607 cout << "*** FAILED ***" << endl
608 << "Expected: " << expected << " but got: " << actual << endl;
609 }
610 } catch (TTransportException&) {
611 throw;
612 } catch (exception& ex) {
613 cout << "*** FAILED ***" << endl << ex.what() << endl;
614 return_code |= ERR_BASETYPES;
615 }
616
617 try {
James E. King, III7edc8fa2017-01-20 10:11:41 -0500618 double expected = pow(static_cast<double>(10), -292);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900619 cout << "testDouble(" << expected << ") = " << flush;
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900620 double actual = testClient.testDouble(expected);
621 cout << "(" << actual << ")" << endl;
James E. King, III7edc8fa2017-01-20 10:11:41 -0500622 if (expected - actual > pow(static_cast<double>(10), -307)) {
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900623 cout << "*** FAILED ***" << endl
624 << "Expected: " << expected << " but got: " << actual << endl;
625 }
626 } catch (TTransportException&) {
627 throw;
628 } catch (exception& ex) {
629 cout << "*** FAILED ***" << endl << ex.what() << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200630 return_code |= ERR_BASETYPES;
631 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000632
Mark Sleee8540632006-05-30 09:24:40 +0000633 /**
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100634 * BINARY TEST
635 */
James E. King, III39eaae62017-11-19 20:17:33 -0500636 for (string::size_type i = 0; i < 131073 && !return_code; ) {
637 return_code |= binary_test(testClient, i);
638 if (i > 0) { i *= 2; } else { ++i; }
Jens Geyerd629ea02015-09-23 21:16:50 +0200639 }
640
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100641
642 /**
Mark Sleee8540632006-05-30 09:24:40 +0000643 * STRUCT TEST
644 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900645 cout << "testStruct({\"Zero\", 1, -3, -5})" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000646 Xtruct out;
647 out.string_thing = "Zero";
648 out.byte_thing = 1;
Mark Sleee8540632006-05-30 09:24:40 +0000649 out.i32_thing = -3;
Mark Sleee8540632006-05-30 09:24:40 +0000650 out.i64_thing = -5;
Mark Slee1921d202007-01-24 19:43:06 +0000651 Xtruct in;
652 testClient.testStruct(in, out);
Roger Meier0e814802014-01-17 21:07:58 +0100653 printf(" = {\"%s\", %d, %d, %" PRId64 "}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000654 in.string_thing.c_str(),
655 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000656 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000657 in.i64_thing);
Jens Geyerd629ea02015-09-23 21:16:50 +0200658 if (in != out) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900659 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200660 return_code |= ERR_STRUCTS;
661 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000662
Mark Sleee8540632006-05-30 09:24:40 +0000663 /**
664 * NESTED STRUCT TEST
665 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900666 cout << "testNest({1, {\"Zero\", 1, -3, -5}), 5}" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000667 Xtruct2 out2;
668 out2.byte_thing = 1;
669 out2.struct_thing = out;
670 out2.i32_thing = 5;
Mark Slee1921d202007-01-24 19:43:06 +0000671 Xtruct2 in2;
672 testClient.testNest(in2, out2);
Mark Sleee8540632006-05-30 09:24:40 +0000673 in = in2.struct_thing;
Roger Meier0e814802014-01-17 21:07:58 +0100674 printf(" = {%d, {\"%s\", %d, %d, %" PRId64 "}, %d}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000675 in2.byte_thing,
676 in.string_thing.c_str(),
677 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000678 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000679 in.i64_thing,
David Reiss0c90f6f2008-02-06 22:18:40 +0000680 in2.i32_thing);
Jens Geyerd629ea02015-09-23 21:16:50 +0200681 if (in2 != out2) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900682 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200683 return_code |= ERR_STRUCTS;
684 }
Mark Sleee8540632006-05-30 09:24:40 +0000685
686 /**
687 * MAP TEST
688 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100689 map<int32_t, int32_t> mapout;
Mark Sleee8540632006-05-30 09:24:40 +0000690 for (int32_t i = 0; i < 5; ++i) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100691 mapout.insert(make_pair(i, i - 10));
Mark Sleee8540632006-05-30 09:24:40 +0000692 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900693 cout << "testMap({" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000694 map<int32_t, int32_t>::const_iterator m_iter;
695 bool first = true;
696 for (m_iter = mapout.begin(); m_iter != mapout.end(); ++m_iter) {
697 if (first) {
698 first = false;
699 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900700 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000701 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900702 cout << m_iter->first << " => " << m_iter->second;
Mark Sleee8540632006-05-30 09:24:40 +0000703 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900704 cout << "})";
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100705 map<int32_t, int32_t> mapin;
Mark Slee1921d202007-01-24 19:43:06 +0000706 testClient.testMap(mapin, mapout);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900707 cout << " = {";
Mark Sleee8540632006-05-30 09:24:40 +0000708 first = true;
709 for (m_iter = mapin.begin(); m_iter != mapin.end(); ++m_iter) {
710 if (first) {
711 first = false;
712 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900713 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000714 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900715 cout << m_iter->first << " => " << m_iter->second;
Mark Sleee8540632006-05-30 09:24:40 +0000716 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900717 cout << "}" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200718 if (mapin != mapout) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900719 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200720 return_code |= ERR_CONTAINERS;
721 }
Roger Meier4fce9602012-05-04 06:22:09 +0000722
723 /**
724 * STRING MAP TEST
Roger Meier4fce9602012-05-04 06:22:09 +0000725 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900726 cout << "testStringMap({a => 2, b => blah, some => thing}) = {" << flush;
Jens Geyerd629ea02015-09-23 21:16:50 +0200727 map<string, string> smapin;
728 map<string, string> smapout;
729 smapin["a"] = "2";
730 smapin["b"] = "blah";
731 smapin["some"] = "thing";
732 try {
733 testClient.testStringMap(smapout, smapin);
734 first = true;
735 for (map<string, string>::const_iterator it = smapout.begin(); it != smapout.end(); ++it) {
736 if (first)
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900737 cout << ",";
Jens Geyerd629ea02015-09-23 21:16:50 +0200738 else
739 first = false;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900740 cout << it->first << " => " << it->second;
Jens Geyerd629ea02015-09-23 21:16:50 +0200741 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900742 cout << "}" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200743 if (smapin != smapout) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900744 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200745 return_code |= ERR_CONTAINERS;
746 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900747 } catch (TTransportException&) {
748 throw;
Jens Geyerd629ea02015-09-23 21:16:50 +0200749 } catch (exception& ex) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900750 cout << "*** FAILED ***" << endl << ex.what() << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200751 return_code |= ERR_CONTAINERS;
752 }
Mark Sleee8540632006-05-30 09:24:40 +0000753
754 /**
755 * SET TEST
756 */
757 set<int32_t> setout;
758 for (int32_t i = -2; i < 3; ++i) {
759 setout.insert(i);
760 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900761 cout << "testSet({" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000762 set<int32_t>::const_iterator s_iter;
763 first = true;
764 for (s_iter = setout.begin(); s_iter != setout.end(); ++s_iter) {
765 if (first) {
766 first = false;
767 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900768 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000769 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900770 cout << *s_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000771 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900772 cout << "})";
Mark Slee1921d202007-01-24 19:43:06 +0000773 set<int32_t> setin;
774 testClient.testSet(setin, setout);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900775 cout << " = {";
Mark Sleee8540632006-05-30 09:24:40 +0000776 first = true;
777 for (s_iter = setin.begin(); s_iter != setin.end(); ++s_iter) {
778 if (first) {
779 first = false;
780 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900781 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000782 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900783 cout << *s_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000784 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900785 cout << "}" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200786 if (setin != setout) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900787 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200788 return_code |= ERR_CONTAINERS;
789 }
Mark Sleee8540632006-05-30 09:24:40 +0000790
791 /**
792 * LIST TEST
793 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900794 cout << "testList(empty)" << flush;
795 try {
796 vector<int32_t> listout;
797 testClient.testList(listout, vector<int32_t>());
798 if (!listout.empty()) {
799 cout << "*** FAILED ***" << endl;
800 cout << "invalid length: " << listout.size() << endl;
801 return_code |= ERR_CONTAINERS;
Mark Sleee8540632006-05-30 09:24:40 +0000802 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900803 } catch (TTransportException&) {
804 throw;
805 } catch (exception& ex) {
806 cout << "*** FAILED ***" << endl << ex.what() << endl;
807 return_code |= ERR_CONTAINERS;
Mark Sleee8540632006-05-30 09:24:40 +0000808 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900809 try {
810 vector<int32_t> listout;
811 for (int32_t i = -2; i < 3; ++i) {
812 listout.push_back(i);
Mark Sleee8540632006-05-30 09:24:40 +0000813 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900814 cout << "testList({" << flush;
815 vector<int32_t>::const_iterator l_iter;
816 first = true;
817 for (l_iter = listout.begin(); l_iter != listout.end(); ++l_iter) {
818 if (first) {
819 first = false;
820 } else {
821 cout << ",";
822 }
823 cout << *l_iter;
824 }
825 cout << "})";
826 vector<int32_t> listin;
827 testClient.testList(listin, listout);
828 cout << " = {";
829 first = true;
830 for (l_iter = listin.begin(); l_iter != listin.end(); ++l_iter) {
831 if (first) {
832 first = false;
833 } else {
834 cout << ",";
835 }
836 cout << *l_iter;
837 }
838 cout << "}" << endl;
839 if (listin != listout) {
840 cout << "*** FAILED ***" << endl;
841 return_code |= ERR_CONTAINERS;
842 }
843 } catch (TTransportException&) {
844 throw;
845 } catch (exception& ex) {
846 cout << "*** FAILED ***" << endl << ex.what() << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200847 return_code |= ERR_CONTAINERS;
848 }
Mark Sleee8540632006-05-30 09:24:40 +0000849
850 /**
851 * ENUM TEST
852 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900853 cout << "testEnum(ONE)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000854 Numberz::type ret = testClient.testEnum(Numberz::ONE);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900855 cout << " = " << ret << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200856 if (ret != Numberz::ONE) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900857 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200858 return_code |= ERR_STRUCTS;
859 }
Mark Sleee8540632006-05-30 09:24:40 +0000860
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900861 cout << "testEnum(TWO)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000862 ret = testClient.testEnum(Numberz::TWO);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900863 cout << " = " << ret << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200864 if (ret != Numberz::TWO) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900865 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200866 return_code |= ERR_STRUCTS;
867 }
Mark Sleee8540632006-05-30 09:24:40 +0000868
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900869 cout << "testEnum(THREE)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000870 ret = testClient.testEnum(Numberz::THREE);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900871 cout << " = " << ret << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200872 if (ret != Numberz::THREE) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900873 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200874 return_code |= ERR_STRUCTS;
875 }
Mark Sleee8540632006-05-30 09:24:40 +0000876
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900877 cout << "testEnum(FIVE)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000878 ret = testClient.testEnum(Numberz::FIVE);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900879 cout << " = " << ret << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200880 if (ret != Numberz::FIVE) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900881 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200882 return_code |= ERR_STRUCTS;
883 }
Mark Sleee8540632006-05-30 09:24:40 +0000884
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900885 cout << "testEnum(EIGHT)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000886 ret = testClient.testEnum(Numberz::EIGHT);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900887 cout << " = " << ret << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200888 if (ret != Numberz::EIGHT) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900889 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200890 return_code |= ERR_STRUCTS;
891 }
Mark Sleee8540632006-05-30 09:24:40 +0000892
893 /**
894 * TYPEDEF TEST
895 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900896 cout << "testTypedef(309858235082523)" << flush;
Marc Slemkobf4fd192006-08-15 21:29:39 +0000897 UserId uid = testClient.testTypedef(309858235082523LL);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900898 cout << " = " << uid << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200899 if (uid != 309858235082523LL) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900900 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200901 return_code |= ERR_STRUCTS;
902 }
Mark Sleee8540632006-05-30 09:24:40 +0000903
904 /**
905 * NESTED MAP TEST
906 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900907 cout << "testMapMap(1)" << flush;
Mark Slee1921d202007-01-24 19:43:06 +0000908 map<int32_t, map<int32_t, int32_t> > mm;
909 testClient.testMapMap(mm, 1);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900910 cout << " = {";
Mark Sleee8540632006-05-30 09:24:40 +0000911 map<int32_t, map<int32_t, int32_t> >::const_iterator mi;
912 for (mi = mm.begin(); mi != mm.end(); ++mi) {
913 printf("%d => {", mi->first);
914 map<int32_t, int32_t>::const_iterator mi2;
915 for (mi2 = mi->second.begin(); mi2 != mi->second.end(); ++mi2) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900916 cout << mi2->first << " => " << mi2->second;
Mark Sleee8540632006-05-30 09:24:40 +0000917 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900918 cout << "}, ";
Mark Sleee8540632006-05-30 09:24:40 +0000919 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900920 cout << "}" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200921 if (mm.size() != 2 ||
922 mm[-4][-4] != -4 ||
923 mm[-4][-3] != -3 ||
924 mm[-4][-2] != -2 ||
925 mm[-4][-1] != -1 ||
926 mm[4][4] != 4 ||
927 mm[4][3] != 3 ||
928 mm[4][2] != 2 ||
929 mm[4][1] != 1) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900930 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200931 return_code |= ERR_CONTAINERS;
932 }
Mark Sleee8540632006-05-30 09:24:40 +0000933
934 /**
935 * INSANITY TEST
936 */
Jens Geyerf4598682014-05-08 23:18:44 +0200937 if (!noinsane) {
938 Insanity insane;
Jens Geyerd629ea02015-09-23 21:16:50 +0200939 insane.userMap.insert(make_pair(Numberz::FIVE, 5));
940 insane.userMap.insert(make_pair(Numberz::EIGHT, 8));
Jens Geyerf4598682014-05-08 23:18:44 +0200941 Xtruct truck;
Jens Geyerd629ea02015-09-23 21:16:50 +0200942 truck.string_thing = "Goodbye4";
943 truck.byte_thing = 4;
944 truck.i32_thing = 4;
945 truck.i64_thing = 4;
946 Xtruct truck2;
947 truck2.string_thing = "Hello2";
948 truck2.byte_thing = 2;
949 truck2.i32_thing = 2;
950 truck2.i64_thing = 2;
Jens Geyerf4598682014-05-08 23:18:44 +0200951 insane.xtructs.push_back(truck);
Jens Geyerd629ea02015-09-23 21:16:50 +0200952 insane.xtructs.push_back(truck2);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900953 cout << "testInsanity()" << flush;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100954 map<UserId, map<Numberz::type, Insanity> > whoa;
Jens Geyerf4598682014-05-08 23:18:44 +0200955 testClient.testInsanity(whoa, insane);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900956 cout << " = {";
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100957 map<UserId, map<Numberz::type, Insanity> >::const_iterator i_iter;
Jens Geyerf4598682014-05-08 23:18:44 +0200958 for (i_iter = whoa.begin(); i_iter != whoa.end(); ++i_iter) {
959 printf("%" PRId64 " => {", i_iter->first);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100960 map<Numberz::type, Insanity>::const_iterator i2_iter;
961 for (i2_iter = i_iter->second.begin(); i2_iter != i_iter->second.end(); ++i2_iter) {
Jens Geyerf4598682014-05-08 23:18:44 +0200962 printf("%d => {", i2_iter->first);
963 map<Numberz::type, UserId> userMap = i2_iter->second.userMap;
964 map<Numberz::type, UserId>::const_iterator um;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900965 cout << "{";
Jens Geyerf4598682014-05-08 23:18:44 +0200966 for (um = userMap.begin(); um != userMap.end(); ++um) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900967 cout << um->first << " => " << um->second;
Jens Geyerf4598682014-05-08 23:18:44 +0200968 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900969 cout << "}, ";
Mark Sleee8540632006-05-30 09:24:40 +0000970
Jens Geyerf4598682014-05-08 23:18:44 +0200971 vector<Xtruct> xtructs = i2_iter->second.xtructs;
972 vector<Xtruct>::const_iterator x;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900973 cout << "{";
Jens Geyerf4598682014-05-08 23:18:44 +0200974 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
975 printf("{\"%s\", %d, %d, %" PRId64 "}, ",
976 x->string_thing.c_str(),
977 (int)x->byte_thing,
978 x->i32_thing,
979 x->i64_thing);
980 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900981 cout << "}";
Mark Sleee8540632006-05-30 09:24:40 +0000982
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900983 cout << "}, ";
Jens Geyerf4598682014-05-08 23:18:44 +0200984 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900985 cout << "}, ";
Mark Sleee8540632006-05-30 09:24:40 +0000986 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900987 cout << "}" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +0200988 bool failed = false;
989 map<UserId, map<Numberz::type, Insanity> >::const_iterator it1 = whoa.find(UserId(1));
990 if (whoa.size() != 2) {
991 failed = true;
992 }
993 if (it1 == whoa.end()) {
994 failed = true;
995 } else {
Sebastian Zenker042580f2019-01-29 15:48:12 +0100996 auto it12 = it1->second.find(Numberz::TWO);
Jens Geyerd629ea02015-09-23 21:16:50 +0200997 if (it12 == it1->second.end() || it12->second != insane) {
998 failed = true;
999 }
Sebastian Zenker042580f2019-01-29 15:48:12 +01001000 auto it13 = it1->second.find(Numberz::THREE);
Jens Geyerd629ea02015-09-23 21:16:50 +02001001 if (it13 == it1->second.end() || it13->second != insane) {
1002 failed = true;
1003 }
1004 }
1005 map<UserId, map<Numberz::type, Insanity> >::const_iterator it2 = whoa.find(UserId(2));
1006 if (it2 == whoa.end()) {
1007 failed = true;
1008 } else {
Sebastian Zenker042580f2019-01-29 15:48:12 +01001009 auto it26 = it2->second.find(Numberz::SIX);
James E. King IIIf5f430d2018-06-08 03:37:55 +00001010 if (it26 == it2->second.end() || it26->second != Insanity()) {
Jens Geyerd629ea02015-09-23 21:16:50 +02001011 failed = true;
1012 }
1013 }
1014 if (failed) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001015 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +02001016 return_code |= ERR_STRUCTS;
1017 }
Mark Sleee8540632006-05-30 09:24:40 +00001018 }
Jens Geyerd629ea02015-09-23 21:16:50 +02001019
1020 /**
1021 * MULTI TEST
1022 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001023 cout << "testMulti()" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +02001024 try {
1025 map<int16_t, string> mul_map;
1026 Xtruct mul_result;
1027 mul_map[1] = "blah";
1028 mul_map[2] = "thing";
1029 testClient.testMulti(mul_result, 42, 4242, 424242, mul_map, Numberz::EIGHT, UserId(24));
1030 Xtruct xxs;
1031 xxs.string_thing = "Hello2";
1032 xxs.byte_thing = 42;
1033 xxs.i32_thing = 4242;
1034 xxs.i64_thing = 424242;
1035 if (mul_result != xxs) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001036 cout << "*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +02001037 return_code |= ERR_STRUCTS;
1038 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001039 } catch (TTransportException&) {
1040 throw;
Jens Geyerd629ea02015-09-23 21:16:50 +02001041 } catch (exception& ex) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001042 cout << "*** FAILED ***" << endl << ex.what() << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +02001043 return_code |= ERR_STRUCTS;
1044 }
1045
Marc Slemko71d4e472006-08-15 22:34:04 +00001046 /* test exception */
Mark Slee95771002006-06-07 06:53:25 +00001047
Marc Slemkobf4fd192006-08-15 21:29:39 +00001048 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001049 cout << "testClient.testException(\"Xception\") =>" << flush;
Marc Slemko71d4e472006-08-15 22:34:04 +00001050 testClient.testException("Xception");
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001051 cout << " void\n*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +02001052 return_code |= ERR_EXCEPTIONS;
David Reiss0c90f6f2008-02-06 22:18:40 +00001053
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001054 } catch (Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +00001055 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +00001056 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001057
Marc Slemkobf4fd192006-08-15 21:29:39 +00001058 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001059 cout << "testClient.testException(\"TException\") =>" << flush;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001060 testClient.testException("TException");
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001061 cout << " void\n*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +02001062 return_code |= ERR_EXCEPTIONS;
Roger Meierf50df7f2012-05-02 22:49:55 +00001063
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001064 } catch (const TException&) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001065 cout << " Caught TException" << endl;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001066 }
Roger Meierf50df7f2012-05-02 22:49:55 +00001067
1068 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001069 cout << "testClient.testException(\"success\") =>" << flush;
Marc Slemko71d4e472006-08-15 22:34:04 +00001070 testClient.testException("success");
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001071 cout << " void" << endl;
1072 } catch (exception & ex) { \
1073 cout << "*** FAILED ***" << endl << ex.what() << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +02001074 return_code |= ERR_EXCEPTIONS;
Marc Slemko71d4e472006-08-15 22:34:04 +00001075 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001076
Marc Slemko71d4e472006-08-15 22:34:04 +00001077 /* test multi exception */
David Reiss0c90f6f2008-02-06 22:18:40 +00001078
Marc Slemko71d4e472006-08-15 22:34:04 +00001079 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001080 cout << "testClient.testMultiException(\"Xception\", \"test 1\") =>" << flush;
Mark Slee1921d202007-01-24 19:43:06 +00001081 Xtruct result;
1082 testClient.testMultiException(result, "Xception", "test 1");
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001083 cout << " result\n*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +02001084 return_code |= ERR_EXCEPTIONS;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001085 } catch (Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +00001086 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
1087 }
1088
1089 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001090 cout << "testClient.testMultiException(\"Xception2\", \"test 2\") =>" << flush;
Mark Slee1921d202007-01-24 19:43:06 +00001091 Xtruct result;
1092 testClient.testMultiException(result, "Xception2", "test 2");
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001093 cout << " result\n*** FAILED ***" << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +02001094 return_code |= ERR_EXCEPTIONS;
David Reiss0c90f6f2008-02-06 22:18:40 +00001095
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001096 } catch (Xception2& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +00001097 printf(" {%u, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +00001098 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001099
Marc Slemko71d4e472006-08-15 22:34:04 +00001100 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001101 cout << "testClient.testMultiException(\"success\", \"test 3\") =>" << flush;
Mark Slee1921d202007-01-24 19:43:06 +00001102 Xtruct result;
1103 testClient.testMultiException(result, "success", "test 3");
Marc Slemko71d4e472006-08-15 22:34:04 +00001104 printf(" {{\"%s\"}}\n", result.string_thing.c_str());
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001105 } catch (exception & ex) { \
1106 cout << "*** FAILED ***" << endl << ex.what() << endl;
Jens Geyerd629ea02015-09-23 21:16:50 +02001107 return_code |= ERR_EXCEPTIONS;
Marc Slemko71d4e472006-08-15 22:34:04 +00001108 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001109
David Reissc51986f2009-03-24 20:01:25 +00001110 /* test oneway void */
David Reiss2ab6fe82008-02-18 02:11:44 +00001111 {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001112 cout << "testClient.testOneway(1) =>" << flush;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001113 uint64_t startOneway = now();
1114 testClient.testOneway(1);
1115 uint64_t elapsed = now() - startOneway;
1116 if (elapsed > 200 * 1000) { // 0.2 seconds
Jens Geyerd629ea02015-09-23 21:16:50 +02001117 printf("*** FAILED *** - took %.2f ms\n", (double)elapsed / 1000.0);
1118 return_code |= ERR_BASETYPES;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001119 } else {
1120 printf(" success - took %.2f ms\n", (double)elapsed / 1000.0);
1121 }
David Reiss2ab6fe82008-02-18 02:11:44 +00001122 }
1123
David Reiss2845b522008-02-18 02:11:52 +00001124 /**
David Reissc51986f2009-03-24 20:01:25 +00001125 * redo a simple test after the oneway to make sure we aren't "off by one" --
1126 * if the server treated oneway void like normal void, this next test will
David Reiss2845b522008-02-18 02:11:52 +00001127 * fail since it will get the void confirmation rather than the correct
1128 * result. In this circumstance, the client will throw the exception:
1129 *
1130 * TApplicationException: Wrong method namea
1131 */
1132 /**
1133 * I32 TEST
1134 */
James E. King, III58402ff2017-11-17 14:41:46 -05001135 cout << "re-test testI32(-1)" << flush;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001136 int i32 = testClient.testI32(-1);
1137 cout << " = " << i32 << endl;
Roger Meier4fce9602012-05-04 06:22:09 +00001138 if (i32 != -1)
Jens Geyerd629ea02015-09-23 21:16:50 +02001139 return_code |= ERR_BASETYPES;
David Reiss2845b522008-02-18 02:11:52 +00001140
James E. King, III58402ff2017-11-17 14:41:46 -05001141 cout << endl << "All tests done." << endl << flush;
James E. King, III39eaae62017-11-19 20:17:33 -05001142
Marc Slemkobf4fd192006-08-15 21:29:39 +00001143 uint64_t stop = now();
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001144 uint64_t tot = stop - start;
Mark Sleed788b2e2006-09-07 01:26:35 +00001145
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001146 cout << "Total time: " << stop - start << " us" << endl;
David Reiss0c90f6f2008-02-06 22:18:40 +00001147
Mark Sleed788b2e2006-09-07 01:26:35 +00001148 time_tot += tot;
1149 if (time_min == 0 || tot < time_min) {
1150 time_min = tot;
1151 }
1152 if (tot > time_max) {
1153 time_max = tot;
1154 }
1155
James E. King, III58402ff2017-11-17 14:41:46 -05001156 cout << flush;
Mark Sleea3302652006-10-25 19:03:32 +00001157 transport->close();
Mark Sleee8540632006-05-30 09:24:40 +00001158 }
1159
Mark Sleed788b2e2006-09-07 01:26:35 +00001160
1161 uint64_t time_avg = time_tot / numTests;
1162
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001163 cout << "Min time: " << time_min << " us" << endl;
1164 cout << "Max time: " << time_max << " us" << endl;
1165 cout << "Avg time: " << time_avg << " us" << endl;
Mark Sleed788b2e2006-09-07 01:26:35 +00001166
Jens Geyerd629ea02015-09-23 21:16:50 +02001167 return return_code;
Mark Sleee8540632006-05-30 09:24:40 +00001168}
James E. King, III39eaae62017-11-19 20:17:33 -05001169
1170void binary_fill(std::string& str, string::size_type siz)
1171{
1172 static const signed char bin_data[256]
1173 = {-128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114,
1174 -113, -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99,
1175 -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84,
1176 -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, -69,
1177 -68, -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54,
1178 -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39,
1179 -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24,
1180 -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9,
1181 -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6,
1182 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
1183 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
1184 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
1185 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
1186 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
1187 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
1188 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
1189 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
1190 127};
1191
1192 str.resize(siz);
1193 char *ptr = &str[0];
1194 string::size_type pos = 0;
1195 for (string::size_type i = 0; i < siz; ++i)
1196 {
1197 if (pos == 255) { pos = 0; } else { ++pos; }
1198 *ptr++ = bin_data[pos];
1199 }
1200}
1201
1202int binary_test(ThriftTestClient& testClient, string::size_type siz)
1203{
1204 string bin_request;
1205 string bin_result;
1206
1207 cout << "testBinary(siz = " << siz << ")" << endl;
1208 binary_fill(bin_request, siz);
1209 try {
1210 testClient.testBinary(bin_result, bin_request);
1211
1212 if (bin_request.size() != bin_result.size()) {
1213 cout << "*** FAILED: request size " << bin_request.size() << "; result size " << bin_result.size() << endl;
1214 return ERR_BASETYPES;
1215 }
1216
1217 for (string::size_type i = 0; i < siz; ++i) {
1218 if (bin_request.at(i) != bin_result.at(i)) {
1219 cout << "*** FAILED: at position " << i << " request[i] is h" << hex << bin_request.at(i) << " result[i] is h" << hex << bin_result.at(i) << endl;
1220 return ERR_BASETYPES;
1221 }
1222 }
1223 } catch (TTransportException&) {
1224 throw;
1225 } catch (exception& ex) {
1226 cout << "*** FAILED ***" << endl << ex.what() << endl;
1227 return ERR_BASETYPES;
1228 }
1229
1230 return 0;
1231}