blob: b0e5ef74bcfe8a3fbdc08c5bd1214af487cf521a [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +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.
Todd Lipcon53ae9f32009-12-07 00:42:38 +000018 *
19 * Contains some contributions under the Thrift Software License.
20 * Please see doc/old-thrift-license.txt in the Thrift distribution for
21 * details.
David Reissea2cba82009-03-30 21:35:00 +000022 */
23
David Reiss8320a922007-08-14 19:59:26 +000024#include <map>
Roger Meier49ff8b12012-04-13 09:12:31 +000025#include <thrift/protocol/TDebugProtocol.h>
26#include <thrift/protocol/TBinaryProtocol.h>
27#include <thrift/transport/TBufferTransports.h>
David Reiss8320a922007-08-14 19:59:26 +000028#include "gen-cpp/OptionalRequiredTest_types.h"
29
Claudius Heine5ef662b2015-06-24 10:03:50 +020030#define BOOST_TEST_MODULE OptionalRequiredTest
31#include <boost/test/unit_test.hpp>
32
David Reiss8320a922007-08-14 19:59:26 +000033using namespace thrift::test;
T Jake Lucianib5e62212009-01-31 22:36:20 +000034using namespace apache::thrift;
35using namespace apache::thrift::transport;
36using namespace apache::thrift::protocol;
David Reiss8320a922007-08-14 19:59:26 +000037
David Reiss8320a922007-08-14 19:59:26 +000038/*
39template<typename Struct>
40void trywrite(const Struct& s, bool should_work) {
41 bool worked;
42 try {
43 TBinaryProtocol protocol(boost::shared_ptr<TTransport>(new TMemoryBuffer));
44 s.write(&protocol);
45 worked = true;
46 } catch (TProtocolException & ex) {
47 worked = false;
48 }
Claudius Heine5ef662b2015-06-24 10:03:50 +020049 BOOST_CHECK(worked == should_work);
David Reiss8320a922007-08-14 19:59:26 +000050}
51*/
52
53template <typename Struct1, typename Struct2>
Konrad Grochowski16a23a62014-11-13 15:33:38 +010054void write_to_read(const Struct1& w, Struct2& r) {
David Reiss8320a922007-08-14 19:59:26 +000055 TBinaryProtocol protocol(boost::shared_ptr<TTransport>(new TMemoryBuffer));
56 w.write(&protocol);
57 r.read(&protocol);
58}
59
Claudius Heine5ef662b2015-06-24 10:03:50 +020060BOOST_AUTO_TEST_CASE(test_optional_required_1) {
61 OldSchool o;
David Reiss8320a922007-08-14 19:59:26 +000062
Claudius Heine5ef662b2015-06-24 10:03:50 +020063 const std::string expected_result(
64 "OldSchool {\n"
65 " 01: im_int (i16) = 0,\n"
66 " 02: im_str (string) = \"\",\n"
67 " 03: im_big (list) = list<map>[0] {\n"
68 " },\n"
69 "}");
70 const std::string result(apache::thrift::ThriftDebugString(o));
David Reiss8320a922007-08-14 19:59:26 +000071
Claudius Heine5ef662b2015-06-24 10:03:50 +020072 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
73 "Expected:\n" << expected_result << "\nGotten:\n" << result);
74}
David Reiss8320a922007-08-14 19:59:26 +000075
Claudius Heine5ef662b2015-06-24 10:03:50 +020076BOOST_AUTO_TEST_CASE(test_optional_required_2_1) {
77 Simple s;
David Reiss8320a922007-08-14 19:59:26 +000078
Claudius Heine5ef662b2015-06-24 10:03:50 +020079 const std::string expected_result(
80 "Simple {\n"
81 " 01: im_default (i16) = 0,\n"
82 " 02: im_required (i16) = 0,\n"
83 "}");
84 const std::string result(apache::thrift::ThriftDebugString(s));
85
86 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
87 "Expected:\n" << expected_result << "\nGotten:\n" << result);
88}
89
90BOOST_AUTO_TEST_CASE(test_optional_required_2_2) {
91 Simple s;
92 s.im_optional = 10;
93
94 const std::string expected_result(
95 "Simple {\n"
96 " 01: im_default (i16) = 0,\n"
97 " 02: im_required (i16) = 0,\n"
98 "}");
99 const std::string result(apache::thrift::ThriftDebugString(s));
100
101 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
102 "Expected:\n" << expected_result << "\nGotten:\n" << result);
103}
104
105BOOST_AUTO_TEST_CASE(test_optional_required_2_3) {
106 Simple s;
107 s.im_optional = 10;
108 s.__isset.im_optional = true;
109
110 const std::string expected_result(
111 "Simple {\n"
112 " 01: im_default (i16) = 0,\n"
113 " 02: im_required (i16) = 0,\n"
114 " 03: im_optional (i16) = 10,\n"
115 "}");
116 const std::string result(apache::thrift::ThriftDebugString(s));
117
118 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
119 "Expected:\n" << expected_result << "\nGotten:\n" << result);
120}
121
122BOOST_AUTO_TEST_CASE(test_optional_required_2_4) {
123 Simple s;
124 s.__isset.im_optional = true;
125
126 const std::string expected_result(
127 "Simple {\n"
128 " 01: im_default (i16) = 0,\n"
129 " 02: im_required (i16) = 0,\n"
130 " 03: im_optional (i16) = 0,\n"
131 "}");
132 const std::string result(apache::thrift::ThriftDebugString(s));
133
134 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
135 "Expected:\n" << expected_result << "\nGotten:\n" << result);
136}
137
138BOOST_AUTO_TEST_CASE(test_optional_required_2_5) {
139 Simple s;
140 s.__isset.im_optional = true;
141 s.im_optional = 10;
142
143 const std::string expected_result(
144 "Simple {\n"
145 " 01: im_default (i16) = 0,\n"
146 " 02: im_required (i16) = 0,\n"
147 " 03: im_optional (i16) = 10,\n"
148 "}");
149 const std::string result(apache::thrift::ThriftDebugString(s));
150
151 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
152 "Expected:\n" << expected_result << "\nGotten:\n" << result);
153}
154
155BOOST_AUTO_TEST_CASE(test_optional_required_3) {
Konrad Grochowski9db4b512014-12-04 23:32:52 +0100156 // assign/copy-construct with non-required fields
Konrad Grochowski9db4b512014-12-04 23:32:52 +0100157
Claudius Heine5ef662b2015-06-24 10:03:50 +0200158 Simple s1, s2;
159 s1.__isset.im_default = true;
160 s1.__set_im_optional(10);
161 BOOST_CHECK(s1.__isset.im_default);
162 BOOST_CHECK(s1.__isset.im_optional);
Konrad Grochowski9db4b512014-12-04 23:32:52 +0100163
Claudius Heine5ef662b2015-06-24 10:03:50 +0200164 s2 = s1;
Konrad Grochowski9db4b512014-12-04 23:32:52 +0100165
Claudius Heine5ef662b2015-06-24 10:03:50 +0200166 BOOST_CHECK(s2.__isset.im_default);
167 BOOST_CHECK(s2.__isset.im_optional);
Konrad Grochowski9db4b512014-12-04 23:32:52 +0100168
Claudius Heine5ef662b2015-06-24 10:03:50 +0200169 Simple s3(s1);
Konrad Grochowski9db4b512014-12-04 23:32:52 +0100170
Claudius Heine5ef662b2015-06-24 10:03:50 +0200171 BOOST_CHECK(s3.__isset.im_default);
172 BOOST_CHECK(s3.__isset.im_optional);
173}
174
175BOOST_AUTO_TEST_CASE(test_optional_required_4) {
David Reiss8320a922007-08-14 19:59:26 +0000176 // Write-to-read with optional fields.
David Reiss8320a922007-08-14 19:59:26 +0000177
Claudius Heine5ef662b2015-06-24 10:03:50 +0200178 Simple s1, s2, s3;
179 s1.im_optional = 10;
180 BOOST_CHECK(!s1.__isset.im_default);
181 // BOOST_CHECK(!s1.__isset.im_required); // Compile error.
182 BOOST_CHECK(!s1.__isset.im_optional);
David Reiss8320a922007-08-14 19:59:26 +0000183
Claudius Heine5ef662b2015-06-24 10:03:50 +0200184 write_to_read(s1, s2);
David Reiss8320a922007-08-14 19:59:26 +0000185
Claudius Heine5ef662b2015-06-24 10:03:50 +0200186 BOOST_CHECK(s2.__isset.im_default);
187 // BOOST_CHECK( s2.__isset.im_required); // Compile error.
188 BOOST_CHECK(!s2.__isset.im_optional);
189 BOOST_CHECK(s3.im_optional == 0);
David Reiss8320a922007-08-14 19:59:26 +0000190
Claudius Heine5ef662b2015-06-24 10:03:50 +0200191 s1.__isset.im_optional = true;
192 write_to_read(s1, s3);
David Reiss8320a922007-08-14 19:59:26 +0000193
Claudius Heine5ef662b2015-06-24 10:03:50 +0200194 BOOST_CHECK(s3.__isset.im_default);
195 // BOOST_CHECK( s3.__isset.im_required); // Compile error.
196 BOOST_CHECK(s3.__isset.im_optional);
197 BOOST_CHECK(s3.im_optional == 10);
198}
199
200BOOST_AUTO_TEST_CASE(test_optional_required_5) {
David Reiss8320a922007-08-14 19:59:26 +0000201 // Writing between optional and default.
David Reiss8320a922007-08-14 19:59:26 +0000202
Claudius Heine5ef662b2015-06-24 10:03:50 +0200203 Tricky1 t1;
204 Tricky2 t2;
David Reiss8320a922007-08-14 19:59:26 +0000205
Claudius Heine5ef662b2015-06-24 10:03:50 +0200206 t2.im_optional = 10;
207 write_to_read(t2, t1);
208 write_to_read(t1, t2);
209 BOOST_CHECK(!t1.__isset.im_default);
210 BOOST_CHECK(t2.__isset.im_optional);
211 BOOST_CHECK(t1.im_default == t2.im_optional);
212 BOOST_CHECK(t1.im_default == 0);
213}
214
215BOOST_AUTO_TEST_CASE(test_optional_required_6) {
David Reiss8320a922007-08-14 19:59:26 +0000216 // Writing between default and required.
David Reiss8320a922007-08-14 19:59:26 +0000217
Claudius Heine5ef662b2015-06-24 10:03:50 +0200218 Tricky1 t1;
219 Tricky3 t3;
220 write_to_read(t1, t3);
221 write_to_read(t3, t1);
222 BOOST_CHECK(t1.__isset.im_default);
223}
224
225BOOST_AUTO_TEST_CASE(test_optional_required_7) {
David Reiss8320a922007-08-14 19:59:26 +0000226 // Writing between optional and required.
David Reiss8320a922007-08-14 19:59:26 +0000227
Claudius Heine5ef662b2015-06-24 10:03:50 +0200228 Tricky2 t2;
229 Tricky3 t3;
230 t2.__isset.im_optional = true;
231 write_to_read(t2, t3);
232 write_to_read(t3, t2);
233}
234
235BOOST_AUTO_TEST_CASE(test_optional_required_8) {
David Reiss8320a922007-08-14 19:59:26 +0000236 // Mu-hu-ha-ha-ha!
David Reiss8320a922007-08-14 19:59:26 +0000237
Claudius Heine5ef662b2015-06-24 10:03:50 +0200238 Tricky2 t2;
239 Tricky3 t3;
240 try {
241 write_to_read(t2, t3);
242 abort();
243 } catch (const TProtocolException&) {
David Reiss8320a922007-08-14 19:59:26 +0000244 }
245
Claudius Heine5ef662b2015-06-24 10:03:50 +0200246 write_to_read(t3, t2);
247 BOOST_CHECK(t2.__isset.im_optional);
248}
David Reiss8320a922007-08-14 19:59:26 +0000249
Claudius Heine5ef662b2015-06-24 10:03:50 +0200250BOOST_AUTO_TEST_CASE(test_optional_required_9) {
251 Complex c;
David Reiss8320a922007-08-14 19:59:26 +0000252
Claudius Heine5ef662b2015-06-24 10:03:50 +0200253 const std::string expected_result(
254 "Complex {\n"
255 " 01: cp_default (i16) = 0,\n"
256 " 02: cp_required (i16) = 0,\n"
257 " 04: the_map (map) = map<i16,struct>[0] {\n"
258 " },\n"
259 " 05: req_simp (struct) = Simple {\n"
260 " 01: im_default (i16) = 0,\n"
261 " 02: im_required (i16) = 0,\n"
262 " },\n"
263 "}");
264 const std::string result(apache::thrift::ThriftDebugString(c));
David Reiss8320a922007-08-14 19:59:26 +0000265
Claudius Heine5ef662b2015-06-24 10:03:50 +0200266 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
267 "Expected:\n" << expected_result << "\nGotten:\n" << result);
268}
David Reiss8320a922007-08-14 19:59:26 +0000269
Claudius Heine5ef662b2015-06-24 10:03:50 +0200270BOOST_AUTO_TEST_CASE(test_optional_required_10) {
271 Tricky1 t1;
272 Tricky2 t2;
273 // Compile error.
274 //(void)(t1 == t2);
275}
David Reiss8320a922007-08-14 19:59:26 +0000276
Claudius Heine5ef662b2015-06-24 10:03:50 +0200277BOOST_AUTO_TEST_CASE(test_optional_required_11) {
278 OldSchool o1, o2, o3;
279 BOOST_CHECK(o1 == o2);
280 o1.im_int = o2.im_int = 10;
281 BOOST_CHECK(o1 == o2);
282 o1.__isset.im_int = true;
283 o2.__isset.im_int = false;
284 BOOST_CHECK(o1 == o2);
285 o1.im_int = 20;
286 o1.__isset.im_int = false;
287 BOOST_CHECK(o1 != o2);
288 o1.im_int = 10;
289 BOOST_CHECK(o1 == o2);
290 o1.im_str = o2.im_str = "foo";
291 BOOST_CHECK(o1 == o2);
292 o1.__isset.im_str = o2.__isset.im_str = true;
293 BOOST_CHECK(o1 == o2);
294 std::map<int32_t, std::string> mymap;
295 mymap[1] = "bar";
296 mymap[2] = "baz";
297 o1.im_big.push_back(std::map<int32_t, std::string>());
298 BOOST_CHECK(o1 != o2);
299 o2.im_big.push_back(std::map<int32_t, std::string>());
300 BOOST_CHECK(o1 == o2);
301 o2.im_big.push_back(mymap);
302 BOOST_CHECK(o1 != o2);
303 o1.im_big.push_back(mymap);
304 BOOST_CHECK(o1 == o2);
David Reiss8320a922007-08-14 19:59:26 +0000305
Claudius Heine5ef662b2015-06-24 10:03:50 +0200306 TBinaryProtocol protocol(boost::shared_ptr<TTransport>(new TMemoryBuffer));
307 o1.write(&protocol);
David Reiss8320a922007-08-14 19:59:26 +0000308
Claudius Heine5ef662b2015-06-24 10:03:50 +0200309 o1.im_big.push_back(mymap);
310 mymap[3] = "qux";
311 o2.im_big.push_back(mymap);
312 BOOST_CHECK(o1 != o2);
313 o1.im_big.back()[3] = "qux";
314 BOOST_CHECK(o1 == o2);
315
316 o3.read(&protocol);
317 o3.im_big.push_back(mymap);
318 BOOST_CHECK(o1 == o3);
David Reiss8320a922007-08-14 19:59:26 +0000319
Claudius Heine5ef662b2015-06-24 10:03:50 +0200320 const std::string expected_result(
321 "OldSchool {\n"
322 " 01: im_int (i16) = 10,\n"
323 " 02: im_str (string) = \"foo\",\n"
324 " 03: im_big (list) = list<map>[3] {\n"
325 " [0] = map<i32,string>[0] {\n"
326 " },\n"
327 " [1] = map<i32,string>[2] {\n"
328 " 1 -> \"bar\",\n"
329 " 2 -> \"baz\",\n"
330 " },\n"
331 " [2] = map<i32,string>[3] {\n"
332 " 1 -> \"bar\",\n"
333 " 2 -> \"baz\",\n"
334 " 3 -> \"qux\",\n"
335 " },\n"
336 " },\n"
337 "}");
338 const std::string result(apache::thrift::ThriftDebugString(o3));
Jake Farrellf9f01fa2012-01-27 04:48:26 +0000339
Claudius Heine5ef662b2015-06-24 10:03:50 +0200340 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
341 "Expected:\n" << expected_result << "\nGotten:\n" << result);
342}
Jake Farrellf9f01fa2012-01-27 04:48:26 +0000343
Claudius Heine5ef662b2015-06-24 10:03:50 +0200344BOOST_AUTO_TEST_CASE(test_optional_required_12) {
345 Tricky2 t1, t2;
346 BOOST_CHECK(t1.__isset.im_optional == false);
347 BOOST_CHECK(t2.__isset.im_optional == false);
348 BOOST_CHECK(t1 == t2);
349 t1.im_optional = 5;
350 BOOST_CHECK(t1 == t2);
351 t2.im_optional = 5;
352 BOOST_CHECK(t1 == t2);
353 t1.__isset.im_optional = true;
354 BOOST_CHECK(t1 != t2);
355 t2.__isset.im_optional = true;
356 BOOST_CHECK(t1 == t2);
357 t1.im_optional = 10;
358 BOOST_CHECK(t1 != t2);
359 t2.__isset.im_optional = false;
360 BOOST_CHECK(t1 != t2);
361}
362
363BOOST_AUTO_TEST_CASE(test_optional_required_13) {
364 OptionalDefault t1, t2;
365
366 BOOST_CHECK(t1.__isset.opt_int == true);
367 BOOST_CHECK(t1.__isset.opt_str == true);
368 BOOST_CHECK(t1.opt_int == t2.opt_int);
369 BOOST_CHECK(t1.opt_str == t2.opt_str);
370
371 write_to_read(t1, t2);
372 BOOST_CHECK(t2.__isset.opt_int == true);
373 BOOST_CHECK(t2.__isset.opt_str == true);
374 BOOST_CHECK(t1.opt_int == t2.opt_int);
375 BOOST_CHECK(t1.opt_str == t2.opt_str);
376
377 const std::string expected_result(
378 "OptionalDefault {\n"
379 " 01: opt_int (i16) = 1234,\n"
380 " 02: opt_str (string) = \"default\",\n"
381 "}");
382 const std::string result(apache::thrift::ThriftDebugString(t2));
383
384 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
385 "Expected:\n" << expected_result << "\nGotten:\n" << result);
David Reiss8320a922007-08-14 19:59:26 +0000386}