1 /*
2  * Copyright 2022 Young Mei
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 
9 #include <array>
10 #include <cfloat>
11 #include <locale>
12 #include <stdexcept>
13 
14 #include <sys/time.h>
15 
16 #include "context.hpp"
17 
18 using namespace apache::thrift;
19 
20 using namespace std;
21 
22 static void init_Xtruct(Xtruct &s);
23 
ZTEST(thrift,test_void)24 ZTEST(thrift, test_void)
25 {
26 	context.client->testVoid();
27 }
28 
ZTEST(thrift,test_string)29 ZTEST(thrift, test_string)
30 {
31 	string s;
32 	context.client->testString(s, "Test");
33 	zassert_equal(s, "Test", "");
34 }
35 
ZTEST(thrift,test_bool)36 ZTEST(thrift, test_bool)
37 {
38 	zassert_equal(false, context.client->testBool(false), "");
39 	zassert_equal(true, context.client->testBool(true), "");
40 }
41 
ZTEST(thrift,test_byte)42 ZTEST(thrift, test_byte)
43 {
44 	zassert_equal(0, context.client->testByte(0), "");
45 	zassert_equal(-1, context.client->testByte(-1), "");
46 	zassert_equal(42, context.client->testByte(42), "");
47 	zassert_equal(-42, context.client->testByte(-42), "");
48 	zassert_equal(127, context.client->testByte(127), "");
49 	zassert_equal(-128, context.client->testByte(-128), "");
50 }
51 
ZTEST(thrift,test_i32)52 ZTEST(thrift, test_i32)
53 {
54 	zassert_equal(0, context.client->testI32(0), "");
55 	zassert_equal(-1, context.client->testI32(-1), "");
56 	zassert_equal(190000013, context.client->testI32(190000013), "");
57 	zassert_equal(-190000013, context.client->testI32(-190000013), "");
58 	zassert_equal(INT32_MAX, context.client->testI32(INT32_MAX), "");
59 	zassert_equal(INT32_MIN, context.client->testI32(INT32_MIN), "");
60 }
61 
ZTEST(thrift,test_i64)62 ZTEST(thrift, test_i64)
63 {
64 	zassert_equal(0, context.client->testI64(0), "");
65 	zassert_equal(-1, context.client->testI64(-1), "");
66 	zassert_equal(7000000000000000123LL, context.client->testI64(7000000000000000123LL), "");
67 	zassert_equal(-7000000000000000123LL, context.client->testI64(-7000000000000000123LL), "");
68 	zassert_equal(INT64_MAX, context.client->testI64(INT64_MAX), "");
69 	zassert_equal(INT64_MIN, context.client->testI64(INT64_MIN), "");
70 }
71 
ZTEST(thrift,test_double)72 ZTEST(thrift, test_double)
73 {
74 	zassert_equal(0.0, context.client->testDouble(0.0), "");
75 	zassert_equal(-1.0, context.client->testDouble(-1.0), "");
76 	zassert_equal(-5.2098523, context.client->testDouble(-5.2098523), "");
77 	zassert_equal(-0.000341012439638598279,
78 		      context.client->testDouble(-0.000341012439638598279), "");
79 	zassert_equal(DBL_MAX, context.client->testDouble(DBL_MAX), "");
80 	zassert_equal(-DBL_MAX, context.client->testDouble(-DBL_MAX), "");
81 }
82 
ZTEST(thrift,test_binary)83 ZTEST(thrift, test_binary)
84 {
85 	string rsp;
86 
87 	context.client->testBinary(rsp, "");
88 	zassert_equal("", rsp, "");
89 	context.client->testBinary(rsp, "Hello");
90 	zassert_equal("Hello", rsp, "");
91 	context.client->testBinary(rsp, "H\x03\x01\x01\x00");
92 	zassert_equal("H\x03\x01\x01\x00", rsp, "");
93 }
94 
ZTEST(thrift,test_struct)95 ZTEST(thrift, test_struct)
96 {
97 	Xtruct request_struct;
98 	init_Xtruct(request_struct);
99 	Xtruct response_struct;
100 	context.client->testStruct(response_struct, request_struct);
101 
102 	zassert_equal(response_struct, request_struct, NULL);
103 }
104 
ZTEST(thrift,test_nested_struct)105 ZTEST(thrift, test_nested_struct)
106 {
107 	Xtruct2 request_struct;
108 	request_struct.byte_thing = 1;
109 	init_Xtruct(request_struct.struct_thing);
110 	request_struct.i32_thing = 5;
111 	Xtruct2 response_struct;
112 	context.client->testNest(response_struct, request_struct);
113 
114 	zassert_equal(response_struct, request_struct, NULL);
115 }
116 
ZTEST(thrift,test_map)117 ZTEST(thrift, test_map)
118 {
119 	static const map<int32_t, int32_t> request_map = {
120 		{0, -10}, {1, -9}, {2, -8}, {3, -7}, {4, -6}};
121 
122 	map<int32_t, int32_t> response_map;
123 	context.client->testMap(response_map, request_map);
124 
125 	zassert_equal(request_map, response_map, "");
126 }
127 
ZTEST(thrift,test_string_map)128 ZTEST(thrift, test_string_map)
129 {
130 	static const map<string, string> request_smap = {
131 		{"a", "2"}, {"b", "blah"}, {"some", "thing"}
132 	};
133 	map<string, string> response_smap;
134 
135 	context.client->testStringMap(response_smap, request_smap);
136 	zassert_equal(response_smap, request_smap, "");
137 }
138 
ZTEST(thrift,test_set)139 ZTEST(thrift, test_set)
140 {
141 	static const set<int32_t> request_set = {-2, -1, 0, 1, 2};
142 
143 	set<int32_t> response_set;
144 	context.client->testSet(response_set, request_set);
145 
146 	zassert_equal(request_set, response_set, "");
147 }
148 
ZTEST(thrift,test_list)149 ZTEST(thrift, test_list)
150 {
151 	vector<int32_t> response_list;
152 	context.client->testList(response_list, vector<int32_t>());
153 	zassert_true(response_list.empty(), "Unexpected list size: %llu", response_list.size());
154 
155 	static const vector<int32_t> request_list = {-2, -1, 0, 1, 2};
156 
157 	response_list.clear();
158 	context.client->testList(response_list, request_list);
159 	zassert_equal(request_list, response_list, "");
160 }
161 
ZTEST(thrift,test_enum)162 ZTEST(thrift, test_enum)
163 {
164 	Numberz::type response = context.client->testEnum(Numberz::ONE);
165 	zassert_equal(response, Numberz::ONE, NULL);
166 
167 	response = context.client->testEnum(Numberz::TWO);
168 	zassert_equal(response, Numberz::TWO, NULL);
169 
170 	response = context.client->testEnum(Numberz::EIGHT);
171 	zassert_equal(response, Numberz::EIGHT, NULL);
172 }
173 
ZTEST(thrift,test_typedef)174 ZTEST(thrift, test_typedef)
175 {
176 	UserId uid = context.client->testTypedef(309858235082523LL);
177 	zassert_equal(uid, 309858235082523LL, "Unexpected uid: %llu", uid);
178 }
179 
ZTEST(thrift,test_nested_map)180 ZTEST(thrift, test_nested_map)
181 {
182 	map<int32_t, map<int32_t, int32_t>> mm;
183 	context.client->testMapMap(mm, 1);
184 
185 	zassert_equal(mm.size(), 2, NULL);
186 	zassert_equal(mm[-4][-4], -4, NULL);
187 	zassert_equal(mm[-4][-3], -3, NULL);
188 	zassert_equal(mm[-4][-2], -2, NULL);
189 	zassert_equal(mm[-4][-1], -1, NULL);
190 	zassert_equal(mm[4][4], 4, NULL);
191 	zassert_equal(mm[4][3], 3, NULL);
192 	zassert_equal(mm[4][2], 2, NULL);
193 	zassert_equal(mm[4][1], 1, NULL);
194 }
195 
ZTEST(thrift,test_exception)196 ZTEST(thrift, test_exception)
197 {
198 	std::exception_ptr eptr = nullptr;
199 
200 	try {
201 		context.client->testException("Xception");
202 	} catch (...) {
203 		eptr = std::current_exception();
204 	}
205 	zassert_not_equal(nullptr, eptr, "an exception was not thrown");
206 
207 	eptr = nullptr;
208 	try {
209 		context.client->testException("TException");
210 	} catch (...) {
211 		eptr = std::current_exception();
212 	}
213 	zassert_not_equal(nullptr, eptr, "an exception was not thrown");
214 
215 	context.client->testException("success");
216 }
217 
ZTEST(thrift,test_multi_exception)218 ZTEST(thrift, test_multi_exception)
219 {
220 	std::exception_ptr eptr = nullptr;
221 
222 	try {
223 		Xtruct result;
224 		context.client->testMultiException(result, "Xception", "test 1");
225 	} catch (...) {
226 		eptr = std::current_exception();
227 	}
228 	zassert_not_equal(nullptr, eptr, "an exception was not thrown");
229 
230 	eptr = nullptr;
231 	try {
232 		Xtruct result;
233 		context.client->testMultiException(result, "Xception2", "test 2");
234 	} catch (...) {
235 		eptr = std::current_exception();
236 	}
237 	zassert_not_equal(nullptr, eptr, "an exception was not thrown");
238 }
239 
init_Xtruct(Xtruct & s)240 static void init_Xtruct(Xtruct &s)
241 {
242 	s.string_thing = "Zero";
243 	s.byte_thing = 1;
244 	s.i32_thing = -3;
245 	s.i64_thing = -5;
246 }
247