blob: 4c598791b1b97d27f6554e3b711a37879f518f66 [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
Austin Schuh09d7ffa2019-10-03 23:43:34 -070012namespace 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
Austin Schuhadd6eb32020-11-09 21:24:26 -080021std::string_view FromFbb(const FlatbufferDetachedBuffer<Configuration> &b) {
22 return std::string_view(reinterpret_cast<const char *>(b.span().data()),
23 b.span().size());
Austin Schuha4fc60f2020-11-01 23:06:47 -080024}
25
Austin Schuh09d7ffa2019-10-03 23:43:34 -070026class FlatbufferMerge : public ::testing::Test {
27 public:
28 FlatbufferMerge() {}
29
Austin Schuhadd6eb32020-11-09 21:24:26 -080030 void ExpectMergedOutput(
31 const NonSizePrefixedFlatbuffer<Configuration> &fb_merged,
32 std::string_view expected_output) {
33 ASSERT_NE(fb_merged.span().size(), 0u);
James Kuszmaulf3a3be22020-01-04 12:12:00 -080034
Austin Schuhadd6eb32020-11-09 21:24:26 -080035 const ::std::string merged_output = FlatbufferToJson(fb_merged);
James Kuszmaulf3a3be22020-01-04 12:12:00 -080036 EXPECT_EQ(expected_output, merged_output);
Austin Schuh30d7db92020-01-26 16:45:47 -080037
38 aos::FlatbufferDetachedBuffer<Configuration> expected_message(
39 JsonToFlatbuffer(std::string(expected_output).c_str(),
40 ConfigurationTypeTable()));
41 EXPECT_TRUE(
Austin Schuhadd6eb32020-11-09 21:24:26 -080042 CompareFlatBuffer(&fb_merged.message(), &expected_message.message()));
James Kuszmaulf3a3be22020-01-04 12:12:00 -080043 }
44
Austin Schuh09d7ffa2019-10-03 23:43:34 -070045 void JsonMerge(const ::std::string in1, const ::std::string in2,
46 const ::std::string out) {
Austin Schuhadd6eb32020-11-09 21:24:26 -080047 LOG(INFO) << "Merging: " << in1.c_str();
48 LOG(INFO) << "Merging: " << in2.c_str();
49 const FlatbufferDetachedBuffer<Configuration> fb1 = JsonToFlatbuffer(
Austin Schuh09d7ffa2019-10-03 23:43:34 -070050 static_cast<const char *>(in1.c_str()), ConfigurationTypeTable());
51
52 const ::std::string in1_nested = "{ \"nested_config\": " + in1 + " }";
Austin Schuhadd6eb32020-11-09 21:24:26 -080053 const FlatbufferDetachedBuffer<Configuration> fb1_nested =
Austin Schuhe93d8642019-10-13 15:27:07 -070054 JsonToFlatbuffer(static_cast<const char *>(in1_nested.c_str()),
55 ConfigurationTypeTable());
Austin Schuh09d7ffa2019-10-03 23:43:34 -070056
Austin Schuhadd6eb32020-11-09 21:24:26 -080057 const FlatbufferDetachedBuffer<Configuration> fb2 = JsonToFlatbuffer(
Austin Schuh09d7ffa2019-10-03 23:43:34 -070058 static_cast<const char *>(in2.c_str()), ConfigurationTypeTable());
59
60 const ::std::string in2_nested = "{ \"nested_config\": " + in2 + " }";
Austin Schuhadd6eb32020-11-09 21:24:26 -080061 const FlatbufferDetachedBuffer<Configuration> fb2_nested =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070062 JsonToFlatbuffer(static_cast<const char *>(in2_nested.c_str()),
63 ConfigurationTypeTable());
64
65 const ::std::string out_nested = "{ \"nested_config\": " + out + " }";
66
Austin Schuhadd6eb32020-11-09 21:24:26 -080067 const FlatbufferDetachedBuffer<Configuration> empty =
Austin Schuh09d7ffa2019-10-03 23:43:34 -070068 JsonToFlatbuffer("{ }", ConfigurationTypeTable());
69
Austin Schuhadd6eb32020-11-09 21:24:26 -080070 ASSERT_NE(fb1.span().size(), 0u);
71 ASSERT_NE(fb2.span().size(), 0u);
72 ASSERT_NE(fb1_nested.span().size(), 0u);
73 ASSERT_NE(fb2_nested.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -070074
75 // We now want to run 7 tests.
76 // in1 merged "" -> in1.
77 // in2 merged "" -> in2.
78 // "" merged in1 -> in1.
79 // "" merged in2 -> in2.
80 // nullptr merged in1 -> in1.
81 // in1 merged nullptr -> in1.
82 // in1 merged in2 -> out.
83
84 {
85 // in1 merged with "" => in1.
Austin Schuhadd6eb32020-11-09 21:24:26 -080086 FlatbufferDetachedBuffer<Configuration> fb_merged =
87 MergeFlatBuffers<Configuration>(fb1, empty);
88 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -070089
Austin Schuhadd6eb32020-11-09 21:24:26 -080090 EXPECT_EQ(in1, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -070091 }
92
93 {
94 // in2 merged with "" => in2.
Austin Schuhadd6eb32020-11-09 21:24:26 -080095 FlatbufferDetachedBuffer<Configuration> fb_merged =
96 MergeFlatBuffers<Configuration>(fb2, empty);
97 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -070098
Austin Schuhadd6eb32020-11-09 21:24:26 -080099 EXPECT_EQ(in2, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700100 }
101
102 {
103 // "" merged with in1 => in1.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800104 FlatbufferDetachedBuffer<Configuration> fb_merged =
105 MergeFlatBuffers<Configuration>(empty, fb1);
106 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700107
Austin Schuhadd6eb32020-11-09 21:24:26 -0800108 EXPECT_EQ(in1, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700109 }
110
111 {
112 // "" merged with in2 => in2.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800113 FlatbufferDetachedBuffer<Configuration> fb_merged =
114 MergeFlatBuffers<Configuration>(empty, fb2);
115 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700116
Austin Schuhadd6eb32020-11-09 21:24:26 -0800117 EXPECT_EQ(in2, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700118 }
119
120 {
121 // nullptr merged with in1 => in1.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800122 FlatbufferDetachedBuffer<Configuration> fb_merged =
123 MergeFlatBuffers<Configuration>(nullptr, &fb1.message());
124 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700125
Austin Schuhadd6eb32020-11-09 21:24:26 -0800126 EXPECT_EQ(in1, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700127 }
128
129 {
130 // in1 merged with nullptr => in1.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800131 FlatbufferDetachedBuffer<Configuration> fb_merged =
132 MergeFlatBuffers<Configuration>(&fb1.message(), nullptr);
133 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700134
Austin Schuhadd6eb32020-11-09 21:24:26 -0800135 EXPECT_EQ(in1, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700136 }
137
138 {
139 // in1 merged with in2 => out.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800140 FlatbufferDetachedBuffer<Configuration> fb_merged =
141 MergeFlatBuffers<Configuration>(fb1, fb2);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700142
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800143 ExpectMergedOutput(fb_merged, out);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700144 }
145
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800146 // Test all the different merge methods:
Austin Schuhadd6eb32020-11-09 21:24:26 -0800147 ExpectMergedOutput(MergeFlatBuffers<Configuration>(fb1, fb2), out);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800148 {
149 flatbuffers::FlatBufferBuilder fbb;
Austin Schuhd7b15da2020-02-17 15:06:11 -0800150 fbb.ForceDefaults(true);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800151 fbb.Finish(MergeFlatBuffers(
152 ConfigurationTypeTable(),
Austin Schuhadd6eb32020-11-09 21:24:26 -0800153 reinterpret_cast<const flatbuffers::Table *>(&fb1.message()),
154 reinterpret_cast<const flatbuffers::Table *>(&fb2.message()), &fbb));
155 FlatbufferDetachedBuffer<Configuration> fb(fbb.Release());
156 ExpectMergedOutput(fb, out);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800157 }
158 {
159 flatbuffers::FlatBufferBuilder fbb;
Austin Schuhd7b15da2020-02-17 15:06:11 -0800160 fbb.ForceDefaults(true);
Austin Schuhadd6eb32020-11-09 21:24:26 -0800161 fbb.Finish(MergeFlatBuffers<Configuration>(&fb1.message(), &fb2.message(),
162 &fbb));
163 FlatbufferDetachedBuffer<Configuration> fb(fbb.Release());
164 ExpectMergedOutput(fb, out);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800165 }
Austin Schuhadd6eb32020-11-09 21:24:26 -0800166 ExpectMergedOutput(
167 MergeFlatBuffers<Configuration>(&fb1.message(), &fb2.message()), out);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800168 ExpectMergedOutput(MergeFlatBuffers<Configuration>(fb1, fb2), out);
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800169
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700170 // Now, to make things extra exciting, nest a config inside a config. And
171 // run all the tests. This will exercise some fun nested merges and copies.
172
173 {
174 // in1_nested merged with "" => in1.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800175 FlatbufferDetachedBuffer<Configuration> fb_merged =
176 MergeFlatBuffers<Configuration>(fb1_nested, empty);
177 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700178
Austin Schuhadd6eb32020-11-09 21:24:26 -0800179 EXPECT_EQ(in1_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700180 }
181
182 {
183 // in2_nested merged with "" => in2_nested.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800184 FlatbufferDetachedBuffer<Configuration> fb_merged =
185 MergeFlatBuffers<Configuration>(fb2_nested, empty);
186 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700187
Austin Schuhadd6eb32020-11-09 21:24:26 -0800188 EXPECT_EQ(in2_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700189 }
190
191 {
192 // "" merged with in1_nested => in1_nested.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800193 FlatbufferDetachedBuffer<Configuration> fb_merged =
194 MergeFlatBuffers<Configuration>(empty, fb1_nested);
195 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700196
Austin Schuhadd6eb32020-11-09 21:24:26 -0800197 EXPECT_EQ(in1_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700198 }
199
200 {
201 // "" merged with in2_nested => in2_nested.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800202 FlatbufferDetachedBuffer<Configuration> fb_merged =
203 MergeFlatBuffers<Configuration>(empty, fb2_nested);
204 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700205
Austin Schuhadd6eb32020-11-09 21:24:26 -0800206 EXPECT_EQ(in2_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700207 }
208
209 {
210 // nullptr merged with in1_nested => in1_nested.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800211 FlatbufferDetachedBuffer<Configuration> fb_merged =
212 MergeFlatBuffers<Configuration>(nullptr, &fb1_nested.message());
213 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700214
Austin Schuhadd6eb32020-11-09 21:24:26 -0800215 EXPECT_EQ(in1_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700216 }
217
218 {
219 // nullptr merged with in1_nested => in1_nested.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800220 FlatbufferDetachedBuffer<Configuration> fb_merged(
221 MergeFlatBuffers<Configuration>(&fb1_nested.message(), nullptr));
222 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700223
Austin Schuhadd6eb32020-11-09 21:24:26 -0800224 EXPECT_EQ(in1_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700225 }
226
227 {
228 // in1_nested merged with in2_nested => out_nested.
Austin Schuhadd6eb32020-11-09 21:24:26 -0800229 FlatbufferDetachedBuffer<Configuration> fb_merged(
230 MergeFlatBuffers<Configuration>(fb1_nested, fb2_nested));
231 ASSERT_NE(fb_merged.span().size(), 0u);
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700232
Austin Schuhadd6eb32020-11-09 21:24:26 -0800233 EXPECT_EQ(out_nested, FlatbufferToJson(fb_merged));
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700234 }
Austin Schuha4fc60f2020-11-01 23:06:47 -0800235
236 // TODO(austin): Try more flatbuffers...
237 // Now try copying various flatbuffers and confirming they match.
238 {
239 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
240 aos_flatbuffer_copy_fbb.ForceDefaults(true);
241
242 LOG(INFO) << "Copying " << in1 << " "
243 << absl::BytesToHexString(FromFbb(fb1)) << " at "
Austin Schuhadd6eb32020-11-09 21:24:26 -0800244 << reinterpret_cast<const void *>(fb1.span().data()) << " size "
245 << fb1.span().size();
Austin Schuha4fc60f2020-11-01 23:06:47 -0800246 aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800247 &fb1.message(), &aos_flatbuffer_copy_fbb));
Austin Schuha4fc60f2020-11-01 23:06:47 -0800248
Austin Schuhadd6eb32020-11-09 21:24:26 -0800249 const aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
Austin Schuha4fc60f2020-11-01 23:06:47 -0800250 aos_flatbuffer_copy_fbb.Release());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800251 ASSERT_NE(fb_copy.span().size(), 0u);
Austin Schuha4fc60f2020-11-01 23:06:47 -0800252
Austin Schuhadd6eb32020-11-09 21:24:26 -0800253 EXPECT_TRUE(fb1.Verify());
Austin Schuha4fc60f2020-11-01 23:06:47 -0800254
255 ASSERT_TRUE(fb_copy.Verify()) << in1;
256
257 EXPECT_EQ(in1, FlatbufferToJson(fb_copy));
258 }
259
260 {
Austin Schuh4a5f5d22021-10-12 15:09:35 -0700261 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
262 aos_flatbuffer_copy_fbb.ForceDefaults(false);
263
264 LOG(INFO) << "Copying without defaults " << in1 << " "
265 << absl::BytesToHexString(FromFbb(fb1)) << " at "
266 << reinterpret_cast<const void *>(fb1.span().data()) << " size "
267 << fb1.span().size();
268 aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
269 &fb1.message(), &aos_flatbuffer_copy_fbb));
270
271 const aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
272 aos_flatbuffer_copy_fbb.Release());
273 ASSERT_NE(fb_copy.span().size(), 0u);
274
275 EXPECT_TRUE(fb1.Verify());
276
277 ASSERT_TRUE(fb_copy.Verify()) << in1;
278
279 EXPECT_EQ(in1, FlatbufferToJson(fb_copy));
280 }
281
282 {
Austin Schuha4fc60f2020-11-01 23:06:47 -0800283 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_message_ptr_fbb;
284 aos_flatbuffer_copy_message_ptr_fbb.ForceDefaults(true);
285
286 aos_flatbuffer_copy_message_ptr_fbb.Finish(CopyFlatBuffer<Configuration>(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800287 &fb2.message(), &aos_flatbuffer_copy_message_ptr_fbb));
Austin Schuha4fc60f2020-11-01 23:06:47 -0800288
289 aos::FlatbufferDetachedBuffer<Configuration> fb_copy_message_ptr(
290 aos_flatbuffer_copy_message_ptr_fbb.Release());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800291 ASSERT_NE(fb_copy_message_ptr.span().size(), 0u);
Austin Schuha4fc60f2020-11-01 23:06:47 -0800292
293 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_full_fbb;
294 aos_flatbuffer_copy_full_fbb.ForceDefaults(true);
295
296 aos_flatbuffer_copy_full_fbb.Finish(BlindCopyFlatBuffer<Configuration>(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800297 aos::FlatbufferSpan<Configuration>(fb2.span()),
Austin Schuha4fc60f2020-11-01 23:06:47 -0800298 &aos_flatbuffer_copy_full_fbb));
299
300 aos::FlatbufferDetachedBuffer<Configuration> fb_copy_full(
301 aos_flatbuffer_copy_full_fbb.Release());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800302 ASSERT_NE(fb_copy_full.span().size(), 0u);
Austin Schuha4fc60f2020-11-01 23:06:47 -0800303
Austin Schuhadd6eb32020-11-09 21:24:26 -0800304 EXPECT_TRUE(fb2.Verify());
Austin Schuha4fc60f2020-11-01 23:06:47 -0800305
306 LOG(INFO) << "Verifying copy of " << in2;
307 ASSERT_TRUE(fb_copy_message_ptr.Verify()) << in2;
308 LOG(INFO) << "Verifying full of " << in2;
309 ASSERT_TRUE(fb_copy_full.Verify()) << in2;
310
311 EXPECT_EQ(in2, FlatbufferToJson(fb_copy_message_ptr));
312 EXPECT_EQ(in2, FlatbufferToJson(fb_copy_full));
313 }
314
315 {
316 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
317 aos_flatbuffer_copy_fbb.ForceDefaults(true);
318
319 aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800320 &fb1_nested.message(), &aos_flatbuffer_copy_fbb));
Austin Schuha4fc60f2020-11-01 23:06:47 -0800321
322 aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
323 aos_flatbuffer_copy_fbb.Release());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800324 ASSERT_NE(fb_copy.span().size(), 0u);
Austin Schuha4fc60f2020-11-01 23:06:47 -0800325
326 ASSERT_TRUE(fb_copy.Verify());
327
328 EXPECT_EQ(in1_nested, FlatbufferToJson(fb_copy));
329 }
330
331 {
332 flatbuffers::FlatBufferBuilder aos_flatbuffer_copy_fbb;
333 aos_flatbuffer_copy_fbb.ForceDefaults(true);
334
335 aos_flatbuffer_copy_fbb.Finish(CopyFlatBuffer<Configuration>(
Austin Schuhadd6eb32020-11-09 21:24:26 -0800336 &fb2_nested.message(), &aos_flatbuffer_copy_fbb));
Austin Schuha4fc60f2020-11-01 23:06:47 -0800337
338 aos::FlatbufferDetachedBuffer<Configuration> fb_copy(
339 aos_flatbuffer_copy_fbb.Release());
Austin Schuhadd6eb32020-11-09 21:24:26 -0800340 ASSERT_NE(fb_copy.span().size(), 0u);
Austin Schuha4fc60f2020-11-01 23:06:47 -0800341
342 ASSERT_TRUE(fb_copy.Verify());
343
344 EXPECT_EQ(in2_nested, FlatbufferToJson(fb_copy));
345 }
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700346 }
347};
348
349// Test the easy ones. Test every type, single, no nesting.
350TEST_F(FlatbufferMerge, Basic) {
James Kuszmaulf3a3be22020-01-04 12:12:00 -0800351 JsonMerge("{ }", "{ }", "{ }");
352
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700353 JsonMerge("{ \"foo_bool\": true }", "{ \"foo_bool\": false }",
354 "{ \"foo_bool\": false }");
355
356 JsonMerge("{ \"foo_bool\": false }", "{ \"foo_bool\": true }",
357 "{ \"foo_bool\": true }");
358
359 JsonMerge("{ \"foo_byte\": 5 }", "{ \"foo_byte\": -7 }",
360 "{ \"foo_byte\": -7 }");
361
362 JsonMerge("{ \"foo_ubyte\": 5 }", "{ \"foo_ubyte\": 7 }",
363 "{ \"foo_ubyte\": 7 }");
364
365 JsonMerge("{ \"foo_short\": 5 }", "{ \"foo_short\": 7 }",
366 "{ \"foo_short\": 7 }");
367
368 JsonMerge("{ \"foo_int\": 5 }", "{ \"foo_int\": 7 }", "{ \"foo_int\": 7 }");
369
370 JsonMerge("{ \"foo_uint\": 5 }", "{ \"foo_uint\": 7 }",
371 "{ \"foo_uint\": 7 }");
372
373 JsonMerge("{ \"foo_long\": 5 }", "{ \"foo_long\": 7 }",
374 "{ \"foo_long\": 7 }");
375
376 JsonMerge("{ \"foo_ulong\": 5 }", "{ \"foo_ulong\": 7 }",
377 "{ \"foo_ulong\": 7 }");
378
379 JsonMerge("{ \"foo_float\": 5.0 }", "{ \"foo_float\": 7.1 }",
380 "{ \"foo_float\": 7.1 }");
381
382 JsonMerge("{ \"foo_double\": 5.0 }", "{ \"foo_double\": 7.1 }",
383 "{ \"foo_double\": 7.1 }");
384}
385
386// Test arrays of simple types.
387TEST_F(FlatbufferMerge, Array) {
388 JsonMerge("{ \"foo_string\": \"baz\" }", "{ \"foo_string\": \"bar\" }",
389 "{ \"foo_string\": \"bar\" }");
390
391 JsonMerge("{ \"vector_foo_bool\": [ true, true, false ] }",
392 "{ \"vector_foo_bool\": [ false, true, true, false ] }",
393 "{ \"vector_foo_bool\": [ true, true, false, false, "
394 "true, true, false ] }");
395
396 JsonMerge("{ \"vector_foo_byte\": [ 9, 7, 1 ] }",
397 "{ \"vector_foo_byte\": [ -3, 1, 3, 2 ] }",
398 "{ \"vector_foo_byte\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
399
400 JsonMerge("{ \"vector_foo_ubyte\": [ 9, 7, 1 ] }",
401 "{ \"vector_foo_ubyte\": [ 3, 1, 3, 2 ] }",
402 "{ \"vector_foo_ubyte\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
403
404 JsonMerge("{ \"vector_foo_short\": [ 9, 7, 1 ] }",
405 "{ \"vector_foo_short\": [ -3, 1, 3, 2 ] }",
406 "{ \"vector_foo_short\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
407
408 JsonMerge("{ \"vector_foo_ushort\": [ 9, 7, 1 ] }",
409 "{ \"vector_foo_ushort\": [ 3, 1, 3, 2 ] }",
410 "{ \"vector_foo_ushort\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
411
412 JsonMerge("{ \"vector_foo_int\": [ 9, 7, 1 ] }",
413 "{ \"vector_foo_int\": [ -3, 1, 3, 2 ] }",
414 "{ \"vector_foo_int\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
415
416 JsonMerge("{ \"vector_foo_uint\": [ 9, 7, 1 ] }",
417 "{ \"vector_foo_uint\": [ 3, 1, 3, 2 ] }",
418 "{ \"vector_foo_uint\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
419
420 JsonMerge("{ \"vector_foo_long\": [ 9, 7, 1 ] }",
421 "{ \"vector_foo_long\": [ -3, 1, 3, 2 ] }",
422 "{ \"vector_foo_long\": [ 9, 7, 1, -3, 1, 3, 2 ] }");
423
424 JsonMerge("{ \"vector_foo_ulong\": [ 9, 7, 1 ] }",
425 "{ \"vector_foo_ulong\": [ 3, 1, 3, 2 ] }",
426 "{ \"vector_foo_ulong\": [ 9, 7, 1, 3, 1, 3, 2 ] }");
427
428 JsonMerge("{ \"vector_foo_float\": [ 9.0, 7.0, 1.0 ] }",
429 "{ \"vector_foo_float\": [ -3.0, 1.3, 3.0, 2.0 ] }",
430 "{ \"vector_foo_float\": [ 9.0, 7.0, 1.0, -3.0, 1.3, 3.0, 2.0 ] }");
431
Austin Schuhe93d8642019-10-13 15:27:07 -0700432 JsonMerge(
433 "{ \"vector_foo_string\": [ \"9\", \"7\", \"1 \" ] }",
434 "{ \"vector_foo_string\": [ \"31\", \"32\" ] }",
435 "{ \"vector_foo_string\": [ \"9\", \"7\", \"1 \", \"31\", \"32\" ] }");
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700436}
437
438// Test nested messages, and arrays of nested messages.
439TEST_F(FlatbufferMerge, NestedStruct) {
440 JsonMerge(
441 "{ \"single_application\": { \"name\": \"woot\" } }",
442 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
443 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }");
444
445 JsonMerge(
446 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
447 "{ \"single_application\": { \"name\": \"woot\" } }",
448 "{ \"single_application\": { \"name\": \"woot\", \"priority\": 7 } }");
449
450 JsonMerge("{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" } ] }",
451 "{ \"apps\": [ { \"name\": \"woo2\" }, { \"name\": \"wo3\" } ] }",
452 "{ \"apps\": [ { \"name\": \"woot\" }, { \"name\": \"wow\" }, { "
453 "\"name\": \"woo2\" }, { \"name\": \"wo3\" } ] }");
454}
455
Austin Schuha4fc60f2020-11-01 23:06:47 -0800456// Test nested messages, and arrays of nested messages.
457TEST(FlatbufferCopy, WholesaleCopy) {
458 flatbuffers::FlatBufferBuilder fbb_expected;
459 fbb_expected.ForceDefaults(true);
460 fbb_expected.DedupVtables(false);
461
462 {
463 flatbuffers::Offset<flatbuffers::String> name1_offset =
464 fbb_expected.CreateString("wow");
465
466 std::vector<flatbuffers::Offset<Application>> application_offsets;
467 Application::Builder a1_builder(fbb_expected);
468 a1_builder.add_name(name1_offset);
469 a1_builder.add_priority(7);
470 a1_builder.add_long_thingy(0x2549713132LL);
471 application_offsets.emplace_back(a1_builder.Finish());
472
473 flatbuffers::Offset<flatbuffers::String> name2_offset =
474 fbb_expected.CreateString("foo");
475 Application::Builder a2_builder(fbb_expected);
476 a2_builder.add_name(name2_offset);
477 a2_builder.add_priority(3);
478 a2_builder.add_long_thingy(9);
479 application_offsets.emplace_back(a2_builder.Finish());
480
481 flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Application>>>
482 applications_offset = fbb_expected.CreateVector(application_offsets);
483
484 Configuration::Builder configuration_builder(fbb_expected);
485 configuration_builder.add_apps(applications_offset);
486 fbb_expected.Finish(configuration_builder.Finish());
487 }
488
489 LOG(INFO) << "Initial alignment " << fbb_expected.GetBufferMinAlignment();
490
491 aos::FlatbufferDetachedBuffer<Configuration> expected(fbb_expected.Release());
492
493 LOG(INFO) << "Expected "
494 << absl::BytesToHexString(std::string_view(
495 reinterpret_cast<char *>(expected.span().data()),
496 expected.span().size()));
497
498 aos::FlatbufferDetachedBuffer<Application> a1 = []() {
499 flatbuffers::FlatBufferBuilder fbb;
500 fbb.ForceDefaults(true);
501
502 flatbuffers::Offset<flatbuffers::String> name1_offset =
503 fbb.CreateString("wow");
504
505 Application::Builder a1_builder(fbb);
506 a1_builder.add_name(name1_offset);
507 a1_builder.add_priority(7);
508 a1_builder.add_long_thingy(0x2549713132LL);
509 flatbuffers::Offset<Application> a1 = a1_builder.Finish();
510
511 fbb.Finish(a1);
512 return fbb.Release();
513 }();
514
515 aos::FlatbufferDetachedBuffer<Application> a2 =
516 JsonToFlatbuffer<Application>(static_cast<const char *>(
517 "{ \"name\": \"foo\", \"priority\": 3, \"long_thingy\": 9 }"));
518
519 aos::FlatbufferDetachedBuffer<Configuration> c1 = [&a1, &a2]() {
520 flatbuffers::FlatBufferBuilder fbb;
521 fbb.ForceDefaults(true);
522
523 std::vector<flatbuffers::Offset<Application>> application_offsets;
524 application_offsets.emplace_back(BlindCopyFlatBuffer(a1, &fbb));
525 application_offsets.emplace_back(BlindCopyFlatBuffer(a2, &fbb));
526
527 flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Application>>>
528 applications_offset = fbb.CreateVector(application_offsets);
529
530 Configuration::Builder configuration_builder(fbb);
531 configuration_builder.add_apps(applications_offset);
532 fbb.Finish(configuration_builder.Finish());
533
534 return fbb.Release();
535 }();
536
537 LOG(INFO) << "Got "
538 << absl::BytesToHexString(
539 std::string_view(reinterpret_cast<char *>(c1.span().data()),
540 c1.span().size()));
541
542 aos::FlatbufferDetachedBuffer<Configuration> c2 = [&a1, &a2]() {
543 flatbuffers::FlatBufferBuilder fbb;
544 fbb.ForceDefaults(true);
545
546 std::vector<flatbuffers::Offset<Application>> application_offsets;
547 application_offsets.emplace_back(CopyFlatBuffer(&a1.message(), &fbb));
548 application_offsets.emplace_back(CopyFlatBuffer(&a2.message(), &fbb));
549
550 flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Application>>>
551 applications_offset = fbb.CreateVector(application_offsets);
552
553 Configuration::Builder configuration_builder(fbb);
554 configuration_builder.add_apps(applications_offset);
555 fbb.Finish(configuration_builder.Finish());
556
557 return fbb.Release();
558 }();
559
560 LOG(INFO) << "Got "
561 << absl::BytesToHexString(
562 std::string_view(reinterpret_cast<char *>(c2.span().data()),
563 c2.span().size()));
564
565 ASSERT_TRUE(expected.Verify());
566 ASSERT_TRUE(c1.Verify());
567 ASSERT_TRUE(c2.Verify());
568
569 LOG(INFO) << FlatbufferToJson(expected);
570 LOG(INFO) << FlatbufferToJson(c1);
571 LOG(INFO) << FlatbufferToJson(c2);
572 EXPECT_EQ(FlatbufferToJson(expected), FlatbufferToJson(c1));
573 EXPECT_EQ(FlatbufferToJson(expected), FlatbufferToJson(c2));
574}
575
Austin Schuh30d7db92020-01-26 16:45:47 -0800576// Tests a compare of 2 basic (different) messages.
577TEST_F(FlatbufferMerge, CompareDifferent) {
578 aos::FlatbufferDetachedBuffer<Configuration> message1(JsonToFlatbuffer(
579 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 7 } }",
580 ConfigurationTypeTable()));
581 aos::FlatbufferDetachedBuffer<Configuration> message2(JsonToFlatbuffer(
582 "{ \"single_application\": { \"name\": \"wow\", \"priority\": 8 } }",
583 ConfigurationTypeTable()));
584
585 EXPECT_FALSE(CompareFlatBuffer(&message1.message(), &message2.message()));
586}
587
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700588// TODO(austin): enums
589// TODO(austin): unions
590// TODO(austin): struct
591
592} // namespace testing
593} // namespace aos