blob: a2ac08887267c99d986a6e7248126684fde47aaa [file] [log] [blame]
Austin Schuh09d7ffa2019-10-03 23:43:34 -07001#include "aos/flatbuffer_merge.h"
2
Austin Schuha4fc60f2020-11-01 23:06:47 -08003#include <string_view>
4
5#include "absl/strings/escaping.h"
Austin Schuh09d7ffa2019-10-03 23:43:34 -07006#include "flatbuffers/minireflect.h"
Austin Schuh60e77942022-05-16 17:48:24 -07007#include "gtest/gtest.h"
Austin Schuh09d7ffa2019-10-03 23:43:34 -07008
Philipp Schrader790cb542023-07-05 21:06:52 -07009#include "aos/json_to_flatbuffer.h"
10#include "aos/json_to_flatbuffer_generated.h"
11
Stephan Pleinesf63bde82024-01-13 15:59:33 -080012namespace aos::testing {
Austin Schuh09d7ffa2019-10-03 23:43:34 -070013
Austin Schuha4fc60f2020-11-01 23:06:47 -080014std::string_view FromFbb(const flatbuffers::FlatBufferBuilder &fbb) {
15 return std::string_view(
16 reinterpret_cast<const char *>(fbb.GetCurrentBufferPointer()),
17 fbb.GetSize());
18}
19
Austin Schuhadd6eb32020-11-09 21:24:26 -080020std::string_view FromFbb(const FlatbufferDetachedBuffer<Configuration> &b) {
21 return std::string_view(reinterpret_cast<const char *>(b.span().data()),
22 b.span().size());
Austin Schuha4fc60f2020-11-01 23:06:47 -080023}
24
Austin Schuh09d7ffa2019-10-03 23:43:34 -070025class FlatbufferMerge : public ::testing::Test {
26 public:
27 FlatbufferMerge() {}
28
Austin Schuhadd6eb32020-11-09 21:24:26 -080029 void ExpectMergedOutput(
30 const NonSizePrefixedFlatbuffer<Configuration> &fb_merged,
31 std::string_view expected_output) {
32 ASSERT_NE(fb_merged.span().size(), 0u);
James Kuszmaulf3a3be22020-01-04 12:12:00 -080033
Austin Schuhadd6eb32020-11-09 21:24:26 -080034 const ::std::string merged_output = FlatbufferToJson(fb_merged);
James Kuszmaulf3a3be22020-01-04 12:12:00 -080035 EXPECT_EQ(expected_output, merged_output);
Austin Schuh30d7db92020-01-26 16:45:47 -080036
37 aos::FlatbufferDetachedBuffer<Configuration> expected_message(
38 JsonToFlatbuffer(std::string(expected_output).c_str(),
39 ConfigurationTypeTable()));
40 EXPECT_TRUE(
Austin Schuhadd6eb32020-11-09 21:24:26 -080041 CompareFlatBuffer(&fb_merged.message(), &expected_message.message()));
James Kuszmaulf3a3be22020-01-04 12:12:00 -080042 }
43
Austin Schuh09d7ffa2019-10-03 23:43:34 -070044 void JsonMerge(const ::std::string in1, const ::std::string in2,
45 const ::std::string out) {
Austin Schuhadd6eb32020-11-09 21:24:26 -080046 LOG(INFO) << "Merging: " << in1.c_str();
47 LOG(INFO) << "Merging: " << in2.c_str();
48 const FlatbufferDetachedBuffer<Configuration> fb1 = JsonToFlatbuffer(
Austin Schuh09d7ffa2019-10-03 23:43:34 -070049 static_cast<const char *>(in1.c_str()), ConfigurationTypeTable());
50
51 const ::std::string in1_nested = "{ \"nested_config\": " + in1 + " }";
Austin Schuhadd6eb32020-11-09 21:24:26 -080052 const FlatbufferDetachedBuffer<Configuration> fb1_nested =
Austin Schuhe93d8642019-10-13 15:27:07 -070053 JsonToFlatbuffer(static_cast<const char *>(in1_nested.c_str()),
54 ConfigurationTypeTable());
Austin Schuh09d7ffa2019-10-03 23:43:34 -070055
Austin Schuhadd6eb32020-11-09 21:24:26 -080056 const FlatbufferDetachedBuffer<Configuration> fb2 = JsonToFlatbuffer(
Austin Schuh09d7ffa2019-10-03 23:43:34 -070057 static_cast<const char *>(in2.c_str()), ConfigurationTypeTable());
58
59 const ::std::string in2_nested = "{ \"nested_config\": " + in2 + " }";
Austin Schuhadd6eb32020-11-09 21:24:26 -080060 const FlatbufferDetachedBuffer<Configuration> fb2_nested =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070061 JsonToFlatbuffer(static_cast<const char *>(in2_nested.c_str()),
62 ConfigurationTypeTable());
63
64 const ::std::string out_nested = "{ \"nested_config\": " + out + " }";
65
Austin Schuhadd6eb32020-11-09 21:24:26 -080066 const FlatbufferDetachedBuffer<Configuration> empty =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070067 JsonToFlatbuffer("{ }", ConfigurationTypeTable());
68
Austin Schuhadd6eb32020-11-09 21:24:26 -080069 ASSERT_NE(fb1.span().size(), 0u);
70 ASSERT_NE(fb2.span().size(), 0u);
71 ASSERT_NE(fb1_nested.span().size(), 0u);
72 ASSERT_NE(fb2_nested.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -070073
74 // We now want to run 7 tests.
75 // in1 merged "" -> in1.
76 // in2 merged "" -> in2.
77 // "" merged in1 -> in1.
78 // "" merged in2 -> in2.
79 // nullptr merged in1 -> in1.
80 // in1 merged nullptr -> in1.
81 // in1 merged in2 -> out.
82
83 {
84 // in1 merged with "" => in1.
Austin Schuhadd6eb32020-11-09 21:24:26 -080085 FlatbufferDetachedBuffer<Configuration> fb_merged =
86 MergeFlatBuffers<Configuration>(fb1, empty);
87 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -070088
Austin Schuhadd6eb32020-11-09 21:24:26 -080089 EXPECT_EQ(in1, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -070090 }
91
92 {
93 // in2 merged with "" => in2.
Austin Schuhadd6eb32020-11-09 21:24:26 -080094 FlatbufferDetachedBuffer<Configuration> fb_merged =
95 MergeFlatBuffers<Configuration>(fb2, empty);
96 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -070097
Austin Schuhadd6eb32020-11-09 21:24:26 -080098 EXPECT_EQ(in2, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -070099 }
100
101 {
102 // "" merged with in1 => in1.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800103 FlatbufferDetachedBuffer<Configuration> fb_merged =
104 MergeFlatBuffers<Configuration>(empty, fb1);
105 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700106
Austin Schuhadd6eb32020-11-09 21:24:26 -0800107 EXPECT_EQ(in1, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700108 }
109
110 {
111 // "" merged with in2 => in2.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800112 FlatbufferDetachedBuffer<Configuration> fb_merged =
113 MergeFlatBuffers<Configuration>(empty, fb2);
114 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700115
Austin Schuhadd6eb32020-11-09 21:24:26 -0800116 EXPECT_EQ(in2, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700117 }
118
119 {
120 // nullptr merged with in1 => in1.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800121 FlatbufferDetachedBuffer<Configuration> fb_merged =
122 MergeFlatBuffers<Configuration>(nullptr, &fb1.message());
123 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700124
Austin Schuhadd6eb32020-11-09 21:24:26 -0800125 EXPECT_EQ(in1, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700126 }
127
128 {
129 // in1 merged with nullptr => in1.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800130 FlatbufferDetachedBuffer<Configuration> fb_merged =
131 MergeFlatBuffers<Configuration>(&fb1.message(), nullptr);
132 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700133
Austin Schuhadd6eb32020-11-09 21:24:26 -0800134 EXPECT_EQ(in1, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700135 }
136
137 {
138 // in1 merged with in2 => out.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800139 FlatbufferDetachedBuffer<Configuration> fb_merged =
140 MergeFlatBuffers<Configuration>(fb1, fb2);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700141
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800142 ExpectMergedOutput(fb_merged, out);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700143 }
144
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800145 // Test all the different merge methods:
Austin Schuhadd6eb32020-11-09 21:24:26 -0800146 ExpectMergedOutput(MergeFlatBuffers<Configuration>(fb1, fb2), out);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800147 {
148 flatbuffers::FlatBufferBuilder fbb;
Austin Schuhd7b15da2020-02-17 15:06:11 -0800149 fbb.ForceDefaults(true);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800150 fbb.Finish(MergeFlatBuffers(
151 ConfigurationTypeTable(),
Austin Schuhadd6eb32020-11-09 21:24:26 -0800152 reinterpret_cast<const flatbuffers::Table *>(&fb1.message()),
153 reinterpret_cast<const flatbuffers::Table *>(&fb2.message()), &fbb));
154 FlatbufferDetachedBuffer<Configuration> fb(fbb.Release());
155 ExpectMergedOutput(fb, out);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800156 }
157 {
158 flatbuffers::FlatBufferBuilder fbb;
Austin Schuhd7b15da2020-02-17 15:06:11 -0800159 fbb.ForceDefaults(true);
Austin Schuhadd6eb32020-11-09 21:24:26 -0800160 fbb.Finish(MergeFlatBuffers<Configuration>(&fb1.message(), &fb2.message(),
161 &fbb));
162 FlatbufferDetachedBuffer<Configuration> fb(fbb.Release());
163 ExpectMergedOutput(fb, out);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800164 }
Austin Schuhadd6eb32020-11-09 21:24:26 -0800165 ExpectMergedOutput(
166 MergeFlatBuffers<Configuration>(&fb1.message(), &fb2.message()), out);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800167 ExpectMergedOutput(MergeFlatBuffers<Configuration>(fb1, fb2), out);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800168
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700169 // Now, to make things extra exciting, nest a config inside a config. And
170 // run all the tests. This will exercise some fun nested merges and copies.
171
172 {
173 // in1_nested merged with "" => in1.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800174 FlatbufferDetachedBuffer<Configuration> fb_merged =
175 MergeFlatBuffers<Configuration>(fb1_nested, empty);
176 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700177
Austin Schuhadd6eb32020-11-09 21:24:26 -0800178 EXPECT_EQ(in1_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700179 }
180
181 {
182 // in2_nested merged with "" => in2_nested.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800183 FlatbufferDetachedBuffer<Configuration> fb_merged =
184 MergeFlatBuffers<Configuration>(fb2_nested, empty);
185 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700186
Austin Schuhadd6eb32020-11-09 21:24:26 -0800187 EXPECT_EQ(in2_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700188 }
189
190 {
191 // "" merged with in1_nested => in1_nested.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800192 FlatbufferDetachedBuffer<Configuration> fb_merged =
193 MergeFlatBuffers<Configuration>(empty, fb1_nested);
194 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700195
Austin Schuhadd6eb32020-11-09 21:24:26 -0800196 EXPECT_EQ(in1_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700197 }
198
199 {
200 // "" merged with in2_nested => in2_nested.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800201 FlatbufferDetachedBuffer<Configuration> fb_merged =
202 MergeFlatBuffers<Configuration>(empty, fb2_nested);
203 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700204
Austin Schuhadd6eb32020-11-09 21:24:26 -0800205 EXPECT_EQ(in2_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700206 }
207
208 {
209 // nullptr merged with in1_nested => in1_nested.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800210 FlatbufferDetachedBuffer<Configuration> fb_merged =
211 MergeFlatBuffers<Configuration>(nullptr, &fb1_nested.message());
212 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700213
Austin Schuhadd6eb32020-11-09 21:24:26 -0800214 EXPECT_EQ(in1_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700215 }
216
217 {
218 // nullptr merged with in1_nested => in1_nested.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800219 FlatbufferDetachedBuffer<Configuration> fb_merged(
220 MergeFlatBuffers<Configuration>(&fb1_nested.message(), nullptr));
221 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700222
Austin Schuhadd6eb32020-11-09 21:24:26 -0800223 EXPECT_EQ(in1_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700224 }
225
226 {
227 // in1_nested merged with in2_nested => out_nested.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800228 FlatbufferDetachedBuffer<Configuration> fb_merged(
229 MergeFlatBuffers<Configuration>(fb1_nested, fb2_nested));
230 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700231
Austin Schuhadd6eb32020-11-09 21:24:26 -0800232 EXPECT_EQ(out_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700233 }
Austin Schuha4fc60f2020-11-01 23:06:47 -0800234
235 // TODO(austin): Try more flatbuffers...
236 // Now try copying various flatbuffers and confirming they match.
237 {
238 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
239 aos_flatbuffer_copy_fbb.ForceDefaults(true);
240
241 LOG(INFO) << "Copying " << in1 << " "
242 << absl::BytesToHexString(FromFbb(fb1)) << " at "
Austin Schuhadd6eb32020-11-09 21:24:26 -0800243 << reinterpret_cast<const void *>(fb1.span().data()) << " size "
244 << fb1.span().size();
Austin Schuha4fc60f2020-11-01 23:06:47 -0800245 aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800246 &fb1.message(), &aos_flatbuffer_copy_fbb));
Austin Schuha4fc60f2020-11-01 23:06:47 -0800247
Austin Schuhadd6eb32020-11-09 21:24:26 -0800248 const aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
Austin Schuha4fc60f2020-11-01 23:06:47 -0800249 aos_flatbuffer_copy_fbb.Release());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800250 ASSERT_NE(fb_copy.span().size(), 0u);
Austin Schuha4fc60f2020-11-01 23:06:47 -0800251
Austin Schuhadd6eb32020-11-09 21:24:26 -0800252 EXPECT_TRUE(fb1.Verify());
Austin Schuha4fc60f2020-11-01 23:06:47 -0800253
254 ASSERT_TRUE(fb_copy.Verify()) << in1;
255
256 EXPECT_EQ(in1, FlatbufferToJson(fb_copy));
257 }
258
259 {
Austin Schuh4a5f5d22021-10-12 15:09:35 -0700260 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
261 aos_flatbuffer_copy_fbb.ForceDefaults(false);
262
263 LOG(INFO) << "Copying without defaults " << in1 << " "
264 << absl::BytesToHexString(FromFbb(fb1)) << " at "
265 << reinterpret_cast<const void *>(fb1.span().data()) << " size "
266 << fb1.span().size();
267 aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
268 &fb1.message(), &aos_flatbuffer_copy_fbb));
269
270 const aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
271 aos_flatbuffer_copy_fbb.Release());
272 ASSERT_NE(fb_copy.span().size(), 0u);
273
274 EXPECT_TRUE(fb1.Verify());
275
276 ASSERT_TRUE(fb_copy.Verify()) << in1;
277
278 EXPECT_EQ(in1, FlatbufferToJson(fb_copy));
279 }
280
281 {
Austin Schuha4fc60f2020-11-01 23:06:47 -0800282 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_message_ptr_fbb;
283 aos_flatbuffer_copy_message_ptr_fbb.ForceDefaults(true);
284
285 aos_flatbuffer_copy_message_ptr_fbb.Finish(CopyFlatBuffer<Configuration>(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800286 &fb2.message(), &aos_flatbuffer_copy_message_ptr_fbb));
Austin Schuha4fc60f2020-11-01 23:06:47 -0800287
288 aos::FlatbufferDetachedBuffer<Configuration> fb_copy_message_ptr(
289 aos_flatbuffer_copy_message_ptr_fbb.Release());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800290 ASSERT_NE(fb_copy_message_ptr.span().size(), 0u);
Austin Schuha4fc60f2020-11-01 23:06:47 -0800291
292 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_full_fbb;
293 aos_flatbuffer_copy_full_fbb.ForceDefaults(true);
294
295 aos_flatbuffer_copy_full_fbb.Finish(BlindCopyFlatBuffer<Configuration>(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800296 aos::FlatbufferSpan<Configuration>(fb2.span()),
Austin Schuha4fc60f2020-11-01 23:06:47 -0800297 &aos_flatbuffer_copy_full_fbb));
298
299 aos::FlatbufferDetachedBuffer<Configuration> fb_copy_full(
300 aos_flatbuffer_copy_full_fbb.Release());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800301 ASSERT_NE(fb_copy_full.span().size(), 0u);
Austin Schuha4fc60f2020-11-01 23:06:47 -0800302
Austin Schuhadd6eb32020-11-09 21:24:26 -0800303 EXPECT_TRUE(fb2.Verify());
Austin Schuha4fc60f2020-11-01 23:06:47 -0800304
305 LOG(INFO) << "Verifying copy of " << in2;
306 ASSERT_TRUE(fb_copy_message_ptr.Verify()) << in2;
307 LOG(INFO) << "Verifying full of " << in2;
308 ASSERT_TRUE(fb_copy_full.Verify()) << in2;
309
310 EXPECT_EQ(in2, FlatbufferToJson(fb_copy_message_ptr));
311 EXPECT_EQ(in2, FlatbufferToJson(fb_copy_full));
312 }
313
314 {
315 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
316 aos_flatbuffer_copy_fbb.ForceDefaults(true);
317
318 aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800319 &fb1_nested.message(), &aos_flatbuffer_copy_fbb));
Austin Schuha4fc60f2020-11-01 23:06:47 -0800320
321 aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
322 aos_flatbuffer_copy_fbb.Release());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800323 ASSERT_NE(fb_copy.span().size(), 0u);
Austin Schuha4fc60f2020-11-01 23:06:47 -0800324
325 ASSERT_TRUE(fb_copy.Verify());
326
327 EXPECT_EQ(in1_nested, FlatbufferToJson(fb_copy));
328 }
329
330 {
331 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
332 aos_flatbuffer_copy_fbb.ForceDefaults(true);
333
334 aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800335 &fb2_nested.message(), &aos_flatbuffer_copy_fbb));
Austin Schuha4fc60f2020-11-01 23:06:47 -0800336
337 aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
338 aos_flatbuffer_copy_fbb.Release());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800339 ASSERT_NE(fb_copy.span().size(), 0u);
Austin Schuha4fc60f2020-11-01 23:06:47 -0800340
341 ASSERT_TRUE(fb_copy.Verify());
342
343 EXPECT_EQ(in2_nested, FlatbufferToJson(fb_copy));
344 }
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700345 }
346};
347
348// Test the easy ones. Test every type, single, no nesting.
349TEST_F(FlatbufferMerge, Basic) {
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800350 JsonMerge("{ }", "{ }", "{ }");
351
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700352 JsonMerge("{ \"foo_bool\": true }", "{ \"foo_bool\": false }",
353 "{ \"foo_bool\": false }");
354
355 JsonMerge("{ \"foo_bool\": false }", "{ \"foo_bool\": true }",
356 "{ \"foo_bool\": true }");
357
358 JsonMerge("{ \"foo_byte\": 5 }", "{ \"foo_byte\": -7 }",
359 "{ \"foo_byte\": -7 }");
360
361 JsonMerge("{ \"foo_ubyte\": 5 }", "{ \"foo_ubyte\": 7 }",
362 "{ \"foo_ubyte\": 7 }");
363
364 JsonMerge("{ \"foo_short\": 5 }", "{ \"foo_short\": 7 }",
365 "{ \"foo_short\": 7 }");
366
367 JsonMerge("{ \"foo_int\": 5 }", "{ \"foo_int\": 7 }", "{ \"foo_int\": 7 }");
368
369 JsonMerge("{ \"foo_uint\": 5 }", "{ \"foo_uint\": 7 }",
370 "{ \"foo_uint\": 7 }");
371
372 JsonMerge("{ \"foo_long\": 5 }", "{ \"foo_long\": 7 }",
373 "{ \"foo_long\": 7 }");
374
375 JsonMerge("{ \"foo_ulong\": 5 }", "{ \"foo_ulong\": 7 }",
376 "{ \"foo_ulong\": 7 }");
377
378 JsonMerge("{ \"foo_float\": 5.0 }", "{ \"foo_float\": 7.1 }",
379 "{ \"foo_float\": 7.1 }");
380
381 JsonMerge("{ \"foo_double\": 5.0 }", "{ \"foo_double\": 7.1 }",
382 "{ \"foo_double\": 7.1 }");
383}
384
385// Test arrays of simple types.
386TEST_F(FlatbufferMerge, Array) {
387 JsonMerge("{ \"foo_string\": \"baz\" }", "{ \"foo_string\": \"bar\" }",
388 "{ \"foo_string\": \"bar\" }");
389
390 JsonMerge("{ \"vector_foo_bool\": [ true, true, false ] }",
391 "{ \"vector_foo_bool\": [ false, true, true, false ] }",
392 "{ \"vector_foo_bool\": [ true, true, false, false, "
393 "true, true, false ] }");
394
395 JsonMerge("{ \"vector_foo_byte\": [ 9, 7, 1 ] }",
396 "{ \"vector_foo_byte\": [ -3, 1, 3, 2 ] }",
397 "{ \"vector_foo_byte\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
398
399 JsonMerge("{ \"vector_foo_ubyte\": [ 9, 7, 1 ] }",
400 "{ \"vector_foo_ubyte\": [ 3, 1, 3, 2 ] }",
401 "{ \"vector_foo_ubyte\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
402
403 JsonMerge("{ \"vector_foo_short\": [ 9, 7, 1 ] }",
404 "{ \"vector_foo_short\": [ -3, 1, 3, 2 ] }",
405 "{ \"vector_foo_short\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
406
407 JsonMerge("{ \"vector_foo_ushort\": [ 9, 7, 1 ] }",
408 "{ \"vector_foo_ushort\": [ 3, 1, 3, 2 ] }",
409 "{ \"vector_foo_ushort\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
410
411 JsonMerge("{ \"vector_foo_int\": [ 9, 7, 1 ] }",
412 "{ \"vector_foo_int\": [ -3, 1, 3, 2 ] }",
413 "{ \"vector_foo_int\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
414
415 JsonMerge("{ \"vector_foo_uint\": [ 9, 7, 1 ] }",
416 "{ \"vector_foo_uint\": [ 3, 1, 3, 2 ] }",
417 "{ \"vector_foo_uint\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
418
419 JsonMerge("{ \"vector_foo_long\": [ 9, 7, 1 ] }",
420 "{ \"vector_foo_long\": [ -3, 1, 3, 2 ] }",
421 "{ \"vector_foo_long\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
422
423 JsonMerge("{ \"vector_foo_ulong\": [ 9, 7, 1 ] }",
424 "{ \"vector_foo_ulong\": [ 3, 1, 3, 2 ] }",
425 "{ \"vector_foo_ulong\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
426
427 JsonMerge("{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ] }",
428 "{ \"vector_foo_float\": [ -3.0, 1.3, 3.0, 2.0 ] }",
429 "{ \"vector_foo_float\": [ 9.0, 7.0, 1.0, -3.0, 1.3, 3.0, 2.0 ] }");
430
Austin Schuhe93d8642019-10-13 15:27:07 -0700431 JsonMerge(
432 "{ \"vector_foo_string\": [ \"9\", \"7\", \"1 \" ] }",
433 "{ \"vector_foo_string\": [ \"31\", \"32\" ] }",
434 "{ \"vector_foo_string\": [ \"9\", \"7\", \"1 \", \"31\", \"32\" ] }");
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700435}
436
437// Test nested messages, and arrays of nested messages.
438TEST_F(FlatbufferMerge, NestedStruct) {
439 JsonMerge(
440 "{ \"single_application\": { \"name\": \"woot\" } }",
441 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
442 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }");
443
444 JsonMerge(
445 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
446 "{ \"single_application\": { \"name\": \"woot\" } }",
447 "{ \"single_application\": { \"name\": \"woot\", \"priority\": 7 } }");
448
449 JsonMerge("{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] }",
450 "{ \"apps\": [ { \"name\": \"woo2\" }, { \"name\": \"wo3\" } ] }",
451 "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" }, { "
452 "\"name\": \"woo2\" }, { \"name\": \"wo3\" } ] }");
453}
454
Austin Schuha4fc60f2020-11-01 23:06:47 -0800455// Test nested messages, and arrays of nested messages.
456TEST(FlatbufferCopy, WholesaleCopy) {
457 flatbuffers::FlatBufferBuilder fbb_expected;
458 fbb_expected.ForceDefaults(true);
459 fbb_expected.DedupVtables(false);
460
461 {
462 flatbuffers::Offset<flatbuffers::String> name1_offset =
463 fbb_expected.CreateString("wow");
464
465 std::vector<flatbuffers::Offset<Application>> application_offsets;
466 Application::Builder a1_builder(fbb_expected);
467 a1_builder.add_name(name1_offset);
468 a1_builder.add_priority(7);
469 a1_builder.add_long_thingy(0x2549713132LL);
470 application_offsets.emplace_back(a1_builder.Finish());
471
472 flatbuffers::Offset<flatbuffers::String> name2_offset =
473 fbb_expected.CreateString("foo");
474 Application::Builder a2_builder(fbb_expected);
475 a2_builder.add_name(name2_offset);
476 a2_builder.add_priority(3);
477 a2_builder.add_long_thingy(9);
478 application_offsets.emplace_back(a2_builder.Finish());
479
480 flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Application>>>
481 applications_offset = fbb_expected.CreateVector(application_offsets);
482
483 Configuration::Builder configuration_builder(fbb_expected);
484 configuration_builder.add_apps(applications_offset);
485 fbb_expected.Finish(configuration_builder.Finish());
486 }
487
488 LOG(INFO) << "Initial alignment " << fbb_expected.GetBufferMinAlignment();
489
490 aos::FlatbufferDetachedBuffer<Configuration> expected(fbb_expected.Release());
491
492 LOG(INFO) << "Expected "
493 << absl::BytesToHexString(std::string_view(
494 reinterpret_cast<char *>(expected.span().data()),
495 expected.span().size()));
496
497 aos::FlatbufferDetachedBuffer<Application> a1 = []() {
498 flatbuffers::FlatBufferBuilder fbb;
499 fbb.ForceDefaults(true);
500
501 flatbuffers::Offset<flatbuffers::String> name1_offset =
502 fbb.CreateString("wow");
503
504 Application::Builder a1_builder(fbb);
505 a1_builder.add_name(name1_offset);
506 a1_builder.add_priority(7);
507 a1_builder.add_long_thingy(0x2549713132LL);
508 flatbuffers::Offset<Application> a1 = a1_builder.Finish();
509
510 fbb.Finish(a1);
511 return fbb.Release();
512 }();
513
514 aos::FlatbufferDetachedBuffer<Application> a2 =
515 JsonToFlatbuffer<Application>(static_cast<const char *>(
516 "{ \"name\": \"foo\", \"priority\": 3, \"long_thingy\": 9 }"));
517
518 aos::FlatbufferDetachedBuffer<Configuration> c1 = [&a1, &a2]() {
519 flatbuffers::FlatBufferBuilder fbb;
520 fbb.ForceDefaults(true);
521
522 std::vector<flatbuffers::Offset<Application>> application_offsets;
523 application_offsets.emplace_back(BlindCopyFlatBuffer(a1, &fbb));
524 application_offsets.emplace_back(BlindCopyFlatBuffer(a2, &fbb));
525
526 flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Application>>>
527 applications_offset = fbb.CreateVector(application_offsets);
528
529 Configuration::Builder configuration_builder(fbb);
530 configuration_builder.add_apps(applications_offset);
531 fbb.Finish(configuration_builder.Finish());
532
533 return fbb.Release();
534 }();
535
536 LOG(INFO) << "Got "
537 << absl::BytesToHexString(
538 std::string_view(reinterpret_cast<char *>(c1.span().data()),
539 c1.span().size()));
540
541 aos::FlatbufferDetachedBuffer<Configuration> c2 = [&a1, &a2]() {
542 flatbuffers::FlatBufferBuilder fbb;
543 fbb.ForceDefaults(true);
544
545 std::vector<flatbuffers::Offset<Application>> application_offsets;
546 application_offsets.emplace_back(CopyFlatBuffer(&a1.message(), &fbb));
547 application_offsets.emplace_back(CopyFlatBuffer(&a2.message(), &fbb));
548
549 flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Application>>>
550 applications_offset = fbb.CreateVector(application_offsets);
551
552 Configuration::Builder configuration_builder(fbb);
553 configuration_builder.add_apps(applications_offset);
554 fbb.Finish(configuration_builder.Finish());
555
556 return fbb.Release();
557 }();
558
559 LOG(INFO) << "Got "
560 << absl::BytesToHexString(
561 std::string_view(reinterpret_cast<char *>(c2.span().data()),
562 c2.span().size()));
563
564 ASSERT_TRUE(expected.Verify());
565 ASSERT_TRUE(c1.Verify());
566 ASSERT_TRUE(c2.Verify());
567
568 LOG(INFO) << FlatbufferToJson(expected);
569 LOG(INFO) << FlatbufferToJson(c1);
570 LOG(INFO) << FlatbufferToJson(c2);
571 EXPECT_EQ(FlatbufferToJson(expected), FlatbufferToJson(c1));
572 EXPECT_EQ(FlatbufferToJson(expected), FlatbufferToJson(c2));
573}
574
Austin Schuh30d7db92020-01-26 16:45:47 -0800575// Tests a compare of 2 basic (different) messages.
576TEST_F(FlatbufferMerge, CompareDifferent) {
577 aos::FlatbufferDetachedBuffer<Configuration> message1(JsonToFlatbuffer(
578 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
579 ConfigurationTypeTable()));
580 aos::FlatbufferDetachedBuffer<Configuration> message2(JsonToFlatbuffer(
581 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 8 } }",
582 ConfigurationTypeTable()));
583
584 EXPECT_FALSE(CompareFlatBuffer(&message1.message(), &message2.message()));
585}
586
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700587// TODO(austin): enums
588// TODO(austin): unions
589// TODO(austin): struct
590
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800591} // namespace aos::testing