blob: 85773a32fc96d349febb83a5db1e501c6e7c6847 [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 "gtest/gtest.h"
7
8#include "aos/json_to_flatbuffer.h"
9#include "aos/json_to_flatbuffer_generated.h"
10#include "flatbuffers/minireflect.h"
11
12namespace aos {
13namespace testing {
14
Austin Schuha4fc60f2020-11-01 23:06:47 -080015std::string_view FromFbb(const flatbuffers::FlatBufferBuilder &fbb) {
16 return std::string_view(
17 reinterpret_cast<const char *>(fbb.GetCurrentBufferPointer()),
18 fbb.GetSize());
19}
20
21std::string_view FromFbb(const flatbuffers::DetachedBuffer &b) {
22 return std::string_view(reinterpret_cast<const char *>(b.data()), b.size());
23}
24
25absl::Span<const uint8_t> ToSpan(const flatbuffers::DetachedBuffer &b) {
26 return absl::Span<const uint8_t>(b.data(), b.size());
27}
28
Austin Schuh09d7ffa2019-10-03 23:43:34 -070029class FlatbufferMerge : public ::testing::Test {
30 public:
31 FlatbufferMerge() {}
32
James Kuszmaulf3a3be22020-01-04 12:12:00 -080033 void ExpectMergedOutput(const flatbuffers::DetachedBuffer &fb_merged,
34 std::string_view expected_output) {
35 ASSERT_NE(fb_merged.size(), 0u);
36
37 const ::std::string merged_output =
38 FlatbufferToJson(fb_merged, ConfigurationTypeTable());
39 EXPECT_EQ(expected_output, merged_output);
Austin Schuh30d7db92020-01-26 16:45:47 -080040
41 aos::FlatbufferDetachedBuffer<Configuration> expected_message(
42 JsonToFlatbuffer(std::string(expected_output).c_str(),
43 ConfigurationTypeTable()));
44 EXPECT_TRUE(
45 CompareFlatBuffer(flatbuffers::GetRoot<Configuration>(fb_merged.data()),
46 &expected_message.message()));
James Kuszmaulf3a3be22020-01-04 12:12:00 -080047 }
48
Austin Schuh09d7ffa2019-10-03 23:43:34 -070049 void JsonMerge(const ::std::string in1, const ::std::string in2,
50 const ::std::string out) {
51 printf("Merging: %s\n", in1.c_str());
52 printf("Merging: %s\n", in2.c_str());
Austin Schuhe93d8642019-10-13 15:27:07 -070053 const flatbuffers::DetachedBuffer fb1 = JsonToFlatbuffer(
Austin Schuh09d7ffa2019-10-03 23:43:34 -070054 static_cast<const char *>(in1.c_str()), ConfigurationTypeTable());
55
56 const ::std::string in1_nested = "{ \"nested_config\": " + in1 + " }";
Austin Schuhe93d8642019-10-13 15:27:07 -070057 const flatbuffers::DetachedBuffer fb1_nested =
58 JsonToFlatbuffer(static_cast<const char *>(in1_nested.c_str()),
59 ConfigurationTypeTable());
Austin Schuh09d7ffa2019-10-03 23:43:34 -070060
Austin Schuhe93d8642019-10-13 15:27:07 -070061 const flatbuffers::DetachedBuffer fb2 = JsonToFlatbuffer(
Austin Schuh09d7ffa2019-10-03 23:43:34 -070062 static_cast<const char *>(in2.c_str()), ConfigurationTypeTable());
63
64 const ::std::string in2_nested = "{ \"nested_config\": " + in2 + " }";
Austin Schuhe93d8642019-10-13 15:27:07 -070065 const flatbuffers::DetachedBuffer fb2_nested =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070066 JsonToFlatbuffer(static_cast<const char *>(in2_nested.c_str()),
67 ConfigurationTypeTable());
68
69 const ::std::string out_nested = "{ \"nested_config\": " + out + " }";
70
Austin Schuhe93d8642019-10-13 15:27:07 -070071 const flatbuffers::DetachedBuffer empty =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070072 JsonToFlatbuffer("{ }", ConfigurationTypeTable());
73
74 ASSERT_NE(fb1.size(), 0u);
75 ASSERT_NE(fb2.size(), 0u);
76 ASSERT_NE(fb1_nested.size(), 0u);
77 ASSERT_NE(fb2_nested.size(), 0u);
78
79 // We now want to run 7 tests.
80 // in1 merged "" -> in1.
81 // in2 merged "" -> in2.
82 // "" merged in1 -> in1.
83 // "" merged in2 -> in2.
84 // nullptr merged in1 -> in1.
85 // in1 merged nullptr -> in1.
86 // in1 merged in2 -> out.
87
88 {
89 // in1 merged with "" => in1.
Austin Schuhe93d8642019-10-13 15:27:07 -070090 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070091 MergeFlatBuffers<Configuration>(fb1.data(), empty.data());
92 ASSERT_NE(fb_merged.size(), 0u);
93
Austin Schuhe93d8642019-10-13 15:27:07 -070094 EXPECT_EQ(in1, FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -070095 }
96
97 {
98 // in2 merged with "" => in2.
Austin Schuhe93d8642019-10-13 15:27:07 -070099 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700100 MergeFlatBuffers<Configuration>(fb2.data(), empty.data());
101 ASSERT_NE(fb_merged.size(), 0u);
102
Austin Schuhe93d8642019-10-13 15:27:07 -0700103 EXPECT_EQ(in2, FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700104 }
105
106 {
107 // "" merged with in1 => in1.
Austin Schuhe93d8642019-10-13 15:27:07 -0700108 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700109 MergeFlatBuffers<Configuration>(empty.data(), fb1.data());
110 ASSERT_NE(fb_merged.size(), 0u);
111
Austin Schuhe93d8642019-10-13 15:27:07 -0700112 EXPECT_EQ(in1, FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700113 }
114
115 {
116 // "" merged with in2 => in2.
Austin Schuhe93d8642019-10-13 15:27:07 -0700117 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700118 MergeFlatBuffers<Configuration>(empty.data(), fb2.data());
119 ASSERT_NE(fb_merged.size(), 0u);
120
Austin Schuhe93d8642019-10-13 15:27:07 -0700121 EXPECT_EQ(in2, FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700122 }
123
124 {
125 // nullptr merged with in1 => in1.
Austin Schuhe93d8642019-10-13 15:27:07 -0700126 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700127 MergeFlatBuffers<Configuration>(nullptr, fb1.data());
128 ASSERT_NE(fb_merged.size(), 0u);
129
Austin Schuhe93d8642019-10-13 15:27:07 -0700130 EXPECT_EQ(in1, FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700131 }
132
133 {
134 // in1 merged with nullptr => in1.
Austin Schuhe93d8642019-10-13 15:27:07 -0700135 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700136 MergeFlatBuffers<Configuration>(fb1.data(), nullptr);
137 ASSERT_NE(fb_merged.size(), 0u);
138
Austin Schuhe93d8642019-10-13 15:27:07 -0700139 EXPECT_EQ(in1, FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700140 }
141
142 {
143 // in1 merged with in2 => out.
Austin Schuhe93d8642019-10-13 15:27:07 -0700144 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700145 MergeFlatBuffers<Configuration>(fb1.data(), fb2.data());
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700146
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800147 ExpectMergedOutput(fb_merged, out);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700148 }
149
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800150 // Test all the different merge methods:
151 ExpectMergedOutput(
152 MergeFlatBuffers(ConfigurationTypeTable(), fb1.data(), fb2.data()),
153 out);
154 {
155 flatbuffers::FlatBufferBuilder fbb;
Austin Schuhd7b15da2020-02-17 15:06:11 -0800156 fbb.ForceDefaults(true);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800157 fbb.Finish(MergeFlatBuffers(
158 ConfigurationTypeTable(),
159 flatbuffers::GetRoot<flatbuffers::Table>(fb1.data()),
160 flatbuffers::GetRoot<flatbuffers::Table>(fb2.data()), &fbb));
161 ExpectMergedOutput(fbb.Release(), out);
162 }
163 {
164 flatbuffers::FlatBufferBuilder fbb;
Austin Schuhd7b15da2020-02-17 15:06:11 -0800165 fbb.ForceDefaults(true);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800166 fbb.Finish(MergeFlatBuffers<Configuration>(
167 flatbuffers::GetRoot<flatbuffers::Table>(fb1.data()),
168 flatbuffers::GetRoot<flatbuffers::Table>(fb2.data()), &fbb));
169 ExpectMergedOutput(fbb.Release(), out);
170 }
171 ExpectMergedOutput(MergeFlatBuffers<Configuration>(fb1.data(), fb2.data()),
172 out);
173 ExpectMergedOutput(MergeFlatBuffers<Configuration>(fb1, fb2), out);
174 ExpectMergedOutput(MergeFlatBuffers<Configuration>(
175 flatbuffers::GetRoot<Configuration>(fb1.data()),
176 flatbuffers::GetRoot<Configuration>(fb2.data()))
177 .buffer(),
178 out);
179
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700180 // Now, to make things extra exciting, nest a config inside a config. And
181 // run all the tests. This will exercise some fun nested merges and copies.
182
183 {
184 // in1_nested merged with "" => in1.
Austin Schuhe93d8642019-10-13 15:27:07 -0700185 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700186 MergeFlatBuffers<Configuration>(fb1_nested.data(), empty.data());
187 ASSERT_NE(fb_merged.size(), 0u);
188
189 EXPECT_EQ(in1_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700190 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700191 }
192
193 {
194 // in2_nested merged with "" => in2_nested.
Austin Schuhe93d8642019-10-13 15:27:07 -0700195 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700196 MergeFlatBuffers<Configuration>(fb2_nested.data(), empty.data());
197 ASSERT_NE(fb_merged.size(), 0u);
198
199 EXPECT_EQ(in2_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700200 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700201 }
202
203 {
204 // "" merged with in1_nested => in1_nested.
Austin Schuhe93d8642019-10-13 15:27:07 -0700205 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700206 MergeFlatBuffers<Configuration>(empty.data(), fb1_nested.data());
207 ASSERT_NE(fb_merged.size(), 0u);
208
209 EXPECT_EQ(in1_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700210 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700211 }
212
213 {
214 // "" merged with in2_nested => in2_nested.
Austin Schuhe93d8642019-10-13 15:27:07 -0700215 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700216 MergeFlatBuffers<Configuration>(empty.data(), fb2_nested.data());
217 ASSERT_NE(fb_merged.size(), 0u);
218
219 EXPECT_EQ(in2_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700220 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700221 }
222
223 {
224 // nullptr merged with in1_nested => in1_nested.
Austin Schuhe93d8642019-10-13 15:27:07 -0700225 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700226 MergeFlatBuffers<Configuration>(nullptr, fb1_nested.data());
227 ASSERT_NE(fb_merged.size(), 0u);
228
229 EXPECT_EQ(in1_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700230 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700231 }
232
233 {
234 // nullptr merged with in1_nested => in1_nested.
Austin Schuhe93d8642019-10-13 15:27:07 -0700235 flatbuffers::DetachedBuffer fb_merged =
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700236 MergeFlatBuffers<Configuration>(fb1_nested.data(), nullptr);
237 ASSERT_NE(fb_merged.size(), 0u);
238
239 EXPECT_EQ(in1_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700240 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700241 }
242
243 {
244 // in1_nested merged with in2_nested => out_nested.
Austin Schuhe93d8642019-10-13 15:27:07 -0700245 flatbuffers::DetachedBuffer fb_merged =
246 MergeFlatBuffers<Configuration>(fb1_nested, fb2_nested);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700247 ASSERT_NE(fb_merged.size(), 0u);
248
249 EXPECT_EQ(out_nested,
Austin Schuhe93d8642019-10-13 15:27:07 -0700250 FlatbufferToJson(fb_merged, ConfigurationTypeTable()));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700251 }
Austin Schuha4fc60f2020-11-01 23:06:47 -0800252
253 // TODO(austin): Try more flatbuffers...
254 // Now try copying various flatbuffers and confirming they match.
255 {
256 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
257 aos_flatbuffer_copy_fbb.ForceDefaults(true);
258
259 LOG(INFO) << "Copying " << in1 << " "
260 << absl::BytesToHexString(FromFbb(fb1)) << " at "
261 << reinterpret_cast<const void *>(fb1.data()) << " size "
262 << fb1.size();
263 aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
264 flatbuffers::GetRoot<Configuration>(fb1.data()),
265 &aos_flatbuffer_copy_fbb));
266
267 aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
268 aos_flatbuffer_copy_fbb.Release());
269 ASSERT_NE(fb_copy.size(), 0u);
270
271 flatbuffers::Verifier v(fb1.data(), fb1.size());
272 EXPECT_TRUE(
273 v.VerifyTable(flatbuffers::GetRoot<Configuration>(fb1.data())));
274
275 ASSERT_TRUE(fb_copy.Verify()) << in1;
276
277 EXPECT_EQ(in1, FlatbufferToJson(fb_copy));
278 }
279
280 {
281 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_message_ptr_fbb;
282 aos_flatbuffer_copy_message_ptr_fbb.ForceDefaults(true);
283
284 aos_flatbuffer_copy_message_ptr_fbb.Finish(CopyFlatBuffer<Configuration>(
285 flatbuffers::GetRoot<Configuration>(fb2.data()),
286 &aos_flatbuffer_copy_message_ptr_fbb));
287
288 aos::FlatbufferDetachedBuffer<Configuration> fb_copy_message_ptr(
289 aos_flatbuffer_copy_message_ptr_fbb.Release());
290 ASSERT_NE(fb_copy_message_ptr.size(), 0u);
291
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>(
296 aos::FlatbufferSpan<Configuration>(ToSpan(fb2)),
297 &aos_flatbuffer_copy_full_fbb));
298
299 aos::FlatbufferDetachedBuffer<Configuration> fb_copy_full(
300 aos_flatbuffer_copy_full_fbb.Release());
301 ASSERT_NE(fb_copy_full.size(), 0u);
302
303 flatbuffers::Verifier v(fb2.data(), fb2.size());
304 EXPECT_TRUE(
305 v.VerifyTable(flatbuffers::GetRoot<Configuration>(fb2.data())));
306
307 LOG(INFO) << "Verifying copy of " << in2;
308 ASSERT_TRUE(fb_copy_message_ptr.Verify()) << in2;
309 LOG(INFO) << "Verifying full of " << in2;
310 ASSERT_TRUE(fb_copy_full.Verify()) << in2;
311
312 EXPECT_EQ(in2, FlatbufferToJson(fb_copy_message_ptr));
313 EXPECT_EQ(in2, FlatbufferToJson(fb_copy_full));
314 }
315
316 {
317 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
318 aos_flatbuffer_copy_fbb.ForceDefaults(true);
319
320 aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
321 flatbuffers::GetRoot<Configuration>(fb1_nested.data()),
322 &aos_flatbuffer_copy_fbb));
323
324 aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
325 aos_flatbuffer_copy_fbb.Release());
326 ASSERT_NE(fb_copy.size(), 0u);
327
328 ASSERT_TRUE(fb_copy.Verify());
329
330 EXPECT_EQ(in1_nested, FlatbufferToJson(fb_copy));
331 }
332
333 {
334 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
335 aos_flatbuffer_copy_fbb.ForceDefaults(true);
336
337 aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
338 flatbuffers::GetRoot<Configuration>(fb2_nested.data()),
339 &aos_flatbuffer_copy_fbb));
340
341 aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
342 aos_flatbuffer_copy_fbb.Release());
343 ASSERT_NE(fb_copy.size(), 0u);
344
345 ASSERT_TRUE(fb_copy.Verify());
346
347 EXPECT_EQ(in2_nested, FlatbufferToJson(fb_copy));
348 }
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700349 }
350};
351
352// Test the easy ones. Test every type, single, no nesting.
353TEST_F(FlatbufferMerge, Basic) {
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800354 JsonMerge("{ }", "{ }", "{ }");
355
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700356 JsonMerge("{ \"foo_bool\": true }", "{ \"foo_bool\": false }",
357 "{ \"foo_bool\": false }");
358
359 JsonMerge("{ \"foo_bool\": false }", "{ \"foo_bool\": true }",
360 "{ \"foo_bool\": true }");
361
362 JsonMerge("{ \"foo_byte\": 5 }", "{ \"foo_byte\": -7 }",
363 "{ \"foo_byte\": -7 }");
364
365 JsonMerge("{ \"foo_ubyte\": 5 }", "{ \"foo_ubyte\": 7 }",
366 "{ \"foo_ubyte\": 7 }");
367
368 JsonMerge("{ \"foo_short\": 5 }", "{ \"foo_short\": 7 }",
369 "{ \"foo_short\": 7 }");
370
371 JsonMerge("{ \"foo_int\": 5 }", "{ \"foo_int\": 7 }", "{ \"foo_int\": 7 }");
372
373 JsonMerge("{ \"foo_uint\": 5 }", "{ \"foo_uint\": 7 }",
374 "{ \"foo_uint\": 7 }");
375
376 JsonMerge("{ \"foo_long\": 5 }", "{ \"foo_long\": 7 }",
377 "{ \"foo_long\": 7 }");
378
379 JsonMerge("{ \"foo_ulong\": 5 }", "{ \"foo_ulong\": 7 }",
380 "{ \"foo_ulong\": 7 }");
381
382 JsonMerge("{ \"foo_float\": 5.0 }", "{ \"foo_float\": 7.1 }",
383 "{ \"foo_float\": 7.1 }");
384
385 JsonMerge("{ \"foo_double\": 5.0 }", "{ \"foo_double\": 7.1 }",
386 "{ \"foo_double\": 7.1 }");
387}
388
389// Test arrays of simple types.
390TEST_F(FlatbufferMerge, Array) {
391 JsonMerge("{ \"foo_string\": \"baz\" }", "{ \"foo_string\": \"bar\" }",
392 "{ \"foo_string\": \"bar\" }");
393
394 JsonMerge("{ \"vector_foo_bool\": [ true, true, false ] }",
395 "{ \"vector_foo_bool\": [ false, true, true, false ] }",
396 "{ \"vector_foo_bool\": [ true, true, false, false, "
397 "true, true, false ] }");
398
399 JsonMerge("{ \"vector_foo_byte\": [ 9, 7, 1 ] }",
400 "{ \"vector_foo_byte\": [ -3, 1, 3, 2 ] }",
401 "{ \"vector_foo_byte\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
402
403 JsonMerge("{ \"vector_foo_ubyte\": [ 9, 7, 1 ] }",
404 "{ \"vector_foo_ubyte\": [ 3, 1, 3, 2 ] }",
405 "{ \"vector_foo_ubyte\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
406
407 JsonMerge("{ \"vector_foo_short\": [ 9, 7, 1 ] }",
408 "{ \"vector_foo_short\": [ -3, 1, 3, 2 ] }",
409 "{ \"vector_foo_short\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
410
411 JsonMerge("{ \"vector_foo_ushort\": [ 9, 7, 1 ] }",
412 "{ \"vector_foo_ushort\": [ 3, 1, 3, 2 ] }",
413 "{ \"vector_foo_ushort\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
414
415 JsonMerge("{ \"vector_foo_int\": [ 9, 7, 1 ] }",
416 "{ \"vector_foo_int\": [ -3, 1, 3, 2 ] }",
417 "{ \"vector_foo_int\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
418
419 JsonMerge("{ \"vector_foo_uint\": [ 9, 7, 1 ] }",
420 "{ \"vector_foo_uint\": [ 3, 1, 3, 2 ] }",
421 "{ \"vector_foo_uint\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
422
423 JsonMerge("{ \"vector_foo_long\": [ 9, 7, 1 ] }",
424 "{ \"vector_foo_long\": [ -3, 1, 3, 2 ] }",
425 "{ \"vector_foo_long\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
426
427 JsonMerge("{ \"vector_foo_ulong\": [ 9, 7, 1 ] }",
428 "{ \"vector_foo_ulong\": [ 3, 1, 3, 2 ] }",
429 "{ \"vector_foo_ulong\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
430
431 JsonMerge("{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ] }",
432 "{ \"vector_foo_float\": [ -3.0, 1.3, 3.0, 2.0 ] }",
433 "{ \"vector_foo_float\": [ 9.0, 7.0, 1.0, -3.0, 1.3, 3.0, 2.0 ] }");
434
Austin Schuhe93d8642019-10-13 15:27:07 -0700435 JsonMerge(
436 "{ \"vector_foo_string\": [ \"9\", \"7\", \"1 \" ] }",
437 "{ \"vector_foo_string\": [ \"31\", \"32\" ] }",
438 "{ \"vector_foo_string\": [ \"9\", \"7\", \"1 \", \"31\", \"32\" ] }");
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700439}
440
441// Test nested messages, and arrays of nested messages.
442TEST_F(FlatbufferMerge, NestedStruct) {
443 JsonMerge(
444 "{ \"single_application\": { \"name\": \"woot\" } }",
445 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
446 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }");
447
448 JsonMerge(
449 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
450 "{ \"single_application\": { \"name\": \"woot\" } }",
451 "{ \"single_application\": { \"name\": \"woot\", \"priority\": 7 } }");
452
453 JsonMerge("{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] }",
454 "{ \"apps\": [ { \"name\": \"woo2\" }, { \"name\": \"wo3\" } ] }",
455 "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" }, { "
456 "\"name\": \"woo2\" }, { \"name\": \"wo3\" } ] }");
457}
458
Austin Schuha4fc60f2020-11-01 23:06:47 -0800459// Test nested messages, and arrays of nested messages.
460TEST(FlatbufferCopy, WholesaleCopy) {
461 flatbuffers::FlatBufferBuilder fbb_expected;
462 fbb_expected.ForceDefaults(true);
463 fbb_expected.DedupVtables(false);
464
465 {
466 flatbuffers::Offset<flatbuffers::String> name1_offset =
467 fbb_expected.CreateString("wow");
468
469 std::vector<flatbuffers::Offset<Application>> application_offsets;
470 Application::Builder a1_builder(fbb_expected);
471 a1_builder.add_name(name1_offset);
472 a1_builder.add_priority(7);
473 a1_builder.add_long_thingy(0x2549713132LL);
474 application_offsets.emplace_back(a1_builder.Finish());
475
476 flatbuffers::Offset<flatbuffers::String> name2_offset =
477 fbb_expected.CreateString("foo");
478 Application::Builder a2_builder(fbb_expected);
479 a2_builder.add_name(name2_offset);
480 a2_builder.add_priority(3);
481 a2_builder.add_long_thingy(9);
482 application_offsets.emplace_back(a2_builder.Finish());
483
484 flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Application>>>
485 applications_offset = fbb_expected.CreateVector(application_offsets);
486
487 Configuration::Builder configuration_builder(fbb_expected);
488 configuration_builder.add_apps(applications_offset);
489 fbb_expected.Finish(configuration_builder.Finish());
490 }
491
492 LOG(INFO) << "Initial alignment " << fbb_expected.GetBufferMinAlignment();
493
494 aos::FlatbufferDetachedBuffer<Configuration> expected(fbb_expected.Release());
495
496 LOG(INFO) << "Expected "
497 << absl::BytesToHexString(std::string_view(
498 reinterpret_cast<char *>(expected.span().data()),
499 expected.span().size()));
500
501 aos::FlatbufferDetachedBuffer<Application> a1 = []() {
502 flatbuffers::FlatBufferBuilder fbb;
503 fbb.ForceDefaults(true);
504
505 flatbuffers::Offset<flatbuffers::String> name1_offset =
506 fbb.CreateString("wow");
507
508 Application::Builder a1_builder(fbb);
509 a1_builder.add_name(name1_offset);
510 a1_builder.add_priority(7);
511 a1_builder.add_long_thingy(0x2549713132LL);
512 flatbuffers::Offset<Application> a1 = a1_builder.Finish();
513
514 fbb.Finish(a1);
515 return fbb.Release();
516 }();
517
518 aos::FlatbufferDetachedBuffer<Application> a2 =
519 JsonToFlatbuffer<Application>(static_cast<const char *>(
520 "{ \"name\": \"foo\", \"priority\": 3, \"long_thingy\": 9 }"));
521
522 aos::FlatbufferDetachedBuffer<Configuration> c1 = [&a1, &a2]() {
523 flatbuffers::FlatBufferBuilder fbb;
524 fbb.ForceDefaults(true);
525
526 std::vector<flatbuffers::Offset<Application>> application_offsets;
527 application_offsets.emplace_back(BlindCopyFlatBuffer(a1, &fbb));
528 application_offsets.emplace_back(BlindCopyFlatBuffer(a2, &fbb));
529
530 flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Application>>>
531 applications_offset = fbb.CreateVector(application_offsets);
532
533 Configuration::Builder configuration_builder(fbb);
534 configuration_builder.add_apps(applications_offset);
535 fbb.Finish(configuration_builder.Finish());
536
537 return fbb.Release();
538 }();
539
540 LOG(INFO) << "Got "
541 << absl::BytesToHexString(
542 std::string_view(reinterpret_cast<char *>(c1.span().data()),
543 c1.span().size()));
544
545 aos::FlatbufferDetachedBuffer<Configuration> c2 = [&a1, &a2]() {
546 flatbuffers::FlatBufferBuilder fbb;
547 fbb.ForceDefaults(true);
548
549 std::vector<flatbuffers::Offset<Application>> application_offsets;
550 application_offsets.emplace_back(CopyFlatBuffer(&a1.message(), &fbb));
551 application_offsets.emplace_back(CopyFlatBuffer(&a2.message(), &fbb));
552
553 flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Application>>>
554 applications_offset = fbb.CreateVector(application_offsets);
555
556 Configuration::Builder configuration_builder(fbb);
557 configuration_builder.add_apps(applications_offset);
558 fbb.Finish(configuration_builder.Finish());
559
560 return fbb.Release();
561 }();
562
563 LOG(INFO) << "Got "
564 << absl::BytesToHexString(
565 std::string_view(reinterpret_cast<char *>(c2.span().data()),
566 c2.span().size()));
567
568 ASSERT_TRUE(expected.Verify());
569 ASSERT_TRUE(c1.Verify());
570 ASSERT_TRUE(c2.Verify());
571
572 LOG(INFO) << FlatbufferToJson(expected);
573 LOG(INFO) << FlatbufferToJson(c1);
574 LOG(INFO) << FlatbufferToJson(c2);
575 EXPECT_EQ(FlatbufferToJson(expected), FlatbufferToJson(c1));
576 EXPECT_EQ(FlatbufferToJson(expected), FlatbufferToJson(c2));
577}
578
Austin Schuh30d7db92020-01-26 16:45:47 -0800579// Tests a compare of 2 basic (different) messages.
580TEST_F(FlatbufferMerge, CompareDifferent) {
581 aos::FlatbufferDetachedBuffer<Configuration> message1(JsonToFlatbuffer(
582 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
583 ConfigurationTypeTable()));
584 aos::FlatbufferDetachedBuffer<Configuration> message2(JsonToFlatbuffer(
585 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 8 } }",
586 ConfigurationTypeTable()));
587
588 EXPECT_FALSE(CompareFlatBuffer(&message1.message(), &message2.message()));
589}
590
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700591// TODO(austin): enums
592// TODO(austin): unions
593// TODO(austin): struct
594
595} // namespace testing
596} // namespace aos