xref: /aosp_15_r20/external/flatbuffers/grpc/tests/message_builder_test.cpp (revision 890232f25432b36107d06881e0a25aaa6b473652)
1*890232f2SAndroid Build Coastguard Worker #include "flatbuffers/grpc.h"
2*890232f2SAndroid Build Coastguard Worker #include "monster_test_generated.h"
3*890232f2SAndroid Build Coastguard Worker #include "test_assert.h"
4*890232f2SAndroid Build Coastguard Worker #include "test_builder.h"
5*890232f2SAndroid Build Coastguard Worker 
6*890232f2SAndroid Build Coastguard Worker using MyGame::Example::Any_NONE;
7*890232f2SAndroid Build Coastguard Worker using MyGame::Example::CreateStat;
8*890232f2SAndroid Build Coastguard Worker using MyGame::Example::Vec3;
9*890232f2SAndroid Build Coastguard Worker 
verify(flatbuffers::grpc::Message<Monster> & msg,const std::string & expected_name,Color expected_color)10*890232f2SAndroid Build Coastguard Worker bool verify(flatbuffers::grpc::Message<Monster> &msg,
11*890232f2SAndroid Build Coastguard Worker             const std::string &expected_name, Color expected_color) {
12*890232f2SAndroid Build Coastguard Worker   const Monster *monster = msg.GetRoot();
13*890232f2SAndroid Build Coastguard Worker   const auto name = monster->name()->str();
14*890232f2SAndroid Build Coastguard Worker   const auto color = monster->color();
15*890232f2SAndroid Build Coastguard Worker   TEST_EQ(name, expected_name);
16*890232f2SAndroid Build Coastguard Worker   TEST_EQ(color, expected_color);
17*890232f2SAndroid Build Coastguard Worker   return (name == expected_name) && (color == expected_color);
18*890232f2SAndroid Build Coastguard Worker }
19*890232f2SAndroid Build Coastguard Worker 
release_n_verify(flatbuffers::grpc::MessageBuilder & mbb,const std::string & expected_name,Color expected_color)20*890232f2SAndroid Build Coastguard Worker bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb,
21*890232f2SAndroid Build Coastguard Worker                       const std::string &expected_name, Color expected_color) {
22*890232f2SAndroid Build Coastguard Worker   flatbuffers::grpc::Message<Monster> msg = mbb.ReleaseMessage<Monster>();
23*890232f2SAndroid Build Coastguard Worker   return verify(msg, expected_name, expected_color);
24*890232f2SAndroid Build Coastguard Worker }
25*890232f2SAndroid Build Coastguard Worker 
builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder dst)26*890232f2SAndroid Build Coastguard Worker void builder_move_assign_after_releaseraw_test(
27*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::MessageBuilder dst) {
28*890232f2SAndroid Build Coastguard Worker   auto root_offset1 = populate1(dst);
29*890232f2SAndroid Build Coastguard Worker   dst.Finish(root_offset1);
30*890232f2SAndroid Build Coastguard Worker   size_t size, offset;
31*890232f2SAndroid Build Coastguard Worker   ::grpc::Slice slice;
32*890232f2SAndroid Build Coastguard Worker   dst.ReleaseRaw(size, offset, slice);
33*890232f2SAndroid Build Coastguard Worker   flatbuffers::FlatBufferBuilder src;
34*890232f2SAndroid Build Coastguard Worker   auto root_offset2 = populate2(src);
35*890232f2SAndroid Build Coastguard Worker   src.Finish(root_offset2);
36*890232f2SAndroid Build Coastguard Worker   auto src_size = src.GetSize();
37*890232f2SAndroid Build Coastguard Worker   // Move into a released builder.
38*890232f2SAndroid Build Coastguard Worker   dst = std::move(src);
39*890232f2SAndroid Build Coastguard Worker   TEST_EQ(dst.GetSize(), src_size);
40*890232f2SAndroid Build Coastguard Worker   TEST_ASSERT(release_n_verify(dst, m2_name(), m2_color()));
41*890232f2SAndroid Build Coastguard Worker   TEST_EQ(src.GetSize(), 0);
42*890232f2SAndroid Build Coastguard Worker }
43*890232f2SAndroid Build Coastguard Worker 
44*890232f2SAndroid Build Coastguard Worker template<class SrcBuilder>
45*890232f2SAndroid Build Coastguard Worker struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
builder_reusable_after_release_message_testBuilderReuseTests46*890232f2SAndroid Build Coastguard Worker   static void builder_reusable_after_release_message_test(
47*890232f2SAndroid Build Coastguard Worker       TestSelector selector) {
48*890232f2SAndroid Build Coastguard Worker     if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) { return; }
49*890232f2SAndroid Build Coastguard Worker 
50*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::MessageBuilder mb;
51*890232f2SAndroid Build Coastguard Worker     std::vector<flatbuffers::grpc::Message<Monster>> buffers;
52*890232f2SAndroid Build Coastguard Worker     for (int i = 0; i < 5; ++i) {
53*890232f2SAndroid Build Coastguard Worker       auto root_offset1 = populate1(mb);
54*890232f2SAndroid Build Coastguard Worker       mb.Finish(root_offset1);
55*890232f2SAndroid Build Coastguard Worker       buffers.push_back(mb.ReleaseMessage<Monster>());
56*890232f2SAndroid Build Coastguard Worker       TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
57*890232f2SAndroid Build Coastguard Worker     }
58*890232f2SAndroid Build Coastguard Worker   }
59*890232f2SAndroid Build Coastguard Worker 
builder_reusable_after_release_testBuilderReuseTests60*890232f2SAndroid Build Coastguard Worker   static void builder_reusable_after_release_test(TestSelector selector) {
61*890232f2SAndroid Build Coastguard Worker     if (!selector.count(REUSABLE_AFTER_RELEASE)) { return; }
62*890232f2SAndroid Build Coastguard Worker 
63*890232f2SAndroid Build Coastguard Worker     // FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in
64*890232f2SAndroid Build Coastguard Worker     // SliceAllocator::allocate in the second iteration.
65*890232f2SAndroid Build Coastguard Worker 
66*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::MessageBuilder mb;
67*890232f2SAndroid Build Coastguard Worker     std::vector<flatbuffers::DetachedBuffer> buffers;
68*890232f2SAndroid Build Coastguard Worker     for (int i = 0; i < 2; ++i) {
69*890232f2SAndroid Build Coastguard Worker       auto root_offset1 = populate1(mb);
70*890232f2SAndroid Build Coastguard Worker       mb.Finish(root_offset1);
71*890232f2SAndroid Build Coastguard Worker       buffers.push_back(mb.Release());
72*890232f2SAndroid Build Coastguard Worker       TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
73*890232f2SAndroid Build Coastguard Worker     }
74*890232f2SAndroid Build Coastguard Worker   }
75*890232f2SAndroid Build Coastguard Worker 
builder_reusable_after_releaseraw_testBuilderReuseTests76*890232f2SAndroid Build Coastguard Worker   static void builder_reusable_after_releaseraw_test(TestSelector selector) {
77*890232f2SAndroid Build Coastguard Worker     if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) { return; }
78*890232f2SAndroid Build Coastguard Worker 
79*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::MessageBuilder mb;
80*890232f2SAndroid Build Coastguard Worker     for (int i = 0; i < 5; ++i) {
81*890232f2SAndroid Build Coastguard Worker       auto root_offset1 = populate1(mb);
82*890232f2SAndroid Build Coastguard Worker       mb.Finish(root_offset1);
83*890232f2SAndroid Build Coastguard Worker       size_t size, offset;
84*890232f2SAndroid Build Coastguard Worker       ::grpc::Slice slice;
85*890232f2SAndroid Build Coastguard Worker       const uint8_t *buf = mb.ReleaseRaw(size, offset, slice);
86*890232f2SAndroid Build Coastguard Worker       TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
87*890232f2SAndroid Build Coastguard Worker     }
88*890232f2SAndroid Build Coastguard Worker   }
89*890232f2SAndroid Build Coastguard Worker 
builder_reusable_after_release_and_move_assign_testBuilderReuseTests90*890232f2SAndroid Build Coastguard Worker   static void builder_reusable_after_release_and_move_assign_test(
91*890232f2SAndroid Build Coastguard Worker       TestSelector selector) {
92*890232f2SAndroid Build Coastguard Worker     if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { return; }
93*890232f2SAndroid Build Coastguard Worker 
94*890232f2SAndroid Build Coastguard Worker     // FIXME: Release-move_assign loop fails assert(p ==
95*890232f2SAndroid Build Coastguard Worker     // GRPC_SLICE_START_PTR(slice_)) in DetachedBuffer destructor after all the
96*890232f2SAndroid Build Coastguard Worker     // iterations
97*890232f2SAndroid Build Coastguard Worker 
98*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::MessageBuilder dst;
99*890232f2SAndroid Build Coastguard Worker     std::vector<flatbuffers::DetachedBuffer> buffers;
100*890232f2SAndroid Build Coastguard Worker 
101*890232f2SAndroid Build Coastguard Worker     for (int i = 0; i < 2; ++i) {
102*890232f2SAndroid Build Coastguard Worker       auto root_offset1 = populate1(dst);
103*890232f2SAndroid Build Coastguard Worker       dst.Finish(root_offset1);
104*890232f2SAndroid Build Coastguard Worker       buffers.push_back(dst.Release());
105*890232f2SAndroid Build Coastguard Worker       TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
106*890232f2SAndroid Build Coastguard Worker 
107*890232f2SAndroid Build Coastguard Worker       // bring dst back to life.
108*890232f2SAndroid Build Coastguard Worker       SrcBuilder src;
109*890232f2SAndroid Build Coastguard Worker       dst = std::move(src);
110*890232f2SAndroid Build Coastguard Worker       TEST_EQ_FUNC(dst.GetSize(), 0);
111*890232f2SAndroid Build Coastguard Worker       TEST_EQ_FUNC(src.GetSize(), 0);
112*890232f2SAndroid Build Coastguard Worker     }
113*890232f2SAndroid Build Coastguard Worker   }
114*890232f2SAndroid Build Coastguard Worker 
builder_reusable_after_release_message_and_move_assign_testBuilderReuseTests115*890232f2SAndroid Build Coastguard Worker   static void builder_reusable_after_release_message_and_move_assign_test(
116*890232f2SAndroid Build Coastguard Worker       TestSelector selector) {
117*890232f2SAndroid Build Coastguard Worker     if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN)) {
118*890232f2SAndroid Build Coastguard Worker       return;
119*890232f2SAndroid Build Coastguard Worker     }
120*890232f2SAndroid Build Coastguard Worker 
121*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::MessageBuilder dst;
122*890232f2SAndroid Build Coastguard Worker     std::vector<flatbuffers::grpc::Message<Monster>> buffers;
123*890232f2SAndroid Build Coastguard Worker 
124*890232f2SAndroid Build Coastguard Worker     for (int i = 0; i < 5; ++i) {
125*890232f2SAndroid Build Coastguard Worker       auto root_offset1 = populate1(dst);
126*890232f2SAndroid Build Coastguard Worker       dst.Finish(root_offset1);
127*890232f2SAndroid Build Coastguard Worker       buffers.push_back(dst.ReleaseMessage<Monster>());
128*890232f2SAndroid Build Coastguard Worker       TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
129*890232f2SAndroid Build Coastguard Worker 
130*890232f2SAndroid Build Coastguard Worker       // bring dst back to life.
131*890232f2SAndroid Build Coastguard Worker       SrcBuilder src;
132*890232f2SAndroid Build Coastguard Worker       dst = std::move(src);
133*890232f2SAndroid Build Coastguard Worker       TEST_EQ_FUNC(dst.GetSize(), 0);
134*890232f2SAndroid Build Coastguard Worker       TEST_EQ_FUNC(src.GetSize(), 0);
135*890232f2SAndroid Build Coastguard Worker     }
136*890232f2SAndroid Build Coastguard Worker   }
137*890232f2SAndroid Build Coastguard Worker 
builder_reusable_after_releaseraw_and_move_assign_testBuilderReuseTests138*890232f2SAndroid Build Coastguard Worker   static void builder_reusable_after_releaseraw_and_move_assign_test(
139*890232f2SAndroid Build Coastguard Worker       TestSelector selector) {
140*890232f2SAndroid Build Coastguard Worker     if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { return; }
141*890232f2SAndroid Build Coastguard Worker 
142*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::MessageBuilder dst;
143*890232f2SAndroid Build Coastguard Worker     for (int i = 0; i < 5; ++i) {
144*890232f2SAndroid Build Coastguard Worker       auto root_offset1 = populate1(dst);
145*890232f2SAndroid Build Coastguard Worker       dst.Finish(root_offset1);
146*890232f2SAndroid Build Coastguard Worker       size_t size, offset;
147*890232f2SAndroid Build Coastguard Worker       ::grpc::Slice slice;
148*890232f2SAndroid Build Coastguard Worker       const uint8_t *buf = dst.ReleaseRaw(size, offset, slice);
149*890232f2SAndroid Build Coastguard Worker       TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
150*890232f2SAndroid Build Coastguard Worker 
151*890232f2SAndroid Build Coastguard Worker       SrcBuilder src;
152*890232f2SAndroid Build Coastguard Worker       dst = std::move(src);
153*890232f2SAndroid Build Coastguard Worker       TEST_EQ_FUNC(dst.GetSize(), 0);
154*890232f2SAndroid Build Coastguard Worker       TEST_EQ_FUNC(src.GetSize(), 0);
155*890232f2SAndroid Build Coastguard Worker     }
156*890232f2SAndroid Build Coastguard Worker   }
157*890232f2SAndroid Build Coastguard Worker 
run_testsBuilderReuseTests158*890232f2SAndroid Build Coastguard Worker   static void run_tests(TestSelector selector) {
159*890232f2SAndroid Build Coastguard Worker     builder_reusable_after_release_test(selector);
160*890232f2SAndroid Build Coastguard Worker     builder_reusable_after_release_message_test(selector);
161*890232f2SAndroid Build Coastguard Worker     builder_reusable_after_releaseraw_test(selector);
162*890232f2SAndroid Build Coastguard Worker     builder_reusable_after_release_and_move_assign_test(selector);
163*890232f2SAndroid Build Coastguard Worker     builder_reusable_after_releaseraw_and_move_assign_test(selector);
164*890232f2SAndroid Build Coastguard Worker     builder_reusable_after_release_message_and_move_assign_test(selector);
165*890232f2SAndroid Build Coastguard Worker   }
166*890232f2SAndroid Build Coastguard Worker };
167*890232f2SAndroid Build Coastguard Worker 
slice_allocator_tests()168*890232f2SAndroid Build Coastguard Worker void slice_allocator_tests() {
169*890232f2SAndroid Build Coastguard Worker   // move-construct no-delete test
170*890232f2SAndroid Build Coastguard Worker   {
171*890232f2SAndroid Build Coastguard Worker     size_t size = 2048;
172*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::SliceAllocator sa1;
173*890232f2SAndroid Build Coastguard Worker     uint8_t *buf = sa1.allocate(size);
174*890232f2SAndroid Build Coastguard Worker     TEST_ASSERT_FUNC(buf != 0);
175*890232f2SAndroid Build Coastguard Worker     buf[0] = 100;
176*890232f2SAndroid Build Coastguard Worker     buf[size - 1] = 200;
177*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::SliceAllocator sa2(std::move(sa1));
178*890232f2SAndroid Build Coastguard Worker     // buf should not be deleted after move-construct
179*890232f2SAndroid Build Coastguard Worker     TEST_EQ_FUNC(buf[0], 100);
180*890232f2SAndroid Build Coastguard Worker     TEST_EQ_FUNC(buf[size - 1], 200);
181*890232f2SAndroid Build Coastguard Worker     // buf is freed here
182*890232f2SAndroid Build Coastguard Worker   }
183*890232f2SAndroid Build Coastguard Worker 
184*890232f2SAndroid Build Coastguard Worker   // move-assign test
185*890232f2SAndroid Build Coastguard Worker   {
186*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::SliceAllocator sa1, sa2;
187*890232f2SAndroid Build Coastguard Worker     uint8_t *buf = sa1.allocate(2048);
188*890232f2SAndroid Build Coastguard Worker     sa1 = std::move(sa2);
189*890232f2SAndroid Build Coastguard Worker     // sa1 deletes previously allocated memory in move-assign.
190*890232f2SAndroid Build Coastguard Worker     // So buf is no longer usable here.
191*890232f2SAndroid Build Coastguard Worker     TEST_ASSERT_FUNC(buf != 0);
192*890232f2SAndroid Build Coastguard Worker   }
193*890232f2SAndroid Build Coastguard Worker }
194*890232f2SAndroid Build Coastguard Worker 
195*890232f2SAndroid Build Coastguard Worker /// This function does not populate exactly the first half of the table. But it
196*890232f2SAndroid Build Coastguard Worker /// could.
populate_first_half(MyGame::Example::MonsterBuilder & wrapper,flatbuffers::Offset<flatbuffers::String> name_offset)197*890232f2SAndroid Build Coastguard Worker void populate_first_half(MyGame::Example::MonsterBuilder &wrapper,
198*890232f2SAndroid Build Coastguard Worker                          flatbuffers::Offset<flatbuffers::String> name_offset) {
199*890232f2SAndroid Build Coastguard Worker   wrapper.add_name(name_offset);
200*890232f2SAndroid Build Coastguard Worker   wrapper.add_color(m1_color());
201*890232f2SAndroid Build Coastguard Worker }
202*890232f2SAndroid Build Coastguard Worker 
203*890232f2SAndroid Build Coastguard Worker /// This function does not populate exactly the second half of the table. But it
204*890232f2SAndroid Build Coastguard Worker /// could.
populate_second_half(MyGame::Example::MonsterBuilder & wrapper)205*890232f2SAndroid Build Coastguard Worker void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
206*890232f2SAndroid Build Coastguard Worker   wrapper.add_hp(77);
207*890232f2SAndroid Build Coastguard Worker   wrapper.add_mana(88);
208*890232f2SAndroid Build Coastguard Worker   Vec3 vec3;
209*890232f2SAndroid Build Coastguard Worker   wrapper.add_pos(&vec3);
210*890232f2SAndroid Build Coastguard Worker }
211*890232f2SAndroid Build Coastguard Worker 
212*890232f2SAndroid Build Coastguard Worker /// This function is a hack to update the FlatBufferBuilder reference (fbb_) in
213*890232f2SAndroid Build Coastguard Worker /// the MonsterBuilder object. This function will break if fbb_ is not the first
214*890232f2SAndroid Build Coastguard Worker /// member in MonsterBuilder. In that case, some offset must be added. This
215*890232f2SAndroid Build Coastguard Worker /// function is used exclusively for testing correctness of move operations
216*890232f2SAndroid Build Coastguard Worker /// between FlatBufferBuilders. If MonsterBuilder had a fbb_ pointer, this hack
217*890232f2SAndroid Build Coastguard Worker /// would be unnecessary. That involves a code-generator change though.
test_only_hack_update_fbb_reference(MyGame::Example::MonsterBuilder & monsterBuilder,flatbuffers::grpc::MessageBuilder & mb)218*890232f2SAndroid Build Coastguard Worker void test_only_hack_update_fbb_reference(
219*890232f2SAndroid Build Coastguard Worker     MyGame::Example::MonsterBuilder &monsterBuilder,
220*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::MessageBuilder &mb) {
221*890232f2SAndroid Build Coastguard Worker   *reinterpret_cast<flatbuffers::FlatBufferBuilder **>(&monsterBuilder) = &mb;
222*890232f2SAndroid Build Coastguard Worker }
223*890232f2SAndroid Build Coastguard Worker 
224*890232f2SAndroid Build Coastguard Worker /// This test validates correctness of move conversion of FlatBufferBuilder to a
225*890232f2SAndroid Build Coastguard Worker /// MessageBuilder DURING a table construction. Half of the table is constructed
226*890232f2SAndroid Build Coastguard Worker /// using FlatBufferBuilder and the other half of the table is constructed using
227*890232f2SAndroid Build Coastguard Worker /// a MessageBuilder.
builder_move_ctor_conversion_before_finish_half_n_half_table_test()228*890232f2SAndroid Build Coastguard Worker void builder_move_ctor_conversion_before_finish_half_n_half_table_test() {
229*890232f2SAndroid Build Coastguard Worker   for (size_t initial_size = 4; initial_size <= 2048; initial_size *= 2) {
230*890232f2SAndroid Build Coastguard Worker     flatbuffers::FlatBufferBuilder fbb(initial_size);
231*890232f2SAndroid Build Coastguard Worker     auto name_offset = fbb.CreateString(m1_name());
232*890232f2SAndroid Build Coastguard Worker     MyGame::Example::MonsterBuilder monsterBuilder(
233*890232f2SAndroid Build Coastguard Worker         fbb);  // starts a table in FlatBufferBuilder
234*890232f2SAndroid Build Coastguard Worker     populate_first_half(monsterBuilder, name_offset);
235*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
236*890232f2SAndroid Build Coastguard Worker     test_only_hack_update_fbb_reference(monsterBuilder, mb);  // hack
237*890232f2SAndroid Build Coastguard Worker     populate_second_half(monsterBuilder);
238*890232f2SAndroid Build Coastguard Worker     mb.Finish(monsterBuilder.Finish());  // ends the table in MessageBuilder
239*890232f2SAndroid Build Coastguard Worker     TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
240*890232f2SAndroid Build Coastguard Worker     TEST_EQ_FUNC(fbb.GetSize(), 0);
241*890232f2SAndroid Build Coastguard Worker   }
242*890232f2SAndroid Build Coastguard Worker }
243*890232f2SAndroid Build Coastguard Worker 
244*890232f2SAndroid Build Coastguard Worker /// This test populates a COMPLETE inner table before move conversion and later
245*890232f2SAndroid Build Coastguard Worker /// populates more members in the outer table.
builder_move_ctor_conversion_before_finish_test()246*890232f2SAndroid Build Coastguard Worker void builder_move_ctor_conversion_before_finish_test() {
247*890232f2SAndroid Build Coastguard Worker   for (size_t initial_size = 1; initial_size <= 2048; initial_size += 1) {
248*890232f2SAndroid Build Coastguard Worker     flatbuffers::FlatBufferBuilder fbb(initial_size);
249*890232f2SAndroid Build Coastguard Worker     auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
250*890232f2SAndroid Build Coastguard Worker     flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
251*890232f2SAndroid Build Coastguard Worker     auto monster_offset =
252*890232f2SAndroid Build Coastguard Worker         CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0,
253*890232f2SAndroid Build Coastguard Worker                       m1_color(), Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
254*890232f2SAndroid Build Coastguard Worker     mb.Finish(monster_offset);
255*890232f2SAndroid Build Coastguard Worker     {
256*890232f2SAndroid Build Coastguard Worker       auto mon = flatbuffers::GetRoot<Monster>(mb.GetBufferPointer());
257*890232f2SAndroid Build Coastguard Worker       TEST_NOTNULL(mon);
258*890232f2SAndroid Build Coastguard Worker       TEST_NOTNULL(mon->name());
259*890232f2SAndroid Build Coastguard Worker       TEST_EQ_STR(mon->name()->c_str(), m1_name().c_str());
260*890232f2SAndroid Build Coastguard Worker       TEST_EQ(mon->color(), m1_color());
261*890232f2SAndroid Build Coastguard Worker     }
262*890232f2SAndroid Build Coastguard Worker     TEST_EQ(1, MyGame::Example::Color_Red);
263*890232f2SAndroid Build Coastguard Worker     TEST_EQ(1, m1_color());
264*890232f2SAndroid Build Coastguard Worker     TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
265*890232f2SAndroid Build Coastguard Worker     TEST_EQ_FUNC(fbb.GetSize(), 0);
266*890232f2SAndroid Build Coastguard Worker   }
267*890232f2SAndroid Build Coastguard Worker }
268*890232f2SAndroid Build Coastguard Worker 
269*890232f2SAndroid Build Coastguard Worker /// This test validates correctness of move conversion of FlatBufferBuilder to a
270*890232f2SAndroid Build Coastguard Worker /// MessageBuilder DURING a table construction. Half of the table is constructed
271*890232f2SAndroid Build Coastguard Worker /// using FlatBufferBuilder and the other half of the table is constructed using
272*890232f2SAndroid Build Coastguard Worker /// a MessageBuilder.
builder_move_assign_conversion_before_finish_half_n_half_table_test()273*890232f2SAndroid Build Coastguard Worker void builder_move_assign_conversion_before_finish_half_n_half_table_test() {
274*890232f2SAndroid Build Coastguard Worker   flatbuffers::FlatBufferBuilder fbb;
275*890232f2SAndroid Build Coastguard Worker   flatbuffers::grpc::MessageBuilder mb;
276*890232f2SAndroid Build Coastguard Worker 
277*890232f2SAndroid Build Coastguard Worker   for (int i = 0; i < 5; ++i) {
278*890232f2SAndroid Build Coastguard Worker     flatbuffers::FlatBufferBuilder fbb;
279*890232f2SAndroid Build Coastguard Worker     auto name_offset = fbb.CreateString(m1_name());
280*890232f2SAndroid Build Coastguard Worker     MyGame::Example::MonsterBuilder monsterBuilder(
281*890232f2SAndroid Build Coastguard Worker         fbb);  // starts a table in FlatBufferBuilder
282*890232f2SAndroid Build Coastguard Worker     populate_first_half(monsterBuilder, name_offset);
283*890232f2SAndroid Build Coastguard Worker     mb = std::move(fbb);
284*890232f2SAndroid Build Coastguard Worker     test_only_hack_update_fbb_reference(monsterBuilder, mb);  // hack
285*890232f2SAndroid Build Coastguard Worker     populate_second_half(monsterBuilder);
286*890232f2SAndroid Build Coastguard Worker     mb.Finish(monsterBuilder.Finish());  // ends the table in MessageBuilder
287*890232f2SAndroid Build Coastguard Worker     TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
288*890232f2SAndroid Build Coastguard Worker     TEST_EQ_FUNC(fbb.GetSize(), 0);
289*890232f2SAndroid Build Coastguard Worker   }
290*890232f2SAndroid Build Coastguard Worker }
291*890232f2SAndroid Build Coastguard Worker 
292*890232f2SAndroid Build Coastguard Worker /// This test populates a COMPLETE inner table before move conversion and later
293*890232f2SAndroid Build Coastguard Worker /// populates more members in the outer table.
builder_move_assign_conversion_before_finish_test()294*890232f2SAndroid Build Coastguard Worker void builder_move_assign_conversion_before_finish_test() {
295*890232f2SAndroid Build Coastguard Worker   flatbuffers::FlatBufferBuilder fbb;
296*890232f2SAndroid Build Coastguard Worker   flatbuffers::grpc::MessageBuilder mb;
297*890232f2SAndroid Build Coastguard Worker 
298*890232f2SAndroid Build Coastguard Worker   for (int i = 0; i < 5; ++i) {
299*890232f2SAndroid Build Coastguard Worker     auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
300*890232f2SAndroid Build Coastguard Worker     mb = std::move(fbb);
301*890232f2SAndroid Build Coastguard Worker     auto monster_offset =
302*890232f2SAndroid Build Coastguard Worker         CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0,
303*890232f2SAndroid Build Coastguard Worker                       m1_color(), Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
304*890232f2SAndroid Build Coastguard Worker     mb.Finish(monster_offset);
305*890232f2SAndroid Build Coastguard Worker     TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
306*890232f2SAndroid Build Coastguard Worker     TEST_EQ_FUNC(fbb.GetSize(), 0);
307*890232f2SAndroid Build Coastguard Worker   }
308*890232f2SAndroid Build Coastguard Worker }
309*890232f2SAndroid Build Coastguard Worker 
310*890232f2SAndroid Build Coastguard Worker /// This test populates data, finishes the buffer, and does move conversion
311*890232f2SAndroid Build Coastguard Worker /// after.
builder_move_ctor_conversion_after_finish_test()312*890232f2SAndroid Build Coastguard Worker void builder_move_ctor_conversion_after_finish_test() {
313*890232f2SAndroid Build Coastguard Worker   flatbuffers::FlatBufferBuilder fbb;
314*890232f2SAndroid Build Coastguard Worker   fbb.Finish(populate1(fbb));
315*890232f2SAndroid Build Coastguard Worker   flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
316*890232f2SAndroid Build Coastguard Worker   TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
317*890232f2SAndroid Build Coastguard Worker   TEST_EQ_FUNC(fbb.GetSize(), 0);
318*890232f2SAndroid Build Coastguard Worker }
319*890232f2SAndroid Build Coastguard Worker 
320*890232f2SAndroid Build Coastguard Worker /// This test populates data, finishes the buffer, and does move conversion
321*890232f2SAndroid Build Coastguard Worker /// after.
builder_move_assign_conversion_after_finish_test()322*890232f2SAndroid Build Coastguard Worker void builder_move_assign_conversion_after_finish_test() {
323*890232f2SAndroid Build Coastguard Worker   flatbuffers::FlatBufferBuilder fbb;
324*890232f2SAndroid Build Coastguard Worker   flatbuffers::grpc::MessageBuilder mb;
325*890232f2SAndroid Build Coastguard Worker 
326*890232f2SAndroid Build Coastguard Worker   for (int i = 0; i < 5; ++i) {
327*890232f2SAndroid Build Coastguard Worker     fbb.Finish(populate1(fbb));
328*890232f2SAndroid Build Coastguard Worker     mb = std::move(fbb);
329*890232f2SAndroid Build Coastguard Worker     TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
330*890232f2SAndroid Build Coastguard Worker     TEST_EQ_FUNC(fbb.GetSize(), 0);
331*890232f2SAndroid Build Coastguard Worker   }
332*890232f2SAndroid Build Coastguard Worker }
333*890232f2SAndroid Build Coastguard Worker 
message_builder_tests()334*890232f2SAndroid Build Coastguard Worker void message_builder_tests() {
335*890232f2SAndroid Build Coastguard Worker   using flatbuffers::FlatBufferBuilder;
336*890232f2SAndroid Build Coastguard Worker   using flatbuffers::grpc::MessageBuilder;
337*890232f2SAndroid Build Coastguard Worker 
338*890232f2SAndroid Build Coastguard Worker   slice_allocator_tests();
339*890232f2SAndroid Build Coastguard Worker 
340*890232f2SAndroid Build Coastguard Worker #ifndef __APPLE__
341*890232f2SAndroid Build Coastguard Worker   builder_move_ctor_conversion_before_finish_half_n_half_table_test();
342*890232f2SAndroid Build Coastguard Worker   builder_move_assign_conversion_before_finish_half_n_half_table_test();
343*890232f2SAndroid Build Coastguard Worker #endif  // __APPLE__
344*890232f2SAndroid Build Coastguard Worker   builder_move_ctor_conversion_before_finish_test();
345*890232f2SAndroid Build Coastguard Worker   builder_move_assign_conversion_before_finish_test();
346*890232f2SAndroid Build Coastguard Worker 
347*890232f2SAndroid Build Coastguard Worker   builder_move_ctor_conversion_after_finish_test();
348*890232f2SAndroid Build Coastguard Worker   builder_move_assign_conversion_after_finish_test();
349*890232f2SAndroid Build Coastguard Worker 
350*890232f2SAndroid Build Coastguard Worker   BuilderTests<MessageBuilder, MessageBuilder>::all_tests();
351*890232f2SAndroid Build Coastguard Worker   BuilderTests<MessageBuilder, FlatBufferBuilder>::all_tests();
352*890232f2SAndroid Build Coastguard Worker 
353*890232f2SAndroid Build Coastguard Worker   BuilderReuseTestSelector tests[6] = {
354*890232f2SAndroid Build Coastguard Worker     // REUSABLE_AFTER_RELEASE,                 // Assertion failed:
355*890232f2SAndroid Build Coastguard Worker     // (GRPC_SLICE_IS_EMPTY(slice_))
356*890232f2SAndroid Build Coastguard Worker     // REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p ==
357*890232f2SAndroid Build Coastguard Worker     // GRPC_SLICE_START_PTR(slice_)
358*890232f2SAndroid Build Coastguard Worker 
359*890232f2SAndroid Build Coastguard Worker     REUSABLE_AFTER_RELEASE_RAW, REUSABLE_AFTER_RELEASE_MESSAGE,
360*890232f2SAndroid Build Coastguard Worker     REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN,
361*890232f2SAndroid Build Coastguard Worker     REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
362*890232f2SAndroid Build Coastguard Worker   };
363*890232f2SAndroid Build Coastguard Worker 
364*890232f2SAndroid Build Coastguard Worker   BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(
365*890232f2SAndroid Build Coastguard Worker       TestSelector(tests, tests + 6));
366*890232f2SAndroid Build Coastguard Worker   BuilderReuseTests<MessageBuilder, FlatBufferBuilder>::run_tests(
367*890232f2SAndroid Build Coastguard Worker       TestSelector(tests, tests + 6));
368*890232f2SAndroid Build Coastguard Worker }
369