blob: 5e0c89471d4b517d881a8c672c09e372385284cd [file] [log] [blame]
Roger Meierc1010922010-11-26 10:17:48 +00001/*
2 * 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 */
Roger Meier213a6642010-10-27 12:30:11 +000019
James E. King, III82ae9572017-08-05 12:23:54 -040020/* test a C client with a C++ server (that makes sense...) */
Roger Meier213a6642010-10-27 12:30:11 +000021
Christopher Friedt9c0de2d2022-11-24 20:13:21 -050022#include <thrift/config.h>
23
24#ifdef HAVE_UNISTD_H
25#include <unistd.h>
26#endif
27
Roger Meier213a6642010-10-27 12:30:11 +000028#include <signal.h>
29#include <sys/types.h>
30#include <sys/wait.h>
Roger Meier49ff8b12012-04-13 09:12:31 +000031#include <thrift/protocol/TBinaryProtocol.h>
32#include <thrift/protocol/TDebugProtocol.h>
33#include <thrift/server/TSimpleServer.h>
cyy316723a2019-01-05 16:35:14 +080034#include <memory>
Roger Meier49ff8b12012-04-13 09:12:31 +000035#include <thrift/transport/TServerSocket.h>
Roger Meier213a6642010-10-27 12:30:11 +000036#include "ThriftTest.h"
37#include "ThriftTest_types.h"
38
39#include <iostream>
James E. King, III82ae9572017-08-05 12:23:54 -040040#include <map>
41#include <set>
42#include <string>
43#include <vector>
Roger Meier213a6642010-10-27 12:30:11 +000044
45using namespace apache::thrift;
46using namespace apache::thrift::concurrency;
47using namespace apache::thrift::protocol;
Roger Meier213a6642010-10-27 12:30:11 +000048using namespace apache::thrift::server;
James E. King, III82ae9572017-08-05 12:23:54 -040049using namespace apache::thrift::transport;
Roger Meier213a6642010-10-27 12:30:11 +000050
51using namespace thrift::test;
52
James E. King, III82ae9572017-08-05 12:23:54 -040053using std::cout;
James E. King, III82ae9572017-08-05 12:23:54 -040054using std::fixed;
55using std::make_pair;
56using std::map;
57using std::set;
58using std::string;
59using std::vector;
60
Roger Meier213a6642010-10-27 12:30:11 +000061#define TEST_PORT 9980
62
63// Extra functions required for ThriftTest_types to work
64namespace thrift { namespace test {
65
66bool Insanity::operator<(thrift::test::Insanity const& other) const {
67 using apache::thrift::ThriftDebugString;
68 return ThriftDebugString(*this) < ThriftDebugString(other);
69}
70
71}}
72
73class TestHandler : public ThriftTestIf {
74 public:
Sebastian Zenker042580f2019-01-29 15:48:12 +010075 TestHandler() = default;
Roger Meier213a6642010-10-27 12:30:11 +000076
Sebastian Zenker042580f2019-01-29 15:48:12 +010077 void testVoid() override {
CJCombrink4a280d52024-03-14 19:57:41 +010078 cout << "[C -> C++] testVoid()" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +000079 }
80
Sebastian Zenker042580f2019-01-29 15:48:12 +010081 void testString(string& out, const string &thing) override {
CJCombrink4a280d52024-03-14 19:57:41 +010082 cout << "[C -> C++] testString(\"" << thing << "\")" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +000083 out = thing;
84 }
85
Sebastian Zenker042580f2019-01-29 15:48:12 +010086 bool testBool(const bool thing) override {
CJCombrink4a280d52024-03-14 19:57:41 +010087 cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << '\n';
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +090088 return thing;
89 }
Sebastian Zenker042580f2019-01-29 15:48:12 +010090 int8_t testByte(const int8_t thing) override {
CJCombrink4a280d52024-03-14 19:57:41 +010091 cout << "[C -> C++] testByte(" << (int)thing << ")" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +000092 return thing;
93 }
Sebastian Zenker042580f2019-01-29 15:48:12 +010094 int32_t testI32(const int32_t thing) override {
CJCombrink4a280d52024-03-14 19:57:41 +010095 cout << "[C -> C++] testI32(" << thing << ")" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +000096 return thing;
97 }
98
Sebastian Zenker042580f2019-01-29 15:48:12 +010099 int64_t testI64(const int64_t thing) override {
CJCombrink4a280d52024-03-14 19:57:41 +0100100 cout << "[C -> C++] testI64(" << thing << ")" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000101 return thing;
102 }
103
Sebastian Zenker042580f2019-01-29 15:48:12 +0100104 double testDouble(const double thing) override {
Simon Southbf8f7b42015-12-23 20:29:29 -0500105 cout.precision(6);
CJCombrink4a280d52024-03-14 19:57:41 +0100106 cout << "[C -> C++] testDouble(" << fixed << thing << ")" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000107 return thing;
108 }
109
Sebastian Zenker042580f2019-01-29 15:48:12 +0100110 void testBinary(string& out, const string &thing) override {
CJCombrink4a280d52024-03-14 19:57:41 +0100111 cout << "[C -> C++] testBinary(\"" << thing << "\")" << '\n';
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100112 out = thing;
113 }
114
Sebastian Zenker042580f2019-01-29 15:48:12 +0100115 void testStruct(Xtruct& out, const Xtruct &thing) override {
CJCombrink4a280d52024-03-14 19:57:41 +0100116 cout << "[C -> C++] testStruct({\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "})" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000117 out = thing;
118 }
119
Sebastian Zenker042580f2019-01-29 15:48:12 +0100120 void testNest(Xtruct2& out, const Xtruct2& nest) override {
Roger Meier213a6642010-10-27 12:30:11 +0000121 const Xtruct &thing = nest.struct_thing;
CJCombrink4a280d52024-03-14 19:57:41 +0100122 cout << "[C -> C++] testNest({" << (int)nest.byte_thing << ", {\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "}, " << nest.i32_thing << "})" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000123 out = nest;
124 }
125
Sebastian Zenker042580f2019-01-29 15:48:12 +0100126 void testMap(map<int32_t, int32_t> &out, const map<int32_t, int32_t> &thing) override {
Simon Southbf8f7b42015-12-23 20:29:29 -0500127 cout << "[C -> C++] testMap({";
Roger Meier213a6642010-10-27 12:30:11 +0000128 map<int32_t, int32_t>::const_iterator m_iter;
129 bool first = true;
130 for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
131 if (first) {
132 first = false;
133 } else {
Simon Southbf8f7b42015-12-23 20:29:29 -0500134 cout << ", ";
Roger Meier213a6642010-10-27 12:30:11 +0000135 }
Simon Southbf8f7b42015-12-23 20:29:29 -0500136 cout << m_iter->first << " => " << m_iter->second;
Roger Meier213a6642010-10-27 12:30:11 +0000137 }
CJCombrink4a280d52024-03-14 19:57:41 +0100138 cout << "})" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000139 out = thing;
140 }
141
Sebastian Zenker042580f2019-01-29 15:48:12 +0100142 void testStringMap(map<std::string, std::string> &out, const map<std::string, std::string> &thing) override {
Simon Southbf8f7b42015-12-23 20:29:29 -0500143 cout << "[C -> C++] testStringMap({";
Roger Meiera1c416f2011-06-17 19:40:48 +0000144 map<std::string, std::string>::const_iterator m_iter;
145 bool first = true;
146 for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
147 if (first) {
148 first = false;
149 } else {
Simon Southbf8f7b42015-12-23 20:29:29 -0500150 cout << ", ";
Roger Meiera1c416f2011-06-17 19:40:48 +0000151 }
Simon Southbf8f7b42015-12-23 20:29:29 -0500152 cout << "\"" << m_iter->first << "\" => \"" << m_iter->second << "\"";
Roger Meiera1c416f2011-06-17 19:40:48 +0000153 }
CJCombrink4a280d52024-03-14 19:57:41 +0100154 cout << "})" << '\n';
Roger Meiera1c416f2011-06-17 19:40:48 +0000155 out = thing;
156 }
157
158
Sebastian Zenker042580f2019-01-29 15:48:12 +0100159 void testSet(set<int32_t> &out, const set<int32_t> &thing) override {
Simon Southbf8f7b42015-12-23 20:29:29 -0500160 cout << "[C -> C++] testSet({";
Roger Meier213a6642010-10-27 12:30:11 +0000161 set<int32_t>::const_iterator s_iter;
162 bool first = true;
163 for (s_iter = thing.begin(); s_iter != thing.end(); ++s_iter) {
164 if (first) {
165 first = false;
166 } else {
Simon Southbf8f7b42015-12-23 20:29:29 -0500167 cout << ", ";
Roger Meier213a6642010-10-27 12:30:11 +0000168 }
Simon Southbf8f7b42015-12-23 20:29:29 -0500169 cout << *s_iter;
Roger Meier213a6642010-10-27 12:30:11 +0000170 }
CJCombrink4a280d52024-03-14 19:57:41 +0100171 cout << "})" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000172 out = thing;
173 }
174
Sebastian Zenker042580f2019-01-29 15:48:12 +0100175 void testList(vector<int32_t> &out, const vector<int32_t> &thing) override {
Simon Southbf8f7b42015-12-23 20:29:29 -0500176 cout << "[C -> C++] testList({";
Roger Meier213a6642010-10-27 12:30:11 +0000177 vector<int32_t>::const_iterator l_iter;
178 bool first = true;
179 for (l_iter = thing.begin(); l_iter != thing.end(); ++l_iter) {
180 if (first) {
181 first = false;
Simon Southbf8f7b42015-12-23 20:29:29 -0500182 } else {
183 cout << ", ";
Roger Meier213a6642010-10-27 12:30:11 +0000184 }
Simon Southbf8f7b42015-12-23 20:29:29 -0500185 cout << *l_iter;
Roger Meier213a6642010-10-27 12:30:11 +0000186 }
CJCombrink4a280d52024-03-14 19:57:41 +0100187 cout << "})" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000188 out = thing;
189 }
190
Sebastian Zenker042580f2019-01-29 15:48:12 +0100191 Numberz::type testEnum(const Numberz::type thing) override {
CJCombrink4a280d52024-03-14 19:57:41 +0100192 cout << "[C -> C++] testEnum(" << thing << ")" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000193 return thing;
194 }
195
Sebastian Zenker042580f2019-01-29 15:48:12 +0100196 UserId testTypedef(const UserId thing) override {
CJCombrink4a280d52024-03-14 19:57:41 +0100197 cout << "[C -> C++] testTypedef(" << thing << ")" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000198 return thing; }
199
Sebastian Zenker042580f2019-01-29 15:48:12 +0100200 void testMapMap(map<int32_t, map<int32_t,int32_t> > &mapmap, const int32_t hello) override {
CJCombrink4a280d52024-03-14 19:57:41 +0100201 cout << "[C -> C++] testMapMap(" << hello << ")" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000202
203 map<int32_t,int32_t> pos;
204 map<int32_t,int32_t> neg;
205 for (int i = 1; i < 5; i++) {
206 pos.insert(make_pair(i,i));
207 neg.insert(make_pair(-i,-i));
208 }
209
210 mapmap.insert(make_pair(4, pos));
211 mapmap.insert(make_pair(-4, neg));
212
213 }
214
Sebastian Zenker042580f2019-01-29 15:48:12 +0100215 void testInsanity(map<UserId, map<Numberz::type,Insanity> > &insane, const Insanity &argument) override {
Simon South38e71552015-08-03 10:51:16 +0000216 THRIFT_UNUSED_VARIABLE (argument);
217
CJCombrink4a280d52024-03-14 19:57:41 +0100218 cout << "[C -> C++] testInsanity()" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000219
220 Xtruct hello;
221 hello.string_thing = "Hello2";
222 hello.byte_thing = 2;
223 hello.i32_thing = 2;
224 hello.i64_thing = 2;
225
226 Xtruct goodbye;
227 goodbye.string_thing = "Goodbye4";
228 goodbye.byte_thing = 4;
229 goodbye.i32_thing = 4;
230 goodbye.i64_thing = 4;
231
232 Insanity crazy;
233 crazy.userMap.insert(make_pair(Numberz::EIGHT, 8));
234 crazy.xtructs.push_back(goodbye);
235
236 Insanity looney;
237 crazy.userMap.insert(make_pair(Numberz::FIVE, 5));
238 crazy.xtructs.push_back(hello);
239
240 map<Numberz::type, Insanity> first_map;
241 map<Numberz::type, Insanity> second_map;
242
243 first_map.insert(make_pair(Numberz::TWO, crazy));
244 first_map.insert(make_pair(Numberz::THREE, crazy));
245
246 second_map.insert(make_pair(Numberz::SIX, looney));
247
248 insane.insert(make_pair(1, first_map));
249 insane.insert(make_pair(2, second_map));
250
Simon Southbf8f7b42015-12-23 20:29:29 -0500251 cout << "return = {";
Roger Meier213a6642010-10-27 12:30:11 +0000252 map<UserId, map<Numberz::type,Insanity> >::const_iterator i_iter;
253 for (i_iter = insane.begin(); i_iter != insane.end(); ++i_iter) {
Simon Southbf8f7b42015-12-23 20:29:29 -0500254 cout << i_iter->first << " => {";
Roger Meier213a6642010-10-27 12:30:11 +0000255 map<Numberz::type,Insanity>::const_iterator i2_iter;
256 for (i2_iter = i_iter->second.begin();
257 i2_iter != i_iter->second.end();
258 ++i2_iter) {
Simon Southbf8f7b42015-12-23 20:29:29 -0500259 cout << i2_iter->first << " => {";
Roger Meier213a6642010-10-27 12:30:11 +0000260 map<Numberz::type, UserId> userMap = i2_iter->second.userMap;
261 map<Numberz::type, UserId>::const_iterator um;
Simon Southbf8f7b42015-12-23 20:29:29 -0500262 cout << "{";
Roger Meier213a6642010-10-27 12:30:11 +0000263 for (um = userMap.begin(); um != userMap.end(); ++um) {
Simon Southbf8f7b42015-12-23 20:29:29 -0500264 cout << um->first << " => " << um->second << ", ";
Roger Meier213a6642010-10-27 12:30:11 +0000265 }
Simon Southbf8f7b42015-12-23 20:29:29 -0500266 cout << "}, ";
Roger Meier213a6642010-10-27 12:30:11 +0000267
268 vector<Xtruct> xtructs = i2_iter->second.xtructs;
269 vector<Xtruct>::const_iterator x;
Simon Southbf8f7b42015-12-23 20:29:29 -0500270 cout << "{";
Roger Meier213a6642010-10-27 12:30:11 +0000271 for (x = xtructs.begin(); x != xtructs.end(); ++x) {
Simon Southbf8f7b42015-12-23 20:29:29 -0500272 cout << "{\"" << x->string_thing << "\", " << (int)x->byte_thing << ", " << x->i32_thing << ", " << x->i64_thing << "}, ";
Roger Meier213a6642010-10-27 12:30:11 +0000273 }
Simon Southbf8f7b42015-12-23 20:29:29 -0500274 cout << "}";
Roger Meier213a6642010-10-27 12:30:11 +0000275
Simon Southbf8f7b42015-12-23 20:29:29 -0500276 cout << "}, ";
Roger Meier213a6642010-10-27 12:30:11 +0000277 }
Simon Southbf8f7b42015-12-23 20:29:29 -0500278 cout << "}, ";
Roger Meier213a6642010-10-27 12:30:11 +0000279 }
CJCombrink4a280d52024-03-14 19:57:41 +0100280 cout << "}" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000281
282
283 }
284
Sebastian Zenker042580f2019-01-29 15:48:12 +0100285 void testMulti(Xtruct &hello, const int8_t arg0, const int32_t arg1, const int64_t arg2, const std::map<int16_t, std::string> &arg3, const Numberz::type arg4, const UserId arg5) override {
Simon South38e71552015-08-03 10:51:16 +0000286 THRIFT_UNUSED_VARIABLE (arg3);
287 THRIFT_UNUSED_VARIABLE (arg4);
288 THRIFT_UNUSED_VARIABLE (arg5);
289
CJCombrink4a280d52024-03-14 19:57:41 +0100290 cout << "[C -> C++] testMulti()" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000291
292 hello.string_thing = "Hello2";
293 hello.byte_thing = arg0;
294 hello.i32_thing = arg1;
295 hello.i64_thing = (int64_t)arg2;
296 }
297
298 void testException(const std::string &arg)
zeshuai007c821d252020-08-14 15:44:02 +0800299 noexcept(false) override
Roger Meier213a6642010-10-27 12:30:11 +0000300 {
CJCombrink4a280d52024-03-14 19:57:41 +0100301 cout << "[C -> C++] testException(" << arg << ")" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000302 if (arg.compare("Xception") == 0) {
303 Xception e;
304 e.errorCode = 1001;
305 e.message = arg;
306 throw e;
307 } else if (arg.compare("ApplicationException") == 0) {
308 apache::thrift::TException e;
309 throw e;
310 } else {
311 Xtruct result;
312 result.string_thing = arg;
313 return;
314 }
315 }
316
zeshuai007c821d252020-08-14 15:44:02 +0800317 void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) noexcept(false) override {
Roger Meier213a6642010-10-27 12:30:11 +0000318
CJCombrink4a280d52024-03-14 19:57:41 +0100319 cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000320
321 if (arg0.compare("Xception") == 0) {
322 Xception e;
323 e.errorCode = 1001;
324 e.message = "This is an Xception";
325 throw e;
326 } else if (arg0.compare("Xception2") == 0) {
327 Xception2 e;
328 e.errorCode = 2002;
329 e.struct_thing.string_thing = "This is an Xception2";
330 throw e;
331 } else {
332 result.string_thing = arg1;
333 return;
334 }
335 }
336
Sebastian Zenker042580f2019-01-29 15:48:12 +0100337 void testOneway(int sleepFor) override {
CJCombrink4a280d52024-03-14 19:57:41 +0100338 cout << "testOneway(" << sleepFor << "): Sleeping..." << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000339 sleep(sleepFor);
CJCombrink4a280d52024-03-14 19:57:41 +0100340 cout << "testOneway(" << sleepFor << "): done sleeping!" << '\n';
Roger Meier213a6642010-10-27 12:30:11 +0000341 }
342};
343
344// C CLIENT
345extern "C" {
346
Jim King79c99112015-04-30 07:10:08 -0400347#undef THRIFT_SOCKET /* from lib/cpp */
348
Roger Meier213a6642010-10-27 12:30:11 +0000349#include "t_test_thrift_test.h"
350#include "t_test_thrift_test_types.h"
Roger Meiere3da7682013-01-11 11:41:53 +0100351#include <thrift/c_glib/transport/thrift_socket.h>
352#include <thrift/c_glib/protocol/thrift_protocol.h>
353#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
Roger Meier213a6642010-10-27 12:30:11 +0000354
355static void
356test_thrift_client (void)
357{
Sebastian Zenker042580f2019-01-29 15:48:12 +0100358 ThriftSocket *tsocket = nullptr;
359 ThriftBinaryProtocol *protocol = nullptr;
360 TTestThriftTestClient *client = nullptr;
361 TTestThriftTestIf *iface = nullptr;
362 GError *error = nullptr;
363 gchar *string = nullptr;
Roger Meier213a6642010-10-27 12:30:11 +0000364 gint8 byte = 0;
365 gint16 i16 = 0;
James E. King, III82ae9572017-08-05 12:23:54 -0400366 gint32 i32 = 0, another_i32 = 56789;
Roger Meier213a6642010-10-27 12:30:11 +0000367 gint64 i64 = 0;
368 double dbl = 0.0;
369 TTestXtruct *xtruct_in, *xtruct_out;
370 TTestXtruct2 *xtruct2_in, *xtruct2_out;
Sebastian Zenker042580f2019-01-29 15:48:12 +0100371 GHashTable *map_in = nullptr, *map_out = nullptr;
372 GHashTable *set_in = nullptr, *set_out = nullptr;
373 GArray *list_in = nullptr, *list_out = nullptr;
Roger Meier213a6642010-10-27 12:30:11 +0000374 TTestNumberz enum_in, enum_out;
James E. King, III82ae9572017-08-05 12:23:54 -0400375 TTestUserId user_id_in, user_id_out;
Sebastian Zenker042580f2019-01-29 15:48:12 +0100376 GHashTable *insanity_in = nullptr;
Roger Meier213a6642010-10-27 12:30:11 +0000377 TTestXtruct *xtruct1, *xtruct2;
Sebastian Zenker042580f2019-01-29 15:48:12 +0100378 TTestInsanity *insanity_out = nullptr;
379 TTestXtruct *multi_in = nullptr;
380 GHashTable *multi_map_out = nullptr;
381 TTestXception *xception = nullptr;
382 TTestXception2 *xception2 = nullptr;
Roger Meier213a6642010-10-27 12:30:11 +0000383
Jens Geyer1c190272015-07-28 23:15:18 +0200384#if (!GLIB_CHECK_VERSION (2, 36, 0))
Roger Meier213a6642010-10-27 12:30:11 +0000385 // initialize gobject
386 g_type_init ();
Jens Geyer1c190272015-07-28 23:15:18 +0200387#endif
Roger Meier213a6642010-10-27 12:30:11 +0000388
389 // create a C client
James E. King, III82ae9572017-08-05 12:23:54 -0400390 tsocket = (ThriftSocket *) g_object_new (THRIFT_TYPE_SOCKET,
Roger Meier213a6642010-10-27 12:30:11 +0000391 "hostname", "localhost",
zeshuai00726681fb2020-06-03 17:24:38 +0800392 "port", TEST_PORT, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000393 protocol = (ThriftBinaryProtocol *) g_object_new (THRIFT_TYPE_BINARY_PROTOCOL,
394 "transport",
zeshuai00726681fb2020-06-03 17:24:38 +0800395 tsocket, nullptr);
396 client = (TTestThriftTestClient *) g_object_new (T_TEST_TYPE_THRIFT_TEST_CLIENT, "input_protocol", protocol, "output_protocol", protocol, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000397 iface = T_TEST_THRIFT_TEST_IF (client);
398
399 // open and send
Sebastian Zenker042580f2019-01-29 15:48:12 +0100400 thrift_transport_open (THRIFT_TRANSPORT(tsocket), nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000401
402 assert (t_test_thrift_test_client_test_void (iface, &error) == TRUE);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100403 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000404
405 assert (t_test_thrift_test_client_test_string (iface, &string, "test123", &error) == TRUE);
406 assert (strcmp (string, "test123") == 0);
407 g_free (string);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100408 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000409
410 assert (t_test_thrift_test_client_test_byte (iface, &byte, (gint8) 5, &error) == TRUE);
411 assert (byte == 5);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100412 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000413
414 assert (t_test_thrift_test_client_test_i32 (iface, &i32, 123, &error) == TRUE);
415 assert (i32 == 123);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100416 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000417
418 assert (t_test_thrift_test_client_test_i64 (iface, &i64, 12345, &error) == TRUE);
419 assert (i64 == 12345);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100420 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000421
422 assert (t_test_thrift_test_client_test_double (iface, &dbl, 5.6, &error) == TRUE);
423 assert (dbl == 5.6);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100424 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000425
Sebastian Zenker042580f2019-01-29 15:48:12 +0100426 xtruct_out = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000427 xtruct_out->byte_thing = 1;
428 xtruct_out->__isset_byte_thing = TRUE;
429 xtruct_out->i32_thing = 15;
430 xtruct_out->__isset_i32_thing = TRUE;
431 xtruct_out->i64_thing = 151;
432 xtruct_out->__isset_i64_thing = TRUE;
433 xtruct_out->string_thing = g_strdup ("abc123");
434 xtruct_out->__isset_string_thing = TRUE;
Sebastian Zenker042580f2019-01-29 15:48:12 +0100435 xtruct_in = (TTestXtruct *) g_object_new(T_TEST_TYPE_XTRUCT, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000436 assert (t_test_thrift_test_client_test_struct (iface, &xtruct_in, xtruct_out, &error) == TRUE);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100437 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000438
Sebastian Zenker042580f2019-01-29 15:48:12 +0100439 xtruct2_out = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000440 xtruct2_out->byte_thing = 1;
441 xtruct2_out->__isset_byte_thing = TRUE;
Sebastian Zenker042580f2019-01-29 15:48:12 +0100442 if (xtruct2_out->struct_thing != nullptr)
Roger Meierc75797d2012-04-28 11:33:58 +0000443 g_object_unref(xtruct2_out->struct_thing);
Roger Meier213a6642010-10-27 12:30:11 +0000444 xtruct2_out->struct_thing = xtruct_out;
445 xtruct2_out->__isset_struct_thing = TRUE;
446 xtruct2_out->i32_thing = 123;
447 xtruct2_out->__isset_i32_thing = TRUE;
Sebastian Zenker042580f2019-01-29 15:48:12 +0100448 xtruct2_in = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000449 assert (t_test_thrift_test_client_test_nest (iface, &xtruct2_in, xtruct2_out, &error) == TRUE);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100450 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000451
452 g_object_unref (xtruct2_out);
453 g_object_unref (xtruct2_in);
Roger Meier213a6642010-10-27 12:30:11 +0000454 g_object_unref (xtruct_in);
455
Sebastian Zenker042580f2019-01-29 15:48:12 +0100456 map_out = g_hash_table_new (nullptr, nullptr);
457 map_in = g_hash_table_new (nullptr, nullptr); g_hash_table_insert (map_out, &i32, &i32);
Roger Meier213a6642010-10-27 12:30:11 +0000458 assert (t_test_thrift_test_client_test_map (iface, &map_in, map_out, &error) == TRUE);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100459 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000460 g_hash_table_destroy (map_out);
461 g_hash_table_destroy (map_in);
462
Sebastian Zenker042580f2019-01-29 15:48:12 +0100463 map_out = g_hash_table_new (nullptr, nullptr);
464 map_in = g_hash_table_new (nullptr, nullptr);
Roger Meiera1c416f2011-06-17 19:40:48 +0000465 g_hash_table_insert (map_out, g_strdup ("a"), g_strdup ("123"));
466 g_hash_table_insert (map_out, g_strdup ("a b"), g_strdup ("with spaces "));
467 g_hash_table_insert (map_out, g_strdup ("same"), g_strdup ("same"));
468 g_hash_table_insert (map_out, g_strdup ("0"), g_strdup ("numeric key"));
469 assert (t_test_thrift_test_client_test_string_map (iface, &map_in, map_out, &error) == TRUE);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100470 assert (error == nullptr);
Roger Meiera1c416f2011-06-17 19:40:48 +0000471 g_hash_table_destroy (map_out);
472 g_hash_table_destroy (map_in);
473
Sebastian Zenker042580f2019-01-29 15:48:12 +0100474 set_out = g_hash_table_new (nullptr, nullptr);
475 set_in = g_hash_table_new (nullptr, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000476 g_hash_table_insert (set_out, &i32, &i32);
477 assert (t_test_thrift_test_client_test_set (iface, &set_in, set_out, &error) == TRUE);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100478 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000479 g_hash_table_destroy (set_out);
480 g_hash_table_destroy (set_in);
481
482 list_out = g_array_new(TRUE, TRUE, sizeof(gint32));
483 list_in = g_array_new(TRUE, TRUE, sizeof(gint32));
484 another_i32 = 456;
485 g_array_append_val (list_out, i32);
486 g_array_append_val (list_out, another_i32);
487 assert (t_test_thrift_test_client_test_list (iface, &list_in, list_out, &error) == TRUE);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100488 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000489 g_array_free (list_out, TRUE);
490 g_array_free (list_in, TRUE);
491
492 enum_out = T_TEST_NUMBERZ_ONE;
493 assert (t_test_thrift_test_client_test_enum (iface, &enum_in, enum_out, &error) == TRUE);
494 assert (enum_in == enum_out);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100495 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000496
497 user_id_out = 12345;
498 assert (t_test_thrift_test_client_test_typedef (iface, &user_id_in, user_id_out, &error) == TRUE);
499 assert (user_id_in == user_id_out);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100500 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000501
Sebastian Zenker042580f2019-01-29 15:48:12 +0100502 map_in = g_hash_table_new (nullptr, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000503 assert (t_test_thrift_test_client_test_map_map (iface, &map_in, i32, &error) == TRUE);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100504 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000505 g_hash_table_destroy (map_in);
506
507 // insanity
Sebastian Zenker042580f2019-01-29 15:48:12 +0100508 insanity_out = (TTestInsanity *) g_object_new (T_TEST_TYPE_INSANITY, nullptr);
509 insanity_out->userMap = g_hash_table_new (nullptr, nullptr);
Roger Meier0cc6d3c2014-09-04 00:24:17 +0200510 g_hash_table_insert (insanity_out->userMap, GINT_TO_POINTER (enum_out), &user_id_out);
Roger Meier213a6642010-10-27 12:30:11 +0000511
Sebastian Zenker042580f2019-01-29 15:48:12 +0100512 xtruct1 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000513 xtruct1->byte_thing = 1;
514 xtruct1->__isset_byte_thing = TRUE;
515 xtruct1->i32_thing = 15;
516 xtruct1->__isset_i32_thing = TRUE;
517 xtruct1->i64_thing = 151;
518 xtruct1->__isset_i64_thing = TRUE;
519 xtruct1->string_thing = g_strdup ("abc123");
520 xtruct1->__isset_string_thing = TRUE;
Sebastian Zenker042580f2019-01-29 15:48:12 +0100521 xtruct2 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000522 xtruct2->byte_thing = 1;
523 xtruct2->__isset_byte_thing = TRUE;
524 xtruct2->i32_thing = 15;
525 xtruct2->__isset_i32_thing = TRUE;
526 xtruct2->i64_thing = 151;
527 xtruct2->__isset_i64_thing = TRUE;
528 xtruct2->string_thing = g_strdup ("abc123");
529 xtruct2->__isset_string_thing = TRUE;
530
Sebastian Zenker042580f2019-01-29 15:48:12 +0100531 insanity_in = g_hash_table_new (nullptr, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000532 g_ptr_array_add (insanity_out->xtructs, xtruct1);
533 g_ptr_array_add (insanity_out->xtructs, xtruct2);
534 assert (t_test_thrift_test_client_test_insanity (iface, &insanity_in, insanity_out, &error) == TRUE);
535
536 g_hash_table_unref (insanity_in);
537 g_ptr_array_free (insanity_out->xtructs, TRUE);
Roger Meier213a6642010-10-27 12:30:11 +0000538
Sebastian Zenker042580f2019-01-29 15:48:12 +0100539 multi_map_out = g_hash_table_new (nullptr, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000540 string = g_strdup ("abc123");
541 g_hash_table_insert (multi_map_out, &i16, string);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100542 multi_in = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000543 assert (t_test_thrift_test_client_test_multi (iface, &multi_in, byte, i32, i64, multi_map_out, enum_out, user_id_out, &error) == TRUE);
544 assert (multi_in->i32_thing == i32);
545 assert (multi_in->i64_thing == i64);
546 g_object_unref (multi_in);
547 g_hash_table_unref (multi_map_out);
Roger Meierc75797d2012-04-28 11:33:58 +0000548 g_free (string);
Roger Meier213a6642010-10-27 12:30:11 +0000549
550 assert (t_test_thrift_test_client_test_exception (iface, "Xception", &xception, &error) == FALSE);
551 assert (xception->errorCode == 1001);
552 g_error_free (error);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100553 error = nullptr;
Roger Meierc75797d2012-04-28 11:33:58 +0000554 g_object_unref (xception);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100555 xception = nullptr;
Roger Meier213a6642010-10-27 12:30:11 +0000556
557 assert (t_test_thrift_test_client_test_exception (iface, "ApplicationException", &xception, &error) == FALSE);
558 g_error_free (error);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100559 error = nullptr;
560 assert (xception == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000561
562 assert (t_test_thrift_test_client_test_exception (iface, "Test", &xception, &error) == TRUE);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100563 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000564
Sebastian Zenker042580f2019-01-29 15:48:12 +0100565 multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
566 assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception", nullptr, &xception, &xception2, &error) == FALSE);
Roger Meier213a6642010-10-27 12:30:11 +0000567 assert (xception->errorCode == 1001);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100568 assert (xception2 == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000569 g_error_free (error);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100570 error = nullptr;
Roger Meier213a6642010-10-27 12:30:11 +0000571 g_object_unref (xception);
Roger Meierc75797d2012-04-28 11:33:58 +0000572 g_object_unref (multi_in);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100573 xception = nullptr;
574 multi_in = nullptr;
Roger Meier213a6642010-10-27 12:30:11 +0000575
Sebastian Zenker042580f2019-01-29 15:48:12 +0100576 multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
577 assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception2", nullptr, &xception, &xception2, &error) == FALSE);
Roger Meier213a6642010-10-27 12:30:11 +0000578 assert (xception2->errorCode == 2002);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100579 assert (xception == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000580 g_error_free (error);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100581 error = nullptr;
Roger Meier213a6642010-10-27 12:30:11 +0000582 g_object_unref (xception2);
Roger Meierc75797d2012-04-28 11:33:58 +0000583 g_object_unref (multi_in);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100584 xception2 = nullptr;
585 multi_in = nullptr;
Roger Meier213a6642010-10-27 12:30:11 +0000586
Sebastian Zenker042580f2019-01-29 15:48:12 +0100587 multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
588 assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, nullptr , nullptr, &xception, &xception2, &error) == TRUE);
589 assert (error == nullptr);
Roger Meierc75797d2012-04-28 11:33:58 +0000590 g_object_unref(multi_in);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100591 multi_in = nullptr;
Roger Meier213a6642010-10-27 12:30:11 +0000592
593 assert (t_test_thrift_test_client_test_oneway (iface, 1, &error) == TRUE);
Sebastian Zenker042580f2019-01-29 15:48:12 +0100594 assert (error == nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000595
596 /* sleep to let the oneway call go through */
597 sleep (5);
598
Sebastian Zenker042580f2019-01-29 15:48:12 +0100599 thrift_transport_close (THRIFT_TRANSPORT(tsocket), nullptr);
Roger Meier213a6642010-10-27 12:30:11 +0000600 g_object_unref (client);
601 g_object_unref (protocol);
602 g_object_unref (tsocket);
603}
604
605
606} /* extern "C" */
607
608
609static void
610bailout (int signum)
611{
Simon South38e71552015-08-03 10:51:16 +0000612 THRIFT_UNUSED_VARIABLE (signum);
613
Roger Meier213a6642010-10-27 12:30:11 +0000614 exit (1);
615}
616
617int
Simon South38e71552015-08-03 10:51:16 +0000618main (void)
Roger Meier213a6642010-10-27 12:30:11 +0000619{
620 int status;
621 int pid = fork ();
622 assert (pid >= 0);
623
624 if (pid == 0) /* child */
625 {
cyy316723a2019-01-05 16:35:14 +0800626 std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
627 std::shared_ptr<TestHandler> testHandler(new TestHandler());
628 std::shared_ptr<ThriftTestProcessor> testProcessor(new ThriftTestProcessor(testHandler));
629 std::shared_ptr<TServerSocket> serverSocket(new TServerSocket(TEST_PORT));
630 std::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
Roger Meier213a6642010-10-27 12:30:11 +0000631 TSimpleServer simpleServer(testProcessor, serverSocket, transportFactory, protocolFactory);
632 signal (SIGALRM, bailout);
633 alarm (60);
634 simpleServer.serve();
635 } else {
636 sleep (1);
637 test_thrift_client ();
638 kill (pid, SIGINT);
Simon South38e71552015-08-03 10:51:16 +0000639 assert (wait (&status) == pid);
Roger Meier213a6642010-10-27 12:30:11 +0000640 }
641
642 return 0;
643}
644