blob: 6bda29431efd409b57a984039547b3294b56e837 [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>
CJCombrink1d886ca2024-03-23 21:32:28 +010073class 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 {
CJCombrink4a280d52024-03-14 19:57:41 +0100101 std::cout << "verified seqid " << m_last_seqid << " round trip OK" << '\n';
James E. King IIIf95620d2019-01-28 18:15:13 -0500102 } */
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());
CJCombrink4a280d52024-03-14 19:57:41 +0100130 cout << "testString: " << s << " " << ((ok) ? "ok" : "failed") << '\n';
Roger Meier7e056e72011-07-17 07:28:28 +0000131 } catch (TException& exn) {
CJCombrink4a280d52024-03-14 19:57:41 +0100132 cout << "Error: " << exn.what() << '\n';
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();
CJCombrink4a280d52024-03-14 19:57:41 +0100142 cout << "testVoid" << '\n';
Roger Meier7e056e72011-07-17 07:28:28 +0000143
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) {
CJCombrink4a280d52024-03-14 19:57:41 +0100154 cout << "Error: " << exn.what() << '\n';
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) {
CJCombrink4a280d52024-03-14 19:57:41 +0100161 cout << "(" << actual << ")" << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900162 if (expected != actual) {
CJCombrink4a280d52024-03-14 19:57:41 +0100163 cout << "*** FAILED ***" << '\n' << "Expected: " << expected << " but got: " << actual << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900164 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) { \
CJCombrink4a280d52024-03-14 19:57:41 +0100177 cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; \
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900178 return_code |= ERR_BASETYPES; \
179 }
180
CJCombrink1d886ca2024-03-23 21:32:28 +0100181#define UUID_TEST(func, value, expected) \
182 cout << #func "(" << value << ") = "; \
183 try { \
184 if (!print_eq(expected, testClient.func(value))) \
185 return_code |= ERR_BASETYPES; \
186 } catch (TTransportException&) { \
187 throw; \
188 } catch (exception & ex) { \
CJCombrink4a280d52024-03-14 19:57:41 +0100189 cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; \
CJCombrink1d886ca2024-03-23 21:32:28 +0100190 return_code |= ERR_BASETYPES; \
191 }
192
James E. King, III39eaae62017-11-19 20:17:33 -0500193int binary_test(ThriftTestClient& testClient, string::size_type siz);
194
195BOOST_CONSTEXPR_OR_CONST int ERR_BASETYPES = 1;
196BOOST_CONSTEXPR_OR_CONST int ERR_STRUCTS = 2;
197BOOST_CONSTEXPR_OR_CONST int ERR_CONTAINERS = 4;
198BOOST_CONSTEXPR_OR_CONST int ERR_EXCEPTIONS = 8;
199BOOST_CONSTEXPR_OR_CONST int ERR_UNKNOWN = 64;
200
Mark Sleee8540632006-05-30 09:24:40 +0000201int main(int argc, char** argv) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900202 cout.precision(19);
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900203
James E. King, III06190872017-02-20 08:52:11 -0500204 string testDir = boost::filesystem::system_complete(argv[0]).parent_path().parent_path().parent_path().string();
205 string caPath = testDir + "/keys/CA.pem";
206 string certPath = testDir + "/keys/client.crt";
207 string keyPath = testDir + "/keys/client.key";
208
Jake Farrell5d02b802014-01-07 21:42:01 -0500209#if _WIN32
210 transport::TWinsockSingleton::create();
211#endif
Mark Sleee8540632006-05-30 09:24:40 +0000212 string host = "localhost";
213 int port = 9090;
214 int numTests = 1;
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000215 bool ssl = false;
James E. King IIIb2b767e2018-09-15 20:32:04 +0000216 bool zlib = false;
Roger Meierca142b02011-06-07 17:59:07 +0000217 string transport_type = "buffered";
218 string protocol_type = "binary";
219 string domain_socket = "";
pavlodd08f6e2015-10-08 16:43:56 -0400220 bool abstract_namespace = false;
Jens Geyerf4598682014-05-08 23:18:44 +0200221 bool noinsane = false;
Mark Sleee8540632006-05-30 09:24:40 +0000222
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900223 int return_code = 0;
224
Jake Farrell5d02b802014-01-07 21:42:01 -0500225 boost::program_options::options_description desc("Allowed options");
James E. King, III58402ff2017-11-17 14:41:46 -0500226 desc.add_options()
227 ("help,h", "produce help message")
James E. King, III39eaae62017-11-19 20:17:33 -0500228 ("host",
229 boost::program_options::value<string>(&host)->default_value(host),
James E. King, III58402ff2017-11-17 14:41:46 -0500230 "Host to connect")
James E. King, III39eaae62017-11-19 20:17:33 -0500231 ("port",
232 boost::program_options::value<int>(&port)->default_value(port),
James E. King, III58402ff2017-11-17 14:41:46 -0500233 "Port number to connect")
James E. King, III39eaae62017-11-19 20:17:33 -0500234 ("domain-socket",
James E. King, III58402ff2017-11-17 14:41:46 -0500235 boost::program_options::value<string>(&domain_socket)->default_value(domain_socket),
236 "Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port")
237 ("abstract-namespace",
238 "Look for the domain socket in the Abstract Namespace"
239 " (no connection with filesystem pathnames)")
240 ("transport",
241 boost::program_options::value<string>(&transport_type)->default_value(transport_type),
James E. King IIIb2b767e2018-09-15 20:32:04 +0000242 "Transport: buffered, framed, http, evhttp, zlib")
James E. King, III58402ff2017-11-17 14:41:46 -0500243 ("protocol",
244 boost::program_options::value<string>(&protocol_type)->default_value(protocol_type),
245 "Protocol: binary, compact, header, json, multi, multic, multih, multij")
James E. King, III39eaae62017-11-19 20:17:33 -0500246 ("ssl",
James E. King, III58402ff2017-11-17 14:41:46 -0500247 "Encrypted Transport using SSL")
James E. King IIIb2b767e2018-09-15 20:32:04 +0000248 ("zlib",
249 "Wrap Transport with Zlib")
James E. King, III58402ff2017-11-17 14:41:46 -0500250 ("testloops,n",
251 boost::program_options::value<int>(&numTests)->default_value(numTests),
252 "Number of Tests")
253 ("noinsane",
254 "Do not run insanity test");
Roger Meierca142b02011-06-07 17:59:07 +0000255
Jake Farrell5d02b802014-01-07 21:42:01 -0500256 boost::program_options::variables_map vm;
257 boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
258 boost::program_options::notify(vm);
Roger Meierca142b02011-06-07 17:59:07 +0000259
260 if (vm.count("help")) {
CJCombrink4a280d52024-03-14 19:57:41 +0100261 cout << desc << '\n';
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900262 return ERR_UNKNOWN;
Mark Sleee8540632006-05-30 09:24:40 +0000263 }
Mark Sleea3302652006-10-25 19:03:32 +0000264
Jake Farrell5d02b802014-01-07 21:42:01 -0500265 try {
Roger Meierca142b02011-06-07 17:59:07 +0000266 if (!protocol_type.empty()) {
267 if (protocol_type == "binary") {
Roger Meier284101c2014-03-11 21:20:35 +0100268 } else if (protocol_type == "compact") {
Dave Watson792db4e2015-01-16 11:22:01 -0800269 } else if (protocol_type == "header") {
Roger Meierca142b02011-06-07 17:59:07 +0000270 } else if (protocol_type == "json") {
James E. King, III58402ff2017-11-17 14:41:46 -0500271 } else if (protocol_type == "multi") {
272 } else if (protocol_type == "multic") {
273 } else if (protocol_type == "multih") {
274 } else if (protocol_type == "multij") {
Roger Meierca142b02011-06-07 17:59:07 +0000275 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100276 throw invalid_argument("Unknown protocol type " + protocol_type);
Roger Meierca142b02011-06-07 17:59:07 +0000277 }
278 }
279
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100280 if (!transport_type.empty()) {
Roger Meierca142b02011-06-07 17:59:07 +0000281 if (transport_type == "buffered") {
282 } else if (transport_type == "framed") {
283 } else if (transport_type == "http") {
Roger Meier7e056e72011-07-17 07:28:28 +0000284 } else if (transport_type == "evhttp") {
James E. King IIIb2b767e2018-09-15 20:32:04 +0000285 } else if (transport_type == "zlib") {
286 // crosstest will pass zlib as a transport and as a flag right now..
Roger Meierca142b02011-06-07 17:59:07 +0000287 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100288 throw invalid_argument("Unknown transport type " + transport_type);
Roger Meierca142b02011-06-07 17:59:07 +0000289 }
290 }
291
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900292 } catch (exception& e) {
CJCombrink4a280d52024-03-14 19:57:41 +0100293 cerr << e.what() << '\n';
294 cout << desc << '\n';
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900295 return ERR_UNKNOWN;
Roger Meierca142b02011-06-07 17:59:07 +0000296 }
297
298 if (vm.count("ssl")) {
299 ssl = true;
300 }
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +0530301
James E. King IIIb2b767e2018-09-15 20:32:04 +0000302 if (vm.count("zlib")) {
303 zlib = true;
304 }
305
pavlodd08f6e2015-10-08 16:43:56 -0400306 if (vm.count("abstract-namespace")) {
307 abstract_namespace = true;
308 }
309
Jens Geyerf4598682014-05-08 23:18:44 +0200310 if (vm.count("noinsane")) {
311 noinsane = true;
312 }
Roger Meierca142b02011-06-07 17:59:07 +0000313
James E. King, III7f5a8c22017-04-04 09:36:38 -0400314 // THRIFT-4164: The factory MUST outlive any sockets it creates for correct behavior!
cyy316723a2019-01-05 16:35:14 +0800315 std::shared_ptr<TSSLSocketFactory> factory;
316 std::shared_ptr<TSocket> socket;
317 std::shared_ptr<TTransport> transport;
318 std::shared_ptr<TProtocol> protocol;
319 std::shared_ptr<TProtocol> protocol2; // SecondService for multiplexed
Roger Meierca142b02011-06-07 17:59:07 +0000320
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000321 if (ssl) {
CJCombrink4a280d52024-03-14 19:57:41 +0100322 cout << "Client Certificate File: " << certPath << '\n';
323 cout << "Client Key File: " << keyPath << '\n';
324 cout << "CA File: " << caPath << '\n';
James E. King, III06190872017-02-20 08:52:11 -0500325
cyy316723a2019-01-05 16:35:14 +0800326 factory = std::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000327 factory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
James E. King, III06190872017-02-20 08:52:11 -0500328 factory->loadTrustedCertificates(caPath.c_str());
329 factory->loadCertificate(certPath.c_str());
330 factory->loadPrivateKey(keyPath.c_str());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000331 factory->authenticate(true);
332 socket = factory->createSocket(host, port);
333 } else {
Roger Meierca142b02011-06-07 17:59:07 +0000334 if (domain_socket != "") {
pavlodd08f6e2015-10-08 16:43:56 -0400335 if (abstract_namespace) {
336 std::string abstract_socket("\0", 1);
337 abstract_socket += domain_socket;
cyy316723a2019-01-05 16:35:14 +0800338 socket = std::shared_ptr<TSocket>(new TSocket(abstract_socket));
pavlodd08f6e2015-10-08 16:43:56 -0400339 } else {
cyy316723a2019-01-05 16:35:14 +0800340 socket = std::shared_ptr<TSocket>(new TSocket(domain_socket));
pavlodd08f6e2015-10-08 16:43:56 -0400341 }
Roger Meierca142b02011-06-07 17:59:07 +0000342 port = 0;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100343 } else {
cyy316723a2019-01-05 16:35:14 +0800344 socket = std::shared_ptr<TSocket>(new TSocket(host, port));
Roger Meierca142b02011-06-07 17:59:07 +0000345 }
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000346 }
Mark Sleea3302652006-10-25 19:03:32 +0000347
Roger Meierca142b02011-06-07 17:59:07 +0000348 if (transport_type.compare("http") == 0) {
cyy316723a2019-01-05 16:35:14 +0800349 transport = std::make_shared<THttpClient>(socket, host, "/service");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100350 } else if (transport_type.compare("framed") == 0) {
cyy316723a2019-01-05 16:35:14 +0800351 transport = std::make_shared<TFramedTransport>(socket);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100352 } else {
cyy316723a2019-01-05 16:35:14 +0800353 transport = std::make_shared<TBufferedTransport>(socket);
James E. King IIIb2b767e2018-09-15 20:32:04 +0000354 }
355
356 if (zlib) {
cyy316723a2019-01-05 16:35:14 +0800357 transport = std::make_shared<TZlibTransport>(transport);
Mark Sleea3302652006-10-25 19:03:32 +0000358 }
359
James E. King, III58402ff2017-11-17 14:41:46 -0500360 if (protocol_type == "json" || protocol_type == "multij") {
James E. King IIIf95620d2019-01-28 18:15:13 -0500361 typedef TPedanticProtocol<TJSONProtocol> TPedanticJSONProtocol;
362 protocol = std::make_shared<TPedanticJSONProtocol>(transport);
James E. King, III58402ff2017-11-17 14:41:46 -0500363 } else if (protocol_type == "compact" || protocol_type == "multic") {
James E. King IIIf95620d2019-01-28 18:15:13 -0500364 typedef TPedanticProtocol<TCompactProtocol> TPedanticCompactProtocol;
365 protocol = std::make_shared<TPedanticCompactProtocol>(transport);
James E. King, III58402ff2017-11-17 14:41:46 -0500366 } else if (protocol_type == "header" || protocol_type == "multih") {
James E. King IIIf95620d2019-01-28 18:15:13 -0500367 typedef TPedanticProtocol<THeaderProtocol> TPedanticHeaderProtocol;
368 protocol = std::make_shared<TPedanticHeaderProtocol>(transport);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100369 } else {
James E. King IIIf95620d2019-01-28 18:15:13 -0500370 typedef TPedanticProtocol<TBinaryProtocol> TPedanticBinaryProtocol;
371 protocol = std::make_shared<TPedanticBinaryProtocol>(transport);
James E. King, III58402ff2017-11-17 14:41:46 -0500372 }
373
374 if (boost::starts_with(protocol_type, "multi")) {
James E. King IIIf95620d2019-01-28 18:15:13 -0500375 protocol2 = std::make_shared<TMultiplexedProtocol>(protocol, "SecondService");
376 // we don't need access to the original protocol any more, so...
377 protocol = std::make_shared<TMultiplexedProtocol>(protocol, "ThriftTest");
Roger Meierca142b02011-06-07 17:59:07 +0000378 }
379
380 // Connection info
pavlodd08f6e2015-10-08 16:43:56 -0400381 cout << "Connecting (" << transport_type << "/" << protocol_type << ") to: ";
382 if (abstract_namespace) {
383 cout << '@';
384 }
385 cout << domain_socket;
Roger Meierca142b02011-06-07 17:59:07 +0000386 if (port != 0) {
387 cout << host << ":" << port;
388 }
CJCombrink4a280d52024-03-14 19:57:41 +0100389 cout << '\n';
Roger Meierca142b02011-06-07 17:59:07 +0000390
Roger Meier7e056e72011-07-17 07:28:28 +0000391 if (transport_type.compare("evhttp") == 0) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100392 event_base* base = event_base_new();
CJCombrink4a280d52024-03-14 19:57:41 +0100393 cout << "Libevent Version: " << event_get_version() << '\n';
394 cout << "Libevent Method: " << event_base_get_method(base) << '\n';
Roger Meier7e056e72011-07-17 07:28:28 +0000395#if LIBEVENT_VERSION_NUMBER >= 0x02000000
CJCombrink4a280d52024-03-14 19:57:41 +0100396 cout << "Libevent Features: 0x" << hex << event_base_get_features(base) << '\n';
Roger Meier7e056e72011-07-17 07:28:28 +0000397#endif
398
cyy316723a2019-01-05 16:35:14 +0800399 std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Roger Meier7e056e72011-07-17 07:28:28 +0000400
cyy316723a2019-01-05 16:35:14 +0800401 std::shared_ptr<TAsyncChannel> channel(
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100402 new TEvhttpClientChannel(host.c_str(), "/", host.c_str(), port, base));
Roger Meier7e056e72011-07-17 07:28:28 +0000403 ThriftTestCobClient* client = new ThriftTestCobClient(channel, protocolFactory.get());
cyy316723a2019-01-05 16:35:14 +0800404 client->testVoid(std::bind(testVoid_clientReturn,
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100405 base,
cyy316723a2019-01-05 16:35:14 +0800406 std::placeholders::_1));
Jake Farrell5d02b802014-01-07 21:42:01 -0500407
Roger Meier7e056e72011-07-17 07:28:28 +0000408 event_base_loop(base, 0);
409 return 0;
410 }
411
Roger Meierca142b02011-06-07 17:59:07 +0000412 ThriftTestClient testClient(protocol);
Mark Sleed788b2e2006-09-07 01:26:35 +0000413
414 uint64_t time_min = 0;
415 uint64_t time_max = 0;
416 uint64_t time_tot = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000417
Mark Sleee8540632006-05-30 09:24:40 +0000418 int test = 0;
419 for (test = 0; test < numTests; ++test) {
Mark Slee95771002006-06-07 06:53:25 +0000420
Mark Slee95771002006-06-07 06:53:25 +0000421 try {
Mark Sleea3302652006-10-25 19:03:32 +0000422 transport->open();
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900423 } catch (TTransportException& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100424 cout << "Connect failed: " << ex.what() << '\n';
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900425 return ERR_UNKNOWN;
Mark Sleee8540632006-05-30 09:24:40 +0000426 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000427
Mark Sleed788b2e2006-09-07 01:26:35 +0000428 /**
429 * CONNECT TEST
430 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100431 printf("Test #%d, connect %s:%d\n", test + 1, host.c_str(), port);
Mark Slee95771002006-06-07 06:53:25 +0000432
433 uint64_t start = now();
David Reiss0c90f6f2008-02-06 22:18:40 +0000434
Mark Sleee8540632006-05-30 09:24:40 +0000435 /**
436 * VOID TEST
437 */
Mark Sleee129a2d2007-02-21 05:17:48 +0000438 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900439 cout << "testVoid()" << flush;
Mark Sleee129a2d2007-02-21 05:17:48 +0000440 testClient.testVoid();
CJCombrink4a280d52024-03-14 19:57:41 +0100441 cout << " = void" << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900442 } catch (TTransportException&) {
443 // Stop here if transport got broken
444 throw;
445 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100446 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200447 return_code |= ERR_BASETYPES;
Mark Sleee129a2d2007-02-21 05:17:48 +0000448 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000449
Mark Sleee8540632006-05-30 09:24:40 +0000450 /**
451 * STRING TEST
452 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900453 cout << "testString(\"Test\")" << flush;
Mark Slee1921d202007-01-24 19:43:06 +0000454 string s;
455 testClient.testString(s, "Test");
CJCombrink4a280d52024-03-14 19:57:41 +0100456 cout << " = " << s << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200457 if (s != "Test") {
CJCombrink4a280d52024-03-14 19:57:41 +0100458 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200459 return_code |= ERR_BASETYPES;
460 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000461
James E. King, III58402ff2017-11-17 14:41:46 -0500462 //
463 // Multiplexed protocol - call another service method
464 // in the middle of the ThriftTest
465 //
466 if (boost::starts_with(protocol_type, "multi")) {
James E. King, III39eaae62017-11-19 20:17:33 -0500467 SecondServiceClient ssc(protocol2);
468 // transport is already open...
469
James E. King, III58402ff2017-11-17 14:41:46 -0500470 try {
471 cout << "secondService.secondTestString(\"foo\") => " << flush;
James E. King, III39eaae62017-11-19 20:17:33 -0500472 std::string result;
473 ssc.secondtestString(result, "foo");
CJCombrink4a280d52024-03-14 19:57:41 +0100474 cout << "{" << result << "}" << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -0500475 } catch (std::exception& e) {
CJCombrink4a280d52024-03-14 19:57:41 +0100476 cout << " *** FAILED *** " << e.what() << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -0500477 return_code |= ERR_EXCEPTIONS;
478 }
James E. King, III58402ff2017-11-17 14:41:46 -0500479 }
480
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900481 try {
James E. King, III7edc8fa2017-01-20 10:11:41 -0500482#ifdef _MSC_VER
483#pragma warning( push )
484#pragma warning( disable : 4566 )
485#endif
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900486 string str(
487 "}{Afrikaans, Alemannisch, Aragonés, العربية, مصرى, "
488 "Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, "
489 "Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, "
490 "বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, "
491 "Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, "
492 "Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, "
493 "Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, "
494 "Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, "
495 "Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski, "
496 "Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia, "
497 "Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa, "
498 "ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар, "
499 "Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, "
500 "Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa "
501 "Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, مازِرونی, Bahasa "
502 "Melayu, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, ‪"
503 "Norsk (nynorsk)‬, ‪Norsk (bokmål)‬, Nouormand, Diné bizaad, "
504 "Occitan, Иронау, Papiamentu, Deitsch, Polski, پنجابی, پښتو, "
505 "Norfuk / Pitkern, Português, Runa Simi, Rumantsch, Romani, Română, "
506 "Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple "
507 "English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk, "
508 "Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog, "
509 "Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük, "
510 "Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, "
511 "Bân-lâm-gú, 粵語");
James E. King, III7edc8fa2017-01-20 10:11:41 -0500512#ifdef _MSC_VER
513#pragma warning( pop )
514#endif
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900515 cout << "testString(" << str << ") = " << flush;
516 testClient.testString(s, str);
CJCombrink4a280d52024-03-14 19:57:41 +0100517 cout << s << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900518 if (s != str) {
519 cout.imbue(locale("en_US.UTF8"));
CJCombrink4a280d52024-03-14 19:57:41 +0100520 cout << "*** FAILED ***" << '\n' << "Expected string: " << str << " but got: " << s << '\n' << "CLEAR";
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900521 return_code |= ERR_BASETYPES;
522 }
523 } catch (TTransportException&) {
524 throw;
525 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100526 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900527 return_code |= ERR_BASETYPES;
528 return return_code;
529 }
530 try {
531 string str(
532 "quote: \" backslash:"
533 " forwardslash-escaped: \\/ "
534 " backspace: \b formfeed: \f newline: \n return: \r tab: "
535 " now-all-of-them-together: \"\\\\/\b\n\r\t"
536 " now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><"
537 " char-to-test-json-parsing: ]] \"]] \\\" }}}{ [[[ ");
538 cout << "testString(" << str << ") = " << flush;
539 testClient.testString(s, str);
CJCombrink4a280d52024-03-14 19:57:41 +0100540 cout << s << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900541 if (s != str) {
542 cout.imbue(locale("en_US.UTF8"));
CJCombrink4a280d52024-03-14 19:57:41 +0100543 cout << "*** FAILED ***" << '\n'
544 << "Expected string: " << str << " but got: " << s << '\n'
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900545 << "CLEAR";
546 ;
547 return_code |= ERR_BASETYPES;
548 }
549 } catch (TTransportException&) {
550 throw;
551 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100552 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900553 return_code |= ERR_BASETYPES;
554 return return_code;
555 }
556
Mark Sleee8540632006-05-30 09:24:40 +0000557 /**
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900558 * BOOL TEST
559 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900560 cout << boolalpha;
561 BASETYPE_IDENTITY_TEST(testBool, true);
562 BASETYPE_IDENTITY_TEST(testBool, false);
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900563
564 /**
Mark Sleee8540632006-05-30 09:24:40 +0000565 * BYTE TEST
566 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900567 BASETYPE_IDENTITY_TEST(testByte, (int8_t)0);
568 BASETYPE_IDENTITY_TEST(testByte, (int8_t)-1);
569 BASETYPE_IDENTITY_TEST(testByte, (int8_t)42);
570 BASETYPE_IDENTITY_TEST(testByte, (int8_t)-42);
571 BASETYPE_IDENTITY_TEST(testByte, (int8_t)127);
572 BASETYPE_IDENTITY_TEST(testByte, (int8_t)-128);
David Reiss0c90f6f2008-02-06 22:18:40 +0000573
Mark Sleee8540632006-05-30 09:24:40 +0000574 /**
575 * I32 TEST
576 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900577 BASETYPE_IDENTITY_TEST(testI32, 0);
578 BASETYPE_IDENTITY_TEST(testI32, -1);
579 BASETYPE_IDENTITY_TEST(testI32, 190000013);
580 BASETYPE_IDENTITY_TEST(testI32, -190000013);
James E. King III9b75e4f2018-12-17 16:21:14 -0500581 BASETYPE_IDENTITY_TEST(testI32, (numeric_limits<int32_t>::max)());
582 BASETYPE_IDENTITY_TEST(testI32, (numeric_limits<int32_t>::min)());
Mark Sleee8540632006-05-30 09:24:40 +0000583
584 /**
Mark Sleee8540632006-05-30 09:24:40 +0000585 * I64 TEST
586 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900587 BASETYPE_IDENTITY_TEST(testI64, (int64_t)0);
588 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-1);
589 BASETYPE_IDENTITY_TEST(testI64, (int64_t)7000000000000000123LL);
590 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-7000000000000000123LL);
James E. King, III7edc8fa2017-01-20 10:11:41 -0500591 BASETYPE_IDENTITY_TEST(testI64, (int64_t)pow(static_cast<double>(2LL), 32));
592 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-pow(static_cast<double>(2LL), 32));
593 BASETYPE_IDENTITY_TEST(testI64, (int64_t)pow(static_cast<double>(2LL), 32) + 1);
594 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-pow(static_cast<double>(2LL), 32) - 1);
James E. King III9b75e4f2018-12-17 16:21:14 -0500595 BASETYPE_IDENTITY_TEST(testI64, (numeric_limits<int64_t>::max)());
596 BASETYPE_IDENTITY_TEST(testI64, (numeric_limits<int64_t>::min)());
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100597
Mark Sleec98d0502006-09-06 02:42:25 +0000598 /**
599 * DOUBLE TEST
600 */
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900601 // Comparing double values with plain equality because Thrift handles full precision of double
602 BASETYPE_IDENTITY_TEST(testDouble, 0.0);
603 BASETYPE_IDENTITY_TEST(testDouble, -1.0);
604 BASETYPE_IDENTITY_TEST(testDouble, -5.2098523);
605 BASETYPE_IDENTITY_TEST(testDouble, -0.000341012439638598279);
James E. King, III7edc8fa2017-01-20 10:11:41 -0500606 BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast<double>(2), 32));
607 BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast<double>(2), 32) + 1);
608 BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast<double>(2), 53) - 1);
609 BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast<double>(2), 32));
610 BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast<double>(2), 32) - 1);
611 BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast<double>(2), 53) + 1);
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900612
613 try {
James E. King, III7edc8fa2017-01-20 10:11:41 -0500614 double expected = pow(static_cast<double>(10), 307);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900615 cout << "testDouble(" << expected << ") = " << flush;
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900616 double actual = testClient.testDouble(expected);
CJCombrink4a280d52024-03-14 19:57:41 +0100617 cout << "(" << actual << ")" << '\n';
James E. King, III7edc8fa2017-01-20 10:11:41 -0500618 if (expected - actual > pow(static_cast<double>(10), 292)) {
CJCombrink4a280d52024-03-14 19:57:41 +0100619 cout << "*** FAILED ***" << '\n'
620 << "Expected: " << expected << " but got: " << actual << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900621 }
622 } catch (TTransportException&) {
623 throw;
624 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100625 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900626 return_code |= ERR_BASETYPES;
627 }
628
629 try {
James E. King, III7edc8fa2017-01-20 10:11:41 -0500630 double expected = pow(static_cast<double>(10), -292);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900631 cout << "testDouble(" << expected << ") = " << flush;
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900632 double actual = testClient.testDouble(expected);
CJCombrink4a280d52024-03-14 19:57:41 +0100633 cout << "(" << actual << ")" << '\n';
James E. King, III7edc8fa2017-01-20 10:11:41 -0500634 if (expected - actual > pow(static_cast<double>(10), -307)) {
CJCombrink4a280d52024-03-14 19:57:41 +0100635 cout << "*** FAILED ***" << '\n'
636 << "Expected: " << expected << " but got: " << actual << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900637 }
638 } catch (TTransportException&) {
639 throw;
640 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100641 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200642 return_code |= ERR_BASETYPES;
643 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000644
Mark Sleee8540632006-05-30 09:24:40 +0000645 /**
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100646 * BINARY TEST
647 */
James E. King, III39eaae62017-11-19 20:17:33 -0500648 for (string::size_type i = 0; i < 131073 && !return_code; ) {
649 return_code |= binary_test(testClient, i);
650 if (i > 0) { i *= 2; } else { ++i; }
Jens Geyerd629ea02015-09-23 21:16:50 +0200651 }
652
CJCombrink1d886ca2024-03-23 21:32:28 +0100653 /**
654 * UUID TEST
655 */
CJCombrink4b909092024-04-27 19:51:39 +0200656 const TUuid expected_uuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"};
657 UUID_TEST(testUuid, TUuid{"{5e2ab188-1726-4e75-a04f-1ed9a6a89c4c}"}, expected_uuid);
658 UUID_TEST(testUuid, TUuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}, expected_uuid);
659 UUID_TEST(testUuid, TUuid{"5e2ab18817264e75a04f1ed9a6a89c4c"}, expected_uuid);
660 UUID_TEST(testUuid, TUuid{"{5e2ab18817264e75a04f1ed9a6a89c4c}"}, expected_uuid);
661 UUID_TEST(testUuid, TUuid{}, TUuid{"00000000-0000-0000-0000-000000000000"});
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100662
663 /**
Mark Sleee8540632006-05-30 09:24:40 +0000664 * STRUCT TEST
665 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900666 cout << "testStruct({\"Zero\", 1, -3, -5})" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000667 Xtruct out;
668 out.string_thing = "Zero";
669 out.byte_thing = 1;
Mark Sleee8540632006-05-30 09:24:40 +0000670 out.i32_thing = -3;
Mark Sleee8540632006-05-30 09:24:40 +0000671 out.i64_thing = -5;
Mark Slee1921d202007-01-24 19:43:06 +0000672 Xtruct in;
673 testClient.testStruct(in, out);
Roger Meier0e814802014-01-17 21:07:58 +0100674 printf(" = {\"%s\", %d, %d, %" PRId64 "}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000675 in.string_thing.c_str(),
676 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000677 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000678 in.i64_thing);
Jens Geyerd629ea02015-09-23 21:16:50 +0200679 if (in != out) {
CJCombrink4a280d52024-03-14 19:57:41 +0100680 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200681 return_code |= ERR_STRUCTS;
682 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000683
Mark Sleee8540632006-05-30 09:24:40 +0000684 /**
685 * NESTED STRUCT TEST
686 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900687 cout << "testNest({1, {\"Zero\", 1, -3, -5}), 5}" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000688 Xtruct2 out2;
689 out2.byte_thing = 1;
690 out2.struct_thing = out;
691 out2.i32_thing = 5;
Mark Slee1921d202007-01-24 19:43:06 +0000692 Xtruct2 in2;
693 testClient.testNest(in2, out2);
Mark Sleee8540632006-05-30 09:24:40 +0000694 in = in2.struct_thing;
Roger Meier0e814802014-01-17 21:07:58 +0100695 printf(" = {%d, {\"%s\", %d, %d, %" PRId64 "}, %d}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000696 in2.byte_thing,
697 in.string_thing.c_str(),
698 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000699 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000700 in.i64_thing,
David Reiss0c90f6f2008-02-06 22:18:40 +0000701 in2.i32_thing);
Jens Geyerd629ea02015-09-23 21:16:50 +0200702 if (in2 != out2) {
CJCombrink4a280d52024-03-14 19:57:41 +0100703 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200704 return_code |= ERR_STRUCTS;
705 }
Mark Sleee8540632006-05-30 09:24:40 +0000706
707 /**
708 * MAP TEST
709 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100710 map<int32_t, int32_t> mapout;
Mark Sleee8540632006-05-30 09:24:40 +0000711 for (int32_t i = 0; i < 5; ++i) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100712 mapout.insert(make_pair(i, i - 10));
Mark Sleee8540632006-05-30 09:24:40 +0000713 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900714 cout << "testMap({" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000715 map<int32_t, int32_t>::const_iterator m_iter;
716 bool first = true;
717 for (m_iter = mapout.begin(); m_iter != mapout.end(); ++m_iter) {
718 if (first) {
719 first = false;
720 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900721 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000722 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900723 cout << m_iter->first << " => " << m_iter->second;
Mark Sleee8540632006-05-30 09:24:40 +0000724 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900725 cout << "})";
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100726 map<int32_t, int32_t> mapin;
Mark Slee1921d202007-01-24 19:43:06 +0000727 testClient.testMap(mapin, mapout);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900728 cout << " = {";
Mark Sleee8540632006-05-30 09:24:40 +0000729 first = true;
730 for (m_iter = mapin.begin(); m_iter != mapin.end(); ++m_iter) {
731 if (first) {
732 first = false;
733 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900734 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000735 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900736 cout << m_iter->first << " => " << m_iter->second;
Mark Sleee8540632006-05-30 09:24:40 +0000737 }
CJCombrink4a280d52024-03-14 19:57:41 +0100738 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200739 if (mapin != mapout) {
CJCombrink4a280d52024-03-14 19:57:41 +0100740 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200741 return_code |= ERR_CONTAINERS;
742 }
Roger Meier4fce9602012-05-04 06:22:09 +0000743
744 /**
745 * STRING MAP TEST
Roger Meier4fce9602012-05-04 06:22:09 +0000746 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900747 cout << "testStringMap({a => 2, b => blah, some => thing}) = {" << flush;
Jens Geyerd629ea02015-09-23 21:16:50 +0200748 map<string, string> smapin;
749 map<string, string> smapout;
750 smapin["a"] = "2";
751 smapin["b"] = "blah";
752 smapin["some"] = "thing";
753 try {
754 testClient.testStringMap(smapout, smapin);
755 first = true;
756 for (map<string, string>::const_iterator it = smapout.begin(); it != smapout.end(); ++it) {
757 if (first)
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900758 cout << ",";
Jens Geyerd629ea02015-09-23 21:16:50 +0200759 else
760 first = false;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900761 cout << it->first << " => " << it->second;
Jens Geyerd629ea02015-09-23 21:16:50 +0200762 }
CJCombrink4a280d52024-03-14 19:57:41 +0100763 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200764 if (smapin != smapout) {
CJCombrink4a280d52024-03-14 19:57:41 +0100765 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200766 return_code |= ERR_CONTAINERS;
767 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900768 } catch (TTransportException&) {
769 throw;
Jens Geyerd629ea02015-09-23 21:16:50 +0200770 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100771 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200772 return_code |= ERR_CONTAINERS;
773 }
Mark Sleee8540632006-05-30 09:24:40 +0000774
775 /**
776 * SET TEST
777 */
778 set<int32_t> setout;
779 for (int32_t i = -2; i < 3; ++i) {
780 setout.insert(i);
781 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900782 cout << "testSet({" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000783 set<int32_t>::const_iterator s_iter;
784 first = true;
785 for (s_iter = setout.begin(); s_iter != setout.end(); ++s_iter) {
786 if (first) {
787 first = false;
788 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900789 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000790 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900791 cout << *s_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000792 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900793 cout << "})";
Mark Slee1921d202007-01-24 19:43:06 +0000794 set<int32_t> setin;
795 testClient.testSet(setin, setout);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900796 cout << " = {";
Mark Sleee8540632006-05-30 09:24:40 +0000797 first = true;
798 for (s_iter = setin.begin(); s_iter != setin.end(); ++s_iter) {
799 if (first) {
800 first = false;
801 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900802 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000803 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900804 cout << *s_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000805 }
CJCombrink4a280d52024-03-14 19:57:41 +0100806 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200807 if (setin != setout) {
CJCombrink4a280d52024-03-14 19:57:41 +0100808 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200809 return_code |= ERR_CONTAINERS;
810 }
Mark Sleee8540632006-05-30 09:24:40 +0000811
812 /**
813 * LIST TEST
814 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900815 cout << "testList(empty)" << flush;
816 try {
817 vector<int32_t> listout;
818 testClient.testList(listout, vector<int32_t>());
819 if (!listout.empty()) {
CJCombrink4a280d52024-03-14 19:57:41 +0100820 cout << "*** FAILED ***" << '\n';
821 cout << "invalid length: " << listout.size() << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900822 return_code |= ERR_CONTAINERS;
Mark Sleee8540632006-05-30 09:24:40 +0000823 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900824 } catch (TTransportException&) {
825 throw;
826 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100827 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900828 return_code |= ERR_CONTAINERS;
Mark Sleee8540632006-05-30 09:24:40 +0000829 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900830 try {
831 vector<int32_t> listout;
832 for (int32_t i = -2; i < 3; ++i) {
833 listout.push_back(i);
Mark Sleee8540632006-05-30 09:24:40 +0000834 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900835 cout << "testList({" << flush;
836 vector<int32_t>::const_iterator l_iter;
837 first = true;
838 for (l_iter = listout.begin(); l_iter != listout.end(); ++l_iter) {
839 if (first) {
840 first = false;
841 } else {
842 cout << ",";
843 }
844 cout << *l_iter;
845 }
846 cout << "})";
847 vector<int32_t> listin;
848 testClient.testList(listin, listout);
849 cout << " = {";
850 first = true;
851 for (l_iter = listin.begin(); l_iter != listin.end(); ++l_iter) {
852 if (first) {
853 first = false;
854 } else {
855 cout << ",";
856 }
857 cout << *l_iter;
858 }
CJCombrink4a280d52024-03-14 19:57:41 +0100859 cout << "}" << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900860 if (listin != listout) {
CJCombrink4a280d52024-03-14 19:57:41 +0100861 cout << "*** FAILED ***" << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900862 return_code |= ERR_CONTAINERS;
863 }
864 } catch (TTransportException&) {
865 throw;
866 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100867 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200868 return_code |= ERR_CONTAINERS;
869 }
Mark Sleee8540632006-05-30 09:24:40 +0000870
871 /**
872 * ENUM TEST
873 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900874 cout << "testEnum(ONE)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000875 Numberz::type ret = testClient.testEnum(Numberz::ONE);
CJCombrink4a280d52024-03-14 19:57:41 +0100876 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200877 if (ret != Numberz::ONE) {
CJCombrink4a280d52024-03-14 19:57:41 +0100878 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200879 return_code |= ERR_STRUCTS;
880 }
Mark Sleee8540632006-05-30 09:24:40 +0000881
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900882 cout << "testEnum(TWO)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000883 ret = testClient.testEnum(Numberz::TWO);
CJCombrink4a280d52024-03-14 19:57:41 +0100884 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200885 if (ret != Numberz::TWO) {
CJCombrink4a280d52024-03-14 19:57:41 +0100886 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200887 return_code |= ERR_STRUCTS;
888 }
Mark Sleee8540632006-05-30 09:24:40 +0000889
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900890 cout << "testEnum(THREE)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000891 ret = testClient.testEnum(Numberz::THREE);
CJCombrink4a280d52024-03-14 19:57:41 +0100892 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200893 if (ret != Numberz::THREE) {
CJCombrink4a280d52024-03-14 19:57:41 +0100894 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200895 return_code |= ERR_STRUCTS;
896 }
Mark Sleee8540632006-05-30 09:24:40 +0000897
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900898 cout << "testEnum(FIVE)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000899 ret = testClient.testEnum(Numberz::FIVE);
CJCombrink4a280d52024-03-14 19:57:41 +0100900 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200901 if (ret != Numberz::FIVE) {
CJCombrink4a280d52024-03-14 19:57:41 +0100902 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200903 return_code |= ERR_STRUCTS;
904 }
Mark Sleee8540632006-05-30 09:24:40 +0000905
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900906 cout << "testEnum(EIGHT)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000907 ret = testClient.testEnum(Numberz::EIGHT);
CJCombrink4a280d52024-03-14 19:57:41 +0100908 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200909 if (ret != Numberz::EIGHT) {
CJCombrink4a280d52024-03-14 19:57:41 +0100910 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200911 return_code |= ERR_STRUCTS;
912 }
Mark Sleee8540632006-05-30 09:24:40 +0000913
914 /**
915 * TYPEDEF TEST
916 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900917 cout << "testTypedef(309858235082523)" << flush;
Marc Slemkobf4fd192006-08-15 21:29:39 +0000918 UserId uid = testClient.testTypedef(309858235082523LL);
CJCombrink4a280d52024-03-14 19:57:41 +0100919 cout << " = " << uid << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200920 if (uid != 309858235082523LL) {
CJCombrink4a280d52024-03-14 19:57:41 +0100921 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200922 return_code |= ERR_STRUCTS;
923 }
Mark Sleee8540632006-05-30 09:24:40 +0000924
925 /**
926 * NESTED MAP TEST
927 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900928 cout << "testMapMap(1)" << flush;
Mark Slee1921d202007-01-24 19:43:06 +0000929 map<int32_t, map<int32_t, int32_t> > mm;
930 testClient.testMapMap(mm, 1);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900931 cout << " = {";
Mark Sleee8540632006-05-30 09:24:40 +0000932 map<int32_t, map<int32_t, int32_t> >::const_iterator mi;
933 for (mi = mm.begin(); mi != mm.end(); ++mi) {
934 printf("%d => {", mi->first);
935 map<int32_t, int32_t>::const_iterator mi2;
936 for (mi2 = mi->second.begin(); mi2 != mi->second.end(); ++mi2) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900937 cout << mi2->first << " => " << mi2->second;
Mark Sleee8540632006-05-30 09:24:40 +0000938 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900939 cout << "}, ";
Mark Sleee8540632006-05-30 09:24:40 +0000940 }
CJCombrink4a280d52024-03-14 19:57:41 +0100941 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200942 if (mm.size() != 2 ||
943 mm[-4][-4] != -4 ||
944 mm[-4][-3] != -3 ||
945 mm[-4][-2] != -2 ||
946 mm[-4][-1] != -1 ||
947 mm[4][4] != 4 ||
948 mm[4][3] != 3 ||
949 mm[4][2] != 2 ||
950 mm[4][1] != 1) {
CJCombrink4a280d52024-03-14 19:57:41 +0100951 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200952 return_code |= ERR_CONTAINERS;
953 }
Mark Sleee8540632006-05-30 09:24:40 +0000954
955 /**
956 * INSANITY TEST
957 */
Jens Geyerf4598682014-05-08 23:18:44 +0200958 if (!noinsane) {
959 Insanity insane;
Jens Geyerd629ea02015-09-23 21:16:50 +0200960 insane.userMap.insert(make_pair(Numberz::FIVE, 5));
961 insane.userMap.insert(make_pair(Numberz::EIGHT, 8));
Jens Geyerf4598682014-05-08 23:18:44 +0200962 Xtruct truck;
Jens Geyerd629ea02015-09-23 21:16:50 +0200963 truck.string_thing = "Goodbye4";
964 truck.byte_thing = 4;
965 truck.i32_thing = 4;
966 truck.i64_thing = 4;
967 Xtruct truck2;
968 truck2.string_thing = "Hello2";
969 truck2.byte_thing = 2;
970 truck2.i32_thing = 2;
971 truck2.i64_thing = 2;
Jens Geyerf4598682014-05-08 23:18:44 +0200972 insane.xtructs.push_back(truck);
Jens Geyerd629ea02015-09-23 21:16:50 +0200973 insane.xtructs.push_back(truck2);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900974 cout << "testInsanity()" << flush;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100975 map<UserId, map<Numberz::type, Insanity> > whoa;
Jens Geyerf4598682014-05-08 23:18:44 +0200976 testClient.testInsanity(whoa, insane);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900977 cout << " = {";
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100978 map<UserId, map<Numberz::type, Insanity> >::const_iterator i_iter;
Jens Geyerf4598682014-05-08 23:18:44 +0200979 for (i_iter = whoa.begin(); i_iter != whoa.end(); ++i_iter) {
980 printf("%" PRId64 " => {", i_iter->first);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100981 map<Numberz::type, Insanity>::const_iterator i2_iter;
982 for (i2_iter = i_iter->second.begin(); i2_iter != i_iter->second.end(); ++i2_iter) {
Jens Geyerf4598682014-05-08 23:18:44 +0200983 printf("%d => {", i2_iter->first);
984 map<Numberz::type, UserId> userMap = i2_iter->second.userMap;
985 map<Numberz::type, UserId>::const_iterator um;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900986 cout << "{";
Jens Geyerf4598682014-05-08 23:18:44 +0200987 for (um = userMap.begin(); um != userMap.end(); ++um) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900988 cout << um->first << " => " << um->second;
Jens Geyerf4598682014-05-08 23:18:44 +0200989 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900990 cout << "}, ";
Mark Sleee8540632006-05-30 09:24:40 +0000991
Jens Geyerf4598682014-05-08 23:18:44 +0200992 vector<Xtruct> xtructs = i2_iter->second.xtructs;
993 vector<Xtruct>::const_iterator x;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900994 cout << "{";
Jens Geyerf4598682014-05-08 23:18:44 +0200995 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
996 printf("{\"%s\", %d, %d, %" PRId64 "}, ",
997 x->string_thing.c_str(),
998 (int)x->byte_thing,
999 x->i32_thing,
1000 x->i64_thing);
1001 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001002 cout << "}";
Mark Sleee8540632006-05-30 09:24:40 +00001003
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001004 cout << "}, ";
Jens Geyerf4598682014-05-08 23:18:44 +02001005 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001006 cout << "}, ";
Mark Sleee8540632006-05-30 09:24:40 +00001007 }
CJCombrink4a280d52024-03-14 19:57:41 +01001008 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001009 bool failed = false;
1010 map<UserId, map<Numberz::type, Insanity> >::const_iterator it1 = whoa.find(UserId(1));
1011 if (whoa.size() != 2) {
1012 failed = true;
1013 }
1014 if (it1 == whoa.end()) {
1015 failed = true;
1016 } else {
Sebastian Zenker042580f2019-01-29 15:48:12 +01001017 auto it12 = it1->second.find(Numberz::TWO);
Jens Geyerd629ea02015-09-23 21:16:50 +02001018 if (it12 == it1->second.end() || it12->second != insane) {
1019 failed = true;
1020 }
Sebastian Zenker042580f2019-01-29 15:48:12 +01001021 auto it13 = it1->second.find(Numberz::THREE);
Jens Geyerd629ea02015-09-23 21:16:50 +02001022 if (it13 == it1->second.end() || it13->second != insane) {
1023 failed = true;
1024 }
1025 }
1026 map<UserId, map<Numberz::type, Insanity> >::const_iterator it2 = whoa.find(UserId(2));
1027 if (it2 == whoa.end()) {
1028 failed = true;
1029 } else {
Sebastian Zenker042580f2019-01-29 15:48:12 +01001030 auto it26 = it2->second.find(Numberz::SIX);
James E. King IIIf5f430d2018-06-08 03:37:55 +00001031 if (it26 == it2->second.end() || it26->second != Insanity()) {
Jens Geyerd629ea02015-09-23 21:16:50 +02001032 failed = true;
1033 }
1034 }
1035 if (failed) {
CJCombrink4a280d52024-03-14 19:57:41 +01001036 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001037 return_code |= ERR_STRUCTS;
1038 }
Mark Sleee8540632006-05-30 09:24:40 +00001039 }
Jens Geyerd629ea02015-09-23 21:16:50 +02001040
1041 /**
1042 * MULTI TEST
1043 */
CJCombrink4a280d52024-03-14 19:57:41 +01001044 cout << "testMulti()" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001045 try {
1046 map<int16_t, string> mul_map;
1047 Xtruct mul_result;
1048 mul_map[1] = "blah";
1049 mul_map[2] = "thing";
1050 testClient.testMulti(mul_result, 42, 4242, 424242, mul_map, Numberz::EIGHT, UserId(24));
1051 Xtruct xxs;
1052 xxs.string_thing = "Hello2";
1053 xxs.byte_thing = 42;
1054 xxs.i32_thing = 4242;
1055 xxs.i64_thing = 424242;
1056 if (mul_result != xxs) {
CJCombrink4a280d52024-03-14 19:57:41 +01001057 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001058 return_code |= ERR_STRUCTS;
1059 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001060 } catch (TTransportException&) {
1061 throw;
Jens Geyerd629ea02015-09-23 21:16:50 +02001062 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +01001063 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001064 return_code |= ERR_STRUCTS;
1065 }
1066
Marc Slemko71d4e472006-08-15 22:34:04 +00001067 /* test exception */
Mark Slee95771002006-06-07 06:53:25 +00001068
Marc Slemkobf4fd192006-08-15 21:29:39 +00001069 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001070 cout << "testClient.testException(\"Xception\") =>" << flush;
Marc Slemko71d4e472006-08-15 22:34:04 +00001071 testClient.testException("Xception");
CJCombrink4a280d52024-03-14 19:57:41 +01001072 cout << " void\n*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001073 return_code |= ERR_EXCEPTIONS;
David Reiss0c90f6f2008-02-06 22:18:40 +00001074
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001075 } catch (Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +00001076 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +00001077 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001078
Marc Slemkobf4fd192006-08-15 21:29:39 +00001079 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001080 cout << "testClient.testException(\"TException\") =>" << flush;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001081 testClient.testException("TException");
CJCombrink4a280d52024-03-14 19:57:41 +01001082 cout << " void\n*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001083 return_code |= ERR_EXCEPTIONS;
Roger Meierf50df7f2012-05-02 22:49:55 +00001084
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001085 } catch (const TException&) {
CJCombrink4a280d52024-03-14 19:57:41 +01001086 cout << " Caught TException" << '\n';
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001087 }
Roger Meierf50df7f2012-05-02 22:49:55 +00001088
1089 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001090 cout << "testClient.testException(\"success\") =>" << flush;
Marc Slemko71d4e472006-08-15 22:34:04 +00001091 testClient.testException("success");
CJCombrink4a280d52024-03-14 19:57:41 +01001092 cout << " void" << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001093 } catch (exception & ex) { \
CJCombrink4a280d52024-03-14 19:57:41 +01001094 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001095 return_code |= ERR_EXCEPTIONS;
Marc Slemko71d4e472006-08-15 22:34:04 +00001096 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001097
Marc Slemko71d4e472006-08-15 22:34:04 +00001098 /* test multi exception */
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(\"Xception\", \"test 1\") =>" << flush;
Mark Slee1921d202007-01-24 19:43:06 +00001102 Xtruct result;
1103 testClient.testMultiException(result, "Xception", "test 1");
CJCombrink4a280d52024-03-14 19:57:41 +01001104 cout << " result\n*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001105 return_code |= ERR_EXCEPTIONS;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001106 } catch (Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +00001107 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
1108 }
1109
1110 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001111 cout << "testClient.testMultiException(\"Xception2\", \"test 2\") =>" << flush;
Mark Slee1921d202007-01-24 19:43:06 +00001112 Xtruct result;
1113 testClient.testMultiException(result, "Xception2", "test 2");
CJCombrink4a280d52024-03-14 19:57:41 +01001114 cout << " result\n*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001115 return_code |= ERR_EXCEPTIONS;
David Reiss0c90f6f2008-02-06 22:18:40 +00001116
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001117 } catch (Xception2& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +00001118 printf(" {%u, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +00001119 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001120
Marc Slemko71d4e472006-08-15 22:34:04 +00001121 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001122 cout << "testClient.testMultiException(\"success\", \"test 3\") =>" << flush;
Mark Slee1921d202007-01-24 19:43:06 +00001123 Xtruct result;
1124 testClient.testMultiException(result, "success", "test 3");
Marc Slemko71d4e472006-08-15 22:34:04 +00001125 printf(" {{\"%s\"}}\n", result.string_thing.c_str());
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001126 } catch (exception & ex) { \
CJCombrink4a280d52024-03-14 19:57:41 +01001127 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001128 return_code |= ERR_EXCEPTIONS;
Marc Slemko71d4e472006-08-15 22:34:04 +00001129 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001130
David Reissc51986f2009-03-24 20:01:25 +00001131 /* test oneway void */
David Reiss2ab6fe82008-02-18 02:11:44 +00001132 {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001133 cout << "testClient.testOneway(1) =>" << flush;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001134 uint64_t startOneway = now();
1135 testClient.testOneway(1);
1136 uint64_t elapsed = now() - startOneway;
1137 if (elapsed > 200 * 1000) { // 0.2 seconds
Jens Geyerd629ea02015-09-23 21:16:50 +02001138 printf("*** FAILED *** - took %.2f ms\n", (double)elapsed / 1000.0);
1139 return_code |= ERR_BASETYPES;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001140 } else {
1141 printf(" success - took %.2f ms\n", (double)elapsed / 1000.0);
1142 }
David Reiss2ab6fe82008-02-18 02:11:44 +00001143 }
1144
David Reiss2845b522008-02-18 02:11:52 +00001145 /**
David Reissc51986f2009-03-24 20:01:25 +00001146 * redo a simple test after the oneway to make sure we aren't "off by one" --
1147 * if the server treated oneway void like normal void, this next test will
David Reiss2845b522008-02-18 02:11:52 +00001148 * fail since it will get the void confirmation rather than the correct
1149 * result. In this circumstance, the client will throw the exception:
1150 *
1151 * TApplicationException: Wrong method namea
1152 */
1153 /**
1154 * I32 TEST
1155 */
James E. King, III58402ff2017-11-17 14:41:46 -05001156 cout << "re-test testI32(-1)" << flush;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001157 int i32 = testClient.testI32(-1);
CJCombrink4a280d52024-03-14 19:57:41 +01001158 cout << " = " << i32 << '\n';
Roger Meier4fce9602012-05-04 06:22:09 +00001159 if (i32 != -1)
Jens Geyerd629ea02015-09-23 21:16:50 +02001160 return_code |= ERR_BASETYPES;
David Reiss2845b522008-02-18 02:11:52 +00001161
CJCombrink4a280d52024-03-14 19:57:41 +01001162 cout << '\n' << "All tests done." << '\n' << flush;
James E. King, III39eaae62017-11-19 20:17:33 -05001163
Marc Slemkobf4fd192006-08-15 21:29:39 +00001164 uint64_t stop = now();
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001165 uint64_t tot = stop - start;
Mark Sleed788b2e2006-09-07 01:26:35 +00001166
CJCombrink4a280d52024-03-14 19:57:41 +01001167 cout << "Total time: " << stop - start << " us" << '\n';
David Reiss0c90f6f2008-02-06 22:18:40 +00001168
Mark Sleed788b2e2006-09-07 01:26:35 +00001169 time_tot += tot;
1170 if (time_min == 0 || tot < time_min) {
1171 time_min = tot;
1172 }
1173 if (tot > time_max) {
1174 time_max = tot;
1175 }
1176
James E. King, III58402ff2017-11-17 14:41:46 -05001177 cout << flush;
Mark Sleea3302652006-10-25 19:03:32 +00001178 transport->close();
Mark Sleee8540632006-05-30 09:24:40 +00001179 }
1180
Mark Sleed788b2e2006-09-07 01:26:35 +00001181
1182 uint64_t time_avg = time_tot / numTests;
1183
CJCombrink4a280d52024-03-14 19:57:41 +01001184 cout << "Min time: " << time_min << " us" << '\n';
1185 cout << "Max time: " << time_max << " us" << '\n';
1186 cout << "Avg time: " << time_avg << " us" << '\n';
Mark Sleed788b2e2006-09-07 01:26:35 +00001187
Jens Geyerd629ea02015-09-23 21:16:50 +02001188 return return_code;
Mark Sleee8540632006-05-30 09:24:40 +00001189}
James E. King, III39eaae62017-11-19 20:17:33 -05001190
1191void binary_fill(std::string& str, string::size_type siz)
1192{
1193 static const signed char bin_data[256]
1194 = {-128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114,
1195 -113, -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99,
1196 -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84,
1197 -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, -69,
1198 -68, -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54,
1199 -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39,
1200 -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24,
1201 -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9,
1202 -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6,
1203 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
1204 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
1205 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
1206 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
1207 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
1208 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
1209 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
1210 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
1211 127};
1212
1213 str.resize(siz);
1214 char *ptr = &str[0];
1215 string::size_type pos = 0;
1216 for (string::size_type i = 0; i < siz; ++i)
1217 {
1218 if (pos == 255) { pos = 0; } else { ++pos; }
1219 *ptr++ = bin_data[pos];
1220 }
1221}
1222
1223int binary_test(ThriftTestClient& testClient, string::size_type siz)
1224{
1225 string bin_request;
1226 string bin_result;
1227
CJCombrink4a280d52024-03-14 19:57:41 +01001228 cout << "testBinary(siz = " << siz << ")" << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -05001229 binary_fill(bin_request, siz);
1230 try {
1231 testClient.testBinary(bin_result, bin_request);
1232
1233 if (bin_request.size() != bin_result.size()) {
CJCombrink4a280d52024-03-14 19:57:41 +01001234 cout << "*** FAILED: request size " << bin_request.size() << "; result size " << bin_result.size() << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -05001235 return ERR_BASETYPES;
1236 }
1237
1238 for (string::size_type i = 0; i < siz; ++i) {
1239 if (bin_request.at(i) != bin_result.at(i)) {
CJCombrink4a280d52024-03-14 19:57:41 +01001240 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 -05001241 return ERR_BASETYPES;
1242 }
1243 }
1244 } catch (TTransportException&) {
1245 throw;
1246 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +01001247 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -05001248 return ERR_BASETYPES;
1249 }
1250
1251 return 0;
1252}