blob: 64193c657c69ca316cc3ddfcb4d5b0c965a819af [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 { \
Carel Combrinkaee3f632024-09-05 18:26:42 +0000184 TUuid ret; \
185 testClient.func(ret, value); \
186 if (!print_eq(expected, ret)) \
CJCombrink1d886ca2024-03-23 21:32:28 +0100187 return_code |= ERR_BASETYPES; \
188 } catch (TTransportException&) { \
189 throw; \
190 } catch (exception & ex) { \
CJCombrink4a280d52024-03-14 19:57:41 +0100191 cout << "*** FAILED ***" << '\n' << ex.what() << '\n'; \
CJCombrink1d886ca2024-03-23 21:32:28 +0100192 return_code |= ERR_BASETYPES; \
193 }
194
James E. King, III39eaae62017-11-19 20:17:33 -0500195int binary_test(ThriftTestClient& testClient, string::size_type siz);
196
197BOOST_CONSTEXPR_OR_CONST int ERR_BASETYPES = 1;
198BOOST_CONSTEXPR_OR_CONST int ERR_STRUCTS = 2;
199BOOST_CONSTEXPR_OR_CONST int ERR_CONTAINERS = 4;
200BOOST_CONSTEXPR_OR_CONST int ERR_EXCEPTIONS = 8;
201BOOST_CONSTEXPR_OR_CONST int ERR_UNKNOWN = 64;
202
Mark Sleee8540632006-05-30 09:24:40 +0000203int main(int argc, char** argv) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900204 cout.precision(19);
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900205
James E. King, III06190872017-02-20 08:52:11 -0500206 string testDir = boost::filesystem::system_complete(argv[0]).parent_path().parent_path().parent_path().string();
207 string caPath = testDir + "/keys/CA.pem";
208 string certPath = testDir + "/keys/client.crt";
209 string keyPath = testDir + "/keys/client.key";
210
Jake Farrell5d02b802014-01-07 21:42:01 -0500211#if _WIN32
212 transport::TWinsockSingleton::create();
213#endif
Mark Sleee8540632006-05-30 09:24:40 +0000214 string host = "localhost";
215 int port = 9090;
216 int numTests = 1;
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000217 bool ssl = false;
James E. King IIIb2b767e2018-09-15 20:32:04 +0000218 bool zlib = false;
Roger Meierca142b02011-06-07 17:59:07 +0000219 string transport_type = "buffered";
220 string protocol_type = "binary";
221 string domain_socket = "";
pavlodd08f6e2015-10-08 16:43:56 -0400222 bool abstract_namespace = false;
Jens Geyerf4598682014-05-08 23:18:44 +0200223 bool noinsane = false;
Mark Sleee8540632006-05-30 09:24:40 +0000224
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900225 int return_code = 0;
226
Jake Farrell5d02b802014-01-07 21:42:01 -0500227 boost::program_options::options_description desc("Allowed options");
James E. King, III58402ff2017-11-17 14:41:46 -0500228 desc.add_options()
229 ("help,h", "produce help message")
James E. King, III39eaae62017-11-19 20:17:33 -0500230 ("host",
231 boost::program_options::value<string>(&host)->default_value(host),
James E. King, III58402ff2017-11-17 14:41:46 -0500232 "Host to connect")
James E. King, III39eaae62017-11-19 20:17:33 -0500233 ("port",
234 boost::program_options::value<int>(&port)->default_value(port),
James E. King, III58402ff2017-11-17 14:41:46 -0500235 "Port number to connect")
James E. King, III39eaae62017-11-19 20:17:33 -0500236 ("domain-socket",
James E. King, III58402ff2017-11-17 14:41:46 -0500237 boost::program_options::value<string>(&domain_socket)->default_value(domain_socket),
238 "Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port")
239 ("abstract-namespace",
240 "Look for the domain socket in the Abstract Namespace"
241 " (no connection with filesystem pathnames)")
242 ("transport",
243 boost::program_options::value<string>(&transport_type)->default_value(transport_type),
James E. King IIIb2b767e2018-09-15 20:32:04 +0000244 "Transport: buffered, framed, http, evhttp, zlib")
James E. King, III58402ff2017-11-17 14:41:46 -0500245 ("protocol",
246 boost::program_options::value<string>(&protocol_type)->default_value(protocol_type),
247 "Protocol: binary, compact, header, json, multi, multic, multih, multij")
James E. King, III39eaae62017-11-19 20:17:33 -0500248 ("ssl",
James E. King, III58402ff2017-11-17 14:41:46 -0500249 "Encrypted Transport using SSL")
James E. King IIIb2b767e2018-09-15 20:32:04 +0000250 ("zlib",
251 "Wrap Transport with Zlib")
James E. King, III58402ff2017-11-17 14:41:46 -0500252 ("testloops,n",
253 boost::program_options::value<int>(&numTests)->default_value(numTests),
254 "Number of Tests")
255 ("noinsane",
256 "Do not run insanity test");
Roger Meierca142b02011-06-07 17:59:07 +0000257
Jake Farrell5d02b802014-01-07 21:42:01 -0500258 boost::program_options::variables_map vm;
259 boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
260 boost::program_options::notify(vm);
Roger Meierca142b02011-06-07 17:59:07 +0000261
262 if (vm.count("help")) {
CJCombrink4a280d52024-03-14 19:57:41 +0100263 cout << desc << '\n';
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900264 return ERR_UNKNOWN;
Mark Sleee8540632006-05-30 09:24:40 +0000265 }
Mark Sleea3302652006-10-25 19:03:32 +0000266
Jake Farrell5d02b802014-01-07 21:42:01 -0500267 try {
Roger Meierca142b02011-06-07 17:59:07 +0000268 if (!protocol_type.empty()) {
269 if (protocol_type == "binary") {
Roger Meier284101c2014-03-11 21:20:35 +0100270 } else if (protocol_type == "compact") {
Dave Watson792db4e2015-01-16 11:22:01 -0800271 } else if (protocol_type == "header") {
Roger Meierca142b02011-06-07 17:59:07 +0000272 } else if (protocol_type == "json") {
James E. King, III58402ff2017-11-17 14:41:46 -0500273 } else if (protocol_type == "multi") {
274 } else if (protocol_type == "multic") {
275 } else if (protocol_type == "multih") {
276 } else if (protocol_type == "multij") {
Roger Meierca142b02011-06-07 17:59:07 +0000277 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100278 throw invalid_argument("Unknown protocol type " + protocol_type);
Roger Meierca142b02011-06-07 17:59:07 +0000279 }
280 }
281
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100282 if (!transport_type.empty()) {
Roger Meierca142b02011-06-07 17:59:07 +0000283 if (transport_type == "buffered") {
284 } else if (transport_type == "framed") {
285 } else if (transport_type == "http") {
Roger Meier7e056e72011-07-17 07:28:28 +0000286 } else if (transport_type == "evhttp") {
James E. King IIIb2b767e2018-09-15 20:32:04 +0000287 } else if (transport_type == "zlib") {
288 // crosstest will pass zlib as a transport and as a flag right now..
Roger Meierca142b02011-06-07 17:59:07 +0000289 } else {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100290 throw invalid_argument("Unknown transport type " + transport_type);
Roger Meierca142b02011-06-07 17:59:07 +0000291 }
292 }
293
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900294 } catch (exception& e) {
CJCombrink4a280d52024-03-14 19:57:41 +0100295 cerr << e.what() << '\n';
296 cout << desc << '\n';
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900297 return ERR_UNKNOWN;
Roger Meierca142b02011-06-07 17:59:07 +0000298 }
299
300 if (vm.count("ssl")) {
301 ssl = true;
302 }
cdwijayarathnaa07ec0b2014-08-09 17:45:56 +0530303
James E. King IIIb2b767e2018-09-15 20:32:04 +0000304 if (vm.count("zlib")) {
305 zlib = true;
306 }
307
pavlodd08f6e2015-10-08 16:43:56 -0400308 if (vm.count("abstract-namespace")) {
309 abstract_namespace = true;
310 }
311
Jens Geyerf4598682014-05-08 23:18:44 +0200312 if (vm.count("noinsane")) {
313 noinsane = true;
314 }
Roger Meierca142b02011-06-07 17:59:07 +0000315
James E. King, III7f5a8c22017-04-04 09:36:38 -0400316 // THRIFT-4164: The factory MUST outlive any sockets it creates for correct behavior!
cyy316723a2019-01-05 16:35:14 +0800317 std::shared_ptr<TSSLSocketFactory> factory;
318 std::shared_ptr<TSocket> socket;
319 std::shared_ptr<TTransport> transport;
320 std::shared_ptr<TProtocol> protocol;
321 std::shared_ptr<TProtocol> protocol2; // SecondService for multiplexed
Roger Meierca142b02011-06-07 17:59:07 +0000322
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000323 if (ssl) {
CJCombrink4a280d52024-03-14 19:57:41 +0100324 cout << "Client Certificate File: " << certPath << '\n';
325 cout << "Client Key File: " << keyPath << '\n';
326 cout << "CA File: " << caPath << '\n';
James E. King, III06190872017-02-20 08:52:11 -0500327
cyy316723a2019-01-05 16:35:14 +0800328 factory = std::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000329 factory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
James E. King, III06190872017-02-20 08:52:11 -0500330 factory->loadTrustedCertificates(caPath.c_str());
331 factory->loadCertificate(certPath.c_str());
332 factory->loadPrivateKey(keyPath.c_str());
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000333 factory->authenticate(true);
334 socket = factory->createSocket(host, port);
335 } else {
Roger Meierca142b02011-06-07 17:59:07 +0000336 if (domain_socket != "") {
pavlodd08f6e2015-10-08 16:43:56 -0400337 if (abstract_namespace) {
338 std::string abstract_socket("\0", 1);
339 abstract_socket += domain_socket;
cyy316723a2019-01-05 16:35:14 +0800340 socket = std::shared_ptr<TSocket>(new TSocket(abstract_socket));
pavlodd08f6e2015-10-08 16:43:56 -0400341 } else {
cyy316723a2019-01-05 16:35:14 +0800342 socket = std::shared_ptr<TSocket>(new TSocket(domain_socket));
pavlodd08f6e2015-10-08 16:43:56 -0400343 }
Roger Meierca142b02011-06-07 17:59:07 +0000344 port = 0;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100345 } else {
cyy316723a2019-01-05 16:35:14 +0800346 socket = std::shared_ptr<TSocket>(new TSocket(host, port));
Roger Meierca142b02011-06-07 17:59:07 +0000347 }
Bryan Duxburycd9aea12011-02-22 18:12:06 +0000348 }
Mark Sleea3302652006-10-25 19:03:32 +0000349
Roger Meierca142b02011-06-07 17:59:07 +0000350 if (transport_type.compare("http") == 0) {
cyy316723a2019-01-05 16:35:14 +0800351 transport = std::make_shared<THttpClient>(socket, host, "/service");
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100352 } else if (transport_type.compare("framed") == 0) {
cyy316723a2019-01-05 16:35:14 +0800353 transport = std::make_shared<TFramedTransport>(socket);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100354 } else {
cyy316723a2019-01-05 16:35:14 +0800355 transport = std::make_shared<TBufferedTransport>(socket);
James E. King IIIb2b767e2018-09-15 20:32:04 +0000356 }
357
358 if (zlib) {
cyy316723a2019-01-05 16:35:14 +0800359 transport = std::make_shared<TZlibTransport>(transport);
Mark Sleea3302652006-10-25 19:03:32 +0000360 }
361
James E. King, III58402ff2017-11-17 14:41:46 -0500362 if (protocol_type == "json" || protocol_type == "multij") {
James E. King IIIf95620d2019-01-28 18:15:13 -0500363 typedef TPedanticProtocol<TJSONProtocol> TPedanticJSONProtocol;
364 protocol = std::make_shared<TPedanticJSONProtocol>(transport);
James E. King, III58402ff2017-11-17 14:41:46 -0500365 } else if (protocol_type == "compact" || protocol_type == "multic") {
James E. King IIIf95620d2019-01-28 18:15:13 -0500366 typedef TPedanticProtocol<TCompactProtocol> TPedanticCompactProtocol;
367 protocol = std::make_shared<TPedanticCompactProtocol>(transport);
James E. King, III58402ff2017-11-17 14:41:46 -0500368 } else if (protocol_type == "header" || protocol_type == "multih") {
James E. King IIIf95620d2019-01-28 18:15:13 -0500369 typedef TPedanticProtocol<THeaderProtocol> TPedanticHeaderProtocol;
370 protocol = std::make_shared<TPedanticHeaderProtocol>(transport);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100371 } else {
James E. King IIIf95620d2019-01-28 18:15:13 -0500372 typedef TPedanticProtocol<TBinaryProtocol> TPedanticBinaryProtocol;
373 protocol = std::make_shared<TPedanticBinaryProtocol>(transport);
James E. King, III58402ff2017-11-17 14:41:46 -0500374 }
375
376 if (boost::starts_with(protocol_type, "multi")) {
James E. King IIIf95620d2019-01-28 18:15:13 -0500377 protocol2 = std::make_shared<TMultiplexedProtocol>(protocol, "SecondService");
378 // we don't need access to the original protocol any more, so...
379 protocol = std::make_shared<TMultiplexedProtocol>(protocol, "ThriftTest");
Roger Meierca142b02011-06-07 17:59:07 +0000380 }
381
382 // Connection info
pavlodd08f6e2015-10-08 16:43:56 -0400383 cout << "Connecting (" << transport_type << "/" << protocol_type << ") to: ";
384 if (abstract_namespace) {
385 cout << '@';
386 }
387 cout << domain_socket;
Roger Meierca142b02011-06-07 17:59:07 +0000388 if (port != 0) {
389 cout << host << ":" << port;
390 }
CJCombrink4a280d52024-03-14 19:57:41 +0100391 cout << '\n';
Roger Meierca142b02011-06-07 17:59:07 +0000392
Roger Meier7e056e72011-07-17 07:28:28 +0000393 if (transport_type.compare("evhttp") == 0) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100394 event_base* base = event_base_new();
CJCombrink4a280d52024-03-14 19:57:41 +0100395 cout << "Libevent Version: " << event_get_version() << '\n';
396 cout << "Libevent Method: " << event_base_get_method(base) << '\n';
Roger Meier7e056e72011-07-17 07:28:28 +0000397#if LIBEVENT_VERSION_NUMBER >= 0x02000000
CJCombrink4a280d52024-03-14 19:57:41 +0100398 cout << "Libevent Features: 0x" << hex << event_base_get_features(base) << '\n';
Roger Meier7e056e72011-07-17 07:28:28 +0000399#endif
400
cyy316723a2019-01-05 16:35:14 +0800401 std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
Roger Meier7e056e72011-07-17 07:28:28 +0000402
cyy316723a2019-01-05 16:35:14 +0800403 std::shared_ptr<TAsyncChannel> channel(
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100404 new TEvhttpClientChannel(host.c_str(), "/", host.c_str(), port, base));
Roger Meier7e056e72011-07-17 07:28:28 +0000405 ThriftTestCobClient* client = new ThriftTestCobClient(channel, protocolFactory.get());
cyy316723a2019-01-05 16:35:14 +0800406 client->testVoid(std::bind(testVoid_clientReturn,
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100407 base,
cyy316723a2019-01-05 16:35:14 +0800408 std::placeholders::_1));
Jake Farrell5d02b802014-01-07 21:42:01 -0500409
Roger Meier7e056e72011-07-17 07:28:28 +0000410 event_base_loop(base, 0);
411 return 0;
412 }
413
Roger Meierca142b02011-06-07 17:59:07 +0000414 ThriftTestClient testClient(protocol);
Mark Sleed788b2e2006-09-07 01:26:35 +0000415
416 uint64_t time_min = 0;
417 uint64_t time_max = 0;
418 uint64_t time_tot = 0;
David Reiss0c90f6f2008-02-06 22:18:40 +0000419
Mark Sleee8540632006-05-30 09:24:40 +0000420 int test = 0;
421 for (test = 0; test < numTests; ++test) {
Mark Slee95771002006-06-07 06:53:25 +0000422
Mark Slee95771002006-06-07 06:53:25 +0000423 try {
Mark Sleea3302652006-10-25 19:03:32 +0000424 transport->open();
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900425 } catch (TTransportException& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100426 cout << "Connect failed: " << ex.what() << '\n';
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900427 return ERR_UNKNOWN;
Mark Sleee8540632006-05-30 09:24:40 +0000428 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000429
Mark Sleed788b2e2006-09-07 01:26:35 +0000430 /**
431 * CONNECT TEST
432 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100433 printf("Test #%d, connect %s:%d\n", test + 1, host.c_str(), port);
Mark Slee95771002006-06-07 06:53:25 +0000434
435 uint64_t start = now();
David Reiss0c90f6f2008-02-06 22:18:40 +0000436
Mark Sleee8540632006-05-30 09:24:40 +0000437 /**
438 * VOID TEST
439 */
Mark Sleee129a2d2007-02-21 05:17:48 +0000440 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900441 cout << "testVoid()" << flush;
Mark Sleee129a2d2007-02-21 05:17:48 +0000442 testClient.testVoid();
CJCombrink4a280d52024-03-14 19:57:41 +0100443 cout << " = void" << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900444 } catch (TTransportException&) {
445 // Stop here if transport got broken
446 throw;
447 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100448 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200449 return_code |= ERR_BASETYPES;
Mark Sleee129a2d2007-02-21 05:17:48 +0000450 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000451
Mark Sleee8540632006-05-30 09:24:40 +0000452 /**
453 * STRING TEST
454 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900455 cout << "testString(\"Test\")" << flush;
Mark Slee1921d202007-01-24 19:43:06 +0000456 string s;
457 testClient.testString(s, "Test");
CJCombrink4a280d52024-03-14 19:57:41 +0100458 cout << " = " << s << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200459 if (s != "Test") {
CJCombrink4a280d52024-03-14 19:57:41 +0100460 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200461 return_code |= ERR_BASETYPES;
462 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000463
James E. King, III58402ff2017-11-17 14:41:46 -0500464 //
465 // Multiplexed protocol - call another service method
466 // in the middle of the ThriftTest
467 //
468 if (boost::starts_with(protocol_type, "multi")) {
James E. King, III39eaae62017-11-19 20:17:33 -0500469 SecondServiceClient ssc(protocol2);
470 // transport is already open...
471
James E. King, III58402ff2017-11-17 14:41:46 -0500472 try {
473 cout << "secondService.secondTestString(\"foo\") => " << flush;
James E. King, III39eaae62017-11-19 20:17:33 -0500474 std::string result;
475 ssc.secondtestString(result, "foo");
CJCombrink4a280d52024-03-14 19:57:41 +0100476 cout << "{" << result << "}" << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -0500477 } catch (std::exception& e) {
CJCombrink4a280d52024-03-14 19:57:41 +0100478 cout << " *** FAILED *** " << e.what() << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -0500479 return_code |= ERR_EXCEPTIONS;
480 }
James E. King, III58402ff2017-11-17 14:41:46 -0500481 }
482
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900483 try {
James E. King, III7edc8fa2017-01-20 10:11:41 -0500484#ifdef _MSC_VER
485#pragma warning( push )
486#pragma warning( disable : 4566 )
487#endif
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900488 string str(
489 "}{Afrikaans, Alemannisch, Aragonés, العربية, مصرى, "
490 "Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, "
491 "Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, "
492 "বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, "
493 "Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, "
494 "Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, "
495 "Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, "
496 "Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, "
497 "Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski, "
498 "Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia, "
499 "Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa, "
500 "ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар, "
501 "Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, "
502 "Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa "
503 "Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, مازِرونی, Bahasa "
504 "Melayu, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, ‪"
505 "Norsk (nynorsk)‬, ‪Norsk (bokmål)‬, Nouormand, Diné bizaad, "
506 "Occitan, Иронау, Papiamentu, Deitsch, Polski, پنجابی, پښتو, "
507 "Norfuk / Pitkern, Português, Runa Simi, Rumantsch, Romani, Română, "
508 "Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple "
509 "English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk, "
510 "Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog, "
511 "Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük, "
512 "Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, "
513 "Bân-lâm-gú, 粵語");
James E. King, III7edc8fa2017-01-20 10:11:41 -0500514#ifdef _MSC_VER
515#pragma warning( pop )
516#endif
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900517 cout << "testString(" << str << ") = " << flush;
518 testClient.testString(s, str);
CJCombrink4a280d52024-03-14 19:57:41 +0100519 cout << s << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900520 if (s != str) {
521 cout.imbue(locale("en_US.UTF8"));
CJCombrink4a280d52024-03-14 19:57:41 +0100522 cout << "*** FAILED ***" << '\n' << "Expected string: " << str << " but got: " << s << '\n' << "CLEAR";
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900523 return_code |= ERR_BASETYPES;
524 }
525 } catch (TTransportException&) {
526 throw;
527 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100528 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900529 return_code |= ERR_BASETYPES;
530 return return_code;
531 }
532 try {
533 string str(
534 "quote: \" backslash:"
535 " forwardslash-escaped: \\/ "
536 " backspace: \b formfeed: \f newline: \n return: \r tab: "
537 " now-all-of-them-together: \"\\\\/\b\n\r\t"
538 " now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><"
539 " char-to-test-json-parsing: ]] \"]] \\\" }}}{ [[[ ");
540 cout << "testString(" << str << ") = " << flush;
541 testClient.testString(s, str);
CJCombrink4a280d52024-03-14 19:57:41 +0100542 cout << s << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900543 if (s != str) {
544 cout.imbue(locale("en_US.UTF8"));
CJCombrink4a280d52024-03-14 19:57:41 +0100545 cout << "*** FAILED ***" << '\n'
546 << "Expected string: " << str << " but got: " << s << '\n'
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900547 << "CLEAR";
548 ;
549 return_code |= ERR_BASETYPES;
550 }
551 } catch (TTransportException&) {
552 throw;
553 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100554 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900555 return_code |= ERR_BASETYPES;
556 return return_code;
557 }
558
Mark Sleee8540632006-05-30 09:24:40 +0000559 /**
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900560 * BOOL TEST
561 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900562 cout << boolalpha;
563 BASETYPE_IDENTITY_TEST(testBool, true);
564 BASETYPE_IDENTITY_TEST(testBool, false);
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900565
566 /**
Mark Sleee8540632006-05-30 09:24:40 +0000567 * BYTE TEST
568 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900569 BASETYPE_IDENTITY_TEST(testByte, (int8_t)0);
570 BASETYPE_IDENTITY_TEST(testByte, (int8_t)-1);
571 BASETYPE_IDENTITY_TEST(testByte, (int8_t)42);
572 BASETYPE_IDENTITY_TEST(testByte, (int8_t)-42);
573 BASETYPE_IDENTITY_TEST(testByte, (int8_t)127);
574 BASETYPE_IDENTITY_TEST(testByte, (int8_t)-128);
David Reiss0c90f6f2008-02-06 22:18:40 +0000575
Mark Sleee8540632006-05-30 09:24:40 +0000576 /**
577 * I32 TEST
578 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900579 BASETYPE_IDENTITY_TEST(testI32, 0);
580 BASETYPE_IDENTITY_TEST(testI32, -1);
581 BASETYPE_IDENTITY_TEST(testI32, 190000013);
582 BASETYPE_IDENTITY_TEST(testI32, -190000013);
James E. King III9b75e4f2018-12-17 16:21:14 -0500583 BASETYPE_IDENTITY_TEST(testI32, (numeric_limits<int32_t>::max)());
584 BASETYPE_IDENTITY_TEST(testI32, (numeric_limits<int32_t>::min)());
Mark Sleee8540632006-05-30 09:24:40 +0000585
586 /**
Mark Sleee8540632006-05-30 09:24:40 +0000587 * I64 TEST
588 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900589 BASETYPE_IDENTITY_TEST(testI64, (int64_t)0);
590 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-1);
591 BASETYPE_IDENTITY_TEST(testI64, (int64_t)7000000000000000123LL);
592 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-7000000000000000123LL);
James E. King, III7edc8fa2017-01-20 10:11:41 -0500593 BASETYPE_IDENTITY_TEST(testI64, (int64_t)pow(static_cast<double>(2LL), 32));
594 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-pow(static_cast<double>(2LL), 32));
595 BASETYPE_IDENTITY_TEST(testI64, (int64_t)pow(static_cast<double>(2LL), 32) + 1);
596 BASETYPE_IDENTITY_TEST(testI64, (int64_t)-pow(static_cast<double>(2LL), 32) - 1);
James E. King III9b75e4f2018-12-17 16:21:14 -0500597 BASETYPE_IDENTITY_TEST(testI64, (numeric_limits<int64_t>::max)());
598 BASETYPE_IDENTITY_TEST(testI64, (numeric_limits<int64_t>::min)());
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100599
Mark Sleec98d0502006-09-06 02:42:25 +0000600 /**
601 * DOUBLE TEST
602 */
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900603 // Comparing double values with plain equality because Thrift handles full precision of double
604 BASETYPE_IDENTITY_TEST(testDouble, 0.0);
605 BASETYPE_IDENTITY_TEST(testDouble, -1.0);
606 BASETYPE_IDENTITY_TEST(testDouble, -5.2098523);
607 BASETYPE_IDENTITY_TEST(testDouble, -0.000341012439638598279);
James E. King, III7edc8fa2017-01-20 10:11:41 -0500608 BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast<double>(2), 32));
609 BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast<double>(2), 32) + 1);
610 BASETYPE_IDENTITY_TEST(testDouble, pow(static_cast<double>(2), 53) - 1);
611 BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast<double>(2), 32));
612 BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast<double>(2), 32) - 1);
613 BASETYPE_IDENTITY_TEST(testDouble, -pow(static_cast<double>(2), 53) + 1);
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900614
615 try {
James E. King, III7edc8fa2017-01-20 10:11:41 -0500616 double expected = pow(static_cast<double>(10), 307);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900617 cout << "testDouble(" << expected << ") = " << flush;
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900618 double actual = testClient.testDouble(expected);
CJCombrink4a280d52024-03-14 19:57:41 +0100619 cout << "(" << actual << ")" << '\n';
James E. King, III7edc8fa2017-01-20 10:11:41 -0500620 if (expected - actual > pow(static_cast<double>(10), 292)) {
CJCombrink4a280d52024-03-14 19:57:41 +0100621 cout << "*** FAILED ***" << '\n'
622 << "Expected: " << expected << " but got: " << actual << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900623 }
624 } catch (TTransportException&) {
625 throw;
626 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100627 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900628 return_code |= ERR_BASETYPES;
629 }
630
631 try {
James E. King, III7edc8fa2017-01-20 10:11:41 -0500632 double expected = pow(static_cast<double>(10), -292);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900633 cout << "testDouble(" << expected << ") = " << flush;
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900634 double actual = testClient.testDouble(expected);
CJCombrink4a280d52024-03-14 19:57:41 +0100635 cout << "(" << actual << ")" << '\n';
James E. King, III7edc8fa2017-01-20 10:11:41 -0500636 if (expected - actual > pow(static_cast<double>(10), -307)) {
CJCombrink4a280d52024-03-14 19:57:41 +0100637 cout << "*** FAILED ***" << '\n'
638 << "Expected: " << expected << " but got: " << actual << '\n';
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900639 }
640 } catch (TTransportException&) {
641 throw;
642 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100643 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200644 return_code |= ERR_BASETYPES;
645 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000646
Mark Sleee8540632006-05-30 09:24:40 +0000647 /**
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100648 * BINARY TEST
649 */
James E. King, III39eaae62017-11-19 20:17:33 -0500650 for (string::size_type i = 0; i < 131073 && !return_code; ) {
651 return_code |= binary_test(testClient, i);
652 if (i > 0) { i *= 2; } else { ++i; }
Jens Geyerd629ea02015-09-23 21:16:50 +0200653 }
654
CJCombrink1d886ca2024-03-23 21:32:28 +0100655 /**
656 * UUID TEST
657 */
CJCombrink4b909092024-04-27 19:51:39 +0200658 const TUuid expected_uuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"};
659 UUID_TEST(testUuid, TUuid{"{5e2ab188-1726-4e75-a04f-1ed9a6a89c4c}"}, expected_uuid);
660 UUID_TEST(testUuid, TUuid{"5e2ab188-1726-4e75-a04f-1ed9a6a89c4c"}, expected_uuid);
661 UUID_TEST(testUuid, TUuid{"5e2ab18817264e75a04f1ed9a6a89c4c"}, expected_uuid);
662 UUID_TEST(testUuid, TUuid{"{5e2ab18817264e75a04f1ed9a6a89c4c}"}, expected_uuid);
663 UUID_TEST(testUuid, TUuid{}, TUuid{"00000000-0000-0000-0000-000000000000"});
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100664
665 /**
Mark Sleee8540632006-05-30 09:24:40 +0000666 * STRUCT TEST
667 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900668 cout << "testStruct({\"Zero\", 1, -3, -5})" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000669 Xtruct out;
670 out.string_thing = "Zero";
671 out.byte_thing = 1;
Mark Sleee8540632006-05-30 09:24:40 +0000672 out.i32_thing = -3;
Mark Sleee8540632006-05-30 09:24:40 +0000673 out.i64_thing = -5;
Mark Slee1921d202007-01-24 19:43:06 +0000674 Xtruct in;
675 testClient.testStruct(in, out);
Roger Meier0e814802014-01-17 21:07:58 +0100676 printf(" = {\"%s\", %d, %d, %" PRId64 "}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000677 in.string_thing.c_str(),
678 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000679 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000680 in.i64_thing);
Jens Geyerd629ea02015-09-23 21:16:50 +0200681 if (in != out) {
CJCombrink4a280d52024-03-14 19:57:41 +0100682 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200683 return_code |= ERR_STRUCTS;
684 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000685
Mark Sleee8540632006-05-30 09:24:40 +0000686 /**
687 * NESTED STRUCT TEST
688 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900689 cout << "testNest({1, {\"Zero\", 1, -3, -5}), 5}" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000690 Xtruct2 out2;
691 out2.byte_thing = 1;
692 out2.struct_thing = out;
693 out2.i32_thing = 5;
Mark Slee1921d202007-01-24 19:43:06 +0000694 Xtruct2 in2;
695 testClient.testNest(in2, out2);
Mark Sleee8540632006-05-30 09:24:40 +0000696 in = in2.struct_thing;
Roger Meier0e814802014-01-17 21:07:58 +0100697 printf(" = {%d, {\"%s\", %d, %d, %" PRId64 "}, %d}\n",
Mark Sleee8540632006-05-30 09:24:40 +0000698 in2.byte_thing,
699 in.string_thing.c_str(),
700 (int)in.byte_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000701 in.i32_thing,
Mark Sleee8540632006-05-30 09:24:40 +0000702 in.i64_thing,
David Reiss0c90f6f2008-02-06 22:18:40 +0000703 in2.i32_thing);
Jens Geyerd629ea02015-09-23 21:16:50 +0200704 if (in2 != out2) {
CJCombrink4a280d52024-03-14 19:57:41 +0100705 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200706 return_code |= ERR_STRUCTS;
707 }
Mark Sleee8540632006-05-30 09:24:40 +0000708
709 /**
710 * MAP TEST
711 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100712 map<int32_t, int32_t> mapout;
Mark Sleee8540632006-05-30 09:24:40 +0000713 for (int32_t i = 0; i < 5; ++i) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100714 mapout.insert(make_pair(i, i - 10));
Mark Sleee8540632006-05-30 09:24:40 +0000715 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900716 cout << "testMap({" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000717 map<int32_t, int32_t>::const_iterator m_iter;
718 bool first = true;
719 for (m_iter = mapout.begin(); m_iter != mapout.end(); ++m_iter) {
720 if (first) {
721 first = false;
722 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900723 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000724 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900725 cout << m_iter->first << " => " << m_iter->second;
Mark Sleee8540632006-05-30 09:24:40 +0000726 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900727 cout << "})";
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100728 map<int32_t, int32_t> mapin;
Mark Slee1921d202007-01-24 19:43:06 +0000729 testClient.testMap(mapin, mapout);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900730 cout << " = {";
Mark Sleee8540632006-05-30 09:24:40 +0000731 first = true;
732 for (m_iter = mapin.begin(); m_iter != mapin.end(); ++m_iter) {
733 if (first) {
734 first = false;
735 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900736 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000737 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900738 cout << m_iter->first << " => " << m_iter->second;
Mark Sleee8540632006-05-30 09:24:40 +0000739 }
CJCombrink4a280d52024-03-14 19:57:41 +0100740 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200741 if (mapin != mapout) {
CJCombrink4a280d52024-03-14 19:57:41 +0100742 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200743 return_code |= ERR_CONTAINERS;
744 }
Roger Meier4fce9602012-05-04 06:22:09 +0000745
746 /**
747 * STRING MAP TEST
Roger Meier4fce9602012-05-04 06:22:09 +0000748 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900749 cout << "testStringMap({a => 2, b => blah, some => thing}) = {" << flush;
Jens Geyerd629ea02015-09-23 21:16:50 +0200750 map<string, string> smapin;
751 map<string, string> smapout;
752 smapin["a"] = "2";
753 smapin["b"] = "blah";
754 smapin["some"] = "thing";
755 try {
756 testClient.testStringMap(smapout, smapin);
757 first = true;
758 for (map<string, string>::const_iterator it = smapout.begin(); it != smapout.end(); ++it) {
759 if (first)
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900760 cout << ",";
Jens Geyerd629ea02015-09-23 21:16:50 +0200761 else
762 first = false;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900763 cout << it->first << " => " << it->second;
Jens Geyerd629ea02015-09-23 21:16:50 +0200764 }
CJCombrink4a280d52024-03-14 19:57:41 +0100765 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200766 if (smapin != smapout) {
CJCombrink4a280d52024-03-14 19:57:41 +0100767 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200768 return_code |= ERR_CONTAINERS;
769 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900770 } catch (TTransportException&) {
771 throw;
Jens Geyerd629ea02015-09-23 21:16:50 +0200772 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100773 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200774 return_code |= ERR_CONTAINERS;
775 }
Mark Sleee8540632006-05-30 09:24:40 +0000776
777 /**
778 * SET TEST
779 */
780 set<int32_t> setout;
781 for (int32_t i = -2; i < 3; ++i) {
782 setout.insert(i);
783 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900784 cout << "testSet({" << flush;
Mark Sleee8540632006-05-30 09:24:40 +0000785 set<int32_t>::const_iterator s_iter;
786 first = true;
787 for (s_iter = setout.begin(); s_iter != setout.end(); ++s_iter) {
788 if (first) {
789 first = false;
790 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900791 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000792 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900793 cout << *s_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000794 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900795 cout << "})";
Mark Slee1921d202007-01-24 19:43:06 +0000796 set<int32_t> setin;
797 testClient.testSet(setin, setout);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900798 cout << " = {";
Mark Sleee8540632006-05-30 09:24:40 +0000799 first = true;
800 for (s_iter = setin.begin(); s_iter != setin.end(); ++s_iter) {
801 if (first) {
802 first = false;
803 } else {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900804 cout << ",";
Mark Sleee8540632006-05-30 09:24:40 +0000805 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900806 cout << *s_iter;
Mark Sleee8540632006-05-30 09:24:40 +0000807 }
CJCombrink4a280d52024-03-14 19:57:41 +0100808 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200809 if (setin != setout) {
CJCombrink4a280d52024-03-14 19:57:41 +0100810 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200811 return_code |= ERR_CONTAINERS;
812 }
Mark Sleee8540632006-05-30 09:24:40 +0000813
814 /**
815 * LIST TEST
816 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900817 cout << "testList(empty)" << flush;
818 try {
819 vector<int32_t> listout;
820 testClient.testList(listout, vector<int32_t>());
821 if (!listout.empty()) {
CJCombrink4a280d52024-03-14 19:57:41 +0100822 cout << "*** FAILED ***" << '\n';
823 cout << "invalid length: " << listout.size() << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900824 return_code |= ERR_CONTAINERS;
Mark Sleee8540632006-05-30 09:24:40 +0000825 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900826 } catch (TTransportException&) {
827 throw;
828 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100829 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900830 return_code |= ERR_CONTAINERS;
Mark Sleee8540632006-05-30 09:24:40 +0000831 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900832 try {
833 vector<int32_t> listout;
834 for (int32_t i = -2; i < 3; ++i) {
835 listout.push_back(i);
Mark Sleee8540632006-05-30 09:24:40 +0000836 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900837 cout << "testList({" << flush;
838 vector<int32_t>::const_iterator l_iter;
839 first = true;
840 for (l_iter = listout.begin(); l_iter != listout.end(); ++l_iter) {
841 if (first) {
842 first = false;
843 } else {
844 cout << ",";
845 }
846 cout << *l_iter;
847 }
848 cout << "})";
849 vector<int32_t> listin;
850 testClient.testList(listin, listout);
851 cout << " = {";
852 first = true;
853 for (l_iter = listin.begin(); l_iter != listin.end(); ++l_iter) {
854 if (first) {
855 first = false;
856 } else {
857 cout << ",";
858 }
859 cout << *l_iter;
860 }
CJCombrink4a280d52024-03-14 19:57:41 +0100861 cout << "}" << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900862 if (listin != listout) {
CJCombrink4a280d52024-03-14 19:57:41 +0100863 cout << "*** FAILED ***" << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900864 return_code |= ERR_CONTAINERS;
865 }
866 } catch (TTransportException&) {
867 throw;
868 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +0100869 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200870 return_code |= ERR_CONTAINERS;
871 }
Mark Sleee8540632006-05-30 09:24:40 +0000872
873 /**
874 * ENUM TEST
875 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900876 cout << "testEnum(ONE)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000877 Numberz::type ret = testClient.testEnum(Numberz::ONE);
CJCombrink4a280d52024-03-14 19:57:41 +0100878 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200879 if (ret != Numberz::ONE) {
CJCombrink4a280d52024-03-14 19:57:41 +0100880 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200881 return_code |= ERR_STRUCTS;
882 }
Mark Sleee8540632006-05-30 09:24:40 +0000883
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900884 cout << "testEnum(TWO)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000885 ret = testClient.testEnum(Numberz::TWO);
CJCombrink4a280d52024-03-14 19:57:41 +0100886 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200887 if (ret != Numberz::TWO) {
CJCombrink4a280d52024-03-14 19:57:41 +0100888 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200889 return_code |= ERR_STRUCTS;
890 }
Mark Sleee8540632006-05-30 09:24:40 +0000891
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900892 cout << "testEnum(THREE)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000893 ret = testClient.testEnum(Numberz::THREE);
CJCombrink4a280d52024-03-14 19:57:41 +0100894 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200895 if (ret != Numberz::THREE) {
CJCombrink4a280d52024-03-14 19:57:41 +0100896 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200897 return_code |= ERR_STRUCTS;
898 }
Mark Sleee8540632006-05-30 09:24:40 +0000899
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900900 cout << "testEnum(FIVE)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000901 ret = testClient.testEnum(Numberz::FIVE);
CJCombrink4a280d52024-03-14 19:57:41 +0100902 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200903 if (ret != Numberz::FIVE) {
CJCombrink4a280d52024-03-14 19:57:41 +0100904 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200905 return_code |= ERR_STRUCTS;
906 }
Mark Sleee8540632006-05-30 09:24:40 +0000907
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900908 cout << "testEnum(EIGHT)" << flush;
Bryan Duxbury833ae492010-09-27 17:26:02 +0000909 ret = testClient.testEnum(Numberz::EIGHT);
CJCombrink4a280d52024-03-14 19:57:41 +0100910 cout << " = " << ret << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200911 if (ret != Numberz::EIGHT) {
CJCombrink4a280d52024-03-14 19:57:41 +0100912 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200913 return_code |= ERR_STRUCTS;
914 }
Mark Sleee8540632006-05-30 09:24:40 +0000915
916 /**
917 * TYPEDEF TEST
918 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900919 cout << "testTypedef(309858235082523)" << flush;
Marc Slemkobf4fd192006-08-15 21:29:39 +0000920 UserId uid = testClient.testTypedef(309858235082523LL);
CJCombrink4a280d52024-03-14 19:57:41 +0100921 cout << " = " << uid << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200922 if (uid != 309858235082523LL) {
CJCombrink4a280d52024-03-14 19:57:41 +0100923 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200924 return_code |= ERR_STRUCTS;
925 }
Mark Sleee8540632006-05-30 09:24:40 +0000926
927 /**
928 * NESTED MAP TEST
929 */
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900930 cout << "testMapMap(1)" << flush;
Mark Slee1921d202007-01-24 19:43:06 +0000931 map<int32_t, map<int32_t, int32_t> > mm;
932 testClient.testMapMap(mm, 1);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900933 cout << " = {";
Mark Sleee8540632006-05-30 09:24:40 +0000934 map<int32_t, map<int32_t, int32_t> >::const_iterator mi;
935 for (mi = mm.begin(); mi != mm.end(); ++mi) {
936 printf("%d => {", mi->first);
937 map<int32_t, int32_t>::const_iterator mi2;
938 for (mi2 = mi->second.begin(); mi2 != mi->second.end(); ++mi2) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900939 cout << mi2->first << " => " << mi2->second;
Mark Sleee8540632006-05-30 09:24:40 +0000940 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900941 cout << "}, ";
Mark Sleee8540632006-05-30 09:24:40 +0000942 }
CJCombrink4a280d52024-03-14 19:57:41 +0100943 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200944 if (mm.size() != 2 ||
945 mm[-4][-4] != -4 ||
946 mm[-4][-3] != -3 ||
947 mm[-4][-2] != -2 ||
948 mm[-4][-1] != -1 ||
949 mm[4][4] != 4 ||
950 mm[4][3] != 3 ||
951 mm[4][2] != 2 ||
952 mm[4][1] != 1) {
CJCombrink4a280d52024-03-14 19:57:41 +0100953 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +0200954 return_code |= ERR_CONTAINERS;
955 }
Mark Sleee8540632006-05-30 09:24:40 +0000956
957 /**
958 * INSANITY TEST
959 */
Jens Geyerf4598682014-05-08 23:18:44 +0200960 if (!noinsane) {
961 Insanity insane;
Jens Geyerd629ea02015-09-23 21:16:50 +0200962 insane.userMap.insert(make_pair(Numberz::FIVE, 5));
963 insane.userMap.insert(make_pair(Numberz::EIGHT, 8));
Jens Geyerf4598682014-05-08 23:18:44 +0200964 Xtruct truck;
Jens Geyerd629ea02015-09-23 21:16:50 +0200965 truck.string_thing = "Goodbye4";
966 truck.byte_thing = 4;
967 truck.i32_thing = 4;
968 truck.i64_thing = 4;
969 Xtruct truck2;
970 truck2.string_thing = "Hello2";
971 truck2.byte_thing = 2;
972 truck2.i32_thing = 2;
973 truck2.i64_thing = 2;
Jens Geyerf4598682014-05-08 23:18:44 +0200974 insane.xtructs.push_back(truck);
Jens Geyerd629ea02015-09-23 21:16:50 +0200975 insane.xtructs.push_back(truck2);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900976 cout << "testInsanity()" << flush;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100977 map<UserId, map<Numberz::type, Insanity> > whoa;
Jens Geyerf4598682014-05-08 23:18:44 +0200978 testClient.testInsanity(whoa, insane);
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900979 cout << " = {";
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100980 map<UserId, map<Numberz::type, Insanity> >::const_iterator i_iter;
Jens Geyerf4598682014-05-08 23:18:44 +0200981 for (i_iter = whoa.begin(); i_iter != whoa.end(); ++i_iter) {
982 printf("%" PRId64 " => {", i_iter->first);
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100983 map<Numberz::type, Insanity>::const_iterator i2_iter;
984 for (i2_iter = i_iter->second.begin(); i2_iter != i_iter->second.end(); ++i2_iter) {
Jens Geyerf4598682014-05-08 23:18:44 +0200985 printf("%d => {", i2_iter->first);
986 map<Numberz::type, UserId> userMap = i2_iter->second.userMap;
987 map<Numberz::type, UserId>::const_iterator um;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900988 cout << "{";
Jens Geyerf4598682014-05-08 23:18:44 +0200989 for (um = userMap.begin(); um != userMap.end(); ++um) {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900990 cout << um->first << " => " << um->second;
Jens Geyerf4598682014-05-08 23:18:44 +0200991 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900992 cout << "}, ";
Mark Sleee8540632006-05-30 09:24:40 +0000993
Jens Geyerf4598682014-05-08 23:18:44 +0200994 vector<Xtruct> xtructs = i2_iter->second.xtructs;
995 vector<Xtruct>::const_iterator x;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +0900996 cout << "{";
Jens Geyerf4598682014-05-08 23:18:44 +0200997 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
998 printf("{\"%s\", %d, %d, %" PRId64 "}, ",
999 x->string_thing.c_str(),
1000 (int)x->byte_thing,
1001 x->i32_thing,
1002 x->i64_thing);
1003 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001004 cout << "}";
Mark Sleee8540632006-05-30 09:24:40 +00001005
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001006 cout << "}, ";
Jens Geyerf4598682014-05-08 23:18:44 +02001007 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001008 cout << "}, ";
Mark Sleee8540632006-05-30 09:24:40 +00001009 }
CJCombrink4a280d52024-03-14 19:57:41 +01001010 cout << "}" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001011 bool failed = false;
1012 map<UserId, map<Numberz::type, Insanity> >::const_iterator it1 = whoa.find(UserId(1));
1013 if (whoa.size() != 2) {
1014 failed = true;
1015 }
1016 if (it1 == whoa.end()) {
1017 failed = true;
1018 } else {
Sebastian Zenker042580f2019-01-29 15:48:12 +01001019 auto it12 = it1->second.find(Numberz::TWO);
Jens Geyerd629ea02015-09-23 21:16:50 +02001020 if (it12 == it1->second.end() || it12->second != insane) {
1021 failed = true;
1022 }
Sebastian Zenker042580f2019-01-29 15:48:12 +01001023 auto it13 = it1->second.find(Numberz::THREE);
Jens Geyerd629ea02015-09-23 21:16:50 +02001024 if (it13 == it1->second.end() || it13->second != insane) {
1025 failed = true;
1026 }
1027 }
1028 map<UserId, map<Numberz::type, Insanity> >::const_iterator it2 = whoa.find(UserId(2));
1029 if (it2 == whoa.end()) {
1030 failed = true;
1031 } else {
Sebastian Zenker042580f2019-01-29 15:48:12 +01001032 auto it26 = it2->second.find(Numberz::SIX);
James E. King IIIf5f430d2018-06-08 03:37:55 +00001033 if (it26 == it2->second.end() || it26->second != Insanity()) {
Jens Geyerd629ea02015-09-23 21:16:50 +02001034 failed = true;
1035 }
1036 }
1037 if (failed) {
CJCombrink4a280d52024-03-14 19:57:41 +01001038 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001039 return_code |= ERR_STRUCTS;
1040 }
Mark Sleee8540632006-05-30 09:24:40 +00001041 }
Jens Geyerd629ea02015-09-23 21:16:50 +02001042
1043 /**
1044 * MULTI TEST
1045 */
CJCombrink4a280d52024-03-14 19:57:41 +01001046 cout << "testMulti()" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001047 try {
1048 map<int16_t, string> mul_map;
1049 Xtruct mul_result;
1050 mul_map[1] = "blah";
1051 mul_map[2] = "thing";
1052 testClient.testMulti(mul_result, 42, 4242, 424242, mul_map, Numberz::EIGHT, UserId(24));
1053 Xtruct xxs;
1054 xxs.string_thing = "Hello2";
1055 xxs.byte_thing = 42;
1056 xxs.i32_thing = 4242;
1057 xxs.i64_thing = 424242;
1058 if (mul_result != xxs) {
CJCombrink4a280d52024-03-14 19:57:41 +01001059 cout << "*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001060 return_code |= ERR_STRUCTS;
1061 }
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001062 } catch (TTransportException&) {
1063 throw;
Jens Geyerd629ea02015-09-23 21:16:50 +02001064 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +01001065 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001066 return_code |= ERR_STRUCTS;
1067 }
1068
Marc Slemko71d4e472006-08-15 22:34:04 +00001069 /* test exception */
Mark Slee95771002006-06-07 06:53:25 +00001070
Marc Slemkobf4fd192006-08-15 21:29:39 +00001071 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001072 cout << "testClient.testException(\"Xception\") =>" << flush;
Marc Slemko71d4e472006-08-15 22:34:04 +00001073 testClient.testException("Xception");
CJCombrink4a280d52024-03-14 19:57:41 +01001074 cout << " void\n*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001075 return_code |= ERR_EXCEPTIONS;
David Reiss0c90f6f2008-02-06 22:18:40 +00001076
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001077 } catch (Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +00001078 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +00001079 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001080
Marc Slemkobf4fd192006-08-15 21:29:39 +00001081 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001082 cout << "testClient.testException(\"TException\") =>" << flush;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001083 testClient.testException("TException");
CJCombrink4a280d52024-03-14 19:57:41 +01001084 cout << " void\n*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001085 return_code |= ERR_EXCEPTIONS;
Roger Meierf50df7f2012-05-02 22:49:55 +00001086
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001087 } catch (const TException&) {
CJCombrink4a280d52024-03-14 19:57:41 +01001088 cout << " Caught TException" << '\n';
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001089 }
Roger Meierf50df7f2012-05-02 22:49:55 +00001090
1091 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001092 cout << "testClient.testException(\"success\") =>" << flush;
Marc Slemko71d4e472006-08-15 22:34:04 +00001093 testClient.testException("success");
CJCombrink4a280d52024-03-14 19:57:41 +01001094 cout << " void" << '\n';
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001095 } catch (exception & ex) { \
CJCombrink4a280d52024-03-14 19:57:41 +01001096 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001097 return_code |= ERR_EXCEPTIONS;
Marc Slemko71d4e472006-08-15 22:34:04 +00001098 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001099
Marc Slemko71d4e472006-08-15 22:34:04 +00001100 /* test multi exception */
David Reiss0c90f6f2008-02-06 22:18:40 +00001101
Marc Slemko71d4e472006-08-15 22:34:04 +00001102 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001103 cout << "testClient.testMultiException(\"Xception\", \"test 1\") =>" << flush;
Mark Slee1921d202007-01-24 19:43:06 +00001104 Xtruct result;
1105 testClient.testMultiException(result, "Xception", "test 1");
CJCombrink4a280d52024-03-14 19:57:41 +01001106 cout << " result\n*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001107 return_code |= ERR_EXCEPTIONS;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001108 } catch (Xception& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +00001109 printf(" {%u, \"%s\"}\n", e.errorCode, e.message.c_str());
1110 }
1111
1112 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001113 cout << "testClient.testMultiException(\"Xception2\", \"test 2\") =>" << flush;
Mark Slee1921d202007-01-24 19:43:06 +00001114 Xtruct result;
1115 testClient.testMultiException(result, "Xception2", "test 2");
CJCombrink4a280d52024-03-14 19:57:41 +01001116 cout << " result\n*** FAILED ***" << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001117 return_code |= ERR_EXCEPTIONS;
David Reiss0c90f6f2008-02-06 22:18:40 +00001118
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001119 } catch (Xception2& e) {
Marc Slemko71d4e472006-08-15 22:34:04 +00001120 printf(" {%u, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing.c_str());
Marc Slemkobf4fd192006-08-15 21:29:39 +00001121 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001122
Marc Slemko71d4e472006-08-15 22:34:04 +00001123 try {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001124 cout << "testClient.testMultiException(\"success\", \"test 3\") =>" << flush;
Mark Slee1921d202007-01-24 19:43:06 +00001125 Xtruct result;
1126 testClient.testMultiException(result, "success", "test 3");
Marc Slemko71d4e472006-08-15 22:34:04 +00001127 printf(" {{\"%s\"}}\n", result.string_thing.c_str());
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001128 } catch (exception & ex) { \
CJCombrink4a280d52024-03-14 19:57:41 +01001129 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
Jens Geyerd629ea02015-09-23 21:16:50 +02001130 return_code |= ERR_EXCEPTIONS;
Marc Slemko71d4e472006-08-15 22:34:04 +00001131 }
David Reiss0c90f6f2008-02-06 22:18:40 +00001132
David Reissc51986f2009-03-24 20:01:25 +00001133 /* test oneway void */
David Reiss2ab6fe82008-02-18 02:11:44 +00001134 {
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001135 cout << "testClient.testOneway(1) =>" << flush;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001136 uint64_t startOneway = now();
1137 testClient.testOneway(1);
1138 uint64_t elapsed = now() - startOneway;
1139 if (elapsed > 200 * 1000) { // 0.2 seconds
Jens Geyerd629ea02015-09-23 21:16:50 +02001140 printf("*** FAILED *** - took %.2f ms\n", (double)elapsed / 1000.0);
1141 return_code |= ERR_BASETYPES;
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001142 } else {
1143 printf(" success - took %.2f ms\n", (double)elapsed / 1000.0);
1144 }
David Reiss2ab6fe82008-02-18 02:11:44 +00001145 }
1146
David Reiss2845b522008-02-18 02:11:52 +00001147 /**
David Reissc51986f2009-03-24 20:01:25 +00001148 * redo a simple test after the oneway to make sure we aren't "off by one" --
1149 * if the server treated oneway void like normal void, this next test will
David Reiss2845b522008-02-18 02:11:52 +00001150 * fail since it will get the void confirmation rather than the correct
1151 * result. In this circumstance, the client will throw the exception:
1152 *
1153 * TApplicationException: Wrong method namea
1154 */
1155 /**
1156 * I32 TEST
1157 */
James E. King, III58402ff2017-11-17 14:41:46 -05001158 cout << "re-test testI32(-1)" << flush;
Nobuaki Sukegawa9b35a7c2015-11-17 11:01:41 +09001159 int i32 = testClient.testI32(-1);
CJCombrink4a280d52024-03-14 19:57:41 +01001160 cout << " = " << i32 << '\n';
Roger Meier4fce9602012-05-04 06:22:09 +00001161 if (i32 != -1)
Jens Geyerd629ea02015-09-23 21:16:50 +02001162 return_code |= ERR_BASETYPES;
David Reiss2845b522008-02-18 02:11:52 +00001163
CJCombrink4a280d52024-03-14 19:57:41 +01001164 cout << '\n' << "All tests done." << '\n' << flush;
James E. King, III39eaae62017-11-19 20:17:33 -05001165
Marc Slemkobf4fd192006-08-15 21:29:39 +00001166 uint64_t stop = now();
Konrad Grochowski16a23a62014-11-13 15:33:38 +01001167 uint64_t tot = stop - start;
Mark Sleed788b2e2006-09-07 01:26:35 +00001168
CJCombrink4a280d52024-03-14 19:57:41 +01001169 cout << "Total time: " << stop - start << " us" << '\n';
David Reiss0c90f6f2008-02-06 22:18:40 +00001170
Mark Sleed788b2e2006-09-07 01:26:35 +00001171 time_tot += tot;
1172 if (time_min == 0 || tot < time_min) {
1173 time_min = tot;
1174 }
1175 if (tot > time_max) {
1176 time_max = tot;
1177 }
1178
James E. King, III58402ff2017-11-17 14:41:46 -05001179 cout << flush;
Mark Sleea3302652006-10-25 19:03:32 +00001180 transport->close();
Mark Sleee8540632006-05-30 09:24:40 +00001181 }
1182
Mark Sleed788b2e2006-09-07 01:26:35 +00001183
1184 uint64_t time_avg = time_tot / numTests;
1185
CJCombrink4a280d52024-03-14 19:57:41 +01001186 cout << "Min time: " << time_min << " us" << '\n';
1187 cout << "Max time: " << time_max << " us" << '\n';
1188 cout << "Avg time: " << time_avg << " us" << '\n';
Mark Sleed788b2e2006-09-07 01:26:35 +00001189
Jens Geyerd629ea02015-09-23 21:16:50 +02001190 return return_code;
Mark Sleee8540632006-05-30 09:24:40 +00001191}
James E. King, III39eaae62017-11-19 20:17:33 -05001192
1193void binary_fill(std::string& str, string::size_type siz)
1194{
1195 static const signed char bin_data[256]
1196 = {-128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114,
1197 -113, -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99,
1198 -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84,
1199 -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, -69,
1200 -68, -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54,
1201 -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39,
1202 -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24,
1203 -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9,
1204 -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6,
1205 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
1206 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
1207 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
1208 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
1209 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
1210 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
1211 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
1212 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
1213 127};
1214
1215 str.resize(siz);
1216 char *ptr = &str[0];
1217 string::size_type pos = 0;
1218 for (string::size_type i = 0; i < siz; ++i)
1219 {
1220 if (pos == 255) { pos = 0; } else { ++pos; }
1221 *ptr++ = bin_data[pos];
1222 }
1223}
1224
1225int binary_test(ThriftTestClient& testClient, string::size_type siz)
1226{
1227 string bin_request;
1228 string bin_result;
1229
CJCombrink4a280d52024-03-14 19:57:41 +01001230 cout << "testBinary(siz = " << siz << ")" << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -05001231 binary_fill(bin_request, siz);
1232 try {
1233 testClient.testBinary(bin_result, bin_request);
1234
1235 if (bin_request.size() != bin_result.size()) {
CJCombrink4a280d52024-03-14 19:57:41 +01001236 cout << "*** FAILED: request size " << bin_request.size() << "; result size " << bin_result.size() << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -05001237 return ERR_BASETYPES;
1238 }
1239
1240 for (string::size_type i = 0; i < siz; ++i) {
1241 if (bin_request.at(i) != bin_result.at(i)) {
CJCombrink4a280d52024-03-14 19:57:41 +01001242 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 -05001243 return ERR_BASETYPES;
1244 }
1245 }
1246 } catch (TTransportException&) {
1247 throw;
1248 } catch (exception& ex) {
CJCombrink4a280d52024-03-14 19:57:41 +01001249 cout << "*** FAILED ***" << '\n' << ex.what() << '\n';
James E. King, III39eaae62017-11-19 20:17:33 -05001250 return ERR_BASETYPES;
1251 }
1252
1253 return 0;
1254}