blob: 41f5007e7926ced574ac4f5d8047f2992df119b9 [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>
Carel Combrinkfbe685a2025-06-05 08:38:07 +020025#include <fstream>
Roger Meier49ff8b12012-04-13 09:12:31 +000026#include <thrift/protocol/TBinaryProtocol.h>
Roger Meier023192f2014-02-12 09:35:12 +010027#include <thrift/protocol/TCompactProtocol.h>
Dave Watson792db4e2015-01-16 11:22:01 -080028#include <thrift/protocol/THeaderProtocol.h>
Roger Meier49ff8b12012-04-13 09:12:31 +000029#include <thrift/protocol/TJSONProtocol.h>
James E. King, III58402ff2017-11-17 14:41:46 -050030#include <thrift/protocol/TMultiplexedProtocol.h>
Roger Meier49ff8b12012-04-13 09:12:31 +000031#include <thrift/transport/THttpClient.h>
32#include <thrift/transport/TTransportUtils.h>
33#include <thrift/transport/TSocket.h>
34#include <thrift/transport/TSSLSocket.h>
James E. King IIIb2b767e2018-09-15 20:32:04 +000035#include <thrift/transport/TZlibTransport.h>
Roger Meier49ff8b12012-04-13 09:12:31 +000036#include <thrift/async/TEvhttpClientChannel.h>
37#include <thrift/server/TNonblockingServer.h> // <event.h>
Mark Sleee8540632006-05-30 09:24:40 +000038
James E. King, III7edc8fa2017-01-20 10:11:41 -050039#ifdef HAVE_STDINT_H
40#include <stdint.h>
41#endif
42#ifdef HAVE_INTTYPES_H
43#include <inttypes.h>
44#endif
45
James E. King, III58402ff2017-11-17 14:41:46 -050046#include <boost/algorithm/string.hpp>
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +053047#include <boost/filesystem.hpp>
James E. King, III58402ff2017-11-17 14:41:46 -050048#include <boost/program_options.hpp>
James E. King, III39eaae62017-11-19 20:17:33 -050049#include <boost/random/random_device.hpp>
Jake Farrell5d02b802014-01-07 21:42:01 -050050#if _WIN32
Konrad Grochowski16a23a62014-11-13 15:33:38 +010051#include <thrift/windows/TWinsockSingleton.h>
Jake Farrell5d02b802014-01-07 21:42:01 -050052#endif
Roger Meierca142b02011-06-07 17:59:07 +000053
James E. King, III58402ff2017-11-17 14:41:46 -050054#include "SecondService.h"
Marc Slemko6be374b2006-08-04 03:16:25 +000055#include "ThriftTest.h"
56
Marc Slemko6be374b2006-08-04 03:16:25 +000057using namespace std;
T Jake Lucianib5e62212009-01-31 22:36:20 +000058using namespace apache::thrift;
James E. King, III82ae9572017-08-05 12:23:54 -040059using namespace apache::thrift::async;
T Jake Lucianib5e62212009-01-31 22:36:20 +000060using namespace apache::thrift::protocol;
61using namespace apache::thrift::transport;
Marc Slemkobf4fd192006-08-15 21:29:39 +000062using namespace thrift::test;
Roger Meier7e056e72011-07-17 07:28:28 +000063
James E. King IIIf95620d2019-01-28 18:15:13 -050064//
65// A pedantic protocol that checks to make sure the response sequence ID
66// is the same as the sent sequence ID. lib/cpp always sends zero for
67// synchronous clients, so this bumps the number to make sure it gets
68// returned properly from the remote server. Any server that does not
69// respond with the same sequence number is violating the sequence ID
70// agreement between client and server.
71//
72
James E. King III3ec40312019-01-31 18:35:51 -050073template<typename Proto>
CJCombrink1d886ca2024-03-23 21:32:28 +010074class TPedanticProtocol : public Proto
James E. King IIIf95620d2019-01-28 18:15:13 -050075{
76 public:
77 TPedanticProtocol(std::shared_ptr<TTransport>& transport)
James E. King III3ec40312019-01-31 18:35:51 -050078 : Proto(transport), m_last_seqid((std::numeric_limits<int32_t>::max)() - 10) { }
James E. King IIIf95620d2019-01-28 18:15:13 -050079
80 virtual uint32_t writeMessageBegin_virt(const std::string& name,
81 const TMessageType messageType,
82 const int32_t in_seqid) override
83 {
84 int32_t seqid = in_seqid;
85 if (!seqid) { // this is typical for normal cpp generated code
86 seqid = ++m_last_seqid;
87 }
88
James E. King III3ec40312019-01-31 18:35:51 -050089 return Proto::writeMessageBegin_virt(name, messageType, seqid);
James E. King IIIf95620d2019-01-28 18:15:13 -050090 }
91
92 virtual uint32_t readMessageBegin_virt(std::string& name,
93 TMessageType& messageType,
94 int32_t& seqid) override
95 {
James E. King III3ec40312019-01-31 18:35:51 -050096 uint32_t result = Proto::readMessageBegin_virt(name, messageType, seqid);
James E. King IIIf95620d2019-01-28 18:15:13 -050097 if (seqid != m_last_seqid) {
98 std::stringstream ss;
99 ss << "ERROR: send request with seqid " << m_last_seqid << " and got reply with seqid " << seqid;
100 throw std::logic_error(ss.str());
101 } /* else {
CJCombrink4a280d52024-03-14 19:57:41 +0100102 std::cout << "verified seqid " << m_last_seqid << " round trip OK" << '\n';
James E. King IIIf95620d2019-01-28 18:15:13 -0500103 } */
104 return result;
105 }
106
107 private:
108 int32_t m_last_seqid;
109};
110
Mark Slee95771002006-06-07 06:53:25 +0000111// Current time, microseconds since the epoch
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100112uint64_t now() {
Roger Meier5f9614c2010-11-21 16:59:05 +0000113 int64_t ret;
Mark Slee95771002006-06-07 06:53:25 +0000114 struct timeval tv;
David Reiss0c90f6f2008-02-06 22:18:40 +0000115
Sebastian Zenker042580f2019-01-29 15:48:12 +0100116 THRIFT_GETTIMEOFDAY(&tv, nullptr);
Mark Slee95771002006-06-07 06:53:25 +0000117 ret = tv.tv_sec;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100118 ret = ret * 1000 * 1000 + tv.tv_usec;
Mark Slee95771002006-06-07 06:53:25 +0000119 return ret;
120}
121
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100122static void testString_clientReturn(event_base* base,
123 int testNr,
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100124 ThriftTestCobClient* client) {
Roger Meier7e056e72011-07-17 07:28:28 +0000125 try {
126 string s;
127 client->recv_testString(s);
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100128 std::ostringstream os;
129 os << "test" << testNr;
130 const bool ok = (s == os.str());
CJCombrink4a280d52024-03-14 19:57:41 +0100131 cout << "testString: " << s << " " << ((ok) ? "ok" : "failed") << '\n';
Roger Meier7e056e72011-07-17 07:28:28 +0000132 } catch (TException& exn) {
CJCombrink4a280d52024-03-14 19:57:41 +0100133 cout << "Error: " << exn.what() << '\n';
Roger Meier7e056e72011-07-17 07:28:28 +0000134 }
135
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100136 if (testNr == 9)
137 event_base_loopbreak(base); // end test
Roger Meier7e056e72011-07-17 07:28:28 +0000138}
139
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100140static void testVoid_clientReturn(event_base* base, ThriftTestCobClient* client) {
Roger Meier7e056e72011-07-17 07:28:28 +0000141 try {
142 client->recv_testVoid();
CJCombrink4a280d52024-03-14 19:57:41 +0100143 cout << "testVoid" << '\n';
Roger Meier7e056e72011-07-17 07:28:28 +0000144
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100145 for (int testNr = 0; testNr < 10; ++testNr) {
146 std::ostringstream os;
147 os << "test" << testNr;
cyy316723a2019-01-05 16:35:14 +0800148 client->testString(std::bind(testString_clientReturn,
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100149 base,
150 testNr,
cyy316723a2019-01-05 16:35:14 +0800151 std::placeholders::_1),
Sebastian Zenker39e505c2015-12-18 16:15:08 +0100152 os.str());
153 }
Roger Meier7e056e72011-07-17 07:28:28 +0000154 } catch (TException& exn) {
CJCombrink4a280d52024-03-14 19:57:41 +0100155 cout << "Error: " << exn.what() << '\n';
Roger Meier7e056e72011-07-17 07:28:28 +0000156 }
157}
158
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900159// Workaround for absense of C++11 "auto" keyword.
160template <typename T>
161bool print_eq(T expected, T actual) {
CJCombrink4a280d52024-03-14 19:57:41 +0100162 cout << "(" << actual << ")" << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900163 if (expected != actual) {
CJCombrink4a280d52024-03-14 19:57:41 +0100164 cout << "*** FAILED ***" << '\n' << "Expected: " << expected << " but got: " << actual << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900165 return false;
166 }
167 return true;
168}
169
170#define BASETYPE_IDENTITY_TEST(func, value) \
171 cout << #func "(" << value << ") = "; \
172 try { \
173 if (!print_eq(value, testClient.func(value))) \
174 return_code |= ERR_BASETYPES; \
175 } catch (TTransportException&) { \
176 throw; \
177 } catch (exception & ex) { \
CJCombrink4a280d52024-03-14 19:57:41 +0100178 cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; \
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900179 return_code |= ERR_BASETYPES; \
180 }
181
CJCombrink1d886ca2024-03-23 21:32:28 +0100182#define UUID_TEST(func, value, expected) \
183 cout << #func "(" << value << ") = "; \
184 try { \
Carel Combrinkaee3f632024-09-05 18:26:42 +0000185 TUuid ret; \
186 testClient.func(ret, value); \
187 if (!print_eq(expected, ret)) \
CJCombrink1d886ca2024-03-23 21:32:28 +0100188 return_code |= ERR_BASETYPES; \
189 } catch (TTransportException&) { \
190 throw; \
191 } catch (exception & ex) { \
CJCombrink4a280d52024-03-14 19:57:41 +0100192 cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; \
CJCombrink1d886ca2024-03-23 21:32:28 +0100193 return_code |= ERR_BASETYPES; \
194 }
195
James E. King, III39eaae62017-11-19 20:17:33 -0500196int binary_test(ThriftTestClient& testClient, string::size_type siz);
197
198BOOST_CONSTEXPR_OR_CONST int ERR_BASETYPES = 1;
199BOOST_CONSTEXPR_OR_CONST int ERR_STRUCTS = 2;
200BOOST_CONSTEXPR_OR_CONST int ERR_CONTAINERS = 4;
201BOOST_CONSTEXPR_OR_CONST int ERR_EXCEPTIONS = 8;
202BOOST_CONSTEXPR_OR_CONST int ERR_UNKNOWN = 64;
203
Mark Sleee8540632006-05-30 09:24:40 +0000204int main(int argc, char** argv) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900205 cout.precision(19);
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900206
James E. King, III06190872017-02-20 08:52:11 -0500207 string testDir = boost::filesystem::system_complete(argv[0]).parent_path().parent_path().parent_path().string();
208 string caPath = testDir + "/keys/CA.pem";
209 string certPath = testDir + "/keys/client.crt";
210 string keyPath = testDir + "/keys/client.key";
211
Jake Farrell5d02b802014-01-07 21:42:01 -0500212#if _WIN32
213 transport::TWinsockSingleton::create();
214#endif
Mark Sleee8540632006-05-30 09:24:40 +0000215 string host = "localhost";
216 int port = 9090;
217 int numTests = 1;
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000218 bool ssl = false;
James E. King IIIb2b767e2018-09-15 20:32:04 +0000219 bool zlib = false;
Roger Meierca142b02011-06-07 17:59:07 +0000220 string transport_type = "buffered";
221 string protocol_type = "binary";
222 string domain_socket = "";
pavlodd08f6e2015-10-08 16:43:56 -0400223 bool abstract_namespace = false;
Jens Geyerf4598682014-05-08 23:18:44 +0200224 bool noinsane = false;
Mark Sleee8540632006-05-30 09:24:40 +0000225
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900226 int return_code = 0;
227
Jake Farrell5d02b802014-01-07 21:42:01 -0500228 boost::program_options::options_description desc("Allowed options");
James E. King, III58402ff2017-11-17 14:41:46 -0500229 desc.add_options()
230 ("help,h", "produce help message")
James E. King, III39eaae62017-11-19 20:17:33 -0500231 ("host",
232 boost::program_options::value<string>(&host)->default_value(host),
James E. King, III58402ff2017-11-17 14:41:46 -0500233 "Host to connect")
James E. King, III39eaae62017-11-19 20:17:33 -0500234 ("port",
235 boost::program_options::value<int>(&port)->default_value(port),
James E. King, III58402ff2017-11-17 14:41:46 -0500236 "Port number to connect")
James E. King, III39eaae62017-11-19 20:17:33 -0500237 ("domain-socket",
James E. King, III58402ff2017-11-17 14:41:46 -0500238 boost::program_options::value<string>(&domain_socket)->default_value(domain_socket),
239 "Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port")
240 ("abstract-namespace",
241 "Look for the domain socket in the Abstract Namespace"
242 " (no connection with filesystem pathnames)")
243 ("transport",
244 boost::program_options::value<string>(&transport_type)->default_value(transport_type),
James E. King IIIb2b767e2018-09-15 20:32:04 +0000245 "Transport: buffered, framed, http, evhttp, zlib")
James E. King, III58402ff2017-11-17 14:41:46 -0500246 ("protocol",
247 boost::program_options::value<string>(&protocol_type)->default_value(protocol_type),
248 "Protocol: binary, compact, header, json, multi, multic, multih, multij")
James E. King, III39eaae62017-11-19 20:17:33 -0500249 ("ssl",
James E. King, III58402ff2017-11-17 14:41:46 -0500250 "Encrypted Transport using SSL")
James E. King IIIb2b767e2018-09-15 20:32:04 +0000251 ("zlib",
252 "Wrap Transport with Zlib")
James E. King, III58402ff2017-11-17 14:41:46 -0500253 ("testloops,n",
254 boost::program_options::value<int>(&numTests)->default_value(numTests),
255 "Number of Tests")
256 ("noinsane",
257 "Do not run insanity test");
Roger Meierca142b02011-06-07 17:59:07 +0000258
Jake Farrell5d02b802014-01-07 21:42:01 -0500259 boost::program_options::variables_map vm;
260 boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
261 boost::program_options::notify(vm);
Roger Meierca142b02011-06-07 17:59:07 +0000262
263 if (vm.count("help")) {
CJCombrink4a280d52024-03-14 19:57:41 +0100264 cout << desc << '\n';
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900265 return ERR_UNKNOWN;
Mark Sleee8540632006-05-30 09:24:40 +0000266 }
Mark Sleea3302652006-10-25 19:03:32 +0000267
Jake Farrell5d02b802014-01-07 21:42:01 -0500268 try {
Roger Meierca142b02011-06-07 17:59:07 +0000269 if (!protocol_type.empty()) {
270 if (protocol_type == "binary") {
Roger Meier284101c2014-03-11 21:20:35 +0100271 } else if (protocol_type == "compact") {
Dave Watson792db4e2015-01-16 11:22:01 -0800272 } else if (protocol_type == "header") {
Roger Meierca142b02011-06-07 17:59:07 +0000273 } else if (protocol_type == "json") {
James E. King, III58402ff2017-11-17 14:41:46 -0500274 } else if (protocol_type == "multi") {
275 } else if (protocol_type == "multic") {
276 } else if (protocol_type == "multih") {
277 } else if (protocol_type == "multij") {
Roger Meierca142b02011-06-07 17:59:07 +0000278 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100279 throw invalid_argument("Unknown protocol type " + protocol_type);
Roger Meierca142b02011-06-07 17:59:07 +0000280 }
281 }
282
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100283 if (!transport_type.empty()) {
Roger Meierca142b02011-06-07 17:59:07 +0000284 if (transport_type == "buffered") {
285 } else if (transport_type == "framed") {
286 } else if (transport_type == "http") {
Roger Meier7e056e72011-07-17 07:28:28 +0000287 } else if (transport_type == "evhttp") {
James E. King IIIb2b767e2018-09-15 20:32:04 +0000288 } else if (transport_type == "zlib") {
289 // crosstest will pass zlib as a transport and as a flag right now..
Roger Meierca142b02011-06-07 17:59:07 +0000290 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100291 throw invalid_argument("Unknown transport type " + transport_type);
Roger Meierca142b02011-06-07 17:59:07 +0000292 }
293 }
294
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900295 } catch (exception& e) {
CJCombrink4a280d52024-03-14 19:57:41 +0100296 cerr << e.what() << '\n';
297 cout << desc << '\n';
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900298 return ERR_UNKNOWN;
Roger Meierca142b02011-06-07 17:59:07 +0000299 }
300
301 if (vm.count("ssl")) {
302 ssl = true;
303 }
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +0530304
James E. King IIIb2b767e2018-09-15 20:32:04 +0000305 if (vm.count("zlib")) {
306 zlib = true;
307 }
308
pavlodd08f6e2015-10-08 16:43:56 -0400309 if (vm.count("abstract-namespace")) {
310 abstract_namespace = true;
311 }
312
Jens Geyerf4598682014-05-08 23:18:44 +0200313 if (vm.count("noinsane")) {
314 noinsane = true;
315 }
Roger Meierca142b02011-06-07 17:59:07 +0000316
James E. King, III7f5a8c22017-04-04 09:36:38 -0400317 // THRIFT-4164: The factory MUST outlive any sockets it creates for correct behavior!
cyy316723a2019-01-05 16:35:14 +0800318 std::shared_ptr<TSSLSocketFactory> factory;
319 std::shared_ptr<TSocket> socket;
320 std::shared_ptr<TTransport> transport;
321 std::shared_ptr<TProtocol> protocol;
322 std::shared_ptr<TProtocol> protocol2; // SecondService for multiplexed
Roger Meierca142b02011-06-07 17:59:07 +0000323
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000324 if (ssl) {
Carel Combrinkfbe685a2025-06-05 08:38:07 +0200325 auto fileExists = [](const std::string& path) {
326 std::ifstream f(path.c_str());
327 return f.good();
328 };
329
330 cout << "Client Path : " << testDir << '\n';
331 cout << "Client Certificate File: " << certPath << " (" << std::boolalpha << fileExists(certPath) << ")"<< '\n';
332 cout << "Client Key File: " << keyPath << " (" << std::boolalpha << fileExists(keyPath) << ")"<< '\n';
333 cout << "CA File: " << caPath << " (" << std::boolalpha << fileExists(caPath) << ")"<< '\n';
James E. King, III06190872017-02-20 08:52:11 -0500334
cyy316723a2019-01-05 16:35:14 +0800335 factory = std::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000336 factory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
James E. King, III06190872017-02-20 08:52:11 -0500337 factory->loadTrustedCertificates(caPath.c_str());
338 factory->loadCertificate(certPath.c_str());
339 factory->loadPrivateKey(keyPath.c_str());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000340 factory->authenticate(true);
341 socket = factory->createSocket(host, port);
342 } else {
Roger Meierca142b02011-06-07 17:59:07 +0000343 if (domain_socket != "") {
pavlodd08f6e2015-10-08 16:43:56 -0400344 if (abstract_namespace) {
345 std::string abstract_socket("\0", 1);
346 abstract_socket += domain_socket;
cyy316723a2019-01-05 16:35:14 +0800347 socket = std::shared_ptr<TSocket>(new TSocket(abstract_socket));
pavlodd08f6e2015-10-08 16:43:56 -0400348 } else {
cyy316723a2019-01-05 16:35:14 +0800349 socket = std::shared_ptr<TSocket>(new TSocket(domain_socket));
pavlodd08f6e2015-10-08 16:43:56 -0400350 }
Roger Meierca142b02011-06-07 17:59:07 +0000351 port = 0;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100352 } else {
cyy316723a2019-01-05 16:35:14 +0800353 socket = std::shared_ptr<TSocket>(new TSocket(host, port));
Roger Meierca142b02011-06-07 17:59:07 +0000354 }
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000355 }
Mark Sleea3302652006-10-25 19:03:32 +0000356
Roger Meierca142b02011-06-07 17:59:07 +0000357 if (transport_type.compare("http") == 0) {
cyy316723a2019-01-05 16:35:14 +0800358 transport = std::make_shared<THttpClient>(socket, host, "/service");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100359 } else if (transport_type.compare("framed") == 0) {
cyy316723a2019-01-05 16:35:14 +0800360 transport = std::make_shared<TFramedTransport>(socket);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100361 } else {
cyy316723a2019-01-05 16:35:14 +0800362 transport = std::make_shared<TBufferedTransport>(socket);
James E. King IIIb2b767e2018-09-15 20:32:04 +0000363 }
364
365 if (zlib) {
cyy316723a2019-01-05 16:35:14 +0800366 transport = std::make_shared<TZlibTransport>(transport);
Mark Sleea3302652006-10-25 19:03:32 +0000367 }
368
James E. King, III58402ff2017-11-17 14:41:46 -0500369 if (protocol_type == "json" || protocol_type == "multij") {
James E. King IIIf95620d2019-01-28 18:15:13 -0500370 typedef TPedanticProtocol<TJSONProtocol> TPedanticJSONProtocol;
371 protocol = std::make_shared<TPedanticJSONProtocol>(transport);
James E. King, III58402ff2017-11-17 14:41:46 -0500372 } else if (protocol_type == "compact" || protocol_type == "multic") {
James E. King IIIf95620d2019-01-28 18:15:13 -0500373 typedef TPedanticProtocol<TCompactProtocol> TPedanticCompactProtocol;
374 protocol = std::make_shared<TPedanticCompactProtocol>(transport);
James E. King, III58402ff2017-11-17 14:41:46 -0500375 } else if (protocol_type == "header" || protocol_type == "multih") {
James E. King IIIf95620d2019-01-28 18:15:13 -0500376 typedef TPedanticProtocol<THeaderProtocol> TPedanticHeaderProtocol;
377 protocol = std::make_shared<TPedanticHeaderProtocol>(transport);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100378 } else {
James E. King IIIf95620d2019-01-28 18:15:13 -0500379 typedef TPedanticProtocol<TBinaryProtocol> TPedanticBinaryProtocol;
380 protocol = std::make_shared<TPedanticBinaryProtocol>(transport);
James E. King, III58402ff2017-11-17 14:41:46 -0500381 }
382
383 if (boost::starts_with(protocol_type, "multi")) {
James E. King IIIf95620d2019-01-28 18:15:13 -0500384 protocol2 = std::make_shared<TMultiplexedProtocol>(protocol, "SecondService");
385 // we don't need access to the original protocol any more, so...
386 protocol = std::make_shared<TMultiplexedProtocol>(protocol, "ThriftTest");
Roger Meierca142b02011-06-07 17:59:07 +0000387 }
388
389 // Connection info
pavlodd08f6e2015-10-08 16:43:56 -0400390 cout << "Connecting (" << transport_type << "/" << protocol_type << ") to: ";
391 if (abstract_namespace) {
392 cout << '@';
393 }
394 cout << domain_socket;
Roger Meierca142b02011-06-07 17:59:07 +0000395 if (port != 0) {
396 cout << host << ":" << port;
397 }
CJCombrink4a280d52024-03-14 19:57:41 +0100398 cout << '\n';
Roger Meierca142b02011-06-07 17:59:07 +0000399
Roger Meier7e056e72011-07-17 07:28:28 +0000400 if (transport_type.compare("evhttp") == 0) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100401 event_base* base = event_base_new();
CJCombrink4a280d52024-03-14 19:57:41 +0100402 cout << "Libevent Version: " << event_get_version() << '\n';
403 cout << "Libevent Method: " << event_base_get_method(base) << '\n';
Roger Meier7e056e72011-07-17 07:28:28 +0000404#if LIBEVENT_VERSION_NUMBER >= 0x02000000
CJCombrink4a280d52024-03-14 19:57:41 +0100405 cout << "Libevent Features: 0x" << hex << event_base_get_features(base) << '\n';
Roger Meier7e056e72011-07-17 07:28:28 +0000406#endif
407
cyy316723a2019-01-05 16:35:14 +0800408 std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Roger Meier7e056e72011-07-17 07:28:28 +0000409
cyy316723a2019-01-05 16:35:14 +0800410 std::shared_ptr<TAsyncChannel> channel(
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100411 new TEvhttpClientChannel(host.c_str(), "/", host.c_str(), port, base));
Roger Meier7e056e72011-07-17 07:28:28 +0000412 ThriftTestCobClient* client = new ThriftTestCobClient(channel, protocolFactory.get());
cyy316723a2019-01-05 16:35:14 +0800413 client->testVoid(std::bind(testVoid_clientReturn,
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100414 base,
cyy316723a2019-01-05 16:35:14 +0800415 std::placeholders::_1));
Jake Farrell5d02b802014-01-07 21:42:01 -0500416
Roger Meier7e056e72011-07-17 07:28:28 +0000417 event_base_loop(base, 0);
418 return 0;
419 }
420
Roger Meierca142b02011-06-07 17:59:07 +0000421 ThriftTestClient testClient(protocol);
Mark Sleed788b2e2006-09-07 01:26:35 +0000422
423 uint64_t time_min = 0;
424 uint64_t time_max = 0;
425 uint64_t time_tot = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000426
Mark Sleee8540632006-05-30 09:24:40 +0000427 int test = 0;
428 for (test = 0; test < numTests; ++test) {
Mark Slee95771002006-06-07 06:53:25 +0000429
Mark Slee95771002006-06-07 06:53:25 +0000430 try {
Mark Sleea3302652006-10-25 19:03:32 +0000431 transport->open();
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900432 } catch (TTransportException& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100433 cout << "Connect failed: " << ex.what() << '\n';
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900434 return ERR_UNKNOWN;
Mark Sleee8540632006-05-30 09:24:40 +0000435 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000436
Mark Sleed788b2e2006-09-07 01:26:35 +0000437 /**
438 * CONNECT TEST
439 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100440 printf("Test #%d, connect %s:%d\n", test + 1, host.c_str(), port);
Mark Slee95771002006-06-07 06:53:25 +0000441
442 uint64_t start = now();
David Reiss0c90f6f2008-02-06 22:18:40 +0000443
Mark Sleee8540632006-05-30 09:24:40 +0000444 /**
445 * VOID TEST
446 */
Mark Sleee129a2d2007-02-21 05:17:48 +0000447 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900448 cout << "testVoid()" << flush;
Mark Sleee129a2d2007-02-21 05:17:48 +0000449 testClient.testVoid();
CJCombrink4a280d52024-03-14 19:57:41 +0100450 cout << " = void" << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900451 } catch (TTransportException&) {
452 // Stop here if transport got broken
453 throw;
454 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100455 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200456 return_code |= ERR_BASETYPES;
Mark Sleee129a2d2007-02-21 05:17:48 +0000457 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000458
Mark Sleee8540632006-05-30 09:24:40 +0000459 /**
460 * STRING TEST
461 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900462 cout << "testString(\"Test\")" << flush;
Mark Slee1921d202007-01-24 19:43:06 +0000463 string s;
464 testClient.testString(s, "Test");
CJCombrink4a280d52024-03-14 19:57:41 +0100465 cout << " = " << s << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200466 if (s != "Test") {
CJCombrink4a280d52024-03-14 19:57:41 +0100467 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200468 return_code |= ERR_BASETYPES;
469 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000470
James E. King, III58402ff2017-11-17 14:41:46 -0500471 //
472 // Multiplexed protocol - call another service method
473 // in the middle of the ThriftTest
474 //
475 if (boost::starts_with(protocol_type, "multi")) {
James E. King, III39eaae62017-11-19 20:17:33 -0500476 SecondServiceClient ssc(protocol2);
477 // transport is already open...
478
James E. King, III58402ff2017-11-17 14:41:46 -0500479 try {
480 cout << "secondService.secondTestString(\"foo\") => " << flush;
James E. King, III39eaae62017-11-19 20:17:33 -0500481 std::string result;
482 ssc.secondtestString(result, "foo");
CJCombrink4a280d52024-03-14 19:57:41 +0100483 cout << "{" << result << "}" << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -0500484 } catch (std::exception& e) {
CJCombrink4a280d52024-03-14 19:57:41 +0100485 cout << " *** FAILED *** " << e.what() << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -0500486 return_code |= ERR_EXCEPTIONS;
487 }
James E. King, III58402ff2017-11-17 14:41:46 -0500488 }
489
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900490 try {
James E. King, III7edc8fa2017-01-20 10:11:41 -0500491#ifdef _MSC_VER
492#pragma warning( push )
493#pragma warning( disable : 4566 )
494#endif
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900495 string str(
496 "}{Afrikaans, Alemannisch, Aragonés, العربية, مصرى, "
497 "Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, "
498 "Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, "
499 "বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, "
500 "Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, "
501 "Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, "
502 "Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, "
503 "Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, "
504 "Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski, "
505 "Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia, "
506 "Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa, "
507 "ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар, "
508 "Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, "
509 "Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa "
510 "Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, مازِرونی, Bahasa "
511 "Melayu, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, ‪"
512 "Norsk (nynorsk)‬, ‪Norsk (bokmål)‬, Nouormand, Diné bizaad, "
513 "Occitan, Иронау, Papiamentu, Deitsch, Polski, پنجابی, پښتو, "
514 "Norfuk / Pitkern, Português, Runa Simi, Rumantsch, Romani, Română, "
515 "Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple "
516 "English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk, "
517 "Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog, "
518 "Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük, "
519 "Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, "
520 "Bân-lâm-gú, 粵語");
James E. King, III7edc8fa2017-01-20 10:11:41 -0500521#ifdef _MSC_VER
522#pragma warning( pop )
523#endif
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900524 cout << "testString(" << str << ") = " << flush;
525 testClient.testString(s, str);
CJCombrink4a280d52024-03-14 19:57:41 +0100526 cout << s << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900527 if (s != str) {
528 cout.imbue(locale("en_US.UTF8"));
CJCombrink4a280d52024-03-14 19:57:41 +0100529 cout << "*** FAILED ***" << '\n' << "Expected string: " << str << " but got: " << s << '\n' << "CLEAR";
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900530 return_code |= ERR_BASETYPES;
531 }
532 } catch (TTransportException&) {
533 throw;
534 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100535 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900536 return_code |= ERR_BASETYPES;
537 return return_code;
538 }
539 try {
540 string str(
541 "quote: \" backslash:"
542 " forwardslash-escaped: \\/ "
543 " backspace: \b formfeed: \f newline: \n return: \r tab: "
544 " now-all-of-them-together: \"\\\\/\b\n\r\t"
545 " now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><"
546 " char-to-test-json-parsing: ]] \"]] \\\" }}}{ [[[ ");
547 cout << "testString(" << str << ") = " << flush;
548 testClient.testString(s, str);
CJCombrink4a280d52024-03-14 19:57:41 +0100549 cout << s << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900550 if (s != str) {
551 cout.imbue(locale("en_US.UTF8"));
CJCombrink4a280d52024-03-14 19:57:41 +0100552 cout << "*** FAILED ***" << '\n'
553 << "Expected string: " << str << " but got: " << s << '\n'
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900554 << "CLEAR";
555 ;
556 return_code |= ERR_BASETYPES;
557 }
558 } catch (TTransportException&) {
559 throw;
560 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100561 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900562 return_code |= ERR_BASETYPES;
563 return return_code;
564 }
565
Mark Sleee8540632006-05-30 09:24:40 +0000566 /**
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900567 * BOOL TEST
568 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900569 cout << boolalpha;
570 BASETYPE_IDENTITY_TEST(testBool, true);
571 BASETYPE_IDENTITY_TEST(testBool, false);
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900572
573 /**
Mark Sleee8540632006-05-30 09:24:40 +0000574 * BYTE TEST
575 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900576 BASETYPE_IDENTITY_TEST(testByte, (int8_t)0);
577 BASETYPE_IDENTITY_TEST(testByte, (int8_t)-1);
578 BASETYPE_IDENTITY_TEST(testByte, (int8_t)42);
579 BASETYPE_IDENTITY_TEST(testByte, (int8_t)-42);
580 BASETYPE_IDENTITY_TEST(testByte, (int8_t)127);
581 BASETYPE_IDENTITY_TEST(testByte, (int8_t)-128);
David Reiss0c90f6f2008-02-06 22:18:40 +0000582
Mark Sleee8540632006-05-30 09:24:40 +0000583 /**
584 * I32 TEST
585 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900586 BASETYPE_IDENTITY_TEST(testI32, 0);
587 BASETYPE_IDENTITY_TEST(testI32, -1);
588 BASETYPE_IDENTITY_TEST(testI32, 190000013);
589 BASETYPE_IDENTITY_TEST(testI32, -190000013);
James E. King III9b75e4f2018-12-17 16:21:14 -0500590 BASETYPE_IDENTITY_TEST(testI32, (numeric_limits<int32_t>::max)());
591 BASETYPE_IDENTITY_TEST(testI32, (numeric_limits<int32_t>::min)());
Mark Sleee8540632006-05-30 09:24:40 +0000592
593 /**
Mark Sleee8540632006-05-30 09:24:40 +0000594 * I64 TEST
595 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900596 BASETYPE_IDENTITY_TEST(testI64, (int64_t)0);
597 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-1);
598 BASETYPE_IDENTITY_TEST(testI64, (int64_t)7000000000000000123LL);
599 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-7000000000000000123LL);
James E. King, III7edc8fa2017-01-20 10:11:41 -0500600 BASETYPE_IDENTITY_TEST(testI64, (int64_t)pow(static_cast<double>(2LL), 32));
601 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-pow(static_cast<double>(2LL), 32));
602 BASETYPE_IDENTITY_TEST(testI64, (int64_t)pow(static_cast<double>(2LL), 32) + 1);
603 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-pow(static_cast<double>(2LL), 32) - 1);
James E. King III9b75e4f2018-12-17 16:21:14 -0500604 BASETYPE_IDENTITY_TEST(testI64, (numeric_limits<int64_t>::max)());
605 BASETYPE_IDENTITY_TEST(testI64, (numeric_limits<int64_t>::min)());
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100606
Mark Sleec98d0502006-09-06 02:42:25 +0000607 /**
608 * DOUBLE TEST
609 */
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900610 // Comparing double values with plain equality because Thrift handles full precision of double
611 BASETYPE_IDENTITY_TEST(testDouble, 0.0);
612 BASETYPE_IDENTITY_TEST(testDouble, -1.0);
613 BASETYPE_IDENTITY_TEST(testDouble, -5.2098523);
614 BASETYPE_IDENTITY_TEST(testDouble, -0.000341012439638598279);
James E. King, III7edc8fa2017-01-20 10:11:41 -0500615 BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast<double>(2), 32));
616 BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast<double>(2), 32) + 1);
617 BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast<double>(2), 53) - 1);
618 BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast<double>(2), 32));
619 BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast<double>(2), 32) - 1);
620 BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast<double>(2), 53) + 1);
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900621
622 try {
James E. King, III7edc8fa2017-01-20 10:11:41 -0500623 double expected = pow(static_cast<double>(10), 307);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900624 cout << "testDouble(" << expected << ") = " << flush;
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900625 double actual = testClient.testDouble(expected);
CJCombrink4a280d52024-03-14 19:57:41 +0100626 cout << "(" << actual << ")" << '\n';
James E. King, III7edc8fa2017-01-20 10:11:41 -0500627 if (expected - actual > pow(static_cast<double>(10), 292)) {
CJCombrink4a280d52024-03-14 19:57:41 +0100628 cout << "*** FAILED ***" << '\n'
629 << "Expected: " << expected << " but got: " << actual << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900630 }
631 } catch (TTransportException&) {
632 throw;
633 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100634 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900635 return_code |= ERR_BASETYPES;
636 }
637
638 try {
James E. King, III7edc8fa2017-01-20 10:11:41 -0500639 double expected = pow(static_cast<double>(10), -292);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900640 cout << "testDouble(" << expected << ") = " << flush;
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900641 double actual = testClient.testDouble(expected);
CJCombrink4a280d52024-03-14 19:57:41 +0100642 cout << "(" << actual << ")" << '\n';
James E. King, III7edc8fa2017-01-20 10:11:41 -0500643 if (expected - actual > pow(static_cast<double>(10), -307)) {
CJCombrink4a280d52024-03-14 19:57:41 +0100644 cout << "*** FAILED ***" << '\n'
645 << "Expected: " << expected << " but got: " << actual << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900646 }
647 } catch (TTransportException&) {
648 throw;
649 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100650 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200651 return_code |= ERR_BASETYPES;
652 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000653
Mark Sleee8540632006-05-30 09:24:40 +0000654 /**
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100655 * BINARY TEST
656 */
James E. King, III39eaae62017-11-19 20:17:33 -0500657 for (string::size_type i = 0; i < 131073 && !return_code; ) {
658 return_code |= binary_test(testClient, i);
659 if (i > 0) { i *= 2; } else { ++i; }
Jens Geyerd629ea02015-09-23 21:16:50 +0200660 }
661
CJCombrink1d886ca2024-03-23 21:32:28 +0100662 /**
663 * UUID TEST
664 */
CJCombrink4b909092024-04-27 19:51:39 +0200665 const TUuid expected_uuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"};
666 UUID_TEST(testUuid, TUuid{"{5e2ab188-1726-4e75-a04f-1ed9a6a89c4c}"}, expected_uuid);
667 UUID_TEST(testUuid, TUuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}, expected_uuid);
668 UUID_TEST(testUuid, TUuid{"5e2ab18817264e75a04f1ed9a6a89c4c"}, expected_uuid);
669 UUID_TEST(testUuid, TUuid{"{5e2ab18817264e75a04f1ed9a6a89c4c}"}, expected_uuid);
670 UUID_TEST(testUuid, TUuid{}, TUuid{"00000000-0000-0000-0000-000000000000"});
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100671
672 /**
Mark Sleee8540632006-05-30 09:24:40 +0000673 * STRUCT TEST
674 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900675 cout << "testStruct({\"Zero\", 1, -3, -5})" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000676 Xtruct out;
677 out.string_thing = "Zero";
678 out.byte_thing = 1;
Mark Sleee8540632006-05-30 09:24:40 +0000679 out.i32_thing = -3;
Mark Sleee8540632006-05-30 09:24:40 +0000680 out.i64_thing = -5;
Mark Slee1921d202007-01-24 19:43:06 +0000681 Xtruct in;
682 testClient.testStruct(in, out);
Roger Meier0e814802014-01-17 21:07:58 +0100683 printf(" = {\"%s\", %d, %d, %" PRId64 "}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000684 in.string_thing.c_str(),
685 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000686 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000687 in.i64_thing);
Jens Geyerd629ea02015-09-23 21:16:50 +0200688 if (in != out) {
CJCombrink4a280d52024-03-14 19:57:41 +0100689 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200690 return_code |= ERR_STRUCTS;
691 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000692
Mark Sleee8540632006-05-30 09:24:40 +0000693 /**
694 * NESTED STRUCT TEST
695 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900696 cout << "testNest({1, {\"Zero\", 1, -3, -5}), 5}" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000697 Xtruct2 out2;
698 out2.byte_thing = 1;
699 out2.struct_thing = out;
700 out2.i32_thing = 5;
Mark Slee1921d202007-01-24 19:43:06 +0000701 Xtruct2 in2;
702 testClient.testNest(in2, out2);
Mark Sleee8540632006-05-30 09:24:40 +0000703 in = in2.struct_thing;
Roger Meier0e814802014-01-17 21:07:58 +0100704 printf(" = {%d, {\"%s\", %d, %d, %" PRId64 "}, %d}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000705 in2.byte_thing,
706 in.string_thing.c_str(),
707 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000708 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000709 in.i64_thing,
David Reiss0c90f6f2008-02-06 22:18:40 +0000710 in2.i32_thing);
Jens Geyerd629ea02015-09-23 21:16:50 +0200711 if (in2 != out2) {
CJCombrink4a280d52024-03-14 19:57:41 +0100712 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200713 return_code |= ERR_STRUCTS;
714 }
Mark Sleee8540632006-05-30 09:24:40 +0000715
716 /**
717 * MAP TEST
718 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100719 map<int32_t, int32_t> mapout;
Mark Sleee8540632006-05-30 09:24:40 +0000720 for (int32_t i = 0; i < 5; ++i) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100721 mapout.insert(make_pair(i, i - 10));
Mark Sleee8540632006-05-30 09:24:40 +0000722 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900723 cout << "testMap({" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000724 map<int32_t, int32_t>::const_iterator m_iter;
725 bool first = true;
726 for (m_iter = mapout.begin(); m_iter != mapout.end(); ++m_iter) {
727 if (first) {
728 first = false;
729 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900730 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000731 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900732 cout << m_iter->first << " => " << m_iter->second;
Mark Sleee8540632006-05-30 09:24:40 +0000733 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900734 cout << "})";
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100735 map<int32_t, int32_t> mapin;
Mark Slee1921d202007-01-24 19:43:06 +0000736 testClient.testMap(mapin, mapout);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900737 cout << " = {";
Mark Sleee8540632006-05-30 09:24:40 +0000738 first = true;
739 for (m_iter = mapin.begin(); m_iter != mapin.end(); ++m_iter) {
740 if (first) {
741 first = false;
742 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900743 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000744 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900745 cout << m_iter->first << " => " << m_iter->second;
Mark Sleee8540632006-05-30 09:24:40 +0000746 }
CJCombrink4a280d52024-03-14 19:57:41 +0100747 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200748 if (mapin != mapout) {
CJCombrink4a280d52024-03-14 19:57:41 +0100749 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200750 return_code |= ERR_CONTAINERS;
751 }
Roger Meier4fce9602012-05-04 06:22:09 +0000752
753 /**
754 * STRING MAP TEST
Roger Meier4fce9602012-05-04 06:22:09 +0000755 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900756 cout << "testStringMap({a => 2, b => blah, some => thing}) = {" << flush;
Jens Geyerd629ea02015-09-23 21:16:50 +0200757 map<string, string> smapin;
758 map<string, string> smapout;
759 smapin["a"] = "2";
760 smapin["b"] = "blah";
761 smapin["some"] = "thing";
762 try {
763 testClient.testStringMap(smapout, smapin);
764 first = true;
765 for (map<string, string>::const_iterator it = smapout.begin(); it != smapout.end(); ++it) {
766 if (first)
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900767 cout << ",";
Jens Geyerd629ea02015-09-23 21:16:50 +0200768 else
769 first = false;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900770 cout << it->first << " => " << it->second;
Jens Geyerd629ea02015-09-23 21:16:50 +0200771 }
CJCombrink4a280d52024-03-14 19:57:41 +0100772 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200773 if (smapin != smapout) {
CJCombrink4a280d52024-03-14 19:57:41 +0100774 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200775 return_code |= ERR_CONTAINERS;
776 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900777 } catch (TTransportException&) {
778 throw;
Jens Geyerd629ea02015-09-23 21:16:50 +0200779 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100780 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200781 return_code |= ERR_CONTAINERS;
782 }
Mark Sleee8540632006-05-30 09:24:40 +0000783
784 /**
785 * SET TEST
786 */
787 set<int32_t> setout;
788 for (int32_t i = -2; i < 3; ++i) {
789 setout.insert(i);
790 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900791 cout << "testSet({" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000792 set<int32_t>::const_iterator s_iter;
793 first = true;
794 for (s_iter = setout.begin(); s_iter != setout.end(); ++s_iter) {
795 if (first) {
796 first = false;
797 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900798 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000799 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900800 cout << *s_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000801 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900802 cout << "})";
Mark Slee1921d202007-01-24 19:43:06 +0000803 set<int32_t> setin;
804 testClient.testSet(setin, setout);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900805 cout << " = {";
Mark Sleee8540632006-05-30 09:24:40 +0000806 first = true;
807 for (s_iter = setin.begin(); s_iter != setin.end(); ++s_iter) {
808 if (first) {
809 first = false;
810 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900811 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000812 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900813 cout << *s_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000814 }
CJCombrink4a280d52024-03-14 19:57:41 +0100815 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200816 if (setin != setout) {
CJCombrink4a280d52024-03-14 19:57:41 +0100817 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200818 return_code |= ERR_CONTAINERS;
819 }
Mark Sleee8540632006-05-30 09:24:40 +0000820
821 /**
822 * LIST TEST
823 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900824 cout << "testList(empty)" << flush;
825 try {
826 vector<int32_t> listout;
827 testClient.testList(listout, vector<int32_t>());
828 if (!listout.empty()) {
CJCombrink4a280d52024-03-14 19:57:41 +0100829 cout << "*** FAILED ***" << '\n';
830 cout << "invalid length: " << listout.size() << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900831 return_code |= ERR_CONTAINERS;
Mark Sleee8540632006-05-30 09:24:40 +0000832 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900833 } catch (TTransportException&) {
834 throw;
835 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100836 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900837 return_code |= ERR_CONTAINERS;
Mark Sleee8540632006-05-30 09:24:40 +0000838 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900839 try {
840 vector<int32_t> listout;
841 for (int32_t i = -2; i < 3; ++i) {
842 listout.push_back(i);
Mark Sleee8540632006-05-30 09:24:40 +0000843 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900844 cout << "testList({" << flush;
845 vector<int32_t>::const_iterator l_iter;
846 first = true;
847 for (l_iter = listout.begin(); l_iter != listout.end(); ++l_iter) {
848 if (first) {
849 first = false;
850 } else {
851 cout << ",";
852 }
853 cout << *l_iter;
854 }
855 cout << "})";
856 vector<int32_t> listin;
857 testClient.testList(listin, listout);
858 cout << " = {";
859 first = true;
860 for (l_iter = listin.begin(); l_iter != listin.end(); ++l_iter) {
861 if (first) {
862 first = false;
863 } else {
864 cout << ",";
865 }
866 cout << *l_iter;
867 }
CJCombrink4a280d52024-03-14 19:57:41 +0100868 cout << "}" << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900869 if (listin != listout) {
CJCombrink4a280d52024-03-14 19:57:41 +0100870 cout << "*** FAILED ***" << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900871 return_code |= ERR_CONTAINERS;
872 }
873 } catch (TTransportException&) {
874 throw;
875 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100876 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200877 return_code |= ERR_CONTAINERS;
878 }
Mark Sleee8540632006-05-30 09:24:40 +0000879
880 /**
881 * ENUM TEST
882 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900883 cout << "testEnum(ONE)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000884 Numberz::type ret = testClient.testEnum(Numberz::ONE);
CJCombrink4a280d52024-03-14 19:57:41 +0100885 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200886 if (ret != Numberz::ONE) {
CJCombrink4a280d52024-03-14 19:57:41 +0100887 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200888 return_code |= ERR_STRUCTS;
889 }
Mark Sleee8540632006-05-30 09:24:40 +0000890
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900891 cout << "testEnum(TWO)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000892 ret = testClient.testEnum(Numberz::TWO);
CJCombrink4a280d52024-03-14 19:57:41 +0100893 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200894 if (ret != Numberz::TWO) {
CJCombrink4a280d52024-03-14 19:57:41 +0100895 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200896 return_code |= ERR_STRUCTS;
897 }
Mark Sleee8540632006-05-30 09:24:40 +0000898
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900899 cout << "testEnum(THREE)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000900 ret = testClient.testEnum(Numberz::THREE);
CJCombrink4a280d52024-03-14 19:57:41 +0100901 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200902 if (ret != Numberz::THREE) {
CJCombrink4a280d52024-03-14 19:57:41 +0100903 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200904 return_code |= ERR_STRUCTS;
905 }
Mark Sleee8540632006-05-30 09:24:40 +0000906
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900907 cout << "testEnum(FIVE)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000908 ret = testClient.testEnum(Numberz::FIVE);
CJCombrink4a280d52024-03-14 19:57:41 +0100909 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200910 if (ret != Numberz::FIVE) {
CJCombrink4a280d52024-03-14 19:57:41 +0100911 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200912 return_code |= ERR_STRUCTS;
913 }
Mark Sleee8540632006-05-30 09:24:40 +0000914
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900915 cout << "testEnum(EIGHT)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000916 ret = testClient.testEnum(Numberz::EIGHT);
CJCombrink4a280d52024-03-14 19:57:41 +0100917 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200918 if (ret != Numberz::EIGHT) {
CJCombrink4a280d52024-03-14 19:57:41 +0100919 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200920 return_code |= ERR_STRUCTS;
921 }
Mark Sleee8540632006-05-30 09:24:40 +0000922
923 /**
924 * TYPEDEF TEST
925 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900926 cout << "testTypedef(309858235082523)" << flush;
Marc Slemkobf4fd192006-08-15 21:29:39 +0000927 UserId uid = testClient.testTypedef(309858235082523LL);
CJCombrink4a280d52024-03-14 19:57:41 +0100928 cout << " = " << uid << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200929 if (uid != 309858235082523LL) {
CJCombrink4a280d52024-03-14 19:57:41 +0100930 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200931 return_code |= ERR_STRUCTS;
932 }
Mark Sleee8540632006-05-30 09:24:40 +0000933
934 /**
935 * NESTED MAP TEST
936 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900937 cout << "testMapMap(1)" << flush;
Mark Slee1921d202007-01-24 19:43:06 +0000938 map<int32_t, map<int32_t, int32_t> > mm;
939 testClient.testMapMap(mm, 1);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900940 cout << " = {";
Mark Sleee8540632006-05-30 09:24:40 +0000941 map<int32_t, map<int32_t, int32_t> >::const_iterator mi;
942 for (mi = mm.begin(); mi != mm.end(); ++mi) {
943 printf("%d => {", mi->first);
944 map<int32_t, int32_t>::const_iterator mi2;
945 for (mi2 = mi->second.begin(); mi2 != mi->second.end(); ++mi2) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900946 cout << mi2->first << " => " << mi2->second;
Mark Sleee8540632006-05-30 09:24:40 +0000947 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900948 cout << "}, ";
Mark Sleee8540632006-05-30 09:24:40 +0000949 }
CJCombrink4a280d52024-03-14 19:57:41 +0100950 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200951 if (mm.size() != 2 ||
952 mm[-4][-4] != -4 ||
953 mm[-4][-3] != -3 ||
954 mm[-4][-2] != -2 ||
955 mm[-4][-1] != -1 ||
956 mm[4][4] != 4 ||
957 mm[4][3] != 3 ||
958 mm[4][2] != 2 ||
959 mm[4][1] != 1) {
CJCombrink4a280d52024-03-14 19:57:41 +0100960 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200961 return_code |= ERR_CONTAINERS;
962 }
Mark Sleee8540632006-05-30 09:24:40 +0000963
964 /**
965 * INSANITY TEST
966 */
Jens Geyerf4598682014-05-08 23:18:44 +0200967 if (!noinsane) {
968 Insanity insane;
Jens Geyerd629ea02015-09-23 21:16:50 +0200969 insane.userMap.insert(make_pair(Numberz::FIVE, 5));
970 insane.userMap.insert(make_pair(Numberz::EIGHT, 8));
Jens Geyerf4598682014-05-08 23:18:44 +0200971 Xtruct truck;
Jens Geyerd629ea02015-09-23 21:16:50 +0200972 truck.string_thing = "Goodbye4";
973 truck.byte_thing = 4;
974 truck.i32_thing = 4;
975 truck.i64_thing = 4;
976 Xtruct truck2;
977 truck2.string_thing = "Hello2";
978 truck2.byte_thing = 2;
979 truck2.i32_thing = 2;
980 truck2.i64_thing = 2;
Jens Geyerf4598682014-05-08 23:18:44 +0200981 insane.xtructs.push_back(truck);
Jens Geyerd629ea02015-09-23 21:16:50 +0200982 insane.xtructs.push_back(truck2);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900983 cout << "testInsanity()" << flush;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100984 map<UserId, map<Numberz::type, Insanity> > whoa;
Jens Geyerf4598682014-05-08 23:18:44 +0200985 testClient.testInsanity(whoa, insane);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900986 cout << " = {";
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100987 map<UserId, map<Numberz::type, Insanity> >::const_iterator i_iter;
Jens Geyerf4598682014-05-08 23:18:44 +0200988 for (i_iter = whoa.begin(); i_iter != whoa.end(); ++i_iter) {
989 printf("%" PRId64 " => {", i_iter->first);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100990 map<Numberz::type, Insanity>::const_iterator i2_iter;
991 for (i2_iter = i_iter->second.begin(); i2_iter != i_iter->second.end(); ++i2_iter) {
Jens Geyerf4598682014-05-08 23:18:44 +0200992 printf("%d => {", i2_iter->first);
993 map<Numberz::type, UserId> userMap = i2_iter->second.userMap;
994 map<Numberz::type, UserId>::const_iterator um;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900995 cout << "{";
Jens Geyerf4598682014-05-08 23:18:44 +0200996 for (um = userMap.begin(); um != userMap.end(); ++um) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900997 cout << um->first << " => " << um->second;
Jens Geyerf4598682014-05-08 23:18:44 +0200998 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900999 cout << "}, ";
Mark Sleee8540632006-05-30 09:24:40 +00001000
Jens Geyerf4598682014-05-08 23:18:44 +02001001 vector<Xtruct> xtructs = i2_iter->second.xtructs;
1002 vector<Xtruct>::const_iterator x;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001003 cout << "{";
Jens Geyerf4598682014-05-08 23:18:44 +02001004 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
1005 printf("{\"%s\", %d, %d, %" PRId64 "}, ",
1006 x->string_thing.c_str(),
1007 (int)x->byte_thing,
1008 x->i32_thing,
1009 x->i64_thing);
1010 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001011 cout << "}";
Mark Sleee8540632006-05-30 09:24:40 +00001012
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001013 cout << "}, ";
Jens Geyerf4598682014-05-08 23:18:44 +02001014 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001015 cout << "}, ";
Mark Sleee8540632006-05-30 09:24:40 +00001016 }
CJCombrink4a280d52024-03-14 19:57:41 +01001017 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001018 bool failed = false;
1019 map<UserId, map<Numberz::type, Insanity> >::const_iterator it1 = whoa.find(UserId(1));
1020 if (whoa.size() != 2) {
1021 failed = true;
1022 }
1023 if (it1 == whoa.end()) {
1024 failed = true;
1025 } else {
Sebastian Zenker042580f2019-01-29 15:48:12 +01001026 auto it12 = it1->second.find(Numberz::TWO);
Jens Geyerd629ea02015-09-23 21:16:50 +02001027 if (it12 == it1->second.end() || it12->second != insane) {
1028 failed = true;
1029 }
Sebastian Zenker042580f2019-01-29 15:48:12 +01001030 auto it13 = it1->second.find(Numberz::THREE);
Jens Geyerd629ea02015-09-23 21:16:50 +02001031 if (it13 == it1->second.end() || it13->second != insane) {
1032 failed = true;
1033 }
1034 }
1035 map<UserId, map<Numberz::type, Insanity> >::const_iterator it2 = whoa.find(UserId(2));
1036 if (it2 == whoa.end()) {
1037 failed = true;
1038 } else {
Sebastian Zenker042580f2019-01-29 15:48:12 +01001039 auto it26 = it2->second.find(Numberz::SIX);
James E. King IIIf5f430d2018-06-08 03:37:55 +00001040 if (it26 == it2->second.end() || it26->second != Insanity()) {
Jens Geyerd629ea02015-09-23 21:16:50 +02001041 failed = true;
1042 }
1043 }
1044 if (failed) {
CJCombrink4a280d52024-03-14 19:57:41 +01001045 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001046 return_code |= ERR_STRUCTS;
1047 }
Mark Sleee8540632006-05-30 09:24:40 +00001048 }
Jens Geyerd629ea02015-09-23 21:16:50 +02001049
1050 /**
1051 * MULTI TEST
1052 */
CJCombrink4a280d52024-03-14 19:57:41 +01001053 cout << "testMulti()" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001054 try {
1055 map<int16_t, string> mul_map;
1056 Xtruct mul_result;
1057 mul_map[1] = "blah";
1058 mul_map[2] = "thing";
1059 testClient.testMulti(mul_result, 42, 4242, 424242, mul_map, Numberz::EIGHT, UserId(24));
1060 Xtruct xxs;
1061 xxs.string_thing = "Hello2";
1062 xxs.byte_thing = 42;
1063 xxs.i32_thing = 4242;
1064 xxs.i64_thing = 424242;
1065 if (mul_result != xxs) {
CJCombrink4a280d52024-03-14 19:57:41 +01001066 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001067 return_code |= ERR_STRUCTS;
1068 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001069 } catch (TTransportException&) {
1070 throw;
Jens Geyerd629ea02015-09-23 21:16:50 +02001071 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +01001072 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001073 return_code |= ERR_STRUCTS;
1074 }
1075
Marc Slemko71d4e472006-08-15 22:34:04 +00001076 /* test exception */
Mark Slee95771002006-06-07 06:53:25 +00001077
Marc Slemkobf4fd192006-08-15 21:29:39 +00001078 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001079 cout << "testClient.testException(\"Xception\") =>" << flush;
Marc Slemko71d4e472006-08-15 22:34:04 +00001080 testClient.testException("Xception");
CJCombrink4a280d52024-03-14 19:57:41 +01001081 cout << " void\n*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001082 return_code |= ERR_EXCEPTIONS;
David Reiss0c90f6f2008-02-06 22:18:40 +00001083
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001084 } catch (Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +00001085 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +00001086 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001087
Marc Slemkobf4fd192006-08-15 21:29:39 +00001088 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001089 cout << "testClient.testException(\"TException\") =>" << flush;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001090 testClient.testException("TException");
CJCombrink4a280d52024-03-14 19:57:41 +01001091 cout << " void\n*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001092 return_code |= ERR_EXCEPTIONS;
Roger Meierf50df7f2012-05-02 22:49:55 +00001093
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001094 } catch (const TException&) {
CJCombrink4a280d52024-03-14 19:57:41 +01001095 cout << " Caught TException" << '\n';
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001096 }
Roger Meierf50df7f2012-05-02 22:49:55 +00001097
1098 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001099 cout << "testClient.testException(\"success\") =>" << flush;
Marc Slemko71d4e472006-08-15 22:34:04 +00001100 testClient.testException("success");
CJCombrink4a280d52024-03-14 19:57:41 +01001101 cout << " void" << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001102 } catch (exception & ex) { \
CJCombrink4a280d52024-03-14 19:57:41 +01001103 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001104 return_code |= ERR_EXCEPTIONS;
Marc Slemko71d4e472006-08-15 22:34:04 +00001105 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001106
Marc Slemko71d4e472006-08-15 22:34:04 +00001107 /* test multi exception */
David Reiss0c90f6f2008-02-06 22:18:40 +00001108
Marc Slemko71d4e472006-08-15 22:34:04 +00001109 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001110 cout << "testClient.testMultiException(\"Xception\", \"test 1\") =>" << flush;
Mark Slee1921d202007-01-24 19:43:06 +00001111 Xtruct result;
1112 testClient.testMultiException(result, "Xception", "test 1");
CJCombrink4a280d52024-03-14 19:57:41 +01001113 cout << " result\n*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001114 return_code |= ERR_EXCEPTIONS;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001115 } catch (Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +00001116 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
1117 }
1118
1119 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001120 cout << "testClient.testMultiException(\"Xception2\", \"test 2\") =>" << flush;
Mark Slee1921d202007-01-24 19:43:06 +00001121 Xtruct result;
1122 testClient.testMultiException(result, "Xception2", "test 2");
CJCombrink4a280d52024-03-14 19:57:41 +01001123 cout << " result\n*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001124 return_code |= ERR_EXCEPTIONS;
David Reiss0c90f6f2008-02-06 22:18:40 +00001125
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001126 } catch (Xception2& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +00001127 printf(" {%u, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +00001128 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001129
Marc Slemko71d4e472006-08-15 22:34:04 +00001130 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001131 cout << "testClient.testMultiException(\"success\", \"test 3\") =>" << flush;
Mark Slee1921d202007-01-24 19:43:06 +00001132 Xtruct result;
1133 testClient.testMultiException(result, "success", "test 3");
Marc Slemko71d4e472006-08-15 22:34:04 +00001134 printf(" {{\"%s\"}}\n", result.string_thing.c_str());
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001135 } catch (exception & ex) { \
CJCombrink4a280d52024-03-14 19:57:41 +01001136 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001137 return_code |= ERR_EXCEPTIONS;
Marc Slemko71d4e472006-08-15 22:34:04 +00001138 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001139
David Reissc51986f2009-03-24 20:01:25 +00001140 /* test oneway void */
David Reiss2ab6fe82008-02-18 02:11:44 +00001141 {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001142 cout << "testClient.testOneway(1) =>" << flush;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001143 uint64_t startOneway = now();
1144 testClient.testOneway(1);
1145 uint64_t elapsed = now() - startOneway;
1146 if (elapsed > 200 * 1000) { // 0.2 seconds
Jens Geyerd629ea02015-09-23 21:16:50 +02001147 printf("*** FAILED *** - took %.2f ms\n", (double)elapsed / 1000.0);
1148 return_code |= ERR_BASETYPES;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001149 } else {
1150 printf(" success - took %.2f ms\n", (double)elapsed / 1000.0);
1151 }
David Reiss2ab6fe82008-02-18 02:11:44 +00001152 }
1153
David Reiss2845b522008-02-18 02:11:52 +00001154 /**
David Reissc51986f2009-03-24 20:01:25 +00001155 * redo a simple test after the oneway to make sure we aren't "off by one" --
1156 * if the server treated oneway void like normal void, this next test will
David Reiss2845b522008-02-18 02:11:52 +00001157 * fail since it will get the void confirmation rather than the correct
1158 * result. In this circumstance, the client will throw the exception:
1159 *
1160 * TApplicationException: Wrong method namea
1161 */
1162 /**
1163 * I32 TEST
1164 */
James E. King, III58402ff2017-11-17 14:41:46 -05001165 cout << "re-test testI32(-1)" << flush;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001166 int i32 = testClient.testI32(-1);
CJCombrink4a280d52024-03-14 19:57:41 +01001167 cout << " = " << i32 << '\n';
Roger Meier4fce9602012-05-04 06:22:09 +00001168 if (i32 != -1)
Jens Geyerd629ea02015-09-23 21:16:50 +02001169 return_code |= ERR_BASETYPES;
David Reiss2845b522008-02-18 02:11:52 +00001170
CJCombrink4a280d52024-03-14 19:57:41 +01001171 cout << '\n' << "All tests done." << '\n' << flush;
James E. King, III39eaae62017-11-19 20:17:33 -05001172
Marc Slemkobf4fd192006-08-15 21:29:39 +00001173 uint64_t stop = now();
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001174 uint64_t tot = stop - start;
Mark Sleed788b2e2006-09-07 01:26:35 +00001175
CJCombrink4a280d52024-03-14 19:57:41 +01001176 cout << "Total time: " << stop - start << " us" << '\n';
David Reiss0c90f6f2008-02-06 22:18:40 +00001177
Mark Sleed788b2e2006-09-07 01:26:35 +00001178 time_tot += tot;
1179 if (time_min == 0 || tot < time_min) {
1180 time_min = tot;
1181 }
1182 if (tot > time_max) {
1183 time_max = tot;
1184 }
1185
James E. King, III58402ff2017-11-17 14:41:46 -05001186 cout << flush;
Mark Sleea3302652006-10-25 19:03:32 +00001187 transport->close();
Mark Sleee8540632006-05-30 09:24:40 +00001188 }
1189
Mark Sleed788b2e2006-09-07 01:26:35 +00001190
1191 uint64_t time_avg = time_tot / numTests;
1192
CJCombrink4a280d52024-03-14 19:57:41 +01001193 cout << "Min time: " << time_min << " us" << '\n';
1194 cout << "Max time: " << time_max << " us" << '\n';
1195 cout << "Avg time: " << time_avg << " us" << '\n';
Mark Sleed788b2e2006-09-07 01:26:35 +00001196
Jens Geyerd629ea02015-09-23 21:16:50 +02001197 return return_code;
Mark Sleee8540632006-05-30 09:24:40 +00001198}
James E. King, III39eaae62017-11-19 20:17:33 -05001199
1200void binary_fill(std::string& str, string::size_type siz)
1201{
1202 static const signed char bin_data[256]
1203 = {-128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114,
1204 -113, -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99,
1205 -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84,
1206 -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, -69,
1207 -68, -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54,
1208 -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39,
1209 -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24,
1210 -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9,
1211 -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6,
1212 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
1213 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
1214 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
1215 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
1216 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
1217 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
1218 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
1219 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
1220 127};
1221
1222 str.resize(siz);
1223 char *ptr = &str[0];
1224 string::size_type pos = 0;
1225 for (string::size_type i = 0; i < siz; ++i)
1226 {
1227 if (pos == 255) { pos = 0; } else { ++pos; }
1228 *ptr++ = bin_data[pos];
1229 }
1230}
1231
1232int binary_test(ThriftTestClient& testClient, string::size_type siz)
1233{
1234 string bin_request;
1235 string bin_result;
1236
CJCombrink4a280d52024-03-14 19:57:41 +01001237 cout << "testBinary(siz = " << siz << ")" << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -05001238 binary_fill(bin_request, siz);
1239 try {
1240 testClient.testBinary(bin_result, bin_request);
1241
1242 if (bin_request.size() != bin_result.size()) {
CJCombrink4a280d52024-03-14 19:57:41 +01001243 cout << "*** FAILED: request size " << bin_request.size() << "; result size " << bin_result.size() << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -05001244 return ERR_BASETYPES;
1245 }
1246
1247 for (string::size_type i = 0; i < siz; ++i) {
1248 if (bin_request.at(i) != bin_result.at(i)) {
CJCombrink4a280d52024-03-14 19:57:41 +01001249 cout << "*** FAILED: at position " << i << " request[i] is h" << hex << bin_request.at(i) << " result[i] is h" << hex << bin_result.at(i) << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -05001250 return ERR_BASETYPES;
1251 }
1252 }
1253 } catch (TTransportException&) {
1254 throw;
1255 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +01001256 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -05001257 return ERR_BASETYPES;
1258 }
1259
1260 return 0;
1261}