blob: fe3d10e553fd15cf24be3376f3857b5e3b69e143 [file] [log] [blame]
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001# coding=utf-8
2# Copyright 2014 Google Inc. All rights reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import os.path
17import sys
18import imp
19PY_VERSION = sys.version_info[:2]
20
21import ctypes
22from collections import defaultdict
23import math
24import random
25import timeit
26import unittest
27
28from flatbuffers import compat
29from flatbuffers import util
30from flatbuffers.compat import range_func as compat_range
31from flatbuffers.compat import NumpyRequiredForThisFeature
32
33import flatbuffers
34from flatbuffers import number_types as N
35
36import MyGame # refers to generated code
37import MyGame.Example # refers to generated code
38import MyGame.Example.Any # refers to generated code
39import MyGame.Example.Color # refers to generated code
40import MyGame.Example.Monster # refers to generated code
41import MyGame.Example.Test # refers to generated code
42import MyGame.Example.Stat # refers to generated code
43import MyGame.Example.Vec3 # refers to generated code
44import MyGame.MonsterExtra # refers to generated code
James Kuszmaul8e62b022022-03-22 09:33:25 -070045import MyGame.InParentNamespace # refers to generated code
Austin Schuhe89fa2d2019-08-14 20:24:23 -070046import MyGame.Example.ArrayTable # refers to generated code
47import MyGame.Example.ArrayStruct # refers to generated code
48import MyGame.Example.NestedStruct # refers to generated code
49import MyGame.Example.TestEnum # refers to generated code
James Kuszmaul3b15b0c2022-11-08 14:03:16 -080050import MyGame.Example.NestedUnion.NestedUnionTest # refers to generated code
51import MyGame.Example.NestedUnion.Vec3 # refers to generated code
52import MyGame.Example.NestedUnion.Any # refers to generated code
53import MyGame.Example.NestedUnion.Test # refers to generated code
54import MyGame.Example.NestedUnion.Color # refers to generated code
James Kuszmaul8e62b022022-03-22 09:33:25 -070055import monster_test_generated # the one-file version
Austin Schuh2dd86a92022-09-14 21:19:23 -070056import optional_scalars
57import optional_scalars.ScalarStuff
James Kuszmaul8e62b022022-03-22 09:33:25 -070058
59
60def create_namespace_shortcut(is_onefile):
61 # Create shortcut from either the one-file format or the multi-file format
62 global _ANY
63 global _COLOR
64 global _MONSTER
65 global _TEST
66 global _STAT
67 global _VEC3
68 global _IN_PARENT_NAMESPACE
69 if is_onefile:
70 print('Testing with the one-file generated code')
71 _ANY = monster_test_generated
72 _COLOR = monster_test_generated
73 _MONSTER = monster_test_generated
74 _TEST = monster_test_generated
75 _STAT = monster_test_generated
76 _VEC3 = monster_test_generated
77 _IN_PARENT_NAMESPACE = monster_test_generated
78 else:
79 print('Testing with multi-file generated code')
80 _ANY = MyGame.Example.Any
81 _COLOR = MyGame.Example.Color
82 _MONSTER = MyGame.Example.Monster
83 _TEST = MyGame.Example.Test
84 _STAT = MyGame.Example.Stat
85 _VEC3 = MyGame.Example.Vec3
86 _IN_PARENT_NAMESPACE = MyGame.InParentNamespace
87
Austin Schuhe89fa2d2019-08-14 20:24:23 -070088
89def assertRaises(test_case, fn, exception_class):
James Kuszmaul8e62b022022-03-22 09:33:25 -070090 """ Backwards-compatible assertion for exceptions raised. """
Austin Schuhe89fa2d2019-08-14 20:24:23 -070091
James Kuszmaul8e62b022022-03-22 09:33:25 -070092 exc = None
93 try:
94 fn()
95 except Exception as e:
96 exc = e
97 test_case.assertTrue(exc is not None)
98 test_case.assertTrue(isinstance(exc, exception_class))
Austin Schuhe89fa2d2019-08-14 20:24:23 -070099
100
101class TestWireFormat(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700102
James Kuszmaul8e62b022022-03-22 09:33:25 -0700103 def test_wire_format(self):
104 # Verify that using the generated Python code builds a buffer without
105 # returning errors, and is interpreted correctly, for size prefixed
106 # representation and regular:
107 for sizePrefix in [True, False]:
108 for file_identifier in [None, b'MONS']:
109 gen_buf, gen_off = make_monster_from_generated_code(
110 sizePrefix=sizePrefix, file_identifier=file_identifier)
111 CheckReadBuffer(
112 gen_buf,
113 gen_off,
114 sizePrefix=sizePrefix,
115 file_identifier=file_identifier)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700116
James Kuszmaul8e62b022022-03-22 09:33:25 -0700117 # Verify that the canonical flatbuffer file is readable by the
118 # generated Python code. Note that context managers are not part of
119 # Python 2.5, so we use the simpler open/close methods here:
120 f = open('monsterdata_test.mon', 'rb')
121 canonicalWireData = f.read()
122 f.close()
123 CheckReadBuffer(bytearray(canonicalWireData), 0, file_identifier=b'MONS')
124
125 # Write the generated buffer out to a file:
126 f = open('monsterdata_python_wire.mon', 'wb')
127 f.write(gen_buf[gen_off:])
128 f.close()
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700129
130
Austin Schuh272c6132020-11-14 16:37:52 -0800131class TestObjectBasedAPI(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700132 """ Tests the generated object based API."""
Austin Schuh272c6132020-11-14 16:37:52 -0800133
James Kuszmaul8e62b022022-03-22 09:33:25 -0700134 def test_consistenty_with_repeated_pack_and_unpack(self):
135 """ Checks the serialization and deserialization between a buffer and
136
Austin Schuh272c6132020-11-14 16:37:52 -0800137 its python object. It tests in the same way as the C++ object API test,
James Kuszmaul8e62b022022-03-22 09:33:25 -0700138 ObjectFlatBuffersTest in test.cpp.
139 """
Austin Schuh272c6132020-11-14 16:37:52 -0800140
James Kuszmaul8e62b022022-03-22 09:33:25 -0700141 buf, off = make_monster_from_generated_code()
Austin Schuh272c6132020-11-14 16:37:52 -0800142
James Kuszmaul8e62b022022-03-22 09:33:25 -0700143 # Turns a buffer into Python object (T class).
144 monster1 = _MONSTER.Monster.GetRootAs(buf, off)
145 monsterT1 = _MONSTER.MonsterT.InitFromObj(monster1)
Austin Schuh272c6132020-11-14 16:37:52 -0800146
James Kuszmaul8e62b022022-03-22 09:33:25 -0700147 for sizePrefix in [True, False]:
148 # Re-serialize the data into a buffer.
149 b1 = flatbuffers.Builder(0)
150 if sizePrefix:
151 b1.FinishSizePrefixed(monsterT1.Pack(b1))
152 else:
153 b1.Finish(monsterT1.Pack(b1))
154 CheckReadBuffer(b1.Bytes, b1.Head(), sizePrefix)
Austin Schuh272c6132020-11-14 16:37:52 -0800155
James Kuszmaul8e62b022022-03-22 09:33:25 -0700156 # Deserializes the buffer into Python object again.
157 monster2 = _MONSTER.Monster.GetRootAs(b1.Bytes, b1.Head())
158 # Re-serializes the data into a buffer for one more time.
159 monsterT2 = _MONSTER.MonsterT.InitFromObj(monster2)
160 for sizePrefix in [True, False]:
161 # Re-serializes the data into a buffer
162 b2 = flatbuffers.Builder(0)
163 if sizePrefix:
164 b2.FinishSizePrefixed(monsterT2.Pack(b2))
165 else:
166 b2.Finish(monsterT2.Pack(b2))
167 CheckReadBuffer(b2.Bytes, b2.Head(), sizePrefix)
Austin Schuh272c6132020-11-14 16:37:52 -0800168
James Kuszmaul8e62b022022-03-22 09:33:25 -0700169 def test_default_values_with_pack_and_unpack(self):
170 """ Serializes and deserializes between a buffer with default values (no
171
Austin Schuh272c6132020-11-14 16:37:52 -0800172 specific values are filled when the buffer is created) and its python
James Kuszmaul8e62b022022-03-22 09:33:25 -0700173 object.
174 """
175 # Creates a flatbuffer with default values.
176 b1 = flatbuffers.Builder(0)
177 _MONSTER.MonsterStart(b1)
178 gen_mon = _MONSTER.MonsterEnd(b1)
179 b1.Finish(gen_mon)
Austin Schuh272c6132020-11-14 16:37:52 -0800180
James Kuszmaul8e62b022022-03-22 09:33:25 -0700181 # Converts the flatbuffer into the object class.
182 monster1 = _MONSTER.Monster.GetRootAs(b1.Bytes, b1.Head())
183 monsterT1 = _MONSTER.MonsterT.InitFromObj(monster1)
Austin Schuh272c6132020-11-14 16:37:52 -0800184
James Kuszmaul8e62b022022-03-22 09:33:25 -0700185 # Packs the object class into another flatbuffer.
186 b2 = flatbuffers.Builder(0)
187 b2.Finish(monsterT1.Pack(b2))
188 monster2 = _MONSTER.Monster.GetRootAs(b2.Bytes, b2.Head())
189 # Checks the default values.
190 self.assertTrue(monster2.Pos() is None)
191 self.assertEqual(monster2.Mana(), 150)
192 self.assertEqual(monster2.Hp(), 100)
193 self.assertTrue(monster2.Name() is None)
194 self.assertEqual(monster2.Inventory(0), 0)
195 self.assertEqual(monster2.InventoryAsNumpy(), 0)
196 self.assertEqual(monster2.InventoryLength(), 0)
197 self.assertTrue(monster2.InventoryIsNone())
198 self.assertTrue(monster2.Color() is 8)
199 self.assertEqual(monster2.TestType(), 0)
200 self.assertTrue(monster2.Test() is None)
201 self.assertTrue(monster2.Test4(0) is None)
202 self.assertEqual(monster2.Test4Length(), 0)
203 self.assertTrue(monster2.Test4IsNone())
204 self.assertTrue(monster2.Testarrayofstring(0) is '')
205 self.assertEqual(monster2.TestarrayofstringLength(), 0)
206 self.assertTrue(monster2.TestarrayofstringIsNone())
207 self.assertTrue(monster2.Testarrayoftables(0) is None)
208 self.assertEqual(monster2.TestarrayoftablesLength(), 0)
209 self.assertTrue(monster2.TestarrayoftablesIsNone())
210 self.assertTrue(monster2.Enemy() is None)
211 self.assertEqual(monster2.Testnestedflatbuffer(0), 0)
212 self.assertEqual(monster2.TestnestedflatbufferAsNumpy(), 0)
213 self.assertEqual(monster2.TestnestedflatbufferLength(), 0)
214 self.assertTrue(monster2.TestnestedflatbufferIsNone())
215 self.assertTrue(monster2.Testempty() is None)
216 self.assertTrue(monster2.Testbool() is False)
217 self.assertEqual(monster2.Testhashs32Fnv1(), 0)
218 self.assertEqual(monster2.Testhashu32Fnv1(), 0)
219 self.assertEqual(monster2.Testhashs64Fnv1(), 0)
220 self.assertEqual(monster2.Testhashu64Fnv1(), 0)
221 self.assertEqual(monster2.Testhashs32Fnv1a(), 0)
222 self.assertEqual(monster2.Testhashu32Fnv1a(), 0)
223 self.assertEqual(monster2.Testhashs64Fnv1a(), 0)
224 self.assertEqual(monster2.Testhashu64Fnv1a(), 0)
225 self.assertEqual(monster2.Testarrayofbools(0), 0)
226 self.assertEqual(monster2.TestarrayofboolsAsNumpy(), 0)
227 self.assertEqual(monster2.TestarrayofboolsLength(), 0)
228 self.assertTrue(monster2.TestarrayofboolsIsNone())
229 self.assertEqual(monster2.Testf(), 3.14159)
230 self.assertEqual(monster2.Testf2(), 3.0)
231 self.assertEqual(monster2.Testf3(), 0.0)
232 self.assertTrue(monster2.Testarrayofstring2(0) is '')
233 self.assertEqual(monster2.Testarrayofstring2Length(), 0)
234 self.assertTrue(monster2.Testarrayofstring2IsNone())
235 self.assertTrue(monster2.Testarrayofsortedstruct(0) is None)
236 self.assertEqual(monster2.TestarrayofsortedstructLength(), 0)
237 self.assertTrue(monster2.TestarrayofsortedstructIsNone())
238 self.assertEqual(monster2.Flex(0), 0)
239 self.assertEqual(monster2.FlexAsNumpy(), 0)
240 self.assertEqual(monster2.FlexLength(), 0)
241 self.assertTrue(monster2.FlexIsNone())
242 self.assertTrue(monster2.Test5(0) is None)
243 self.assertEqual(monster2.Test5Length(), 0)
244 self.assertTrue(monster2.Test5IsNone())
245 self.assertEqual(monster2.VectorOfLongs(0), 0)
246 self.assertEqual(monster2.VectorOfLongsAsNumpy(), 0)
247 self.assertEqual(monster2.VectorOfLongsLength(), 0)
248 self.assertTrue(monster2.VectorOfLongsIsNone())
249 self.assertEqual(monster2.VectorOfDoubles(0), 0)
250 self.assertEqual(monster2.VectorOfDoublesAsNumpy(), 0)
251 self.assertEqual(monster2.VectorOfDoublesLength(), 0)
252 self.assertTrue(monster2.VectorOfDoublesIsNone())
253 self.assertTrue(monster2.ParentNamespaceTest() is None)
254 self.assertTrue(monster2.VectorOfReferrables(0) is None)
255 self.assertEqual(monster2.VectorOfReferrablesLength(), 0)
256 self.assertTrue(monster2.VectorOfReferrablesIsNone())
257 self.assertEqual(monster2.SingleWeakReference(), 0)
258 self.assertEqual(monster2.VectorOfWeakReferences(0), 0)
259 self.assertEqual(monster2.VectorOfWeakReferencesAsNumpy(), 0)
260 self.assertEqual(monster2.VectorOfWeakReferencesLength(), 0)
261 self.assertTrue(monster2.VectorOfWeakReferencesIsNone())
262 self.assertTrue(monster2.VectorOfStrongReferrables(0) is None)
263 self.assertEqual(monster2.VectorOfStrongReferrablesLength(), 0)
264 self.assertTrue(monster2.VectorOfStrongReferrablesIsNone())
265 self.assertEqual(monster2.CoOwningReference(), 0)
266 self.assertEqual(monster2.VectorOfCoOwningReferences(0), 0)
267 self.assertEqual(monster2.VectorOfCoOwningReferencesAsNumpy(), 0)
268 self.assertEqual(monster2.VectorOfCoOwningReferencesLength(), 0)
269 self.assertTrue(monster2.VectorOfCoOwningReferencesIsNone())
270 self.assertEqual(monster2.NonOwningReference(), 0)
271 self.assertEqual(monster2.VectorOfNonOwningReferences(0), 0)
272 self.assertEqual(monster2.VectorOfNonOwningReferencesAsNumpy(), 0)
273 self.assertEqual(monster2.VectorOfNonOwningReferencesLength(), 0)
274 self.assertTrue(monster2.VectorOfNonOwningReferencesIsNone())
275 self.assertEqual(monster2.AnyUniqueType(), 0)
276 self.assertTrue(monster2.AnyUnique() is None)
277 self.assertEqual(monster2.AnyAmbiguousType(), 0)
278 self.assertTrue(monster2.AnyAmbiguous() is None)
279 self.assertEqual(monster2.VectorOfEnums(0), 0)
280 self.assertEqual(monster2.VectorOfEnumsAsNumpy(), 0)
281 self.assertEqual(monster2.VectorOfEnumsLength(), 0)
282 self.assertTrue(monster2.VectorOfEnumsIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800283
Austin Schuh2dd86a92022-09-14 21:19:23 -0700284 def test_optional_scalars_with_pack_and_unpack(self):
285 """ Serializes and deserializes between a buffer with optional values (no
286 specific values are filled when the buffer is created) and its python
287 object.
288 """
289 # Creates a flatbuffer with optional values.
290 b1 = flatbuffers.Builder(0)
291 optional_scalars.ScalarStuff.ScalarStuffStart(b1)
292 gen_opt = optional_scalars.ScalarStuff.ScalarStuffEnd(b1)
293 b1.Finish(gen_opt)
294
295 # Converts the flatbuffer into the object class.
296 opts1 = optional_scalars.ScalarStuff.ScalarStuff.GetRootAs(b1.Bytes, b1.Head())
297 optsT1 = optional_scalars.ScalarStuff.ScalarStuffT.InitFromObj(opts1)
298
299 # Packs the object class into another flatbuffer.
300 b2 = flatbuffers.Builder(0)
301 b2.Finish(optsT1.Pack(b2))
302 opts2 = optional_scalars.ScalarStuff.ScalarStuff.GetRootAs(b2.Bytes, b2.Head())
303 optsT2 = optional_scalars.ScalarStuff.ScalarStuffT.InitFromObj(opts2)
304 # Checks the default values.
305 self.assertTrue(opts2.JustI8() == 0)
306 self.assertTrue(opts2.MaybeF32() is None)
307 self.assertTrue(opts2.DefaultBool() is True)
308 self.assertTrue(optsT2.justU16 == 0)
309 self.assertTrue(optsT2.maybeEnum is None)
310 self.assertTrue(optsT2.defaultU64 == 42)
311
312
Austin Schuh272c6132020-11-14 16:37:52 -0800313
314class TestAllMutableCodePathsOfExampleSchema(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700315 """ Tests the object API generated for monster_test.fbs for mutation
316
Austin Schuh272c6132020-11-14 16:37:52 -0800317 purposes. In each test, the default values will be changed through the
318 object API. We'll then pack the object class into the buf class and read
319 the updated values out from it to validate if the values are mutated as
James Kuszmaul8e62b022022-03-22 09:33:25 -0700320 expected.
321 """
Austin Schuh272c6132020-11-14 16:37:52 -0800322
James Kuszmaul8e62b022022-03-22 09:33:25 -0700323 def setUp(self, *args, **kwargs):
324 super(TestAllMutableCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
325 # Creates an empty monster flatbuffer, and loads it into the object
326 # class for future tests.
327 b = flatbuffers.Builder(0)
328 _MONSTER.MonsterStart(b)
329 self.monsterT = self._create_and_load_object_class(b)
Austin Schuh272c6132020-11-14 16:37:52 -0800330
James Kuszmaul8e62b022022-03-22 09:33:25 -0700331 def _pack_and_load_buf_class(self, monsterT):
332 """ Packs the object class into a flatbuffer and loads it into a buf
Austin Schuh272c6132020-11-14 16:37:52 -0800333
James Kuszmaul8e62b022022-03-22 09:33:25 -0700334 class.
335 """
336 b = flatbuffers.Builder(0)
337 b.Finish(monsterT.Pack(b))
338 monster = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
339 return monster
Austin Schuh272c6132020-11-14 16:37:52 -0800340
James Kuszmaul8e62b022022-03-22 09:33:25 -0700341 def _create_and_load_object_class(self, b):
342 """ Finishs the creation of a monster flatbuffer and loads it into an
Austin Schuh272c6132020-11-14 16:37:52 -0800343
James Kuszmaul8e62b022022-03-22 09:33:25 -0700344 object class.
345 """
346 gen_mon = _MONSTER.MonsterEnd(b)
347 b.Finish(gen_mon)
348 monster = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
349 monsterT = _MONSTER.MonsterT()
350 monsterT.InitFromObj(monster)
351 return monsterT
Austin Schuh272c6132020-11-14 16:37:52 -0800352
James Kuszmaul8e62b022022-03-22 09:33:25 -0700353 def test_mutate_pos(self):
354 posT = _VEC3.Vec3T()
355 posT.x = 4.0
356 posT.y = 5.0
357 posT.z = 6.0
358 posT.test1 = 6.0
359 posT.test2 = 7
360 test3T = _TEST.TestT()
361 test3T.a = 8
362 test3T.b = 9
363 posT.test3 = test3T
364 self.monsterT.pos = posT
Austin Schuh272c6132020-11-14 16:37:52 -0800365
James Kuszmaul8e62b022022-03-22 09:33:25 -0700366 # Packs the updated values.
367 monster = self._pack_and_load_buf_class(self.monsterT)
Austin Schuh272c6132020-11-14 16:37:52 -0800368
James Kuszmaul8e62b022022-03-22 09:33:25 -0700369 # Checks if values are loaded correctly into the object class.
370 pos = monster.Pos()
Austin Schuh272c6132020-11-14 16:37:52 -0800371
James Kuszmaul8e62b022022-03-22 09:33:25 -0700372 # Verifies the properties of the Vec3.
373 self.assertEqual(pos.X(), 4.0)
374 self.assertEqual(pos.Y(), 5.0)
375 self.assertEqual(pos.Z(), 6.0)
376 self.assertEqual(pos.Test1(), 6.0)
377 self.assertEqual(pos.Test2(), 7)
378 t3 = _TEST.Test()
379 t3 = pos.Test3(t3)
380 self.assertEqual(t3.A(), 8)
381 self.assertEqual(t3.B(), 9)
Austin Schuh272c6132020-11-14 16:37:52 -0800382
James Kuszmaul8e62b022022-03-22 09:33:25 -0700383 def test_mutate_mana(self):
384 self.monsterT.mana = 200
385 monster = self._pack_and_load_buf_class(self.monsterT)
386 self.assertEqual(monster.Mana(), 200)
Austin Schuh272c6132020-11-14 16:37:52 -0800387
James Kuszmaul8e62b022022-03-22 09:33:25 -0700388 def test_mutate_hp(self):
389 self.monsterT.hp = 200
390 monster = self._pack_and_load_buf_class(self.monsterT)
391 self.assertEqual(monster.Hp(), 200)
Austin Schuh272c6132020-11-14 16:37:52 -0800392
James Kuszmaul8e62b022022-03-22 09:33:25 -0700393 def test_mutate_name(self):
394 self.monsterT.name = 'MyMonster'
395 monster = self._pack_and_load_buf_class(self.monsterT)
396 self.assertEqual(monster.Name(), b'MyMonster')
Austin Schuh272c6132020-11-14 16:37:52 -0800397
James Kuszmaul8e62b022022-03-22 09:33:25 -0700398 def test_mutate_inventory(self):
399 self.monsterT.inventory = [1, 7, 8]
400 monster = self._pack_and_load_buf_class(self.monsterT)
401 self.assertEqual(monster.Inventory(0), 1)
402 self.assertEqual(monster.Inventory(1), 7)
403 self.assertEqual(monster.Inventory(2), 8)
Austin Schuh272c6132020-11-14 16:37:52 -0800404
James Kuszmaul8e62b022022-03-22 09:33:25 -0700405 def test_empty_inventory(self):
406 self.monsterT.inventory = []
407 monster = self._pack_and_load_buf_class(self.monsterT)
408 self.assertFalse(monster.InventoryIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800409
James Kuszmaul8e62b022022-03-22 09:33:25 -0700410 def test_mutate_color(self):
411 self.monsterT.color = _COLOR.Color.Red
412 monster = self._pack_and_load_buf_class(self.monsterT)
413 self.assertEqual(monster.Color(), _COLOR.Color.Red)
Austin Schuh272c6132020-11-14 16:37:52 -0800414
James Kuszmaul8e62b022022-03-22 09:33:25 -0700415 def test_mutate_testtype(self):
416 self.monsterT.testType = _ANY.Any.Monster
417 monster = self._pack_and_load_buf_class(self.monsterT)
418 self.assertEqual(monster.TestType(), _ANY.Any.Monster)
Austin Schuh272c6132020-11-14 16:37:52 -0800419
James Kuszmaul8e62b022022-03-22 09:33:25 -0700420 def test_mutate_test(self):
421 testT = _MONSTER.MonsterT()
422 testT.hp = 200
423 self.monsterT.test = testT
424 monster = self._pack_and_load_buf_class(self.monsterT)
425 # Initializes a Table from a union field Test(...).
426 table = monster.Test()
Austin Schuh272c6132020-11-14 16:37:52 -0800427
James Kuszmaul8e62b022022-03-22 09:33:25 -0700428 # Initializes a Monster from the Table from the union.
429 test_monster = _MONSTER.Monster()
430 test_monster.Init(table.Bytes, table.Pos)
431 self.assertEqual(test_monster.Hp(), 200)
Austin Schuh272c6132020-11-14 16:37:52 -0800432
James Kuszmaul8e62b022022-03-22 09:33:25 -0700433 def test_mutate_test4(self):
434 test0T = _TEST.TestT()
435 test0T.a = 10
436 test0T.b = 20
437 test1T = _TEST.TestT()
438 test1T.a = 30
439 test1T.b = 40
440 self.monsterT.test4 = [test0T, test1T]
Austin Schuh272c6132020-11-14 16:37:52 -0800441
James Kuszmaul8e62b022022-03-22 09:33:25 -0700442 monster = self._pack_and_load_buf_class(self.monsterT)
443 test0 = monster.Test4(0)
444 self.assertEqual(test0.A(), 10)
445 self.assertEqual(test0.B(), 20)
446 test1 = monster.Test4(1)
447 self.assertEqual(test1.A(), 30)
448 self.assertEqual(test1.B(), 40)
Austin Schuh272c6132020-11-14 16:37:52 -0800449
James Kuszmaul8e62b022022-03-22 09:33:25 -0700450 def test_empty_test4(self):
451 self.monsterT.test4 = []
452 monster = self._pack_and_load_buf_class(self.monsterT)
453 self.assertFalse(monster.Test4IsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800454
James Kuszmaul8e62b022022-03-22 09:33:25 -0700455 def test_mutate_testarrayofstring(self):
456 self.monsterT.testarrayofstring = []
457 self.monsterT.testarrayofstring.append('test1')
458 self.monsterT.testarrayofstring.append('test2')
459 monster = self._pack_and_load_buf_class(self.monsterT)
460 self.assertEqual(monster.Testarrayofstring(0), b'test1')
461 self.assertEqual(monster.Testarrayofstring(1), b'test2')
Austin Schuh272c6132020-11-14 16:37:52 -0800462
James Kuszmaul8e62b022022-03-22 09:33:25 -0700463 def test_empty_testarrayofstring(self):
464 self.monsterT.testarrayofstring = []
465 monster = self._pack_and_load_buf_class(self.monsterT)
466 self.assertFalse(monster.TestarrayofstringIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800467
James Kuszmaul8e62b022022-03-22 09:33:25 -0700468 def test_mutate_testarrayoftables(self):
469 monsterT0 = _MONSTER.MonsterT()
470 monsterT0.hp = 200
471 monsterT1 = _MONSTER.MonsterT()
472 monsterT1.hp = 400
473 self.monsterT.testarrayoftables = []
474 self.monsterT.testarrayoftables.append(monsterT0)
475 self.monsterT.testarrayoftables.append(monsterT1)
476 monster = self._pack_and_load_buf_class(self.monsterT)
477 self.assertEqual(monster.Testarrayoftables(0).Hp(), 200)
478 self.assertEqual(monster.Testarrayoftables(1).Hp(), 400)
Austin Schuh272c6132020-11-14 16:37:52 -0800479
James Kuszmaul8e62b022022-03-22 09:33:25 -0700480 def test_empty_testarrayoftables(self):
481 self.monsterT.testarrayoftables = []
482 monster = self._pack_and_load_buf_class(self.monsterT)
483 self.assertFalse(monster.TestarrayoftablesIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800484
James Kuszmaul8e62b022022-03-22 09:33:25 -0700485 def test_mutate_enemy(self):
486 monsterT = _MONSTER.MonsterT()
487 monsterT.hp = 200
488 self.monsterT.enemy = monsterT
489 monster = self._pack_and_load_buf_class(self.monsterT)
490 self.assertEqual(monster.Enemy().Hp(), 200)
Austin Schuh272c6132020-11-14 16:37:52 -0800491
James Kuszmaul8e62b022022-03-22 09:33:25 -0700492 def test_mutate_testnestedflatbuffer(self):
493 self.monsterT.testnestedflatbuffer = [8, 2, 4]
494 monster = self._pack_and_load_buf_class(self.monsterT)
495 self.assertEqual(monster.Testnestedflatbuffer(0), 8)
496 self.assertEqual(monster.Testnestedflatbuffer(1), 2)
497 self.assertEqual(monster.Testnestedflatbuffer(2), 4)
Austin Schuh272c6132020-11-14 16:37:52 -0800498
James Kuszmaul8e62b022022-03-22 09:33:25 -0700499 def test_empty_testnestedflatbuffer(self):
500 self.monsterT.testnestedflatbuffer = []
501 monster = self._pack_and_load_buf_class(self.monsterT)
502 self.assertFalse(monster.TestnestedflatbufferIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800503
James Kuszmaul8e62b022022-03-22 09:33:25 -0700504 def test_mutate_testbool(self):
505 self.monsterT.testbool = True
506 monster = self._pack_and_load_buf_class(self.monsterT)
507 self.assertTrue(monster.Testbool())
Austin Schuh272c6132020-11-14 16:37:52 -0800508
James Kuszmaul8e62b022022-03-22 09:33:25 -0700509 def test_mutate_testhashes(self):
510 self.monsterT.testhashs32Fnv1 = 1
511 self.monsterT.testhashu32Fnv1 = 2
512 self.monsterT.testhashs64Fnv1 = 3
513 self.monsterT.testhashu64Fnv1 = 4
514 self.monsterT.testhashs32Fnv1a = 5
515 self.monsterT.testhashu32Fnv1a = 6
516 self.monsterT.testhashs64Fnv1a = 7
517 self.monsterT.testhashu64Fnv1a = 8
518 monster = self._pack_and_load_buf_class(self.monsterT)
519 self.assertEqual(monster.Testhashs32Fnv1(), 1)
520 self.assertEqual(monster.Testhashu32Fnv1(), 2)
521 self.assertEqual(monster.Testhashs64Fnv1(), 3)
522 self.assertEqual(monster.Testhashu64Fnv1(), 4)
523 self.assertEqual(monster.Testhashs32Fnv1a(), 5)
524 self.assertEqual(monster.Testhashu32Fnv1a(), 6)
525 self.assertEqual(monster.Testhashs64Fnv1a(), 7)
526 self.assertEqual(monster.Testhashu64Fnv1a(), 8)
Austin Schuh272c6132020-11-14 16:37:52 -0800527
James Kuszmaul8e62b022022-03-22 09:33:25 -0700528 def test_mutate_testarrayofbools(self):
529 self.monsterT.testarrayofbools = []
530 self.monsterT.testarrayofbools.append(True)
531 self.monsterT.testarrayofbools.append(True)
532 self.monsterT.testarrayofbools.append(False)
533 monster = self._pack_and_load_buf_class(self.monsterT)
534 self.assertEqual(monster.Testarrayofbools(0), True)
535 self.assertEqual(monster.Testarrayofbools(1), True)
536 self.assertEqual(monster.Testarrayofbools(2), False)
Austin Schuh272c6132020-11-14 16:37:52 -0800537
James Kuszmaul8e62b022022-03-22 09:33:25 -0700538 def test_empty_testarrayofbools(self):
539 self.monsterT.testarrayofbools = []
540 monster = self._pack_and_load_buf_class(self.monsterT)
541 self.assertFalse(monster.TestarrayofboolsIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800542
James Kuszmaul8e62b022022-03-22 09:33:25 -0700543 def test_mutate_testf(self):
544 self.monsterT.testf = 2.0
545 monster = self._pack_and_load_buf_class(self.monsterT)
546 self.assertEqual(monster.Testf(), 2.0)
Austin Schuh272c6132020-11-14 16:37:52 -0800547
James Kuszmaul8e62b022022-03-22 09:33:25 -0700548 def test_mutate_vectoroflongs(self):
549 self.monsterT.vectorOfLongs = []
550 self.monsterT.vectorOfLongs.append(1)
551 self.monsterT.vectorOfLongs.append(100)
552 self.monsterT.vectorOfLongs.append(10000)
553 self.monsterT.vectorOfLongs.append(1000000)
554 self.monsterT.vectorOfLongs.append(100000000)
555 monster = self._pack_and_load_buf_class(self.monsterT)
556 self.assertEqual(monster.VectorOfLongs(0), 1)
557 self.assertEqual(monster.VectorOfLongs(1), 100)
558 self.assertEqual(monster.VectorOfLongs(2), 10000)
559 self.assertEqual(monster.VectorOfLongs(3), 1000000)
560 self.assertEqual(monster.VectorOfLongs(4), 100000000)
Austin Schuh272c6132020-11-14 16:37:52 -0800561
James Kuszmaul8e62b022022-03-22 09:33:25 -0700562 def test_empty_vectoroflongs(self):
563 self.monsterT.vectorOfLongs = []
564 monster = self._pack_and_load_buf_class(self.monsterT)
565 self.assertFalse(monster.VectorOfLongsIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800566
James Kuszmaul8e62b022022-03-22 09:33:25 -0700567 def test_mutate_vectorofdoubles(self):
568 self.monsterT.vectorOfDoubles = []
569 self.monsterT.vectorOfDoubles.append(-1.7976931348623157e+308)
570 self.monsterT.vectorOfDoubles.append(0)
571 self.monsterT.vectorOfDoubles.append(1.7976931348623157e+308)
572 monster = self._pack_and_load_buf_class(self.monsterT)
573 self.assertEqual(monster.VectorOfDoubles(0), -1.7976931348623157e+308)
574 self.assertEqual(monster.VectorOfDoubles(1), 0)
575 self.assertEqual(monster.VectorOfDoubles(2), 1.7976931348623157e+308)
Austin Schuh272c6132020-11-14 16:37:52 -0800576
James Kuszmaul8e62b022022-03-22 09:33:25 -0700577 def test_empty_vectorofdoubles(self):
578 self.monsterT.vectorOfDoubles = []
579 monster = self._pack_and_load_buf_class(self.monsterT)
580 self.assertFalse(monster.VectorOfDoublesIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800581
James Kuszmaul8e62b022022-03-22 09:33:25 -0700582 def test_mutate_parentnamespacetest(self):
583 self.monsterT.parentNamespaceTest = _IN_PARENT_NAMESPACE.InParentNamespaceT(
584 )
585 monster = self._pack_and_load_buf_class(self.monsterT)
586 self.assertTrue(
587 isinstance(monster.ParentNamespaceTest(),
588 _IN_PARENT_NAMESPACE.InParentNamespace))
589
590 def test_mutate_vectorofEnums(self):
591 self.monsterT.vectorOfEnums = []
592 self.monsterT.vectorOfEnums.append(_COLOR.Color.Red)
593 self.monsterT.vectorOfEnums.append(_COLOR.Color.Blue)
594 self.monsterT.vectorOfEnums.append(_COLOR.Color.Red)
595 monster = self._pack_and_load_buf_class(self.monsterT)
596 self.assertEqual(monster.VectorOfEnums(0), _COLOR.Color.Red)
597 self.assertEqual(monster.VectorOfEnums(1), _COLOR.Color.Blue)
598 self.assertEqual(monster.VectorOfEnums(2), _COLOR.Color.Red)
599
600 def test_empty_vectorofEnums(self):
601 self.monsterT.vectorOfEnums = []
602 monster = self._pack_and_load_buf_class(self.monsterT)
603 self.assertFalse(monster.VectorOfEnumsIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800604
605
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700606def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700607 """ CheckReadBuffer checks that the given buffer is evaluated correctly
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700608
James Kuszmaul8e62b022022-03-22 09:33:25 -0700609 as the example Monster.
610 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700611
James Kuszmaul8e62b022022-03-22 09:33:25 -0700612 def asserter(stmt):
613 """ An assertion helper that is separated from TestCase classes. """
614 if not stmt:
615 raise AssertionError('CheckReadBuffer case failed')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700616
James Kuszmaul8e62b022022-03-22 09:33:25 -0700617 if file_identifier:
618 # test prior to removal of size_prefix
619 asserter(
620 util.GetBufferIdentifier(buf, offset, size_prefixed=sizePrefix) ==
621 file_identifier)
622 asserter(
623 util.BufferHasIdentifier(
624 buf,
625 offset,
626 file_identifier=file_identifier,
627 size_prefixed=sizePrefix))
628 asserter(
629 _MONSTER.Monster.MonsterBufferHasIdentifier(
630 buf, offset, size_prefixed=sizePrefix))
631 if sizePrefix:
632 size = util.GetSizePrefix(buf, offset)
633 asserter(size == len(buf[offset:]) - 4)
634 buf, offset = util.RemoveSizePrefix(buf, offset)
635 if file_identifier:
636 asserter(_MONSTER.Monster.MonsterBufferHasIdentifier(buf, offset))
637 else:
638 asserter(not _MONSTER.Monster.MonsterBufferHasIdentifier(buf, offset))
639 monster = _MONSTER.Monster.GetRootAs(buf, offset)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700640
James Kuszmaul8e62b022022-03-22 09:33:25 -0700641 asserter(monster.Hp() == 80)
642 asserter(monster.Mana() == 150)
643 asserter(monster.Name() == b'MyMonster')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700644
James Kuszmaul8e62b022022-03-22 09:33:25 -0700645 # initialize a Vec3 from Pos()
646 vec = monster.Pos()
647 asserter(vec is not None)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700648
James Kuszmaul8e62b022022-03-22 09:33:25 -0700649 # verify the properties of the Vec3
650 asserter(vec.X() == 1.0)
651 asserter(vec.Y() == 2.0)
652 asserter(vec.Z() == 3.0)
653 asserter(vec.Test1() == 3.0)
654 asserter(vec.Test2() == 2)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700655
James Kuszmaul8e62b022022-03-22 09:33:25 -0700656 # initialize a Test from Test3(...)
657 t = _TEST.Test()
658 t = vec.Test3(t)
659 asserter(t is not None)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700660
James Kuszmaul8e62b022022-03-22 09:33:25 -0700661 # verify the properties of the Test
662 asserter(t.A() == 5)
663 asserter(t.B() == 6)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700664
James Kuszmaul8e62b022022-03-22 09:33:25 -0700665 # verify that the enum code matches the enum declaration:
666 union_type = _ANY.Any
667 asserter(monster.TestType() == union_type.Monster)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700668
James Kuszmaul8e62b022022-03-22 09:33:25 -0700669 # initialize a Table from a union field Test(...)
670 table2 = monster.Test()
671 asserter(type(table2) is flatbuffers.table.Table)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700672
James Kuszmaul8e62b022022-03-22 09:33:25 -0700673 # initialize a Monster from the Table from the union
674 monster2 = _MONSTER.Monster()
675 monster2.Init(table2.Bytes, table2.Pos)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700676
James Kuszmaul8e62b022022-03-22 09:33:25 -0700677 asserter(monster2.Name() == b'Fred')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700678
James Kuszmaul8e62b022022-03-22 09:33:25 -0700679 # iterate through the first monster's inventory:
680 asserter(monster.InventoryLength() == 5)
681 asserter(not monster.InventoryIsNone())
682
683 invsum = 0
684 for i in compat_range(monster.InventoryLength()):
685 v = monster.Inventory(i)
686 invsum += int(v)
687 asserter(invsum == 10)
688
689 for i in range(5):
690 asserter(monster.VectorOfLongs(i) == 10**(i * 2))
691
692 asserter(not monster.VectorOfDoublesIsNone())
693 asserter(([-1.7976931348623157e+308, 0, 1.7976931348623157e+308] == [
694 monster.VectorOfDoubles(i) for i in range(monster.VectorOfDoublesLength())
695 ]))
696
697 try:
698 imp.find_module('numpy')
699 # if numpy exists, then we should be able to get the
700 # vector as a numpy array
701 import numpy as np
702
703 asserter(monster.InventoryAsNumpy().sum() == 10)
704 asserter(monster.InventoryAsNumpy().dtype == np.dtype('uint8'))
705
706 VectorOfLongs = monster.VectorOfLongsAsNumpy()
707 asserter(VectorOfLongs.dtype == np.dtype('int64'))
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700708 for i in range(5):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700709 asserter(VectorOfLongs[i] == 10**(i * 2))
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700710
James Kuszmaul8e62b022022-03-22 09:33:25 -0700711 VectorOfDoubles = monster.VectorOfDoublesAsNumpy()
712 asserter(VectorOfDoubles.dtype == np.dtype('float64'))
713 asserter(VectorOfDoubles[0] == np.finfo('float64').min)
714 asserter(VectorOfDoubles[1] == 0.0)
715 asserter(VectorOfDoubles[2] == np.finfo('float64').max)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700716
James Kuszmaul8e62b022022-03-22 09:33:25 -0700717 except ImportError:
718 # If numpy does not exist, trying to get vector as numpy
719 # array should raise NumpyRequiredForThisFeature. The way
720 # assertRaises has been implemented prevents us from
721 # asserting this error is raised outside of a test case.
722 pass
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700723
James Kuszmaul8e62b022022-03-22 09:33:25 -0700724 asserter(monster.Test4Length() == 2)
725 asserter(not monster.Test4IsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700726
James Kuszmaul8e62b022022-03-22 09:33:25 -0700727 # create a 'Test' object and populate it:
728 test0 = monster.Test4(0)
729 asserter(type(test0) is _TEST.Test)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700730
James Kuszmaul8e62b022022-03-22 09:33:25 -0700731 test1 = monster.Test4(1)
732 asserter(type(test1) is _TEST.Test)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700733
James Kuszmaul8e62b022022-03-22 09:33:25 -0700734 # the position of test0 and test1 are swapped in monsterdata_java_wire
735 # and monsterdata_test_wire, so ignore ordering
736 v0 = test0.A()
737 v1 = test0.B()
738 v2 = test1.A()
739 v3 = test1.B()
740 sumtest12 = int(v0) + int(v1) + int(v2) + int(v3)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700741
James Kuszmaul8e62b022022-03-22 09:33:25 -0700742 asserter(sumtest12 == 100)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700743
James Kuszmaul8e62b022022-03-22 09:33:25 -0700744 asserter(not monster.TestarrayofstringIsNone())
745 asserter(monster.TestarrayofstringLength() == 2)
746 asserter(monster.Testarrayofstring(0) == b'test1')
747 asserter(monster.Testarrayofstring(1) == b'test2')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700748
James Kuszmaul8e62b022022-03-22 09:33:25 -0700749 asserter(monster.TestarrayoftablesIsNone())
750 asserter(monster.TestarrayoftablesLength() == 0)
751 asserter(monster.TestnestedflatbufferIsNone())
752 asserter(monster.TestnestedflatbufferLength() == 0)
753 asserter(monster.Testempty() is None)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700754
755
756class TestFuzz(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700757 """ Low level stress/fuzz test: serialize/deserialize a variety of
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700758
James Kuszmaul8e62b022022-03-22 09:33:25 -0700759 different kinds of data in different combinations
760 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700761
James Kuszmaul8e62b022022-03-22 09:33:25 -0700762 binary_type = compat.binary_types[0] # this will always exist
763 ofInt32Bytes = binary_type([0x83, 0x33, 0x33, 0x33])
764 ofInt64Bytes = binary_type([0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44])
765 overflowingInt32Val = flatbuffers.encode.Get(flatbuffers.packer.int32,
766 ofInt32Bytes, 0)
767 overflowingInt64Val = flatbuffers.encode.Get(flatbuffers.packer.int64,
768 ofInt64Bytes, 0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700769
James Kuszmaul8e62b022022-03-22 09:33:25 -0700770 # Values we're testing against: chosen to ensure no bits get chopped
771 # off anywhere, and also be different from eachother.
772 boolVal = True
773 int8Val = N.Int8Flags.py_type(-127) # 0x81
774 uint8Val = N.Uint8Flags.py_type(0xFF)
775 int16Val = N.Int16Flags.py_type(-32222) # 0x8222
776 uint16Val = N.Uint16Flags.py_type(0xFEEE)
777 int32Val = N.Int32Flags.py_type(overflowingInt32Val)
778 uint32Val = N.Uint32Flags.py_type(0xFDDDDDDD)
779 int64Val = N.Int64Flags.py_type(overflowingInt64Val)
780 uint64Val = N.Uint64Flags.py_type(0xFCCCCCCCCCCCCCCC)
781 # Python uses doubles, so force it here
782 float32Val = N.Float32Flags.py_type(ctypes.c_float(3.14159).value)
783 float64Val = N.Float64Flags.py_type(3.14159265359)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700784
James Kuszmaul8e62b022022-03-22 09:33:25 -0700785 def test_fuzz(self):
786 return self.check_once(11, 100)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700787
James Kuszmaul8e62b022022-03-22 09:33:25 -0700788 def check_once(self, fuzzFields, fuzzObjects):
789 testValuesMax = 11 # hardcoded to the number of scalar types
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700790
James Kuszmaul8e62b022022-03-22 09:33:25 -0700791 builder = flatbuffers.Builder(0)
792 l = LCG()
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700793
James Kuszmaul8e62b022022-03-22 09:33:25 -0700794 objects = [0 for _ in compat_range(fuzzObjects)]
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700795
James Kuszmaul8e62b022022-03-22 09:33:25 -0700796 # Generate fuzzObjects random objects each consisting of
797 # fuzzFields fields, each of a random type.
798 for i in compat_range(fuzzObjects):
799 builder.StartObject(fuzzFields)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700800
James Kuszmaul8e62b022022-03-22 09:33:25 -0700801 for j in compat_range(fuzzFields):
802 choice = int(l.Next()) % testValuesMax
803 if choice == 0:
804 builder.PrependBoolSlot(int(j), self.boolVal, False)
805 elif choice == 1:
806 builder.PrependInt8Slot(int(j), self.int8Val, 0)
807 elif choice == 2:
808 builder.PrependUint8Slot(int(j), self.uint8Val, 0)
809 elif choice == 3:
810 builder.PrependInt16Slot(int(j), self.int16Val, 0)
811 elif choice == 4:
812 builder.PrependUint16Slot(int(j), self.uint16Val, 0)
813 elif choice == 5:
814 builder.PrependInt32Slot(int(j), self.int32Val, 0)
815 elif choice == 6:
816 builder.PrependUint32Slot(int(j), self.uint32Val, 0)
817 elif choice == 7:
818 builder.PrependInt64Slot(int(j), self.int64Val, 0)
819 elif choice == 8:
820 builder.PrependUint64Slot(int(j), self.uint64Val, 0)
821 elif choice == 9:
822 builder.PrependFloat32Slot(int(j), self.float32Val, 0)
823 elif choice == 10:
824 builder.PrependFloat64Slot(int(j), self.float64Val, 0)
825 else:
826 raise RuntimeError('unreachable')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700827
James Kuszmaul8e62b022022-03-22 09:33:25 -0700828 off = builder.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700829
James Kuszmaul8e62b022022-03-22 09:33:25 -0700830 # store the offset from the end of the builder buffer,
831 # since it will keep growing:
832 objects[i] = off
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700833
James Kuszmaul8e62b022022-03-22 09:33:25 -0700834 # Do some bookkeeping to generate stats on fuzzes:
835 stats = defaultdict(int)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700836
James Kuszmaul8e62b022022-03-22 09:33:25 -0700837 def check(table, desc, want, got):
838 stats[desc] += 1
839 self.assertEqual(want, got, '%s != %s, %s' % (want, got, desc))
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700840
James Kuszmaul8e62b022022-03-22 09:33:25 -0700841 l = LCG() # Reset.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700842
James Kuszmaul8e62b022022-03-22 09:33:25 -0700843 # Test that all objects we generated are readable and return the
844 # expected values. We generate random objects in the same order
845 # so this is deterministic.
846 for i in compat_range(fuzzObjects):
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700847
James Kuszmaul8e62b022022-03-22 09:33:25 -0700848 table = flatbuffers.table.Table(builder.Bytes,
849 len(builder.Bytes) - objects[i])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700850
James Kuszmaul8e62b022022-03-22 09:33:25 -0700851 for j in compat_range(fuzzFields):
852 field_count = flatbuffers.builder.VtableMetadataFields + j
853 f = N.VOffsetTFlags.py_type(field_count * N.VOffsetTFlags.bytewidth)
854 choice = int(l.Next()) % testValuesMax
855
856 if choice == 0:
857 check(table, 'bool', self.boolVal,
858 table.GetSlot(f, False, N.BoolFlags))
859 elif choice == 1:
860 check(table, 'int8', self.int8Val, table.GetSlot(f, 0, N.Int8Flags))
861 elif choice == 2:
862 check(table, 'uint8', self.uint8Val,
863 table.GetSlot(f, 0, N.Uint8Flags))
864 elif choice == 3:
865 check(table, 'int16', self.int16Val,
866 table.GetSlot(f, 0, N.Int16Flags))
867 elif choice == 4:
868 check(table, 'uint16', self.uint16Val,
869 table.GetSlot(f, 0, N.Uint16Flags))
870 elif choice == 5:
871 check(table, 'int32', self.int32Val,
872 table.GetSlot(f, 0, N.Int32Flags))
873 elif choice == 6:
874 check(table, 'uint32', self.uint32Val,
875 table.GetSlot(f, 0, N.Uint32Flags))
876 elif choice == 7:
877 check(table, 'int64', self.int64Val,
878 table.GetSlot(f, 0, N.Int64Flags))
879 elif choice == 8:
880 check(table, 'uint64', self.uint64Val,
881 table.GetSlot(f, 0, N.Uint64Flags))
882 elif choice == 9:
883 check(table, 'float32', self.float32Val,
884 table.GetSlot(f, 0, N.Float32Flags))
885 elif choice == 10:
886 check(table, 'float64', self.float64Val,
887 table.GetSlot(f, 0, N.Float64Flags))
888 else:
889 raise RuntimeError('unreachable')
890
891 # If enough checks were made, verify that all scalar types were used:
892 self.assertEqual(testValuesMax, len(stats),
893 'fuzzing failed to test all scalar types: %s' % stats)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700894
895
896class TestByteLayout(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700897 """ TestByteLayout checks the bytes of a Builder in various scenarios. """
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700898
James Kuszmaul8e62b022022-03-22 09:33:25 -0700899 def assertBuilderEquals(self, builder, want_chars_or_ints):
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700900
James Kuszmaul8e62b022022-03-22 09:33:25 -0700901 def integerize(x):
902 if isinstance(x, compat.string_types):
903 return ord(x)
904 return x
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700905
James Kuszmaul8e62b022022-03-22 09:33:25 -0700906 want_ints = list(map(integerize, want_chars_or_ints))
907 want = bytearray(want_ints)
908 got = builder.Bytes[builder.Head():] # use the buffer directly
909 self.assertEqual(want, got)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700910
James Kuszmaul8e62b022022-03-22 09:33:25 -0700911 def test_numbers(self):
912 b = flatbuffers.Builder(0)
913 self.assertBuilderEquals(b, [])
914 b.PrependBool(True)
915 self.assertBuilderEquals(b, [1])
916 b.PrependInt8(-127)
917 self.assertBuilderEquals(b, [129, 1])
918 b.PrependUint8(255)
919 self.assertBuilderEquals(b, [255, 129, 1])
920 b.PrependInt16(-32222)
921 self.assertBuilderEquals(b, [0x22, 0x82, 0, 255, 129, 1]) # first pad
922 b.PrependUint16(0xFEEE)
923 # no pad this time:
924 self.assertBuilderEquals(b, [0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1])
925 b.PrependInt32(-53687092)
926 self.assertBuilderEquals(
927 b, [204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1])
928 b.PrependUint32(0x98765432)
929 self.assertBuilderEquals(b, [
930 0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0,
931 255, 129, 1
932 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700933
James Kuszmaul8e62b022022-03-22 09:33:25 -0700934 def test_numbers64(self):
935 b = flatbuffers.Builder(0)
936 b.PrependUint64(0x1122334455667788)
937 self.assertBuilderEquals(b,
938 [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700939
James Kuszmaul8e62b022022-03-22 09:33:25 -0700940 b = flatbuffers.Builder(0)
941 b.PrependInt64(0x1122334455667788)
942 self.assertBuilderEquals(b,
943 [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700944
James Kuszmaul8e62b022022-03-22 09:33:25 -0700945 def test_1xbyte_vector(self):
946 b = flatbuffers.Builder(0)
947 self.assertBuilderEquals(b, [])
948 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 1, 1)
949 self.assertBuilderEquals(b, [0, 0, 0]) # align to 4bytes
950 b.PrependByte(1)
951 self.assertBuilderEquals(b, [1, 0, 0, 0])
952 b.EndVector()
953 self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700954
James Kuszmaul8e62b022022-03-22 09:33:25 -0700955 def test_2xbyte_vector(self):
956 b = flatbuffers.Builder(0)
957 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 2, 1)
958 self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
959 b.PrependByte(1)
960 self.assertBuilderEquals(b, [1, 0, 0])
961 b.PrependByte(2)
962 self.assertBuilderEquals(b, [2, 1, 0, 0])
963 b.EndVector()
964 self.assertBuilderEquals(b, [2, 0, 0, 0, 2, 1, 0, 0]) # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700965
James Kuszmaul8e62b022022-03-22 09:33:25 -0700966 def test_1xuint16_vector(self):
967 b = flatbuffers.Builder(0)
968 b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 1, 1)
969 self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
970 b.PrependUint16(1)
971 self.assertBuilderEquals(b, [1, 0, 0, 0])
972 b.EndVector()
973 self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700974
James Kuszmaul8e62b022022-03-22 09:33:25 -0700975 def test_2xuint16_vector(self):
976 b = flatbuffers.Builder(0)
977 b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 2, 1)
978 self.assertBuilderEquals(b, []) # align to 4bytes
979 b.PrependUint16(0xABCD)
980 self.assertBuilderEquals(b, [0xCD, 0xAB])
981 b.PrependUint16(0xDCBA)
982 self.assertBuilderEquals(b, [0xBA, 0xDC, 0xCD, 0xAB])
983 b.EndVector()
984 self.assertBuilderEquals(b, [2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700985
James Kuszmaul3b15b0c2022-11-08 14:03:16 -0800986 def test_create_ascii_shared_string(self):
987 b = flatbuffers.Builder(0)
988 b.CreateSharedString(u'foo', encoding='ascii')
989 b.CreateSharedString(u'foo', encoding='ascii')
990
991 # 0-terminated, no pad:
992 self.assertBuilderEquals(b, [3, 0, 0, 0, 'f', 'o', 'o', 0])
993 b.CreateSharedString(u'moop', encoding='ascii')
994 b.CreateSharedString(u'moop', encoding='ascii')
995 # 0-terminated, 3-byte pad:
996 self.assertBuilderEquals(b, [
997 4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, 3, 0, 0, 0, 'f', 'o', 'o', 0
998 ])
999
1000 def test_create_utf8_shared_string(self):
1001 b = flatbuffers.Builder(0)
1002 b.CreateSharedString(u'Цлїςσδε')
1003 b.CreateSharedString(u'Цлїςσδε')
1004 self.assertBuilderEquals(b, '\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97' \
1005 '\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00')
1006
1007 b.CreateSharedString(u'フムアムカモケモ')
1008 b.CreateSharedString(u'フムアムカモケモ')
1009 self.assertBuilderEquals(b, '\x18\x00\x00\x00\xef\xbe\x8c\xef\xbe\x91' \
1010 '\xef\xbd\xb1\xef\xbe\x91\xef\xbd\xb6\xef\xbe\x93\xef\xbd\xb9\xef' \
1011 '\xbe\x93\x00\x00\x00\x00\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97' \
1012 '\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00')
1013
1014 def test_create_arbitrary_shared_string(self):
1015 b = flatbuffers.Builder(0)
1016 s = '\x01\x02\x03'
1017 b.CreateSharedString(s) # Default encoding is utf-8.
1018 b.CreateSharedString(s)
1019 # 0-terminated, no pad:
1020 self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
1021 s2 = '\x04\x05\x06\x07'
1022 b.CreateSharedString(s2) # Default encoding is utf-8.
1023 b.CreateSharedString(s2)
1024 # 0-terminated, 3-byte pad:
1025 self.assertBuilderEquals(
1026 b, [4, 0, 0, 0, 4, 5, 6, 7, 0, 0, 0, 0, 3, 0, 0, 0, 1, 2, 3, 0])
1027
James Kuszmaul8e62b022022-03-22 09:33:25 -07001028 def test_create_ascii_string(self):
1029 b = flatbuffers.Builder(0)
1030 b.CreateString(u'foo', encoding='ascii')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001031
James Kuszmaul8e62b022022-03-22 09:33:25 -07001032 # 0-terminated, no pad:
1033 self.assertBuilderEquals(b, [3, 0, 0, 0, 'f', 'o', 'o', 0])
1034 b.CreateString(u'moop', encoding='ascii')
1035 # 0-terminated, 3-byte pad:
1036 self.assertBuilderEquals(b, [
1037 4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, 3, 0, 0, 0, 'f', 'o', 'o', 0
1038 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001039
James Kuszmaul8e62b022022-03-22 09:33:25 -07001040 def test_create_utf8_string(self):
1041 b = flatbuffers.Builder(0)
1042 b.CreateString(u'Цлїςσδε')
1043 self.assertBuilderEquals(b, '\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97' \
1044 '\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001045
James Kuszmaul8e62b022022-03-22 09:33:25 -07001046 b.CreateString(u'フムアムカモケモ')
1047 self.assertBuilderEquals(b, '\x18\x00\x00\x00\xef\xbe\x8c\xef\xbe\x91' \
1048 '\xef\xbd\xb1\xef\xbe\x91\xef\xbd\xb6\xef\xbe\x93\xef\xbd\xb9\xef' \
1049 '\xbe\x93\x00\x00\x00\x00\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97' \
1050 '\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001051
James Kuszmaul8e62b022022-03-22 09:33:25 -07001052 def test_create_arbitrary_string(self):
1053 b = flatbuffers.Builder(0)
1054 s = '\x01\x02\x03'
1055 b.CreateString(s) # Default encoding is utf-8.
1056 # 0-terminated, no pad:
1057 self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
1058 s2 = '\x04\x05\x06\x07'
1059 b.CreateString(s2) # Default encoding is utf-8.
1060 # 0-terminated, 3-byte pad:
1061 self.assertBuilderEquals(
1062 b, [4, 0, 0, 0, 4, 5, 6, 7, 0, 0, 0, 0, 3, 0, 0, 0, 1, 2, 3, 0])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001063
James Kuszmaul8e62b022022-03-22 09:33:25 -07001064 def test_create_byte_vector(self):
1065 b = flatbuffers.Builder(0)
1066 b.CreateByteVector(b'')
1067 # 0-byte pad:
1068 self.assertBuilderEquals(b, [0, 0, 0, 0])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001069
James Kuszmaul8e62b022022-03-22 09:33:25 -07001070 b = flatbuffers.Builder(0)
1071 b.CreateByteVector(b'\x01\x02\x03')
1072 # 1-byte pad:
1073 self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001074
James Kuszmaul8e62b022022-03-22 09:33:25 -07001075 def test_create_numpy_vector_int8(self):
1076 try:
1077 imp.find_module('numpy')
1078 # if numpy exists, then we should be able to get the
1079 # vector as a numpy array
1080 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001081
James Kuszmaul8e62b022022-03-22 09:33:25 -07001082 # Systems endian:
1083 b = flatbuffers.Builder(0)
1084 x = np.array([1, 2, -3], dtype=np.int8)
1085 b.CreateNumpyVector(x)
1086 self.assertBuilderEquals(
1087 b,
1088 [
1089 3,
1090 0,
1091 0,
1092 0, # vector length
1093 1,
1094 2,
1095 256 - 3,
1096 0 # vector value + padding
1097 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001098
James Kuszmaul8e62b022022-03-22 09:33:25 -07001099 # Reverse endian:
1100 b = flatbuffers.Builder(0)
1101 x_other_endian = x.byteswap().newbyteorder()
1102 b.CreateNumpyVector(x_other_endian)
1103 self.assertBuilderEquals(
1104 b,
1105 [
1106 3,
1107 0,
1108 0,
1109 0, # vector length
1110 1,
1111 2,
1112 256 - 3,
1113 0 # vector value + padding
1114 ])
1115 except ImportError:
1116 b = flatbuffers.Builder(0)
1117 x = 0
1118 assertRaises(self, lambda: b.CreateNumpyVector(x),
1119 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001120
James Kuszmaul8e62b022022-03-22 09:33:25 -07001121 def test_create_numpy_vector_uint16(self):
1122 try:
1123 imp.find_module('numpy')
1124 # if numpy exists, then we should be able to get the
1125 # vector as a numpy array
1126 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001127
James Kuszmaul8e62b022022-03-22 09:33:25 -07001128 # Systems endian:
1129 b = flatbuffers.Builder(0)
1130 x = np.array([1, 2, 312], dtype=np.uint16)
1131 b.CreateNumpyVector(x)
1132 self.assertBuilderEquals(
1133 b,
1134 [
1135 3,
1136 0,
1137 0,
1138 0, # vector length
1139 1,
1140 0, # 1
1141 2,
1142 0, # 2
1143 312 - 256,
1144 1, # 312
1145 0,
1146 0 # padding
1147 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001148
James Kuszmaul8e62b022022-03-22 09:33:25 -07001149 # Reverse endian:
1150 b = flatbuffers.Builder(0)
1151 x_other_endian = x.byteswap().newbyteorder()
1152 b.CreateNumpyVector(x_other_endian)
1153 self.assertBuilderEquals(
1154 b,
1155 [
1156 3,
1157 0,
1158 0,
1159 0, # vector length
1160 1,
1161 0, # 1
1162 2,
1163 0, # 2
1164 312 - 256,
1165 1, # 312
1166 0,
1167 0 # padding
1168 ])
1169 except ImportError:
1170 b = flatbuffers.Builder(0)
1171 x = 0
1172 assertRaises(self, lambda: b.CreateNumpyVector(x),
1173 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001174
James Kuszmaul8e62b022022-03-22 09:33:25 -07001175 def test_create_numpy_vector_int64(self):
1176 try:
1177 imp.find_module('numpy')
1178 # if numpy exists, then we should be able to get the
1179 # vector as a numpy array
1180 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001181
James Kuszmaul8e62b022022-03-22 09:33:25 -07001182 # Systems endian:
1183 b = flatbuffers.Builder(0)
1184 x = np.array([1, 2, -12], dtype=np.int64)
1185 b.CreateNumpyVector(x)
1186 self.assertBuilderEquals(
1187 b,
1188 [
1189 3,
1190 0,
1191 0,
1192 0, # vector length
1193 1,
1194 0,
1195 0,
1196 0,
1197 0,
1198 0,
1199 0,
1200 0, # 1
1201 2,
1202 0,
1203 0,
1204 0,
1205 0,
1206 0,
1207 0,
1208 0, # 2
1209 256 - 12,
1210 255,
1211 255,
1212 255,
1213 255,
1214 255,
1215 255,
1216 255 # -12
1217 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001218
James Kuszmaul8e62b022022-03-22 09:33:25 -07001219 # Reverse endian:
1220 b = flatbuffers.Builder(0)
1221 x_other_endian = x.byteswap().newbyteorder()
1222 b.CreateNumpyVector(x_other_endian)
1223 self.assertBuilderEquals(
1224 b,
1225 [
1226 3,
1227 0,
1228 0,
1229 0, # vector length
1230 1,
1231 0,
1232 0,
1233 0,
1234 0,
1235 0,
1236 0,
1237 0, # 1
1238 2,
1239 0,
1240 0,
1241 0,
1242 0,
1243 0,
1244 0,
1245 0, # 2
1246 256 - 12,
1247 255,
1248 255,
1249 255,
1250 255,
1251 255,
1252 255,
1253 255 # -12
1254 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001255
James Kuszmaul8e62b022022-03-22 09:33:25 -07001256 except ImportError:
1257 b = flatbuffers.Builder(0)
1258 x = 0
1259 assertRaises(self, lambda: b.CreateNumpyVector(x),
1260 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001261
James Kuszmaul8e62b022022-03-22 09:33:25 -07001262 def test_create_numpy_vector_float32(self):
1263 try:
1264 imp.find_module('numpy')
1265 # if numpy exists, then we should be able to get the
1266 # vector as a numpy array
1267 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001268
James Kuszmaul8e62b022022-03-22 09:33:25 -07001269 # Systems endian:
1270 b = flatbuffers.Builder(0)
1271 x = np.array([1, 2, -12], dtype=np.float32)
1272 b.CreateNumpyVector(x)
1273 self.assertBuilderEquals(
1274 b,
1275 [
1276 3,
1277 0,
1278 0,
1279 0, # vector length
1280 0,
1281 0,
1282 128,
1283 63, # 1
1284 0,
1285 0,
1286 0,
1287 64, # 2
1288 0,
1289 0,
1290 64,
1291 193 # -12
1292 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001293
James Kuszmaul8e62b022022-03-22 09:33:25 -07001294 # Reverse endian:
1295 b = flatbuffers.Builder(0)
1296 x_other_endian = x.byteswap().newbyteorder()
1297 b.CreateNumpyVector(x_other_endian)
1298 self.assertBuilderEquals(
1299 b,
1300 [
1301 3,
1302 0,
1303 0,
1304 0, # vector length
1305 0,
1306 0,
1307 128,
1308 63, # 1
1309 0,
1310 0,
1311 0,
1312 64, # 2
1313 0,
1314 0,
1315 64,
1316 193 # -12
1317 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001318
James Kuszmaul8e62b022022-03-22 09:33:25 -07001319 except ImportError:
1320 b = flatbuffers.Builder(0)
1321 x = 0
1322 assertRaises(self, lambda: b.CreateNumpyVector(x),
1323 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001324
James Kuszmaul8e62b022022-03-22 09:33:25 -07001325 def test_create_numpy_vector_float64(self):
1326 try:
1327 imp.find_module('numpy')
1328 # if numpy exists, then we should be able to get the
1329 # vector as a numpy array
1330 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001331
James Kuszmaul8e62b022022-03-22 09:33:25 -07001332 # Systems endian:
1333 b = flatbuffers.Builder(0)
1334 x = np.array([1, 2, -12], dtype=np.float64)
1335 b.CreateNumpyVector(x)
1336 self.assertBuilderEquals(
1337 b,
1338 [
1339 3,
1340 0,
1341 0,
1342 0, # vector length
1343 0,
1344 0,
1345 0,
1346 0,
1347 0,
1348 0,
1349 240,
1350 63, # 1
1351 0,
1352 0,
1353 0,
1354 0,
1355 0,
1356 0,
1357 0,
1358 64, # 2
1359 0,
1360 0,
1361 0,
1362 0,
1363 0,
1364 0,
1365 40,
1366 192 # -12
1367 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001368
James Kuszmaul8e62b022022-03-22 09:33:25 -07001369 # Reverse endian:
1370 b = flatbuffers.Builder(0)
1371 x_other_endian = x.byteswap().newbyteorder()
1372 b.CreateNumpyVector(x_other_endian)
1373 self.assertBuilderEquals(
1374 b,
1375 [
1376 3,
1377 0,
1378 0,
1379 0, # vector length
1380 0,
1381 0,
1382 0,
1383 0,
1384 0,
1385 0,
1386 240,
1387 63, # 1
1388 0,
1389 0,
1390 0,
1391 0,
1392 0,
1393 0,
1394 0,
1395 64, # 2
1396 0,
1397 0,
1398 0,
1399 0,
1400 0,
1401 0,
1402 40,
1403 192 # -12
1404 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001405
James Kuszmaul8e62b022022-03-22 09:33:25 -07001406 except ImportError:
1407 b = flatbuffers.Builder(0)
1408 x = 0
1409 assertRaises(self, lambda: b.CreateNumpyVector(x),
1410 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001411
James Kuszmaul8e62b022022-03-22 09:33:25 -07001412 def test_create_numpy_vector_bool(self):
1413 try:
1414 imp.find_module('numpy')
1415 # if numpy exists, then we should be able to get the
1416 # vector as a numpy array
1417 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001418
James Kuszmaul8e62b022022-03-22 09:33:25 -07001419 # Systems endian:
1420 b = flatbuffers.Builder(0)
1421 x = np.array([True, False, True], dtype=np.bool)
1422 b.CreateNumpyVector(x)
1423 self.assertBuilderEquals(
1424 b,
1425 [
1426 3,
1427 0,
1428 0,
1429 0, # vector length
1430 1,
1431 0,
1432 1,
1433 0 # vector values + padding
1434 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001435
James Kuszmaul8e62b022022-03-22 09:33:25 -07001436 # Reverse endian:
1437 b = flatbuffers.Builder(0)
1438 x_other_endian = x.byteswap().newbyteorder()
1439 b.CreateNumpyVector(x_other_endian)
1440 self.assertBuilderEquals(
1441 b,
1442 [
1443 3,
1444 0,
1445 0,
1446 0, # vector length
1447 1,
1448 0,
1449 1,
1450 0 # vector values + padding
1451 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001452
James Kuszmaul8e62b022022-03-22 09:33:25 -07001453 except ImportError:
1454 b = flatbuffers.Builder(0)
1455 x = 0
1456 assertRaises(self, lambda: b.CreateNumpyVector(x),
1457 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001458
James Kuszmaul8e62b022022-03-22 09:33:25 -07001459 def test_create_numpy_vector_reject_strings(self):
1460 try:
1461 imp.find_module('numpy')
1462 # if numpy exists, then we should be able to get the
1463 # vector as a numpy array
1464 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001465
James Kuszmaul8e62b022022-03-22 09:33:25 -07001466 # Create String array
1467 b = flatbuffers.Builder(0)
1468 x = np.array(['hello', 'fb', 'testing'])
1469 assertRaises(self, lambda: b.CreateNumpyVector(x), TypeError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001470
James Kuszmaul8e62b022022-03-22 09:33:25 -07001471 except ImportError:
1472 b = flatbuffers.Builder(0)
1473 x = 0
1474 assertRaises(self, lambda: b.CreateNumpyVector(x),
1475 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001476
James Kuszmaul8e62b022022-03-22 09:33:25 -07001477 def test_create_numpy_vector_reject_object(self):
1478 try:
1479 imp.find_module('numpy')
1480 # if numpy exists, then we should be able to get the
1481 # vector as a numpy array
1482 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001483
James Kuszmaul8e62b022022-03-22 09:33:25 -07001484 # Create String array
1485 b = flatbuffers.Builder(0)
1486 x = np.array([{'m': 0}, {'as': -2.1, 'c': 'c'}])
1487 assertRaises(self, lambda: b.CreateNumpyVector(x), TypeError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001488
James Kuszmaul8e62b022022-03-22 09:33:25 -07001489 except ImportError:
1490 b = flatbuffers.Builder(0)
1491 x = 0
1492 assertRaises(self, lambda: b.CreateNumpyVector(x),
1493 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001494
James Kuszmaul8e62b022022-03-22 09:33:25 -07001495 def test_empty_vtable(self):
1496 b = flatbuffers.Builder(0)
1497 b.StartObject(0)
1498 self.assertBuilderEquals(b, [])
1499 b.EndObject()
1500 self.assertBuilderEquals(b, [4, 0, 4, 0, 4, 0, 0, 0])
1501
1502 def test_vtable_with_one_true_bool(self):
1503 b = flatbuffers.Builder(0)
1504 self.assertBuilderEquals(b, [])
1505 b.StartObject(1)
1506 self.assertBuilderEquals(b, [])
1507 b.PrependBoolSlot(0, True, False)
1508 b.EndObject()
1509 self.assertBuilderEquals(
1510 b,
1511 [
1512 6,
1513 0, # vtable bytes
1514 8,
1515 0, # length of object including vtable offset
1516 7,
1517 0, # start of bool value
1518 6,
1519 0,
1520 0,
1521 0, # offset for start of vtable (int32)
1522 0,
1523 0,
1524 0, # padded to 4 bytes
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001525 1, # bool value
1526 ])
1527
James Kuszmaul8e62b022022-03-22 09:33:25 -07001528 def test_vtable_with_one_default_bool(self):
1529 b = flatbuffers.Builder(0)
1530 self.assertBuilderEquals(b, [])
1531 b.StartObject(1)
1532 self.assertBuilderEquals(b, [])
1533 b.PrependBoolSlot(0, False, False)
1534 b.EndObject()
1535 self.assertBuilderEquals(
1536 b,
1537 [
1538 4,
1539 0, # vtable bytes
1540 4,
1541 0, # end of object from here
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001542 # entry 1 is zero and not stored
James Kuszmaul8e62b022022-03-22 09:33:25 -07001543 4,
1544 0,
1545 0,
1546 0, # offset for start of vtable (int32)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001547 ])
1548
James Kuszmaul8e62b022022-03-22 09:33:25 -07001549 def test_vtable_with_one_int16(self):
1550 b = flatbuffers.Builder(0)
1551 b.StartObject(1)
1552 b.PrependInt16Slot(0, 0x789A, 0)
1553 b.EndObject()
1554 self.assertBuilderEquals(
1555 b,
1556 [
1557 6,
1558 0, # vtable bytes
1559 8,
1560 0, # end of object from here
1561 6,
1562 0, # offset to value
1563 6,
1564 0,
1565 0,
1566 0, # offset for start of vtable (int32)
1567 0,
1568 0, # padding to 4 bytes
1569 0x9A,
1570 0x78,
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001571 ])
1572
James Kuszmaul8e62b022022-03-22 09:33:25 -07001573 def test_vtable_with_two_int16(self):
1574 b = flatbuffers.Builder(0)
1575 b.StartObject(2)
1576 b.PrependInt16Slot(0, 0x3456, 0)
1577 b.PrependInt16Slot(1, 0x789A, 0)
1578 b.EndObject()
1579 self.assertBuilderEquals(
1580 b,
1581 [
1582 8,
1583 0, # vtable bytes
1584 8,
1585 0, # end of object from here
1586 6,
1587 0, # offset to value 0
1588 4,
1589 0, # offset to value 1
1590 8,
1591 0,
1592 0,
1593 0, # offset for start of vtable (int32)
1594 0x9A,
1595 0x78, # value 1
1596 0x56,
1597 0x34, # value 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001598 ])
1599
James Kuszmaul8e62b022022-03-22 09:33:25 -07001600 def test_vtable_with_int16_and_bool(self):
1601 b = flatbuffers.Builder(0)
1602 b.StartObject(2)
1603 b.PrependInt16Slot(0, 0x3456, 0)
1604 b.PrependBoolSlot(1, True, False)
1605 b.EndObject()
1606 self.assertBuilderEquals(
1607 b,
1608 [
1609 8,
1610 0, # vtable bytes
1611 8,
1612 0, # end of object from here
1613 6,
1614 0, # offset to value 0
1615 5,
1616 0, # offset to value 1
1617 8,
1618 0,
1619 0,
1620 0, # offset for start of vtable (int32)
1621 0, # padding
1622 1, # value 1
1623 0x56,
1624 0x34, # value 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001625 ])
1626
James Kuszmaul8e62b022022-03-22 09:33:25 -07001627 def test_vtable_with_empty_vector(self):
1628 b = flatbuffers.Builder(0)
1629 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
1630 vecend = b.EndVector()
1631 b.StartObject(1)
1632 b.PrependUOffsetTRelativeSlot(0, vecend, 0)
1633 b.EndObject()
1634 self.assertBuilderEquals(
1635 b,
1636 [
1637 6,
1638 0, # vtable bytes
1639 8,
1640 0,
1641 4,
1642 0, # offset to vector offset
1643 6,
1644 0,
1645 0,
1646 0, # offset for start of vtable (int32)
1647 4,
1648 0,
1649 0,
1650 0,
1651 0,
1652 0,
1653 0,
1654 0, # length of vector (not in struct)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001655 ])
1656
James Kuszmaul8e62b022022-03-22 09:33:25 -07001657 def test_vtable_with_empty_vector_of_byte_and_some_scalars(self):
1658 b = flatbuffers.Builder(0)
1659 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
1660 vecend = b.EndVector()
1661 b.StartObject(2)
1662 b.PrependInt16Slot(0, 55, 0)
1663 b.PrependUOffsetTRelativeSlot(1, vecend, 0)
1664 b.EndObject()
1665 self.assertBuilderEquals(
1666 b,
1667 [
1668 8,
1669 0, # vtable bytes
1670 12,
1671 0,
1672 10,
1673 0, # offset to value 0
1674 4,
1675 0, # offset to vector offset
1676 8,
1677 0,
1678 0,
1679 0, # vtable loc
1680 8,
1681 0,
1682 0,
1683 0, # value 1
1684 0,
1685 0,
1686 55,
1687 0, # value 0
1688 0,
1689 0,
1690 0,
1691 0, # length of vector (not in struct)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001692 ])
1693
James Kuszmaul8e62b022022-03-22 09:33:25 -07001694 def test_vtable_with_1_int16_and_2vector_of_int16(self):
1695 b = flatbuffers.Builder(0)
1696 b.StartVector(flatbuffers.number_types.Int16Flags.bytewidth, 2, 1)
1697 b.PrependInt16(0x1234)
1698 b.PrependInt16(0x5678)
1699 vecend = b.EndVector()
1700 b.StartObject(2)
1701 b.PrependUOffsetTRelativeSlot(1, vecend, 0)
1702 b.PrependInt16Slot(0, 55, 0)
1703 b.EndObject()
1704 self.assertBuilderEquals(
1705 b,
1706 [
1707 8,
1708 0, # vtable bytes
1709 12,
1710 0, # length of object
1711 6,
1712 0, # start of value 0 from end of vtable
1713 8,
1714 0, # start of value 1 from end of buffer
1715 8,
1716 0,
1717 0,
1718 0, # offset for start of vtable (int32)
1719 0,
1720 0, # padding
1721 55,
1722 0, # value 0
1723 4,
1724 0,
1725 0,
1726 0, # vector position from here
1727 2,
1728 0,
1729 0,
1730 0, # length of vector (uint32)
1731 0x78,
1732 0x56, # vector value 1
1733 0x34,
1734 0x12, # vector value 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001735 ])
1736
James Kuszmaul8e62b022022-03-22 09:33:25 -07001737 def test_vtable_with_1_struct_of_1_int8__1_int16__1_int32(self):
1738 b = flatbuffers.Builder(0)
1739 b.StartObject(1)
1740 b.Prep(4 + 4 + 4, 0)
1741 b.PrependInt8(55)
1742 b.Pad(3)
1743 b.PrependInt16(0x1234)
1744 b.Pad(2)
1745 b.PrependInt32(0x12345678)
1746 structStart = b.Offset()
1747 b.PrependStructSlot(0, structStart, 0)
1748 b.EndObject()
1749 self.assertBuilderEquals(
1750 b,
1751 [
1752 6,
1753 0, # vtable bytes
1754 16,
1755 0, # end of object from here
1756 4,
1757 0, # start of struct from here
1758 6,
1759 0,
1760 0,
1761 0, # offset for start of vtable (int32)
1762 0x78,
1763 0x56,
1764 0x34,
1765 0x12, # value 2
1766 0,
1767 0, # padding
1768 0x34,
1769 0x12, # value 1
1770 0,
1771 0,
1772 0, # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001773 55, # value 0
1774 ])
1775
James Kuszmaul8e62b022022-03-22 09:33:25 -07001776 def test_vtable_with_1_vector_of_2_struct_of_2_int8(self):
1777 b = flatbuffers.Builder(0)
1778 b.StartVector(flatbuffers.number_types.Int8Flags.bytewidth * 2, 2, 1)
1779 b.PrependInt8(33)
1780 b.PrependInt8(44)
1781 b.PrependInt8(55)
1782 b.PrependInt8(66)
1783 vecend = b.EndVector()
1784 b.StartObject(1)
1785 b.PrependUOffsetTRelativeSlot(0, vecend, 0)
1786 b.EndObject()
1787 self.assertBuilderEquals(
1788 b,
1789 [
1790 6,
1791 0, # vtable bytes
1792 8,
1793 0,
1794 4,
1795 0, # offset of vector offset
1796 6,
1797 0,
1798 0,
1799 0, # offset for start of vtable (int32)
1800 4,
1801 0,
1802 0,
1803 0, # vector start offset
1804 2,
1805 0,
1806 0,
1807 0, # vector length
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001808 66, # vector value 1,1
1809 55, # vector value 1,0
1810 44, # vector value 0,1
1811 33, # vector value 0,0
1812 ])
1813
James Kuszmaul8e62b022022-03-22 09:33:25 -07001814 def test_table_with_some_elements(self):
1815 b = flatbuffers.Builder(0)
1816 b.StartObject(2)
1817 b.PrependInt8Slot(0, 33, 0)
1818 b.PrependInt16Slot(1, 66, 0)
1819 off = b.EndObject()
1820 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001821
James Kuszmaul8e62b022022-03-22 09:33:25 -07001822 self.assertBuilderEquals(
1823 b,
1824 [
1825 12,
1826 0,
1827 0,
1828 0, # root of table: points to vtable offset
1829 8,
1830 0, # vtable bytes
1831 8,
1832 0, # end of object from here
1833 7,
1834 0, # start of value 0
1835 4,
1836 0, # start of value 1
1837 8,
1838 0,
1839 0,
1840 0, # offset for start of vtable (int32)
1841 66,
1842 0, # value 1
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001843 0, # padding
1844 33, # value 0
1845 ])
1846
James Kuszmaul8e62b022022-03-22 09:33:25 -07001847 def test__one_unfinished_table_and_one_finished_table(self):
1848 b = flatbuffers.Builder(0)
1849 b.StartObject(2)
1850 b.PrependInt8Slot(0, 33, 0)
1851 b.PrependInt8Slot(1, 44, 0)
1852 off = b.EndObject()
1853 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001854
James Kuszmaul8e62b022022-03-22 09:33:25 -07001855 b.StartObject(3)
1856 b.PrependInt8Slot(0, 55, 0)
1857 b.PrependInt8Slot(1, 66, 0)
1858 b.PrependInt8Slot(2, 77, 0)
1859 off = b.EndObject()
1860 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001861
James Kuszmaul8e62b022022-03-22 09:33:25 -07001862 self.assertBuilderEquals(
1863 b,
1864 [
1865 16,
1866 0,
1867 0,
1868 0, # root of table: points to object
1869 0,
1870 0, # padding
1871 10,
1872 0, # vtable bytes
1873 8,
1874 0, # size of object
1875 7,
1876 0, # start of value 0
1877 6,
1878 0, # start of value 1
1879 5,
1880 0, # start of value 2
1881 10,
1882 0,
1883 0,
1884 0, # offset for start of vtable (int32)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001885 0, # padding
1886 77, # value 2
1887 66, # value 1
1888 55, # value 0
James Kuszmaul8e62b022022-03-22 09:33:25 -07001889 12,
1890 0,
1891 0,
1892 0, # root of table: points to object
1893 8,
1894 0, # vtable bytes
1895 8,
1896 0, # size of object
1897 7,
1898 0, # start of value 0
1899 6,
1900 0, # start of value 1
1901 8,
1902 0,
1903 0,
1904 0, # offset for start of vtable (int32)
1905 0,
1906 0, # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001907 44, # value 1
1908 33, # value 0
1909 ])
1910
James Kuszmaul8e62b022022-03-22 09:33:25 -07001911 def test_a_bunch_of_bools(self):
1912 b = flatbuffers.Builder(0)
1913 b.StartObject(8)
1914 b.PrependBoolSlot(0, True, False)
1915 b.PrependBoolSlot(1, True, False)
1916 b.PrependBoolSlot(2, True, False)
1917 b.PrependBoolSlot(3, True, False)
1918 b.PrependBoolSlot(4, True, False)
1919 b.PrependBoolSlot(5, True, False)
1920 b.PrependBoolSlot(6, True, False)
1921 b.PrependBoolSlot(7, True, False)
1922 off = b.EndObject()
1923 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001924
James Kuszmaul8e62b022022-03-22 09:33:25 -07001925 self.assertBuilderEquals(
1926 b,
1927 [
1928 24,
1929 0,
1930 0,
1931 0, # root of table: points to vtable offset
1932 20,
1933 0, # vtable bytes
1934 12,
1935 0, # size of object
1936 11,
1937 0, # start of value 0
1938 10,
1939 0, # start of value 1
1940 9,
1941 0, # start of value 2
1942 8,
1943 0, # start of value 3
1944 7,
1945 0, # start of value 4
1946 6,
1947 0, # start of value 5
1948 5,
1949 0, # start of value 6
1950 4,
1951 0, # start of value 7
1952 20,
1953 0,
1954 0,
1955 0, # vtable offset
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001956 1, # value 7
1957 1, # value 6
1958 1, # value 5
1959 1, # value 4
1960 1, # value 3
1961 1, # value 2
1962 1, # value 1
1963 1, # value 0
1964 ])
1965
James Kuszmaul8e62b022022-03-22 09:33:25 -07001966 def test_three_bools(self):
1967 b = flatbuffers.Builder(0)
1968 b.StartObject(3)
1969 b.PrependBoolSlot(0, True, False)
1970 b.PrependBoolSlot(1, True, False)
1971 b.PrependBoolSlot(2, True, False)
1972 off = b.EndObject()
1973 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001974
James Kuszmaul8e62b022022-03-22 09:33:25 -07001975 self.assertBuilderEquals(
1976 b,
1977 [
1978 16,
1979 0,
1980 0,
1981 0, # root of table: points to vtable offset
1982 0,
1983 0, # padding
1984 10,
1985 0, # vtable bytes
1986 8,
1987 0, # size of object
1988 7,
1989 0, # start of value 0
1990 6,
1991 0, # start of value 1
1992 5,
1993 0, # start of value 2
1994 10,
1995 0,
1996 0,
1997 0, # vtable offset from here
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001998 0, # padding
1999 1, # value 2
2000 1, # value 1
2001 1, # value 0
2002 ])
2003
James Kuszmaul8e62b022022-03-22 09:33:25 -07002004 def test_some_floats(self):
2005 b = flatbuffers.Builder(0)
2006 b.StartObject(1)
2007 b.PrependFloat32Slot(0, 1.0, 0.0)
2008 off = b.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002009
James Kuszmaul8e62b022022-03-22 09:33:25 -07002010 self.assertBuilderEquals(
2011 b,
2012 [
2013 6,
2014 0, # vtable bytes
2015 8,
2016 0, # size of object
2017 4,
2018 0, # start of value 0
2019 6,
2020 0,
2021 0,
2022 0, # vtable offset
2023 0,
2024 0,
2025 128,
2026 63, # value 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002027 ])
2028
2029
James Kuszmaul8e62b022022-03-22 09:33:25 -07002030def make_monster_from_generated_code(sizePrefix=False, file_identifier=None):
2031 """ Use generated code to build the example Monster. """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002032
James Kuszmaul8e62b022022-03-22 09:33:25 -07002033 b = flatbuffers.Builder(0)
2034 string = b.CreateString('MyMonster')
2035 test1 = b.CreateString('test1')
2036 test2 = b.CreateString('test2')
2037 fred = b.CreateString('Fred')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002038
James Kuszmaul8e62b022022-03-22 09:33:25 -07002039 _MONSTER.MonsterStartInventoryVector(b, 5)
2040 b.PrependByte(4)
2041 b.PrependByte(3)
2042 b.PrependByte(2)
2043 b.PrependByte(1)
2044 b.PrependByte(0)
2045 inv = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002046
James Kuszmaul8e62b022022-03-22 09:33:25 -07002047 _MONSTER.MonsterStart(b)
2048 _MONSTER.MonsterAddName(b, fred)
2049 mon2 = _MONSTER.MonsterEnd(b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002050
James Kuszmaul8e62b022022-03-22 09:33:25 -07002051 _MONSTER.MonsterStartTest4Vector(b, 2)
2052 _TEST.CreateTest(b, 10, 20)
2053 _TEST.CreateTest(b, 30, 40)
2054 test4 = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002055
James Kuszmaul8e62b022022-03-22 09:33:25 -07002056 _MONSTER.MonsterStartTestarrayofstringVector(b, 2)
2057 b.PrependUOffsetTRelative(test2)
2058 b.PrependUOffsetTRelative(test1)
2059 testArrayOfString = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002060
James Kuszmaul8e62b022022-03-22 09:33:25 -07002061 _MONSTER.MonsterStartVectorOfLongsVector(b, 5)
2062 b.PrependInt64(100000000)
2063 b.PrependInt64(1000000)
2064 b.PrependInt64(10000)
2065 b.PrependInt64(100)
2066 b.PrependInt64(1)
2067 VectorOfLongs = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002068
James Kuszmaul8e62b022022-03-22 09:33:25 -07002069 _MONSTER.MonsterStartVectorOfDoublesVector(b, 3)
2070 b.PrependFloat64(1.7976931348623157e+308)
2071 b.PrependFloat64(0)
2072 b.PrependFloat64(-1.7976931348623157e+308)
2073 VectorOfDoubles = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002074
James Kuszmaul8e62b022022-03-22 09:33:25 -07002075 _MONSTER.MonsterStart(b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002076
James Kuszmaul8e62b022022-03-22 09:33:25 -07002077 pos = _VEC3.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 2, 5, 6)
2078 _MONSTER.MonsterAddPos(b, pos)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002079
James Kuszmaul8e62b022022-03-22 09:33:25 -07002080 _MONSTER.MonsterAddHp(b, 80)
2081 _MONSTER.MonsterAddName(b, string)
2082 _MONSTER.MonsterAddInventory(b, inv)
2083 _MONSTER.MonsterAddTestType(b, 1)
2084 _MONSTER.MonsterAddTest(b, mon2)
2085 _MONSTER.MonsterAddTest4(b, test4)
2086 _MONSTER.MonsterAddTestarrayofstring(b, testArrayOfString)
2087 _MONSTER.MonsterAddVectorOfLongs(b, VectorOfLongs)
2088 _MONSTER.MonsterAddVectorOfDoubles(b, VectorOfDoubles)
2089 mon = _MONSTER.MonsterEnd(b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002090
James Kuszmaul8e62b022022-03-22 09:33:25 -07002091 if sizePrefix:
2092 b.FinishSizePrefixed(mon, file_identifier)
2093 else:
2094 b.Finish(mon, file_identifier)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002095
James Kuszmaul8e62b022022-03-22 09:33:25 -07002096 return b.Bytes, b.Head()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002097
2098
Austin Schuh272c6132020-11-14 16:37:52 -08002099class TestBuilderForceDefaults(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002100 """Verify that the builder adds default values when forced."""
Austin Schuh272c6132020-11-14 16:37:52 -08002101
James Kuszmaul8e62b022022-03-22 09:33:25 -07002102 test_flags = [N.BoolFlags(), N.Uint8Flags(), N.Uint16Flags(), \
2103 N.Uint32Flags(), N.Uint64Flags(), N.Int8Flags(), \
2104 N.Int16Flags(), N.Int32Flags(), N.Int64Flags(), \
2105 N.Float32Flags(), N.Float64Flags(), N.UOffsetTFlags()]
Austin Schuh272c6132020-11-14 16:37:52 -08002106
James Kuszmaul8e62b022022-03-22 09:33:25 -07002107 def test_default_force_defaults(self):
2108 for flag in self.test_flags:
2109 b = flatbuffers.Builder(0)
2110 b.StartObject(1)
2111 stored_offset = b.Offset()
2112 if flag != N.UOffsetTFlags():
2113 b.PrependSlot(flag, 0, 0, 0)
2114 else:
2115 b.PrependUOffsetTRelativeSlot(0, 0, 0)
2116 end_offset = b.Offset()
2117 b.EndObject()
2118 self.assertEqual(0, end_offset - stored_offset)
2119
2120 def test_force_defaults_true(self):
2121 for flag in self.test_flags:
2122 b = flatbuffers.Builder(0)
2123 b.ForceDefaults(True)
2124 b.StartObject(1)
2125 stored_offset = b.Offset()
2126 if flag != N.UOffsetTFlags():
2127 b.PrependSlot(flag, 0, 0, 0)
2128 else:
2129 b.PrependUOffsetTRelativeSlot(0, 0, 0)
2130 end_offset = b.Offset()
2131 b.EndObject()
2132 self.assertEqual(flag.bytewidth, end_offset - stored_offset)
Austin Schuh272c6132020-11-14 16:37:52 -08002133
2134
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002135class TestAllCodePathsOfExampleSchema(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002136
James Kuszmaul8e62b022022-03-22 09:33:25 -07002137 def setUp(self, *args, **kwargs):
2138 super(TestAllCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002139
James Kuszmaul8e62b022022-03-22 09:33:25 -07002140 b = flatbuffers.Builder(0)
2141 _MONSTER.MonsterStart(b)
2142 gen_mon = _MONSTER.MonsterEnd(b)
2143 b.Finish(gen_mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002144
James Kuszmaul8e62b022022-03-22 09:33:25 -07002145 self.mon = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002146
James Kuszmaul8e62b022022-03-22 09:33:25 -07002147 def test_default_monster_pos(self):
2148 self.assertTrue(self.mon.Pos() is None)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002149
James Kuszmaul8e62b022022-03-22 09:33:25 -07002150 def test_nondefault_monster_mana(self):
2151 b = flatbuffers.Builder(0)
2152 _MONSTER.MonsterStart(b)
2153 _MONSTER.MonsterAddMana(b, 50)
2154 mon = _MONSTER.MonsterEnd(b)
2155 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002156
James Kuszmaul8e62b022022-03-22 09:33:25 -07002157 got_mon = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2158 self.assertEqual(50, got_mon.Mana())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002159
James Kuszmaul8e62b022022-03-22 09:33:25 -07002160 def test_default_monster_hp(self):
2161 self.assertEqual(100, self.mon.Hp())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002162
James Kuszmaul8e62b022022-03-22 09:33:25 -07002163 def test_default_monster_name(self):
2164 self.assertEqual(None, self.mon.Name())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002165
James Kuszmaul8e62b022022-03-22 09:33:25 -07002166 def test_default_monster_inventory_item(self):
2167 self.assertEqual(0, self.mon.Inventory(0))
Austin Schuh272c6132020-11-14 16:37:52 -08002168
James Kuszmaul8e62b022022-03-22 09:33:25 -07002169 def test_default_monster_inventory_length(self):
2170 self.assertEqual(0, self.mon.InventoryLength())
2171 self.assertTrue(self.mon.InventoryIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002172
James Kuszmaul8e62b022022-03-22 09:33:25 -07002173 def test_empty_monster_inventory_vector(self):
2174 b = flatbuffers.Builder(0)
2175 _MONSTER.MonsterStartInventoryVector(b, 0)
2176 inv = b.EndVector()
2177 _MONSTER.MonsterStart(b)
2178 _MONSTER.MonsterAddInventory(b, inv)
2179 mon = _MONSTER.MonsterEnd(b)
2180 b.Finish(mon)
2181 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2182 self.assertFalse(mon2.InventoryIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002183
James Kuszmaul8e62b022022-03-22 09:33:25 -07002184 def test_default_monster_color(self):
2185 self.assertEqual(_COLOR.Color.Blue, self.mon.Color())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002186
James Kuszmaul8e62b022022-03-22 09:33:25 -07002187 def test_nondefault_monster_color(self):
2188 b = flatbuffers.Builder(0)
2189 color = _COLOR.Color.Red
2190 _MONSTER.MonsterStart(b)
2191 _MONSTER.MonsterAddColor(b, color)
2192 mon = _MONSTER.MonsterEnd(b)
2193 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002194
James Kuszmaul8e62b022022-03-22 09:33:25 -07002195 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2196 self.assertEqual(_COLOR.Color.Red, mon2.Color())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002197
James Kuszmaul8e62b022022-03-22 09:33:25 -07002198 def test_default_monster_testtype(self):
2199 self.assertEqual(0, self.mon.TestType())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002200
James Kuszmaul8e62b022022-03-22 09:33:25 -07002201 def test_default_monster_test_field(self):
2202 self.assertEqual(None, self.mon.Test())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002203
James Kuszmaul8e62b022022-03-22 09:33:25 -07002204 def test_default_monster_test4_item(self):
2205 self.assertEqual(None, self.mon.Test4(0))
Austin Schuh272c6132020-11-14 16:37:52 -08002206
James Kuszmaul8e62b022022-03-22 09:33:25 -07002207 def test_default_monster_test4_length(self):
2208 self.assertEqual(0, self.mon.Test4Length())
2209 self.assertTrue(self.mon.Test4IsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002210
James Kuszmaul8e62b022022-03-22 09:33:25 -07002211 def test_empty_monster_test4_vector(self):
2212 b = flatbuffers.Builder(0)
2213 _MONSTER.MonsterStartTest4Vector(b, 0)
2214 test4 = b.EndVector()
2215 _MONSTER.MonsterStart(b)
2216 _MONSTER.MonsterAddTest4(b, test4)
2217 mon = _MONSTER.MonsterEnd(b)
2218 b.Finish(mon)
2219 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2220 self.assertFalse(mon2.Test4IsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002221
James Kuszmaul8e62b022022-03-22 09:33:25 -07002222 def test_default_monster_testarrayofstring(self):
2223 self.assertEqual('', self.mon.Testarrayofstring(0))
Austin Schuh272c6132020-11-14 16:37:52 -08002224
James Kuszmaul8e62b022022-03-22 09:33:25 -07002225 def test_default_monster_testarrayofstring_length(self):
2226 self.assertEqual(0, self.mon.TestarrayofstringLength())
2227 self.assertTrue(self.mon.TestarrayofstringIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002228
James Kuszmaul8e62b022022-03-22 09:33:25 -07002229 def test_empty_monster_testarrayofstring_vector(self):
2230 b = flatbuffers.Builder(0)
2231 _MONSTER.MonsterStartTestarrayofstringVector(b, 0)
2232 testarrayofstring = b.EndVector()
2233 _MONSTER.MonsterStart(b)
2234 _MONSTER.MonsterAddTestarrayofstring(b, testarrayofstring)
2235 mon = _MONSTER.MonsterEnd(b)
2236 b.Finish(mon)
2237 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2238 self.assertFalse(mon2.TestarrayofstringIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002239
James Kuszmaul8e62b022022-03-22 09:33:25 -07002240 def test_default_monster_testarrayoftables(self):
2241 self.assertEqual(None, self.mon.Testarrayoftables(0))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002242
James Kuszmaul8e62b022022-03-22 09:33:25 -07002243 def test_nondefault_monster_testarrayoftables(self):
2244 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002245
James Kuszmaul8e62b022022-03-22 09:33:25 -07002246 # make a child Monster within a vector of Monsters:
2247 _MONSTER.MonsterStart(b)
2248 _MONSTER.MonsterAddHp(b, 99)
2249 sub_monster = _MONSTER.MonsterEnd(b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002250
James Kuszmaul8e62b022022-03-22 09:33:25 -07002251 # build the vector:
2252 _MONSTER.MonsterStartTestarrayoftablesVector(b, 1)
2253 b.PrependUOffsetTRelative(sub_monster)
2254 vec = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002255
James Kuszmaul8e62b022022-03-22 09:33:25 -07002256 # make the parent monster and include the vector of Monster:
2257 _MONSTER.MonsterStart(b)
2258 _MONSTER.MonsterAddTestarrayoftables(b, vec)
2259 mon = _MONSTER.MonsterEnd(b)
2260 b.Finish(mon)
Austin Schuh272c6132020-11-14 16:37:52 -08002261
James Kuszmaul8e62b022022-03-22 09:33:25 -07002262 # inspect the resulting data:
2263 mon2 = _MONSTER.Monster.GetRootAs(b.Output(), 0)
2264 self.assertEqual(99, mon2.Testarrayoftables(0).Hp())
2265 self.assertEqual(1, mon2.TestarrayoftablesLength())
2266 self.assertFalse(mon2.TestarrayoftablesIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -08002267
James Kuszmaul8e62b022022-03-22 09:33:25 -07002268 def test_default_monster_testarrayoftables_length(self):
2269 self.assertEqual(0, self.mon.TestarrayoftablesLength())
2270 self.assertTrue(self.mon.TestarrayoftablesIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002271
James Kuszmaul8e62b022022-03-22 09:33:25 -07002272 def test_empty_monster_testarrayoftables_vector(self):
2273 b = flatbuffers.Builder(0)
2274 _MONSTER.MonsterStartTestarrayoftablesVector(b, 0)
2275 testarrayoftables = b.EndVector()
2276 _MONSTER.MonsterStart(b)
2277 _MONSTER.MonsterAddTestarrayoftables(b, testarrayoftables)
2278 mon = _MONSTER.MonsterEnd(b)
2279 b.Finish(mon)
2280 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2281 self.assertFalse(mon2.TestarrayoftablesIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002282
James Kuszmaul8e62b022022-03-22 09:33:25 -07002283 def test_default_monster_testarrayoftables_length(self):
2284 self.assertEqual(0, self.mon.TestarrayoftablesLength())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002285
James Kuszmaul8e62b022022-03-22 09:33:25 -07002286 def test_nondefault_monster_enemy(self):
2287 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002288
James Kuszmaul8e62b022022-03-22 09:33:25 -07002289 # make an Enemy object:
2290 _MONSTER.MonsterStart(b)
2291 _MONSTER.MonsterAddHp(b, 88)
2292 enemy = _MONSTER.MonsterEnd(b)
2293 b.Finish(enemy)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002294
James Kuszmaul8e62b022022-03-22 09:33:25 -07002295 # make the parent monster and include the vector of Monster:
2296 _MONSTER.MonsterStart(b)
2297 _MONSTER.MonsterAddEnemy(b, enemy)
2298 mon = _MONSTER.MonsterEnd(b)
2299 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002300
James Kuszmaul8e62b022022-03-22 09:33:25 -07002301 # inspect the resulting data:
2302 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2303 self.assertEqual(88, mon2.Enemy().Hp())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002304
James Kuszmaul8e62b022022-03-22 09:33:25 -07002305 def test_default_monster_testnestedflatbuffer(self):
2306 self.assertEqual(0, self.mon.Testnestedflatbuffer(0))
Austin Schuh272c6132020-11-14 16:37:52 -08002307
James Kuszmaul8e62b022022-03-22 09:33:25 -07002308 def test_default_monster_testnestedflatbuffer_length(self):
2309 self.assertEqual(0, self.mon.TestnestedflatbufferLength())
2310 self.assertTrue(self.mon.TestnestedflatbufferIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002311
James Kuszmaul8e62b022022-03-22 09:33:25 -07002312 def test_empty_monster_testnestedflatbuffer_vector(self):
2313 b = flatbuffers.Builder(0)
2314 _MONSTER.MonsterStartTestnestedflatbufferVector(b, 0)
2315 testnestedflatbuffer = b.EndVector()
2316 _MONSTER.MonsterStart(b)
2317 _MONSTER.MonsterAddTestnestedflatbuffer(b, testnestedflatbuffer)
2318 mon = _MONSTER.MonsterEnd(b)
2319 b.Finish(mon)
2320 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2321 self.assertFalse(mon2.TestnestedflatbufferIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002322
James Kuszmaul8e62b022022-03-22 09:33:25 -07002323 def test_nondefault_monster_testnestedflatbuffer(self):
2324 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002325
James Kuszmaul8e62b022022-03-22 09:33:25 -07002326 _MONSTER.MonsterStartTestnestedflatbufferVector(b, 3)
2327 b.PrependByte(4)
2328 b.PrependByte(2)
2329 b.PrependByte(0)
2330 sub_buf = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002331
James Kuszmaul8e62b022022-03-22 09:33:25 -07002332 # make the parent monster and include the vector of Monster:
2333 _MONSTER.MonsterStart(b)
2334 _MONSTER.MonsterAddTestnestedflatbuffer(b, sub_buf)
2335 mon = _MONSTER.MonsterEnd(b)
2336 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002337
James Kuszmaul8e62b022022-03-22 09:33:25 -07002338 # inspect the resulting data:
2339 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2340 self.assertEqual(3, mon2.TestnestedflatbufferLength())
2341 self.assertFalse(mon2.TestnestedflatbufferIsNone())
2342 self.assertEqual(0, mon2.Testnestedflatbuffer(0))
2343 self.assertEqual(2, mon2.Testnestedflatbuffer(1))
2344 self.assertEqual(4, mon2.Testnestedflatbuffer(2))
2345 try:
2346 imp.find_module('numpy')
2347 # if numpy exists, then we should be able to get the
2348 # vector as a numpy array
2349 self.assertEqual([0, 2, 4], mon2.TestnestedflatbufferAsNumpy().tolist())
2350 except ImportError:
2351 assertRaises(self, lambda: mon2.TestnestedflatbufferAsNumpy(),
2352 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002353
James Kuszmaul8e62b022022-03-22 09:33:25 -07002354 def test_nested_monster_testnestedflatbuffer(self):
2355 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002356
James Kuszmaul8e62b022022-03-22 09:33:25 -07002357 # build another monster to nest inside testnestedflatbuffer
2358 nestedB = flatbuffers.Builder(0)
2359 nameStr = nestedB.CreateString('Nested Monster')
2360 _MONSTER.MonsterStart(nestedB)
2361 _MONSTER.MonsterAddHp(nestedB, 30)
2362 _MONSTER.MonsterAddName(nestedB, nameStr)
2363 nestedMon = _MONSTER.MonsterEnd(nestedB)
2364 nestedB.Finish(nestedMon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002365
James Kuszmaul8e62b022022-03-22 09:33:25 -07002366 # write the nested FB bytes
2367 sub_buf = _MONSTER.MonsterMakeTestnestedflatbufferVectorFromBytes(
2368 b, nestedB.Output())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002369
James Kuszmaul8e62b022022-03-22 09:33:25 -07002370 # make the parent monster and include the bytes of the nested monster
2371 _MONSTER.MonsterStart(b)
2372 _MONSTER.MonsterAddTestnestedflatbuffer(b, sub_buf)
2373 mon = _MONSTER.MonsterEnd(b)
2374 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002375
James Kuszmaul8e62b022022-03-22 09:33:25 -07002376 # inspect the resulting data:
2377 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2378 nestedMon2 = mon2.TestnestedflatbufferNestedRoot()
2379 self.assertEqual(b'Nested Monster', nestedMon2.Name())
2380 self.assertEqual(30, nestedMon2.Hp())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002381
James Kuszmaul8e62b022022-03-22 09:33:25 -07002382 def test_nondefault_monster_testempty(self):
2383 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002384
James Kuszmaul8e62b022022-03-22 09:33:25 -07002385 # make a Stat object:
2386 _STAT.StatStart(b)
2387 _STAT.StatAddVal(b, 123)
2388 my_stat = _STAT.StatEnd(b)
2389 b.Finish(my_stat)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002390
James Kuszmaul8e62b022022-03-22 09:33:25 -07002391 # include the stat object in a monster:
2392 _MONSTER.MonsterStart(b)
2393 _MONSTER.MonsterAddTestempty(b, my_stat)
2394 mon = _MONSTER.MonsterEnd(b)
2395 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002396
James Kuszmaul8e62b022022-03-22 09:33:25 -07002397 # inspect the resulting data:
2398 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2399 self.assertEqual(123, mon2.Testempty().Val())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002400
James Kuszmaul8e62b022022-03-22 09:33:25 -07002401 def test_default_monster_testbool(self):
2402 self.assertFalse(self.mon.Testbool())
Austin Schuh272c6132020-11-14 16:37:52 -08002403
James Kuszmaul8e62b022022-03-22 09:33:25 -07002404 def test_nondefault_monster_testbool(self):
2405 b = flatbuffers.Builder(0)
2406 _MONSTER.MonsterStart(b)
2407 _MONSTER.MonsterAddTestbool(b, True)
2408 mon = _MONSTER.MonsterEnd(b)
2409 b.Finish(mon)
Austin Schuh272c6132020-11-14 16:37:52 -08002410
James Kuszmaul8e62b022022-03-22 09:33:25 -07002411 # inspect the resulting data:
2412 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2413 self.assertTrue(mon2.Testbool())
Austin Schuh272c6132020-11-14 16:37:52 -08002414
James Kuszmaul8e62b022022-03-22 09:33:25 -07002415 def test_default_monster_testhashes(self):
2416 self.assertEqual(0, self.mon.Testhashs32Fnv1())
2417 self.assertEqual(0, self.mon.Testhashu32Fnv1())
2418 self.assertEqual(0, self.mon.Testhashs64Fnv1())
2419 self.assertEqual(0, self.mon.Testhashu64Fnv1())
2420 self.assertEqual(0, self.mon.Testhashs32Fnv1a())
2421 self.assertEqual(0, self.mon.Testhashu32Fnv1a())
2422 self.assertEqual(0, self.mon.Testhashs64Fnv1a())
2423 self.assertEqual(0, self.mon.Testhashu64Fnv1a())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002424
James Kuszmaul8e62b022022-03-22 09:33:25 -07002425 def test_nondefault_monster_testhashes(self):
2426 b = flatbuffers.Builder(0)
2427 _MONSTER.MonsterStart(b)
2428 _MONSTER.MonsterAddTesthashs32Fnv1(b, 1)
2429 _MONSTER.MonsterAddTesthashu32Fnv1(b, 2)
2430 _MONSTER.MonsterAddTesthashs64Fnv1(b, 3)
2431 _MONSTER.MonsterAddTesthashu64Fnv1(b, 4)
2432 _MONSTER.MonsterAddTesthashs32Fnv1a(b, 5)
2433 _MONSTER.MonsterAddTesthashu32Fnv1a(b, 6)
2434 _MONSTER.MonsterAddTesthashs64Fnv1a(b, 7)
2435 _MONSTER.MonsterAddTesthashu64Fnv1a(b, 8)
2436 mon = _MONSTER.MonsterEnd(b)
2437 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002438
James Kuszmaul8e62b022022-03-22 09:33:25 -07002439 # inspect the resulting data:
2440 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2441 self.assertEqual(1, mon2.Testhashs32Fnv1())
2442 self.assertEqual(2, mon2.Testhashu32Fnv1())
2443 self.assertEqual(3, mon2.Testhashs64Fnv1())
2444 self.assertEqual(4, mon2.Testhashu64Fnv1())
2445 self.assertEqual(5, mon2.Testhashs32Fnv1a())
2446 self.assertEqual(6, mon2.Testhashu32Fnv1a())
2447 self.assertEqual(7, mon2.Testhashs64Fnv1a())
2448 self.assertEqual(8, mon2.Testhashu64Fnv1a())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002449
James Kuszmaul8e62b022022-03-22 09:33:25 -07002450 def test_default_monster_parent_namespace_test(self):
2451 self.assertEqual(None, self.mon.ParentNamespaceTest())
2452
2453 def test_nondefault_monster_parent_namespace_test(self):
2454 b = flatbuffers.Builder(0)
2455 _IN_PARENT_NAMESPACE.InParentNamespaceStart(b)
2456 parent = _IN_PARENT_NAMESPACE.InParentNamespaceEnd(b)
2457 _MONSTER.MonsterStart(b)
2458 _MONSTER.MonsterAddParentNamespaceTest(b, parent)
2459 mon = _MONSTER.MonsterEnd(b)
2460 b.Finish(mon)
2461
2462 # Inspect the resulting data.
2463 monster = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2464 self.assertTrue(
2465 isinstance(monster.ParentNamespaceTest(),
2466 _IN_PARENT_NAMESPACE.InParentNamespace))
2467
2468 def test_getrootas_for_nonroot_table(self):
2469 b = flatbuffers.Builder(0)
2470 string = b.CreateString('MyStat')
2471
2472 _STAT.StatStart(b)
2473 _STAT.StatAddId(b, string)
2474 _STAT.StatAddVal(b, 12345678)
2475 _STAT.StatAddCount(b, 12345)
2476 stat = _STAT.StatEnd(b)
2477 b.Finish(stat)
2478
2479 stat2 = _STAT.Stat.GetRootAs(b.Bytes, b.Head())
2480
2481 self.assertEqual(b'MyStat', stat2.Id())
2482 self.assertEqual(12345678, stat2.Val())
2483 self.assertEqual(12345, stat2.Count())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002484
2485
2486class TestAllCodePathsOfMonsterExtraSchema(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002487
James Kuszmaul8e62b022022-03-22 09:33:25 -07002488 def setUp(self, *args, **kwargs):
2489 super(TestAllCodePathsOfMonsterExtraSchema, self).setUp(*args, **kwargs)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002490
James Kuszmaul8e62b022022-03-22 09:33:25 -07002491 b = flatbuffers.Builder(0)
2492 MyGame.MonsterExtra.Start(b)
2493 gen_mon = MyGame.MonsterExtra.End(b)
2494 b.Finish(gen_mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002495
James Kuszmaul8e62b022022-03-22 09:33:25 -07002496 self.mon = MyGame.MonsterExtra.MonsterExtra.GetRootAs(b.Bytes, b.Head())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002497
James Kuszmaul8e62b022022-03-22 09:33:25 -07002498 def test_default_nan_inf(self):
2499 self.assertTrue(math.isnan(self.mon.F1()))
2500 self.assertEqual(self.mon.F2(), float('inf'))
2501 self.assertEqual(self.mon.F3(), float('-inf'))
2502
2503 self.assertTrue(math.isnan(self.mon.D1()))
2504 self.assertEqual(self.mon.D2(), float('inf'))
2505 self.assertEqual(self.mon.D3(), float('-inf'))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002506
2507
2508class TestVtableDeduplication(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002509 """ TestVtableDeduplication verifies that vtables are deduplicated. """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002510
James Kuszmaul8e62b022022-03-22 09:33:25 -07002511 def test_vtable_deduplication(self):
2512 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002513
James Kuszmaul8e62b022022-03-22 09:33:25 -07002514 b.StartObject(4)
2515 b.PrependByteSlot(0, 0, 0)
2516 b.PrependByteSlot(1, 11, 0)
2517 b.PrependByteSlot(2, 22, 0)
2518 b.PrependInt16Slot(3, 33, 0)
2519 obj0 = b.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002520
James Kuszmaul8e62b022022-03-22 09:33:25 -07002521 b.StartObject(4)
2522 b.PrependByteSlot(0, 0, 0)
2523 b.PrependByteSlot(1, 44, 0)
2524 b.PrependByteSlot(2, 55, 0)
2525 b.PrependInt16Slot(3, 66, 0)
2526 obj1 = b.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002527
James Kuszmaul8e62b022022-03-22 09:33:25 -07002528 b.StartObject(4)
2529 b.PrependByteSlot(0, 0, 0)
2530 b.PrependByteSlot(1, 77, 0)
2531 b.PrependByteSlot(2, 88, 0)
2532 b.PrependInt16Slot(3, 99, 0)
2533 obj2 = b.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002534
James Kuszmaul8e62b022022-03-22 09:33:25 -07002535 got = b.Bytes[b.Head():]
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002536
James Kuszmaul8e62b022022-03-22 09:33:25 -07002537 want = bytearray([
2538 240,
2539 255,
2540 255,
2541 255, # == -12. offset to dedupped vtable.
2542 99,
2543 0,
2544 88,
2545 77,
2546 248,
2547 255,
2548 255,
2549 255, # == -8. offset to dedupped vtable.
2550 66,
2551 0,
2552 55,
2553 44,
2554 12,
2555 0,
2556 8,
2557 0,
2558 0,
2559 0,
2560 7,
2561 0,
2562 6,
2563 0,
2564 4,
2565 0,
2566 12,
2567 0,
2568 0,
2569 0,
2570 33,
2571 0,
2572 22,
2573 11,
2574 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002575
James Kuszmaul8e62b022022-03-22 09:33:25 -07002576 self.assertEqual((len(want), want), (len(got), got))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002577
James Kuszmaul8e62b022022-03-22 09:33:25 -07002578 table0 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj0)
2579 table1 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj1)
2580 table2 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj2)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002581
James Kuszmaul8e62b022022-03-22 09:33:25 -07002582 def _checkTable(tab, voffsett_value, b, c, d):
2583 # vtable size
2584 got = tab.GetVOffsetTSlot(0, 0)
2585 self.assertEqual(12, got, 'case 0, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002586
James Kuszmaul8e62b022022-03-22 09:33:25 -07002587 # object size
2588 got = tab.GetVOffsetTSlot(2, 0)
2589 self.assertEqual(8, got, 'case 2, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002590
James Kuszmaul8e62b022022-03-22 09:33:25 -07002591 # default value
2592 got = tab.GetVOffsetTSlot(4, 0)
2593 self.assertEqual(voffsett_value, got, 'case 4, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002594
James Kuszmaul8e62b022022-03-22 09:33:25 -07002595 got = tab.GetSlot(6, 0, N.Uint8Flags)
2596 self.assertEqual(b, got, 'case 6, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002597
James Kuszmaul8e62b022022-03-22 09:33:25 -07002598 val = tab.GetSlot(8, 0, N.Uint8Flags)
2599 self.assertEqual(c, val, 'failed 8, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002600
James Kuszmaul8e62b022022-03-22 09:33:25 -07002601 got = tab.GetSlot(10, 0, N.Uint8Flags)
2602 self.assertEqual(d, got, 'failed 10, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002603
James Kuszmaul8e62b022022-03-22 09:33:25 -07002604 _checkTable(table0, 0, 11, 22, 33)
2605 _checkTable(table1, 0, 44, 55, 66)
2606 _checkTable(table2, 0, 77, 88, 99)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002607
2608
2609class TestExceptions(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002610
James Kuszmaul8e62b022022-03-22 09:33:25 -07002611 def test_object_is_nested_error(self):
2612 b = flatbuffers.Builder(0)
2613 b.StartObject(0)
2614 assertRaises(self, lambda: b.StartObject(0),
2615 flatbuffers.builder.IsNestedError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002616
James Kuszmaul8e62b022022-03-22 09:33:25 -07002617 def test_object_is_not_nested_error(self):
2618 b = flatbuffers.Builder(0)
2619 assertRaises(self, lambda: b.EndObject(),
2620 flatbuffers.builder.IsNotNestedError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002621
James Kuszmaul8e62b022022-03-22 09:33:25 -07002622 def test_struct_is_not_inline_error(self):
2623 b = flatbuffers.Builder(0)
2624 b.StartObject(0)
2625 assertRaises(self, lambda: b.PrependStructSlot(0, 1, 0),
2626 flatbuffers.builder.StructIsNotInlineError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002627
James Kuszmaul8e62b022022-03-22 09:33:25 -07002628 def test_unreachable_error(self):
2629 b = flatbuffers.Builder(0)
2630 assertRaises(self, lambda: b.PrependUOffsetTRelative(1),
2631 flatbuffers.builder.OffsetArithmeticError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002632
James Kuszmaul3b15b0c2022-11-08 14:03:16 -08002633 def test_create_shared_string_is_nested_error(self):
2634 b = flatbuffers.Builder(0)
2635 b.StartObject(0)
2636 s = 'test1'
2637 assertRaises(self, lambda: b.CreateSharedString(s),
2638 flatbuffers.builder.IsNestedError)
2639
James Kuszmaul8e62b022022-03-22 09:33:25 -07002640 def test_create_string_is_nested_error(self):
2641 b = flatbuffers.Builder(0)
2642 b.StartObject(0)
2643 s = 'test1'
2644 assertRaises(self, lambda: b.CreateString(s),
2645 flatbuffers.builder.IsNestedError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002646
James Kuszmaul8e62b022022-03-22 09:33:25 -07002647 def test_create_byte_vector_is_nested_error(self):
2648 b = flatbuffers.Builder(0)
2649 b.StartObject(0)
2650 s = b'test1'
2651 assertRaises(self, lambda: b.CreateByteVector(s),
2652 flatbuffers.builder.IsNestedError)
2653
2654 def test_finished_bytes_error(self):
2655 b = flatbuffers.Builder(0)
2656 assertRaises(self, lambda: b.Output(),
2657 flatbuffers.builder.BuilderNotFinishedError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002658
2659
2660class TestFixedLengthArrays(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002661
James Kuszmaul8e62b022022-03-22 09:33:25 -07002662 def test_fixed_length_array(self):
2663 builder = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002664
James Kuszmaul8e62b022022-03-22 09:33:25 -07002665 a = 0.5
2666 b = range(0, 15)
2667 c = 1
2668 d_a = [[1, 2], [3, 4]]
2669 d_b = [MyGame.Example.TestEnum.TestEnum.B, \
2670 MyGame.Example.TestEnum.TestEnum.C]
2671 d_c = [[MyGame.Example.TestEnum.TestEnum.A, \
2672 MyGame.Example.TestEnum.TestEnum.B], \
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002673 [MyGame.Example.TestEnum.TestEnum.C, \
James Kuszmaul8e62b022022-03-22 09:33:25 -07002674 MyGame.Example.TestEnum.TestEnum.B]]
2675 d_d = [[-1, 1], [-2, 2]]
2676 e = 2
2677 f = [-1, 1]
2678
2679 arrayOffset = MyGame.Example.ArrayStruct.CreateArrayStruct(builder, \
2680 a, b, c, d_a, d_b, d_c, d_d, e, f)
2681
2682 # Create a table with the ArrayStruct.
2683 MyGame.Example.ArrayTable.Start(builder)
2684 MyGame.Example.ArrayTable.AddA(builder, arrayOffset)
2685 tableOffset = MyGame.Example.ArrayTable.End(builder)
2686
2687 builder.Finish(tableOffset)
2688
2689 buf = builder.Output()
2690
2691 table = MyGame.Example.ArrayTable.ArrayTable.GetRootAs(buf)
2692
2693 # Verify structure.
2694 nested = MyGame.Example.NestedStruct.NestedStruct()
2695 self.assertEqual(table.A().A(), 0.5)
2696 self.assertEqual(table.A().B(), \
2697 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
2698 self.assertEqual(table.A().C(), 1)
James Kuszmaul3b15b0c2022-11-08 14:03:16 -08002699 self.assertEqual(table.A().D(0).A(), [1, 2])
2700 self.assertEqual(table.A().D(1).A(), [3, 4])
2701 self.assertEqual(table.A().D(0).B(), \
James Kuszmaul8e62b022022-03-22 09:33:25 -07002702 MyGame.Example.TestEnum.TestEnum.B)
James Kuszmaul3b15b0c2022-11-08 14:03:16 -08002703 self.assertEqual(table.A().D(1).B(), \
James Kuszmaul8e62b022022-03-22 09:33:25 -07002704 MyGame.Example.TestEnum.TestEnum.C)
James Kuszmaul3b15b0c2022-11-08 14:03:16 -08002705 self.assertEqual(table.A().D(0).C(), \
James Kuszmaul8e62b022022-03-22 09:33:25 -07002706 [MyGame.Example.TestEnum.TestEnum.A, \
2707 MyGame.Example.TestEnum.TestEnum.B])
James Kuszmaul3b15b0c2022-11-08 14:03:16 -08002708 self.assertEqual(table.A().D(1).C(), \
James Kuszmaul8e62b022022-03-22 09:33:25 -07002709 [MyGame.Example.TestEnum.TestEnum.C, \
2710 MyGame.Example.TestEnum.TestEnum.B])
James Kuszmaul3b15b0c2022-11-08 14:03:16 -08002711 self.assertEqual(table.A().D(0).D(), [-1, 1])
2712 self.assertEqual(table.A().D(1).D(), [-2, 2])
James Kuszmaul8e62b022022-03-22 09:33:25 -07002713 self.assertEqual(table.A().E(), 2)
2714 self.assertEqual(table.A().F(), [-1, 1])
James Kuszmaul3b15b0c2022-11-08 14:03:16 -08002715 self.assertEqual(table.A().D(0).D(0), -1)
2716 self.assertEqual(table.A().D(0).D(1), 1)
2717 self.assertEqual(table.A().D(1).D(0), -2)
2718 self.assertEqual(table.A().D(1).D(1), 2)
2719
2720class TestNestedUnionTables(unittest.TestCase):
2721
2722 def test_nested_union_tables(self):
2723 nestUnion = MyGame.Example.NestedUnion.NestedUnionTest.NestedUnionTestT()
2724 nestUnion.name = b"testUnion1"
2725 nestUnion.id = 1
2726 nestUnion.data = MyGame.Example.NestedUnion.Vec3.Vec3T()
2727 nestUnion.dataType = MyGame.Example.NestedUnion.Any.Any.Vec3
2728 nestUnion.data.x = 4.278975356
2729 nestUnion.data.y = 5.32
2730 nestUnion.data.z = -6.464
2731 nestUnion.data.test1 = 0.9
2732 nestUnion.data.test2 = MyGame.Example.NestedUnion.Color.Color.Red
2733 nestUnion.data.test3 = MyGame.Example.NestedUnion.Test.TestT()
2734 nestUnion.data.test3.a = 5
2735 nestUnion.data.test3.b = 2
2736
2737 b = flatbuffers.Builder(0)
2738 b.Finish(nestUnion.Pack(b))
2739
2740 nestUnionDecode = MyGame.Example.NestedUnion.NestedUnionTest.NestedUnionTest.GetRootAs(b.Bytes, b.Head())
2741 nestUnionDecodeT = MyGame.Example.NestedUnion.NestedUnionTest.NestedUnionTestT.InitFromObj(nestUnionDecode)
2742 self.assertEqual(nestUnionDecodeT.name, nestUnion.name)
2743 self.assertEqual(nestUnionDecodeT.id, nestUnion.id)
2744 self.assertEqual(nestUnionDecodeT.dataType, nestUnion.dataType)
2745 self.assertEqual(nestUnionDecodeT.data.x, nestUnion.data.x)
2746 self.assertEqual(nestUnionDecodeT.data.y, nestUnion.data.y)
2747 self.assertEqual(nestUnionDecodeT.data.z, nestUnion.data.z)
2748 self.assertEqual(nestUnionDecodeT.data.test1, nestUnion.data.test1)
2749 self.assertEqual(nestUnionDecodeT.data.test2, nestUnion.data.test2)
2750 self.assertEqual(nestUnionDecodeT.data.test3.a, nestUnion.data.test3.a)
2751 self.assertEqual(nestUnionDecodeT.data.test3.b, nestUnion.data.test3.b)
2752
2753 nestUnionDecodeTFromBuf = MyGame.Example.NestedUnion.NestedUnionTest.NestedUnionTestT.InitFromPackedBuf(b.Bytes, b.Head())
2754 self.assertEqual(nestUnionDecodeTFromBuf.name, nestUnion.name)
2755 self.assertEqual(nestUnionDecodeTFromBuf.id, nestUnion.id)
2756 self.assertEqual(nestUnionDecodeTFromBuf.dataType, nestUnion.dataType)
2757 self.assertEqual(nestUnionDecodeTFromBuf.data.x, nestUnion.data.x)
2758 self.assertEqual(nestUnionDecodeTFromBuf.data.y, nestUnion.data.y)
2759 self.assertEqual(nestUnionDecodeTFromBuf.data.z, nestUnion.data.z)
2760 self.assertEqual(nestUnionDecodeTFromBuf.data.test1, nestUnion.data.test1)
2761 self.assertEqual(nestUnionDecodeTFromBuf.data.test2, nestUnion.data.test2)
2762 self.assertEqual(nestUnionDecodeTFromBuf.data.test3.a, nestUnion.data.test3.a)
2763 self.assertEqual(nestUnionDecodeTFromBuf.data.test3.b, nestUnion.data.test3.b)
2764
2765
2766 nestUnionDecodeTFromBuf2 = MyGame.Example.NestedUnion.NestedUnionTest.NestedUnionTestT.InitFromPackedBuf(b.Output())
2767 self.assertEqual(nestUnionDecodeTFromBuf2.name, nestUnion.name)
2768 self.assertEqual(nestUnionDecodeTFromBuf2.id, nestUnion.id)
2769 self.assertEqual(nestUnionDecodeTFromBuf2.dataType, nestUnion.dataType)
2770 self.assertEqual(nestUnionDecodeTFromBuf2.data.x, nestUnion.data.x)
2771 self.assertEqual(nestUnionDecodeTFromBuf2.data.y, nestUnion.data.y)
2772 self.assertEqual(nestUnionDecodeTFromBuf2.data.z, nestUnion.data.z)
2773 self.assertEqual(nestUnionDecodeTFromBuf2.data.test1, nestUnion.data.test1)
2774 self.assertEqual(nestUnionDecodeTFromBuf2.data.test2, nestUnion.data.test2)
2775 self.assertEqual(nestUnionDecodeTFromBuf2.data.test3.a, nestUnion.data.test3.a)
2776 self.assertEqual(nestUnionDecodeTFromBuf2.data.test3.b, nestUnion.data.test3.b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002777
2778
2779def CheckAgainstGoldDataGo():
James Kuszmaul8e62b022022-03-22 09:33:25 -07002780 try:
2781 gen_buf, gen_off = make_monster_from_generated_code()
2782 fn = 'monsterdata_go_wire.mon'
2783 if not os.path.exists(fn):
2784 print('Go-generated data does not exist, failed.')
2785 return False
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002786
James Kuszmaul8e62b022022-03-22 09:33:25 -07002787 # would like to use a context manager here, but it's less
2788 # backwards-compatible:
2789 f = open(fn, 'rb')
2790 go_wire_data = f.read()
2791 f.close()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002792
James Kuszmaul8e62b022022-03-22 09:33:25 -07002793 CheckReadBuffer(bytearray(go_wire_data), 0)
2794 if not bytearray(gen_buf[gen_off:]) == bytearray(go_wire_data):
2795 raise AssertionError('CheckAgainstGoldDataGo failed')
2796 except:
2797 print('Failed to test against Go-generated test data.')
2798 return False
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002799
James Kuszmaul8e62b022022-03-22 09:33:25 -07002800 print(
2801 'Can read Go-generated test data, and Python generates bytewise identical data.'
2802 )
2803 return True
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002804
2805
2806def CheckAgainstGoldDataJava():
James Kuszmaul8e62b022022-03-22 09:33:25 -07002807 try:
2808 gen_buf, gen_off = make_monster_from_generated_code()
2809 fn = 'monsterdata_java_wire.mon'
2810 if not os.path.exists(fn):
2811 print('Java-generated data does not exist, failed.')
2812 return False
2813 f = open(fn, 'rb')
2814 java_wire_data = f.read()
2815 f.close()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002816
James Kuszmaul8e62b022022-03-22 09:33:25 -07002817 CheckReadBuffer(bytearray(java_wire_data), 0)
2818 except:
2819 print('Failed to read Java-generated test data.')
2820 return False
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002821
James Kuszmaul8e62b022022-03-22 09:33:25 -07002822 print('Can read Java-generated test data.')
2823 return True
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002824
2825
2826class LCG(object):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002827 """ Include simple random number generator to ensure results will be the
2828
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002829 same cross platform.
James Kuszmaul8e62b022022-03-22 09:33:25 -07002830 http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
2831 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002832
James Kuszmaul8e62b022022-03-22 09:33:25 -07002833 __slots__ = ['n']
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002834
James Kuszmaul8e62b022022-03-22 09:33:25 -07002835 InitialLCGSeed = 48271
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002836
James Kuszmaul8e62b022022-03-22 09:33:25 -07002837 def __init__(self):
2838 self.n = self.InitialLCGSeed
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002839
James Kuszmaul8e62b022022-03-22 09:33:25 -07002840 def Reset(self):
2841 self.n = self.InitialLCGSeed
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002842
James Kuszmaul8e62b022022-03-22 09:33:25 -07002843 def Next(self):
2844 self.n = ((self.n * 279470273) % 4294967291) & 0xFFFFFFFF
2845 return self.n
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002846
2847
2848def BenchmarkVtableDeduplication(count):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002849 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002850 BenchmarkVtableDeduplication measures the speed of vtable deduplication
2851 by creating `prePop` vtables, then populating `count` objects with a
2852 different single vtable.
2853
2854 When count is large (as in long benchmarks), memory usage may be high.
James Kuszmaul8e62b022022-03-22 09:33:25 -07002855 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002856
James Kuszmaul8e62b022022-03-22 09:33:25 -07002857 for prePop in (1, 10, 100, 1000):
2858 builder = flatbuffers.Builder(0)
2859 n = 1 + int(math.log(prePop, 1.5))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002860
James Kuszmaul8e62b022022-03-22 09:33:25 -07002861 # generate some layouts:
2862 layouts = set()
2863 r = list(compat_range(n))
2864 while len(layouts) < prePop:
2865 layouts.add(tuple(sorted(random.sample(r, int(max(1, n / 2))))))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002866
James Kuszmaul8e62b022022-03-22 09:33:25 -07002867 layouts = list(layouts)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002868
James Kuszmaul8e62b022022-03-22 09:33:25 -07002869 # pre-populate vtables:
2870 for layout in layouts:
2871 builder.StartObject(n)
2872 for j in layout:
2873 builder.PrependInt16Slot(j, j, 0)
2874 builder.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002875
James Kuszmaul8e62b022022-03-22 09:33:25 -07002876 # benchmark deduplication of a new vtable:
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002877 def f():
James Kuszmaul8e62b022022-03-22 09:33:25 -07002878 layout = random.choice(layouts)
2879 builder.StartObject(n)
2880 for j in layout:
2881 builder.PrependInt16Slot(j, j, 0)
2882 builder.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002883
2884 duration = timeit.timeit(stmt=f, number=count)
2885 rate = float(count) / duration
James Kuszmaul8e62b022022-03-22 09:33:25 -07002886 print(('vtable deduplication rate (n=%d, vtables=%d): %.2f sec' %
2887 (prePop, len(builder.vtables), rate)))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002888
James Kuszmaul8e62b022022-03-22 09:33:25 -07002889
2890def BenchmarkCheckReadBuffer(count, buf, off):
2891 """
2892 BenchmarkCheckReadBuffer measures the speed of flatbuffer reading
2893 by re-using the CheckReadBuffer function with the gold data.
2894 """
2895
2896 def f():
2897 CheckReadBuffer(buf, off)
2898
2899 duration = timeit.timeit(stmt=f, number=count)
2900 rate = float(count) / duration
2901 data = float(len(buf) * count) / float(1024 * 1024)
2902 data_rate = data / float(duration)
2903
2904 print(('traversed %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec') %
2905 (count, len(buf), duration, rate, data_rate))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002906
2907
2908def BenchmarkMakeMonsterFromGeneratedCode(count, length):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002909 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002910 BenchmarkMakeMonsterFromGeneratedCode measures the speed of flatbuffer
2911 creation by re-using the make_monster_from_generated_code function for
2912 generating gold data examples.
James Kuszmaul8e62b022022-03-22 09:33:25 -07002913 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002914
James Kuszmaul8e62b022022-03-22 09:33:25 -07002915 duration = timeit.timeit(stmt=make_monster_from_generated_code, number=count)
2916 rate = float(count) / duration
2917 data = float(length * count) / float(1024 * 1024)
2918 data_rate = data / float(duration)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002919
James Kuszmaul8e62b022022-03-22 09:33:25 -07002920 print(('built %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec' % \
2921 (count, length, duration, rate, data_rate)))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002922
2923
2924def backward_compatible_run_tests(**kwargs):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002925 if PY_VERSION < (2, 6):
2926 sys.stderr.write('Python version less than 2.6 are not supported')
2927 sys.stderr.flush()
2928 return False
2929
2930 # python2.6 has a reduced-functionality unittest.main function:
2931 if PY_VERSION == (2, 6):
2932 try:
2933 unittest.main(**kwargs)
2934 except SystemExit as e:
2935 if not e.code == 0:
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002936 return False
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002937 return True
2938
James Kuszmaul8e62b022022-03-22 09:33:25 -07002939 # python2.7 and above let us not exit once unittest.main is run:
2940 kwargs['exit'] = False
2941 kwargs['verbosity'] = 0
2942 ret = unittest.main(**kwargs)
2943 if ret.result.errors or ret.result.failures:
2944 return False
2945
2946 return True
2947
2948
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002949def main():
James Kuszmaul8e62b022022-03-22 09:33:25 -07002950 import os
2951 import sys
2952 if not len(sys.argv) == 5:
2953 sys.stderr.write('Usage: %s <benchmark vtable count> '
2954 '<benchmark read count> <benchmark build count> '
2955 '<is_onefile>\n' % sys.argv[0])
2956 sys.stderr.write(' Provide COMPARE_GENERATED_TO_GO=1 to check'
2957 'for bytewise comparison to Go data.\n')
2958 sys.stderr.write(' Provide COMPARE_GENERATED_TO_JAVA=1 to check'
2959 'for bytewise comparison to Java data.\n')
2960 sys.stderr.flush()
2961 sys.exit(1)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002962
James Kuszmaul8e62b022022-03-22 09:33:25 -07002963 kwargs = dict(argv=sys.argv[:-4])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002964
James Kuszmaul8e62b022022-03-22 09:33:25 -07002965 create_namespace_shortcut(sys.argv[4].lower() == 'true')
Austin Schuh272c6132020-11-14 16:37:52 -08002966
James Kuszmaul8e62b022022-03-22 09:33:25 -07002967 # show whether numpy is present, as it changes the test logic:
2968 try:
2969 import numpy
2970 print('numpy available')
2971 except ImportError:
2972 print('numpy not available')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002973
James Kuszmaul8e62b022022-03-22 09:33:25 -07002974 # run tests, and run some language comparison checks if needed:
2975 success = backward_compatible_run_tests(**kwargs)
2976 if success and os.environ.get('COMPARE_GENERATED_TO_GO', 0) == '1':
2977 success = success and CheckAgainstGoldDataGo()
2978 if success and os.environ.get('COMPARE_GENERATED_TO_JAVA', 0) == '1':
2979 success = success and CheckAgainstGoldDataJava()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002980
James Kuszmaul8e62b022022-03-22 09:33:25 -07002981 if not success:
2982 sys.stderr.write('Tests failed, skipping benchmarks.\n')
2983 sys.stderr.flush()
2984 sys.exit(1)
2985
2986 # run benchmarks (if 0, they will be a noop):
2987 bench_vtable = int(sys.argv[1])
2988 bench_traverse = int(sys.argv[2])
2989 bench_build = int(sys.argv[3])
2990 if bench_vtable:
2991 BenchmarkVtableDeduplication(bench_vtable)
2992 if bench_traverse:
2993 buf, off = make_monster_from_generated_code()
2994 BenchmarkCheckReadBuffer(bench_traverse, buf, off)
2995 if bench_build:
2996 buf, off = make_monster_from_generated_code()
2997 BenchmarkMakeMonsterFromGeneratedCode(bench_build, len(buf))
2998
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002999
3000if __name__ == '__main__':
James Kuszmaul8e62b022022-03-22 09:33:25 -07003001 main()