blob: 5e3c54735b79838b87bac61ae7b31a4d63e13174 [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 Kuszmaul8e62b022022-03-22 09:33:25 -070050import monster_test_generated # the one-file version
Austin Schuh2dd86a92022-09-14 21:19:23 -070051import optional_scalars
52import optional_scalars.ScalarStuff
James Kuszmaul8e62b022022-03-22 09:33:25 -070053
54
55def create_namespace_shortcut(is_onefile):
56 # Create shortcut from either the one-file format or the multi-file format
57 global _ANY
58 global _COLOR
59 global _MONSTER
60 global _TEST
61 global _STAT
62 global _VEC3
63 global _IN_PARENT_NAMESPACE
64 if is_onefile:
65 print('Testing with the one-file generated code')
66 _ANY = monster_test_generated
67 _COLOR = monster_test_generated
68 _MONSTER = monster_test_generated
69 _TEST = monster_test_generated
70 _STAT = monster_test_generated
71 _VEC3 = monster_test_generated
72 _IN_PARENT_NAMESPACE = monster_test_generated
73 else:
74 print('Testing with multi-file generated code')
75 _ANY = MyGame.Example.Any
76 _COLOR = MyGame.Example.Color
77 _MONSTER = MyGame.Example.Monster
78 _TEST = MyGame.Example.Test
79 _STAT = MyGame.Example.Stat
80 _VEC3 = MyGame.Example.Vec3
81 _IN_PARENT_NAMESPACE = MyGame.InParentNamespace
82
Austin Schuhe89fa2d2019-08-14 20:24:23 -070083
84def assertRaises(test_case, fn, exception_class):
James Kuszmaul8e62b022022-03-22 09:33:25 -070085 """ Backwards-compatible assertion for exceptions raised. """
Austin Schuhe89fa2d2019-08-14 20:24:23 -070086
James Kuszmaul8e62b022022-03-22 09:33:25 -070087 exc = None
88 try:
89 fn()
90 except Exception as e:
91 exc = e
92 test_case.assertTrue(exc is not None)
93 test_case.assertTrue(isinstance(exc, exception_class))
Austin Schuhe89fa2d2019-08-14 20:24:23 -070094
95
96class TestWireFormat(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -070097
James Kuszmaul8e62b022022-03-22 09:33:25 -070098 def test_wire_format(self):
99 # Verify that using the generated Python code builds a buffer without
100 # returning errors, and is interpreted correctly, for size prefixed
101 # representation and regular:
102 for sizePrefix in [True, False]:
103 for file_identifier in [None, b'MONS']:
104 gen_buf, gen_off = make_monster_from_generated_code(
105 sizePrefix=sizePrefix, file_identifier=file_identifier)
106 CheckReadBuffer(
107 gen_buf,
108 gen_off,
109 sizePrefix=sizePrefix,
110 file_identifier=file_identifier)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700111
James Kuszmaul8e62b022022-03-22 09:33:25 -0700112 # Verify that the canonical flatbuffer file is readable by the
113 # generated Python code. Note that context managers are not part of
114 # Python 2.5, so we use the simpler open/close methods here:
115 f = open('monsterdata_test.mon', 'rb')
116 canonicalWireData = f.read()
117 f.close()
118 CheckReadBuffer(bytearray(canonicalWireData), 0, file_identifier=b'MONS')
119
120 # Write the generated buffer out to a file:
121 f = open('monsterdata_python_wire.mon', 'wb')
122 f.write(gen_buf[gen_off:])
123 f.close()
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700124
125
Austin Schuh272c6132020-11-14 16:37:52 -0800126class TestObjectBasedAPI(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700127 """ Tests the generated object based API."""
Austin Schuh272c6132020-11-14 16:37:52 -0800128
James Kuszmaul8e62b022022-03-22 09:33:25 -0700129 def test_consistenty_with_repeated_pack_and_unpack(self):
130 """ Checks the serialization and deserialization between a buffer and
131
Austin Schuh272c6132020-11-14 16:37:52 -0800132 its python object. It tests in the same way as the C++ object API test,
James Kuszmaul8e62b022022-03-22 09:33:25 -0700133 ObjectFlatBuffersTest in test.cpp.
134 """
Austin Schuh272c6132020-11-14 16:37:52 -0800135
James Kuszmaul8e62b022022-03-22 09:33:25 -0700136 buf, off = make_monster_from_generated_code()
Austin Schuh272c6132020-11-14 16:37:52 -0800137
James Kuszmaul8e62b022022-03-22 09:33:25 -0700138 # Turns a buffer into Python object (T class).
139 monster1 = _MONSTER.Monster.GetRootAs(buf, off)
140 monsterT1 = _MONSTER.MonsterT.InitFromObj(monster1)
Austin Schuh272c6132020-11-14 16:37:52 -0800141
James Kuszmaul8e62b022022-03-22 09:33:25 -0700142 for sizePrefix in [True, False]:
143 # Re-serialize the data into a buffer.
144 b1 = flatbuffers.Builder(0)
145 if sizePrefix:
146 b1.FinishSizePrefixed(monsterT1.Pack(b1))
147 else:
148 b1.Finish(monsterT1.Pack(b1))
149 CheckReadBuffer(b1.Bytes, b1.Head(), sizePrefix)
Austin Schuh272c6132020-11-14 16:37:52 -0800150
James Kuszmaul8e62b022022-03-22 09:33:25 -0700151 # Deserializes the buffer into Python object again.
152 monster2 = _MONSTER.Monster.GetRootAs(b1.Bytes, b1.Head())
153 # Re-serializes the data into a buffer for one more time.
154 monsterT2 = _MONSTER.MonsterT.InitFromObj(monster2)
155 for sizePrefix in [True, False]:
156 # Re-serializes the data into a buffer
157 b2 = flatbuffers.Builder(0)
158 if sizePrefix:
159 b2.FinishSizePrefixed(monsterT2.Pack(b2))
160 else:
161 b2.Finish(monsterT2.Pack(b2))
162 CheckReadBuffer(b2.Bytes, b2.Head(), sizePrefix)
Austin Schuh272c6132020-11-14 16:37:52 -0800163
James Kuszmaul8e62b022022-03-22 09:33:25 -0700164 def test_default_values_with_pack_and_unpack(self):
165 """ Serializes and deserializes between a buffer with default values (no
166
Austin Schuh272c6132020-11-14 16:37:52 -0800167 specific values are filled when the buffer is created) and its python
James Kuszmaul8e62b022022-03-22 09:33:25 -0700168 object.
169 """
170 # Creates a flatbuffer with default values.
171 b1 = flatbuffers.Builder(0)
172 _MONSTER.MonsterStart(b1)
173 gen_mon = _MONSTER.MonsterEnd(b1)
174 b1.Finish(gen_mon)
Austin Schuh272c6132020-11-14 16:37:52 -0800175
James Kuszmaul8e62b022022-03-22 09:33:25 -0700176 # Converts the flatbuffer into the object class.
177 monster1 = _MONSTER.Monster.GetRootAs(b1.Bytes, b1.Head())
178 monsterT1 = _MONSTER.MonsterT.InitFromObj(monster1)
Austin Schuh272c6132020-11-14 16:37:52 -0800179
James Kuszmaul8e62b022022-03-22 09:33:25 -0700180 # Packs the object class into another flatbuffer.
181 b2 = flatbuffers.Builder(0)
182 b2.Finish(monsterT1.Pack(b2))
183 monster2 = _MONSTER.Monster.GetRootAs(b2.Bytes, b2.Head())
184 # Checks the default values.
185 self.assertTrue(monster2.Pos() is None)
186 self.assertEqual(monster2.Mana(), 150)
187 self.assertEqual(monster2.Hp(), 100)
188 self.assertTrue(monster2.Name() is None)
189 self.assertEqual(monster2.Inventory(0), 0)
190 self.assertEqual(monster2.InventoryAsNumpy(), 0)
191 self.assertEqual(monster2.InventoryLength(), 0)
192 self.assertTrue(monster2.InventoryIsNone())
193 self.assertTrue(monster2.Color() is 8)
194 self.assertEqual(monster2.TestType(), 0)
195 self.assertTrue(monster2.Test() is None)
196 self.assertTrue(monster2.Test4(0) is None)
197 self.assertEqual(monster2.Test4Length(), 0)
198 self.assertTrue(monster2.Test4IsNone())
199 self.assertTrue(monster2.Testarrayofstring(0) is '')
200 self.assertEqual(monster2.TestarrayofstringLength(), 0)
201 self.assertTrue(monster2.TestarrayofstringIsNone())
202 self.assertTrue(monster2.Testarrayoftables(0) is None)
203 self.assertEqual(monster2.TestarrayoftablesLength(), 0)
204 self.assertTrue(monster2.TestarrayoftablesIsNone())
205 self.assertTrue(monster2.Enemy() is None)
206 self.assertEqual(monster2.Testnestedflatbuffer(0), 0)
207 self.assertEqual(monster2.TestnestedflatbufferAsNumpy(), 0)
208 self.assertEqual(monster2.TestnestedflatbufferLength(), 0)
209 self.assertTrue(monster2.TestnestedflatbufferIsNone())
210 self.assertTrue(monster2.Testempty() is None)
211 self.assertTrue(monster2.Testbool() is False)
212 self.assertEqual(monster2.Testhashs32Fnv1(), 0)
213 self.assertEqual(monster2.Testhashu32Fnv1(), 0)
214 self.assertEqual(monster2.Testhashs64Fnv1(), 0)
215 self.assertEqual(monster2.Testhashu64Fnv1(), 0)
216 self.assertEqual(monster2.Testhashs32Fnv1a(), 0)
217 self.assertEqual(monster2.Testhashu32Fnv1a(), 0)
218 self.assertEqual(monster2.Testhashs64Fnv1a(), 0)
219 self.assertEqual(monster2.Testhashu64Fnv1a(), 0)
220 self.assertEqual(monster2.Testarrayofbools(0), 0)
221 self.assertEqual(monster2.TestarrayofboolsAsNumpy(), 0)
222 self.assertEqual(monster2.TestarrayofboolsLength(), 0)
223 self.assertTrue(monster2.TestarrayofboolsIsNone())
224 self.assertEqual(monster2.Testf(), 3.14159)
225 self.assertEqual(monster2.Testf2(), 3.0)
226 self.assertEqual(monster2.Testf3(), 0.0)
227 self.assertTrue(monster2.Testarrayofstring2(0) is '')
228 self.assertEqual(monster2.Testarrayofstring2Length(), 0)
229 self.assertTrue(monster2.Testarrayofstring2IsNone())
230 self.assertTrue(monster2.Testarrayofsortedstruct(0) is None)
231 self.assertEqual(monster2.TestarrayofsortedstructLength(), 0)
232 self.assertTrue(monster2.TestarrayofsortedstructIsNone())
233 self.assertEqual(monster2.Flex(0), 0)
234 self.assertEqual(monster2.FlexAsNumpy(), 0)
235 self.assertEqual(monster2.FlexLength(), 0)
236 self.assertTrue(monster2.FlexIsNone())
237 self.assertTrue(monster2.Test5(0) is None)
238 self.assertEqual(monster2.Test5Length(), 0)
239 self.assertTrue(monster2.Test5IsNone())
240 self.assertEqual(monster2.VectorOfLongs(0), 0)
241 self.assertEqual(monster2.VectorOfLongsAsNumpy(), 0)
242 self.assertEqual(monster2.VectorOfLongsLength(), 0)
243 self.assertTrue(monster2.VectorOfLongsIsNone())
244 self.assertEqual(monster2.VectorOfDoubles(0), 0)
245 self.assertEqual(monster2.VectorOfDoublesAsNumpy(), 0)
246 self.assertEqual(monster2.VectorOfDoublesLength(), 0)
247 self.assertTrue(monster2.VectorOfDoublesIsNone())
248 self.assertTrue(monster2.ParentNamespaceTest() is None)
249 self.assertTrue(monster2.VectorOfReferrables(0) is None)
250 self.assertEqual(monster2.VectorOfReferrablesLength(), 0)
251 self.assertTrue(monster2.VectorOfReferrablesIsNone())
252 self.assertEqual(monster2.SingleWeakReference(), 0)
253 self.assertEqual(monster2.VectorOfWeakReferences(0), 0)
254 self.assertEqual(monster2.VectorOfWeakReferencesAsNumpy(), 0)
255 self.assertEqual(monster2.VectorOfWeakReferencesLength(), 0)
256 self.assertTrue(monster2.VectorOfWeakReferencesIsNone())
257 self.assertTrue(monster2.VectorOfStrongReferrables(0) is None)
258 self.assertEqual(monster2.VectorOfStrongReferrablesLength(), 0)
259 self.assertTrue(monster2.VectorOfStrongReferrablesIsNone())
260 self.assertEqual(monster2.CoOwningReference(), 0)
261 self.assertEqual(monster2.VectorOfCoOwningReferences(0), 0)
262 self.assertEqual(monster2.VectorOfCoOwningReferencesAsNumpy(), 0)
263 self.assertEqual(monster2.VectorOfCoOwningReferencesLength(), 0)
264 self.assertTrue(monster2.VectorOfCoOwningReferencesIsNone())
265 self.assertEqual(monster2.NonOwningReference(), 0)
266 self.assertEqual(monster2.VectorOfNonOwningReferences(0), 0)
267 self.assertEqual(monster2.VectorOfNonOwningReferencesAsNumpy(), 0)
268 self.assertEqual(monster2.VectorOfNonOwningReferencesLength(), 0)
269 self.assertTrue(monster2.VectorOfNonOwningReferencesIsNone())
270 self.assertEqual(monster2.AnyUniqueType(), 0)
271 self.assertTrue(monster2.AnyUnique() is None)
272 self.assertEqual(monster2.AnyAmbiguousType(), 0)
273 self.assertTrue(monster2.AnyAmbiguous() is None)
274 self.assertEqual(monster2.VectorOfEnums(0), 0)
275 self.assertEqual(monster2.VectorOfEnumsAsNumpy(), 0)
276 self.assertEqual(monster2.VectorOfEnumsLength(), 0)
277 self.assertTrue(monster2.VectorOfEnumsIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800278
Austin Schuh2dd86a92022-09-14 21:19:23 -0700279 def test_optional_scalars_with_pack_and_unpack(self):
280 """ Serializes and deserializes between a buffer with optional values (no
281 specific values are filled when the buffer is created) and its python
282 object.
283 """
284 # Creates a flatbuffer with optional values.
285 b1 = flatbuffers.Builder(0)
286 optional_scalars.ScalarStuff.ScalarStuffStart(b1)
287 gen_opt = optional_scalars.ScalarStuff.ScalarStuffEnd(b1)
288 b1.Finish(gen_opt)
289
290 # Converts the flatbuffer into the object class.
291 opts1 = optional_scalars.ScalarStuff.ScalarStuff.GetRootAs(b1.Bytes, b1.Head())
292 optsT1 = optional_scalars.ScalarStuff.ScalarStuffT.InitFromObj(opts1)
293
294 # Packs the object class into another flatbuffer.
295 b2 = flatbuffers.Builder(0)
296 b2.Finish(optsT1.Pack(b2))
297 opts2 = optional_scalars.ScalarStuff.ScalarStuff.GetRootAs(b2.Bytes, b2.Head())
298 optsT2 = optional_scalars.ScalarStuff.ScalarStuffT.InitFromObj(opts2)
299 # Checks the default values.
300 self.assertTrue(opts2.JustI8() == 0)
301 self.assertTrue(opts2.MaybeF32() is None)
302 self.assertTrue(opts2.DefaultBool() is True)
303 self.assertTrue(optsT2.justU16 == 0)
304 self.assertTrue(optsT2.maybeEnum is None)
305 self.assertTrue(optsT2.defaultU64 == 42)
306
307
Austin Schuh272c6132020-11-14 16:37:52 -0800308
309class TestAllMutableCodePathsOfExampleSchema(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700310 """ Tests the object API generated for monster_test.fbs for mutation
311
Austin Schuh272c6132020-11-14 16:37:52 -0800312 purposes. In each test, the default values will be changed through the
313 object API. We'll then pack the object class into the buf class and read
314 the updated values out from it to validate if the values are mutated as
James Kuszmaul8e62b022022-03-22 09:33:25 -0700315 expected.
316 """
Austin Schuh272c6132020-11-14 16:37:52 -0800317
James Kuszmaul8e62b022022-03-22 09:33:25 -0700318 def setUp(self, *args, **kwargs):
319 super(TestAllMutableCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
320 # Creates an empty monster flatbuffer, and loads it into the object
321 # class for future tests.
322 b = flatbuffers.Builder(0)
323 _MONSTER.MonsterStart(b)
324 self.monsterT = self._create_and_load_object_class(b)
Austin Schuh272c6132020-11-14 16:37:52 -0800325
James Kuszmaul8e62b022022-03-22 09:33:25 -0700326 def _pack_and_load_buf_class(self, monsterT):
327 """ Packs the object class into a flatbuffer and loads it into a buf
Austin Schuh272c6132020-11-14 16:37:52 -0800328
James Kuszmaul8e62b022022-03-22 09:33:25 -0700329 class.
330 """
331 b = flatbuffers.Builder(0)
332 b.Finish(monsterT.Pack(b))
333 monster = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
334 return monster
Austin Schuh272c6132020-11-14 16:37:52 -0800335
James Kuszmaul8e62b022022-03-22 09:33:25 -0700336 def _create_and_load_object_class(self, b):
337 """ Finishs the creation of a monster flatbuffer and loads it into an
Austin Schuh272c6132020-11-14 16:37:52 -0800338
James Kuszmaul8e62b022022-03-22 09:33:25 -0700339 object class.
340 """
341 gen_mon = _MONSTER.MonsterEnd(b)
342 b.Finish(gen_mon)
343 monster = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
344 monsterT = _MONSTER.MonsterT()
345 monsterT.InitFromObj(monster)
346 return monsterT
Austin Schuh272c6132020-11-14 16:37:52 -0800347
James Kuszmaul8e62b022022-03-22 09:33:25 -0700348 def test_mutate_pos(self):
349 posT = _VEC3.Vec3T()
350 posT.x = 4.0
351 posT.y = 5.0
352 posT.z = 6.0
353 posT.test1 = 6.0
354 posT.test2 = 7
355 test3T = _TEST.TestT()
356 test3T.a = 8
357 test3T.b = 9
358 posT.test3 = test3T
359 self.monsterT.pos = posT
Austin Schuh272c6132020-11-14 16:37:52 -0800360
James Kuszmaul8e62b022022-03-22 09:33:25 -0700361 # Packs the updated values.
362 monster = self._pack_and_load_buf_class(self.monsterT)
Austin Schuh272c6132020-11-14 16:37:52 -0800363
James Kuszmaul8e62b022022-03-22 09:33:25 -0700364 # Checks if values are loaded correctly into the object class.
365 pos = monster.Pos()
Austin Schuh272c6132020-11-14 16:37:52 -0800366
James Kuszmaul8e62b022022-03-22 09:33:25 -0700367 # Verifies the properties of the Vec3.
368 self.assertEqual(pos.X(), 4.0)
369 self.assertEqual(pos.Y(), 5.0)
370 self.assertEqual(pos.Z(), 6.0)
371 self.assertEqual(pos.Test1(), 6.0)
372 self.assertEqual(pos.Test2(), 7)
373 t3 = _TEST.Test()
374 t3 = pos.Test3(t3)
375 self.assertEqual(t3.A(), 8)
376 self.assertEqual(t3.B(), 9)
Austin Schuh272c6132020-11-14 16:37:52 -0800377
James Kuszmaul8e62b022022-03-22 09:33:25 -0700378 def test_mutate_mana(self):
379 self.monsterT.mana = 200
380 monster = self._pack_and_load_buf_class(self.monsterT)
381 self.assertEqual(monster.Mana(), 200)
Austin Schuh272c6132020-11-14 16:37:52 -0800382
James Kuszmaul8e62b022022-03-22 09:33:25 -0700383 def test_mutate_hp(self):
384 self.monsterT.hp = 200
385 monster = self._pack_and_load_buf_class(self.monsterT)
386 self.assertEqual(monster.Hp(), 200)
Austin Schuh272c6132020-11-14 16:37:52 -0800387
James Kuszmaul8e62b022022-03-22 09:33:25 -0700388 def test_mutate_name(self):
389 self.monsterT.name = 'MyMonster'
390 monster = self._pack_and_load_buf_class(self.monsterT)
391 self.assertEqual(monster.Name(), b'MyMonster')
Austin Schuh272c6132020-11-14 16:37:52 -0800392
James Kuszmaul8e62b022022-03-22 09:33:25 -0700393 def test_mutate_inventory(self):
394 self.monsterT.inventory = [1, 7, 8]
395 monster = self._pack_and_load_buf_class(self.monsterT)
396 self.assertEqual(monster.Inventory(0), 1)
397 self.assertEqual(monster.Inventory(1), 7)
398 self.assertEqual(monster.Inventory(2), 8)
Austin Schuh272c6132020-11-14 16:37:52 -0800399
James Kuszmaul8e62b022022-03-22 09:33:25 -0700400 def test_empty_inventory(self):
401 self.monsterT.inventory = []
402 monster = self._pack_and_load_buf_class(self.monsterT)
403 self.assertFalse(monster.InventoryIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800404
James Kuszmaul8e62b022022-03-22 09:33:25 -0700405 def test_mutate_color(self):
406 self.monsterT.color = _COLOR.Color.Red
407 monster = self._pack_and_load_buf_class(self.monsterT)
408 self.assertEqual(monster.Color(), _COLOR.Color.Red)
Austin Schuh272c6132020-11-14 16:37:52 -0800409
James Kuszmaul8e62b022022-03-22 09:33:25 -0700410 def test_mutate_testtype(self):
411 self.monsterT.testType = _ANY.Any.Monster
412 monster = self._pack_and_load_buf_class(self.monsterT)
413 self.assertEqual(monster.TestType(), _ANY.Any.Monster)
Austin Schuh272c6132020-11-14 16:37:52 -0800414
James Kuszmaul8e62b022022-03-22 09:33:25 -0700415 def test_mutate_test(self):
416 testT = _MONSTER.MonsterT()
417 testT.hp = 200
418 self.monsterT.test = testT
419 monster = self._pack_and_load_buf_class(self.monsterT)
420 # Initializes a Table from a union field Test(...).
421 table = monster.Test()
Austin Schuh272c6132020-11-14 16:37:52 -0800422
James Kuszmaul8e62b022022-03-22 09:33:25 -0700423 # Initializes a Monster from the Table from the union.
424 test_monster = _MONSTER.Monster()
425 test_monster.Init(table.Bytes, table.Pos)
426 self.assertEqual(test_monster.Hp(), 200)
Austin Schuh272c6132020-11-14 16:37:52 -0800427
James Kuszmaul8e62b022022-03-22 09:33:25 -0700428 def test_mutate_test4(self):
429 test0T = _TEST.TestT()
430 test0T.a = 10
431 test0T.b = 20
432 test1T = _TEST.TestT()
433 test1T.a = 30
434 test1T.b = 40
435 self.monsterT.test4 = [test0T, test1T]
Austin Schuh272c6132020-11-14 16:37:52 -0800436
James Kuszmaul8e62b022022-03-22 09:33:25 -0700437 monster = self._pack_and_load_buf_class(self.monsterT)
438 test0 = monster.Test4(0)
439 self.assertEqual(test0.A(), 10)
440 self.assertEqual(test0.B(), 20)
441 test1 = monster.Test4(1)
442 self.assertEqual(test1.A(), 30)
443 self.assertEqual(test1.B(), 40)
Austin Schuh272c6132020-11-14 16:37:52 -0800444
James Kuszmaul8e62b022022-03-22 09:33:25 -0700445 def test_empty_test4(self):
446 self.monsterT.test4 = []
447 monster = self._pack_and_load_buf_class(self.monsterT)
448 self.assertFalse(monster.Test4IsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800449
James Kuszmaul8e62b022022-03-22 09:33:25 -0700450 def test_mutate_testarrayofstring(self):
451 self.monsterT.testarrayofstring = []
452 self.monsterT.testarrayofstring.append('test1')
453 self.monsterT.testarrayofstring.append('test2')
454 monster = self._pack_and_load_buf_class(self.monsterT)
455 self.assertEqual(monster.Testarrayofstring(0), b'test1')
456 self.assertEqual(monster.Testarrayofstring(1), b'test2')
Austin Schuh272c6132020-11-14 16:37:52 -0800457
James Kuszmaul8e62b022022-03-22 09:33:25 -0700458 def test_empty_testarrayofstring(self):
459 self.monsterT.testarrayofstring = []
460 monster = self._pack_and_load_buf_class(self.monsterT)
461 self.assertFalse(monster.TestarrayofstringIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800462
James Kuszmaul8e62b022022-03-22 09:33:25 -0700463 def test_mutate_testarrayoftables(self):
464 monsterT0 = _MONSTER.MonsterT()
465 monsterT0.hp = 200
466 monsterT1 = _MONSTER.MonsterT()
467 monsterT1.hp = 400
468 self.monsterT.testarrayoftables = []
469 self.monsterT.testarrayoftables.append(monsterT0)
470 self.monsterT.testarrayoftables.append(monsterT1)
471 monster = self._pack_and_load_buf_class(self.monsterT)
472 self.assertEqual(monster.Testarrayoftables(0).Hp(), 200)
473 self.assertEqual(monster.Testarrayoftables(1).Hp(), 400)
Austin Schuh272c6132020-11-14 16:37:52 -0800474
James Kuszmaul8e62b022022-03-22 09:33:25 -0700475 def test_empty_testarrayoftables(self):
476 self.monsterT.testarrayoftables = []
477 monster = self._pack_and_load_buf_class(self.monsterT)
478 self.assertFalse(monster.TestarrayoftablesIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800479
James Kuszmaul8e62b022022-03-22 09:33:25 -0700480 def test_mutate_enemy(self):
481 monsterT = _MONSTER.MonsterT()
482 monsterT.hp = 200
483 self.monsterT.enemy = monsterT
484 monster = self._pack_and_load_buf_class(self.monsterT)
485 self.assertEqual(monster.Enemy().Hp(), 200)
Austin Schuh272c6132020-11-14 16:37:52 -0800486
James Kuszmaul8e62b022022-03-22 09:33:25 -0700487 def test_mutate_testnestedflatbuffer(self):
488 self.monsterT.testnestedflatbuffer = [8, 2, 4]
489 monster = self._pack_and_load_buf_class(self.monsterT)
490 self.assertEqual(monster.Testnestedflatbuffer(0), 8)
491 self.assertEqual(monster.Testnestedflatbuffer(1), 2)
492 self.assertEqual(monster.Testnestedflatbuffer(2), 4)
Austin Schuh272c6132020-11-14 16:37:52 -0800493
James Kuszmaul8e62b022022-03-22 09:33:25 -0700494 def test_empty_testnestedflatbuffer(self):
495 self.monsterT.testnestedflatbuffer = []
496 monster = self._pack_and_load_buf_class(self.monsterT)
497 self.assertFalse(monster.TestnestedflatbufferIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800498
James Kuszmaul8e62b022022-03-22 09:33:25 -0700499 def test_mutate_testbool(self):
500 self.monsterT.testbool = True
501 monster = self._pack_and_load_buf_class(self.monsterT)
502 self.assertTrue(monster.Testbool())
Austin Schuh272c6132020-11-14 16:37:52 -0800503
James Kuszmaul8e62b022022-03-22 09:33:25 -0700504 def test_mutate_testhashes(self):
505 self.monsterT.testhashs32Fnv1 = 1
506 self.monsterT.testhashu32Fnv1 = 2
507 self.monsterT.testhashs64Fnv1 = 3
508 self.monsterT.testhashu64Fnv1 = 4
509 self.monsterT.testhashs32Fnv1a = 5
510 self.monsterT.testhashu32Fnv1a = 6
511 self.monsterT.testhashs64Fnv1a = 7
512 self.monsterT.testhashu64Fnv1a = 8
513 monster = self._pack_and_load_buf_class(self.monsterT)
514 self.assertEqual(monster.Testhashs32Fnv1(), 1)
515 self.assertEqual(monster.Testhashu32Fnv1(), 2)
516 self.assertEqual(monster.Testhashs64Fnv1(), 3)
517 self.assertEqual(monster.Testhashu64Fnv1(), 4)
518 self.assertEqual(monster.Testhashs32Fnv1a(), 5)
519 self.assertEqual(monster.Testhashu32Fnv1a(), 6)
520 self.assertEqual(monster.Testhashs64Fnv1a(), 7)
521 self.assertEqual(monster.Testhashu64Fnv1a(), 8)
Austin Schuh272c6132020-11-14 16:37:52 -0800522
James Kuszmaul8e62b022022-03-22 09:33:25 -0700523 def test_mutate_testarrayofbools(self):
524 self.monsterT.testarrayofbools = []
525 self.monsterT.testarrayofbools.append(True)
526 self.monsterT.testarrayofbools.append(True)
527 self.monsterT.testarrayofbools.append(False)
528 monster = self._pack_and_load_buf_class(self.monsterT)
529 self.assertEqual(monster.Testarrayofbools(0), True)
530 self.assertEqual(monster.Testarrayofbools(1), True)
531 self.assertEqual(monster.Testarrayofbools(2), False)
Austin Schuh272c6132020-11-14 16:37:52 -0800532
James Kuszmaul8e62b022022-03-22 09:33:25 -0700533 def test_empty_testarrayofbools(self):
534 self.monsterT.testarrayofbools = []
535 monster = self._pack_and_load_buf_class(self.monsterT)
536 self.assertFalse(monster.TestarrayofboolsIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800537
James Kuszmaul8e62b022022-03-22 09:33:25 -0700538 def test_mutate_testf(self):
539 self.monsterT.testf = 2.0
540 monster = self._pack_and_load_buf_class(self.monsterT)
541 self.assertEqual(monster.Testf(), 2.0)
Austin Schuh272c6132020-11-14 16:37:52 -0800542
James Kuszmaul8e62b022022-03-22 09:33:25 -0700543 def test_mutate_vectoroflongs(self):
544 self.monsterT.vectorOfLongs = []
545 self.monsterT.vectorOfLongs.append(1)
546 self.monsterT.vectorOfLongs.append(100)
547 self.monsterT.vectorOfLongs.append(10000)
548 self.monsterT.vectorOfLongs.append(1000000)
549 self.monsterT.vectorOfLongs.append(100000000)
550 monster = self._pack_and_load_buf_class(self.monsterT)
551 self.assertEqual(monster.VectorOfLongs(0), 1)
552 self.assertEqual(monster.VectorOfLongs(1), 100)
553 self.assertEqual(monster.VectorOfLongs(2), 10000)
554 self.assertEqual(monster.VectorOfLongs(3), 1000000)
555 self.assertEqual(monster.VectorOfLongs(4), 100000000)
Austin Schuh272c6132020-11-14 16:37:52 -0800556
James Kuszmaul8e62b022022-03-22 09:33:25 -0700557 def test_empty_vectoroflongs(self):
558 self.monsterT.vectorOfLongs = []
559 monster = self._pack_and_load_buf_class(self.monsterT)
560 self.assertFalse(monster.VectorOfLongsIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800561
James Kuszmaul8e62b022022-03-22 09:33:25 -0700562 def test_mutate_vectorofdoubles(self):
563 self.monsterT.vectorOfDoubles = []
564 self.monsterT.vectorOfDoubles.append(-1.7976931348623157e+308)
565 self.monsterT.vectorOfDoubles.append(0)
566 self.monsterT.vectorOfDoubles.append(1.7976931348623157e+308)
567 monster = self._pack_and_load_buf_class(self.monsterT)
568 self.assertEqual(monster.VectorOfDoubles(0), -1.7976931348623157e+308)
569 self.assertEqual(monster.VectorOfDoubles(1), 0)
570 self.assertEqual(monster.VectorOfDoubles(2), 1.7976931348623157e+308)
Austin Schuh272c6132020-11-14 16:37:52 -0800571
James Kuszmaul8e62b022022-03-22 09:33:25 -0700572 def test_empty_vectorofdoubles(self):
573 self.monsterT.vectorOfDoubles = []
574 monster = self._pack_and_load_buf_class(self.monsterT)
575 self.assertFalse(monster.VectorOfDoublesIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800576
James Kuszmaul8e62b022022-03-22 09:33:25 -0700577 def test_mutate_parentnamespacetest(self):
578 self.monsterT.parentNamespaceTest = _IN_PARENT_NAMESPACE.InParentNamespaceT(
579 )
580 monster = self._pack_and_load_buf_class(self.monsterT)
581 self.assertTrue(
582 isinstance(monster.ParentNamespaceTest(),
583 _IN_PARENT_NAMESPACE.InParentNamespace))
584
585 def test_mutate_vectorofEnums(self):
586 self.monsterT.vectorOfEnums = []
587 self.monsterT.vectorOfEnums.append(_COLOR.Color.Red)
588 self.monsterT.vectorOfEnums.append(_COLOR.Color.Blue)
589 self.monsterT.vectorOfEnums.append(_COLOR.Color.Red)
590 monster = self._pack_and_load_buf_class(self.monsterT)
591 self.assertEqual(monster.VectorOfEnums(0), _COLOR.Color.Red)
592 self.assertEqual(monster.VectorOfEnums(1), _COLOR.Color.Blue)
593 self.assertEqual(monster.VectorOfEnums(2), _COLOR.Color.Red)
594
595 def test_empty_vectorofEnums(self):
596 self.monsterT.vectorOfEnums = []
597 monster = self._pack_and_load_buf_class(self.monsterT)
598 self.assertFalse(monster.VectorOfEnumsIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800599
600
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700601def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700602 """ CheckReadBuffer checks that the given buffer is evaluated correctly
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700603
James Kuszmaul8e62b022022-03-22 09:33:25 -0700604 as the example Monster.
605 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700606
James Kuszmaul8e62b022022-03-22 09:33:25 -0700607 def asserter(stmt):
608 """ An assertion helper that is separated from TestCase classes. """
609 if not stmt:
610 raise AssertionError('CheckReadBuffer case failed')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700611
James Kuszmaul8e62b022022-03-22 09:33:25 -0700612 if file_identifier:
613 # test prior to removal of size_prefix
614 asserter(
615 util.GetBufferIdentifier(buf, offset, size_prefixed=sizePrefix) ==
616 file_identifier)
617 asserter(
618 util.BufferHasIdentifier(
619 buf,
620 offset,
621 file_identifier=file_identifier,
622 size_prefixed=sizePrefix))
623 asserter(
624 _MONSTER.Monster.MonsterBufferHasIdentifier(
625 buf, offset, size_prefixed=sizePrefix))
626 if sizePrefix:
627 size = util.GetSizePrefix(buf, offset)
628 asserter(size == len(buf[offset:]) - 4)
629 buf, offset = util.RemoveSizePrefix(buf, offset)
630 if file_identifier:
631 asserter(_MONSTER.Monster.MonsterBufferHasIdentifier(buf, offset))
632 else:
633 asserter(not _MONSTER.Monster.MonsterBufferHasIdentifier(buf, offset))
634 monster = _MONSTER.Monster.GetRootAs(buf, offset)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700635
James Kuszmaul8e62b022022-03-22 09:33:25 -0700636 asserter(monster.Hp() == 80)
637 asserter(monster.Mana() == 150)
638 asserter(monster.Name() == b'MyMonster')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700639
James Kuszmaul8e62b022022-03-22 09:33:25 -0700640 # initialize a Vec3 from Pos()
641 vec = monster.Pos()
642 asserter(vec is not None)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700643
James Kuszmaul8e62b022022-03-22 09:33:25 -0700644 # verify the properties of the Vec3
645 asserter(vec.X() == 1.0)
646 asserter(vec.Y() == 2.0)
647 asserter(vec.Z() == 3.0)
648 asserter(vec.Test1() == 3.0)
649 asserter(vec.Test2() == 2)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700650
James Kuszmaul8e62b022022-03-22 09:33:25 -0700651 # initialize a Test from Test3(...)
652 t = _TEST.Test()
653 t = vec.Test3(t)
654 asserter(t is not None)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700655
James Kuszmaul8e62b022022-03-22 09:33:25 -0700656 # verify the properties of the Test
657 asserter(t.A() == 5)
658 asserter(t.B() == 6)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700659
James Kuszmaul8e62b022022-03-22 09:33:25 -0700660 # verify that the enum code matches the enum declaration:
661 union_type = _ANY.Any
662 asserter(monster.TestType() == union_type.Monster)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700663
James Kuszmaul8e62b022022-03-22 09:33:25 -0700664 # initialize a Table from a union field Test(...)
665 table2 = monster.Test()
666 asserter(type(table2) is flatbuffers.table.Table)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700667
James Kuszmaul8e62b022022-03-22 09:33:25 -0700668 # initialize a Monster from the Table from the union
669 monster2 = _MONSTER.Monster()
670 monster2.Init(table2.Bytes, table2.Pos)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700671
James Kuszmaul8e62b022022-03-22 09:33:25 -0700672 asserter(monster2.Name() == b'Fred')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700673
James Kuszmaul8e62b022022-03-22 09:33:25 -0700674 # iterate through the first monster's inventory:
675 asserter(monster.InventoryLength() == 5)
676 asserter(not monster.InventoryIsNone())
677
678 invsum = 0
679 for i in compat_range(monster.InventoryLength()):
680 v = monster.Inventory(i)
681 invsum += int(v)
682 asserter(invsum == 10)
683
684 for i in range(5):
685 asserter(monster.VectorOfLongs(i) == 10**(i * 2))
686
687 asserter(not monster.VectorOfDoublesIsNone())
688 asserter(([-1.7976931348623157e+308, 0, 1.7976931348623157e+308] == [
689 monster.VectorOfDoubles(i) for i in range(monster.VectorOfDoublesLength())
690 ]))
691
692 try:
693 imp.find_module('numpy')
694 # if numpy exists, then we should be able to get the
695 # vector as a numpy array
696 import numpy as np
697
698 asserter(monster.InventoryAsNumpy().sum() == 10)
699 asserter(monster.InventoryAsNumpy().dtype == np.dtype('uint8'))
700
701 VectorOfLongs = monster.VectorOfLongsAsNumpy()
702 asserter(VectorOfLongs.dtype == np.dtype('int64'))
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700703 for i in range(5):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700704 asserter(VectorOfLongs[i] == 10**(i * 2))
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700705
James Kuszmaul8e62b022022-03-22 09:33:25 -0700706 VectorOfDoubles = monster.VectorOfDoublesAsNumpy()
707 asserter(VectorOfDoubles.dtype == np.dtype('float64'))
708 asserter(VectorOfDoubles[0] == np.finfo('float64').min)
709 asserter(VectorOfDoubles[1] == 0.0)
710 asserter(VectorOfDoubles[2] == np.finfo('float64').max)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700711
James Kuszmaul8e62b022022-03-22 09:33:25 -0700712 except ImportError:
713 # If numpy does not exist, trying to get vector as numpy
714 # array should raise NumpyRequiredForThisFeature. The way
715 # assertRaises has been implemented prevents us from
716 # asserting this error is raised outside of a test case.
717 pass
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700718
James Kuszmaul8e62b022022-03-22 09:33:25 -0700719 asserter(monster.Test4Length() == 2)
720 asserter(not monster.Test4IsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700721
James Kuszmaul8e62b022022-03-22 09:33:25 -0700722 # create a 'Test' object and populate it:
723 test0 = monster.Test4(0)
724 asserter(type(test0) is _TEST.Test)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700725
James Kuszmaul8e62b022022-03-22 09:33:25 -0700726 test1 = monster.Test4(1)
727 asserter(type(test1) is _TEST.Test)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700728
James Kuszmaul8e62b022022-03-22 09:33:25 -0700729 # the position of test0 and test1 are swapped in monsterdata_java_wire
730 # and monsterdata_test_wire, so ignore ordering
731 v0 = test0.A()
732 v1 = test0.B()
733 v2 = test1.A()
734 v3 = test1.B()
735 sumtest12 = int(v0) + int(v1) + int(v2) + int(v3)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700736
James Kuszmaul8e62b022022-03-22 09:33:25 -0700737 asserter(sumtest12 == 100)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700738
James Kuszmaul8e62b022022-03-22 09:33:25 -0700739 asserter(not monster.TestarrayofstringIsNone())
740 asserter(monster.TestarrayofstringLength() == 2)
741 asserter(monster.Testarrayofstring(0) == b'test1')
742 asserter(monster.Testarrayofstring(1) == b'test2')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700743
James Kuszmaul8e62b022022-03-22 09:33:25 -0700744 asserter(monster.TestarrayoftablesIsNone())
745 asserter(monster.TestarrayoftablesLength() == 0)
746 asserter(monster.TestnestedflatbufferIsNone())
747 asserter(monster.TestnestedflatbufferLength() == 0)
748 asserter(monster.Testempty() is None)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700749
750
751class TestFuzz(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700752 """ Low level stress/fuzz test: serialize/deserialize a variety of
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700753
James Kuszmaul8e62b022022-03-22 09:33:25 -0700754 different kinds of data in different combinations
755 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700756
James Kuszmaul8e62b022022-03-22 09:33:25 -0700757 binary_type = compat.binary_types[0] # this will always exist
758 ofInt32Bytes = binary_type([0x83, 0x33, 0x33, 0x33])
759 ofInt64Bytes = binary_type([0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44])
760 overflowingInt32Val = flatbuffers.encode.Get(flatbuffers.packer.int32,
761 ofInt32Bytes, 0)
762 overflowingInt64Val = flatbuffers.encode.Get(flatbuffers.packer.int64,
763 ofInt64Bytes, 0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700764
James Kuszmaul8e62b022022-03-22 09:33:25 -0700765 # Values we're testing against: chosen to ensure no bits get chopped
766 # off anywhere, and also be different from eachother.
767 boolVal = True
768 int8Val = N.Int8Flags.py_type(-127) # 0x81
769 uint8Val = N.Uint8Flags.py_type(0xFF)
770 int16Val = N.Int16Flags.py_type(-32222) # 0x8222
771 uint16Val = N.Uint16Flags.py_type(0xFEEE)
772 int32Val = N.Int32Flags.py_type(overflowingInt32Val)
773 uint32Val = N.Uint32Flags.py_type(0xFDDDDDDD)
774 int64Val = N.Int64Flags.py_type(overflowingInt64Val)
775 uint64Val = N.Uint64Flags.py_type(0xFCCCCCCCCCCCCCCC)
776 # Python uses doubles, so force it here
777 float32Val = N.Float32Flags.py_type(ctypes.c_float(3.14159).value)
778 float64Val = N.Float64Flags.py_type(3.14159265359)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700779
James Kuszmaul8e62b022022-03-22 09:33:25 -0700780 def test_fuzz(self):
781 return self.check_once(11, 100)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700782
James Kuszmaul8e62b022022-03-22 09:33:25 -0700783 def check_once(self, fuzzFields, fuzzObjects):
784 testValuesMax = 11 # hardcoded to the number of scalar types
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700785
James Kuszmaul8e62b022022-03-22 09:33:25 -0700786 builder = flatbuffers.Builder(0)
787 l = LCG()
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700788
James Kuszmaul8e62b022022-03-22 09:33:25 -0700789 objects = [0 for _ in compat_range(fuzzObjects)]
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700790
James Kuszmaul8e62b022022-03-22 09:33:25 -0700791 # Generate fuzzObjects random objects each consisting of
792 # fuzzFields fields, each of a random type.
793 for i in compat_range(fuzzObjects):
794 builder.StartObject(fuzzFields)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700795
James Kuszmaul8e62b022022-03-22 09:33:25 -0700796 for j in compat_range(fuzzFields):
797 choice = int(l.Next()) % testValuesMax
798 if choice == 0:
799 builder.PrependBoolSlot(int(j), self.boolVal, False)
800 elif choice == 1:
801 builder.PrependInt8Slot(int(j), self.int8Val, 0)
802 elif choice == 2:
803 builder.PrependUint8Slot(int(j), self.uint8Val, 0)
804 elif choice == 3:
805 builder.PrependInt16Slot(int(j), self.int16Val, 0)
806 elif choice == 4:
807 builder.PrependUint16Slot(int(j), self.uint16Val, 0)
808 elif choice == 5:
809 builder.PrependInt32Slot(int(j), self.int32Val, 0)
810 elif choice == 6:
811 builder.PrependUint32Slot(int(j), self.uint32Val, 0)
812 elif choice == 7:
813 builder.PrependInt64Slot(int(j), self.int64Val, 0)
814 elif choice == 8:
815 builder.PrependUint64Slot(int(j), self.uint64Val, 0)
816 elif choice == 9:
817 builder.PrependFloat32Slot(int(j), self.float32Val, 0)
818 elif choice == 10:
819 builder.PrependFloat64Slot(int(j), self.float64Val, 0)
820 else:
821 raise RuntimeError('unreachable')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700822
James Kuszmaul8e62b022022-03-22 09:33:25 -0700823 off = builder.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700824
James Kuszmaul8e62b022022-03-22 09:33:25 -0700825 # store the offset from the end of the builder buffer,
826 # since it will keep growing:
827 objects[i] = off
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700828
James Kuszmaul8e62b022022-03-22 09:33:25 -0700829 # Do some bookkeeping to generate stats on fuzzes:
830 stats = defaultdict(int)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700831
James Kuszmaul8e62b022022-03-22 09:33:25 -0700832 def check(table, desc, want, got):
833 stats[desc] += 1
834 self.assertEqual(want, got, '%s != %s, %s' % (want, got, desc))
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700835
James Kuszmaul8e62b022022-03-22 09:33:25 -0700836 l = LCG() # Reset.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700837
James Kuszmaul8e62b022022-03-22 09:33:25 -0700838 # Test that all objects we generated are readable and return the
839 # expected values. We generate random objects in the same order
840 # so this is deterministic.
841 for i in compat_range(fuzzObjects):
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700842
James Kuszmaul8e62b022022-03-22 09:33:25 -0700843 table = flatbuffers.table.Table(builder.Bytes,
844 len(builder.Bytes) - objects[i])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700845
James Kuszmaul8e62b022022-03-22 09:33:25 -0700846 for j in compat_range(fuzzFields):
847 field_count = flatbuffers.builder.VtableMetadataFields + j
848 f = N.VOffsetTFlags.py_type(field_count * N.VOffsetTFlags.bytewidth)
849 choice = int(l.Next()) % testValuesMax
850
851 if choice == 0:
852 check(table, 'bool', self.boolVal,
853 table.GetSlot(f, False, N.BoolFlags))
854 elif choice == 1:
855 check(table, 'int8', self.int8Val, table.GetSlot(f, 0, N.Int8Flags))
856 elif choice == 2:
857 check(table, 'uint8', self.uint8Val,
858 table.GetSlot(f, 0, N.Uint8Flags))
859 elif choice == 3:
860 check(table, 'int16', self.int16Val,
861 table.GetSlot(f, 0, N.Int16Flags))
862 elif choice == 4:
863 check(table, 'uint16', self.uint16Val,
864 table.GetSlot(f, 0, N.Uint16Flags))
865 elif choice == 5:
866 check(table, 'int32', self.int32Val,
867 table.GetSlot(f, 0, N.Int32Flags))
868 elif choice == 6:
869 check(table, 'uint32', self.uint32Val,
870 table.GetSlot(f, 0, N.Uint32Flags))
871 elif choice == 7:
872 check(table, 'int64', self.int64Val,
873 table.GetSlot(f, 0, N.Int64Flags))
874 elif choice == 8:
875 check(table, 'uint64', self.uint64Val,
876 table.GetSlot(f, 0, N.Uint64Flags))
877 elif choice == 9:
878 check(table, 'float32', self.float32Val,
879 table.GetSlot(f, 0, N.Float32Flags))
880 elif choice == 10:
881 check(table, 'float64', self.float64Val,
882 table.GetSlot(f, 0, N.Float64Flags))
883 else:
884 raise RuntimeError('unreachable')
885
886 # If enough checks were made, verify that all scalar types were used:
887 self.assertEqual(testValuesMax, len(stats),
888 'fuzzing failed to test all scalar types: %s' % stats)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700889
890
891class TestByteLayout(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700892 """ TestByteLayout checks the bytes of a Builder in various scenarios. """
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700893
James Kuszmaul8e62b022022-03-22 09:33:25 -0700894 def assertBuilderEquals(self, builder, want_chars_or_ints):
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700895
James Kuszmaul8e62b022022-03-22 09:33:25 -0700896 def integerize(x):
897 if isinstance(x, compat.string_types):
898 return ord(x)
899 return x
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700900
James Kuszmaul8e62b022022-03-22 09:33:25 -0700901 want_ints = list(map(integerize, want_chars_or_ints))
902 want = bytearray(want_ints)
903 got = builder.Bytes[builder.Head():] # use the buffer directly
904 self.assertEqual(want, got)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700905
James Kuszmaul8e62b022022-03-22 09:33:25 -0700906 def test_numbers(self):
907 b = flatbuffers.Builder(0)
908 self.assertBuilderEquals(b, [])
909 b.PrependBool(True)
910 self.assertBuilderEquals(b, [1])
911 b.PrependInt8(-127)
912 self.assertBuilderEquals(b, [129, 1])
913 b.PrependUint8(255)
914 self.assertBuilderEquals(b, [255, 129, 1])
915 b.PrependInt16(-32222)
916 self.assertBuilderEquals(b, [0x22, 0x82, 0, 255, 129, 1]) # first pad
917 b.PrependUint16(0xFEEE)
918 # no pad this time:
919 self.assertBuilderEquals(b, [0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1])
920 b.PrependInt32(-53687092)
921 self.assertBuilderEquals(
922 b, [204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1])
923 b.PrependUint32(0x98765432)
924 self.assertBuilderEquals(b, [
925 0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0,
926 255, 129, 1
927 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700928
James Kuszmaul8e62b022022-03-22 09:33:25 -0700929 def test_numbers64(self):
930 b = flatbuffers.Builder(0)
931 b.PrependUint64(0x1122334455667788)
932 self.assertBuilderEquals(b,
933 [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700934
James Kuszmaul8e62b022022-03-22 09:33:25 -0700935 b = flatbuffers.Builder(0)
936 b.PrependInt64(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 def test_1xbyte_vector(self):
941 b = flatbuffers.Builder(0)
942 self.assertBuilderEquals(b, [])
943 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 1, 1)
944 self.assertBuilderEquals(b, [0, 0, 0]) # align to 4bytes
945 b.PrependByte(1)
946 self.assertBuilderEquals(b, [1, 0, 0, 0])
947 b.EndVector()
948 self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700949
James Kuszmaul8e62b022022-03-22 09:33:25 -0700950 def test_2xbyte_vector(self):
951 b = flatbuffers.Builder(0)
952 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 2, 1)
953 self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
954 b.PrependByte(1)
955 self.assertBuilderEquals(b, [1, 0, 0])
956 b.PrependByte(2)
957 self.assertBuilderEquals(b, [2, 1, 0, 0])
958 b.EndVector()
959 self.assertBuilderEquals(b, [2, 0, 0, 0, 2, 1, 0, 0]) # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700960
James Kuszmaul8e62b022022-03-22 09:33:25 -0700961 def test_1xuint16_vector(self):
962 b = flatbuffers.Builder(0)
963 b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 1, 1)
964 self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
965 b.PrependUint16(1)
966 self.assertBuilderEquals(b, [1, 0, 0, 0])
967 b.EndVector()
968 self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700969
James Kuszmaul8e62b022022-03-22 09:33:25 -0700970 def test_2xuint16_vector(self):
971 b = flatbuffers.Builder(0)
972 b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 2, 1)
973 self.assertBuilderEquals(b, []) # align to 4bytes
974 b.PrependUint16(0xABCD)
975 self.assertBuilderEquals(b, [0xCD, 0xAB])
976 b.PrependUint16(0xDCBA)
977 self.assertBuilderEquals(b, [0xBA, 0xDC, 0xCD, 0xAB])
978 b.EndVector()
979 self.assertBuilderEquals(b, [2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700980
James Kuszmaul8e62b022022-03-22 09:33:25 -0700981 def test_create_ascii_string(self):
982 b = flatbuffers.Builder(0)
983 b.CreateString(u'foo', encoding='ascii')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700984
James Kuszmaul8e62b022022-03-22 09:33:25 -0700985 # 0-terminated, no pad:
986 self.assertBuilderEquals(b, [3, 0, 0, 0, 'f', 'o', 'o', 0])
987 b.CreateString(u'moop', encoding='ascii')
988 # 0-terminated, 3-byte pad:
989 self.assertBuilderEquals(b, [
990 4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, 3, 0, 0, 0, 'f', 'o', 'o', 0
991 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700992
James Kuszmaul8e62b022022-03-22 09:33:25 -0700993 def test_create_utf8_string(self):
994 b = flatbuffers.Builder(0)
995 b.CreateString(u'Цлїςσδε')
996 self.assertBuilderEquals(b, '\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97' \
997 '\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700998
James Kuszmaul8e62b022022-03-22 09:33:25 -0700999 b.CreateString(u'フムアムカモケモ')
1000 self.assertBuilderEquals(b, '\x18\x00\x00\x00\xef\xbe\x8c\xef\xbe\x91' \
1001 '\xef\xbd\xb1\xef\xbe\x91\xef\xbd\xb6\xef\xbe\x93\xef\xbd\xb9\xef' \
1002 '\xbe\x93\x00\x00\x00\x00\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97' \
1003 '\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001004
James Kuszmaul8e62b022022-03-22 09:33:25 -07001005 def test_create_arbitrary_string(self):
1006 b = flatbuffers.Builder(0)
1007 s = '\x01\x02\x03'
1008 b.CreateString(s) # Default encoding is utf-8.
1009 # 0-terminated, no pad:
1010 self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
1011 s2 = '\x04\x05\x06\x07'
1012 b.CreateString(s2) # Default encoding is utf-8.
1013 # 0-terminated, 3-byte pad:
1014 self.assertBuilderEquals(
1015 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 -07001016
James Kuszmaul8e62b022022-03-22 09:33:25 -07001017 def test_create_byte_vector(self):
1018 b = flatbuffers.Builder(0)
1019 b.CreateByteVector(b'')
1020 # 0-byte pad:
1021 self.assertBuilderEquals(b, [0, 0, 0, 0])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001022
James Kuszmaul8e62b022022-03-22 09:33:25 -07001023 b = flatbuffers.Builder(0)
1024 b.CreateByteVector(b'\x01\x02\x03')
1025 # 1-byte pad:
1026 self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001027
James Kuszmaul8e62b022022-03-22 09:33:25 -07001028 def test_create_numpy_vector_int8(self):
1029 try:
1030 imp.find_module('numpy')
1031 # if numpy exists, then we should be able to get the
1032 # vector as a numpy array
1033 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001034
James Kuszmaul8e62b022022-03-22 09:33:25 -07001035 # Systems endian:
1036 b = flatbuffers.Builder(0)
1037 x = np.array([1, 2, -3], dtype=np.int8)
1038 b.CreateNumpyVector(x)
1039 self.assertBuilderEquals(
1040 b,
1041 [
1042 3,
1043 0,
1044 0,
1045 0, # vector length
1046 1,
1047 2,
1048 256 - 3,
1049 0 # vector value + padding
1050 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001051
James Kuszmaul8e62b022022-03-22 09:33:25 -07001052 # Reverse endian:
1053 b = flatbuffers.Builder(0)
1054 x_other_endian = x.byteswap().newbyteorder()
1055 b.CreateNumpyVector(x_other_endian)
1056 self.assertBuilderEquals(
1057 b,
1058 [
1059 3,
1060 0,
1061 0,
1062 0, # vector length
1063 1,
1064 2,
1065 256 - 3,
1066 0 # vector value + padding
1067 ])
1068 except ImportError:
1069 b = flatbuffers.Builder(0)
1070 x = 0
1071 assertRaises(self, lambda: b.CreateNumpyVector(x),
1072 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001073
James Kuszmaul8e62b022022-03-22 09:33:25 -07001074 def test_create_numpy_vector_uint16(self):
1075 try:
1076 imp.find_module('numpy')
1077 # if numpy exists, then we should be able to get the
1078 # vector as a numpy array
1079 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001080
James Kuszmaul8e62b022022-03-22 09:33:25 -07001081 # Systems endian:
1082 b = flatbuffers.Builder(0)
1083 x = np.array([1, 2, 312], dtype=np.uint16)
1084 b.CreateNumpyVector(x)
1085 self.assertBuilderEquals(
1086 b,
1087 [
1088 3,
1089 0,
1090 0,
1091 0, # vector length
1092 1,
1093 0, # 1
1094 2,
1095 0, # 2
1096 312 - 256,
1097 1, # 312
1098 0,
1099 0 # padding
1100 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001101
James Kuszmaul8e62b022022-03-22 09:33:25 -07001102 # Reverse endian:
1103 b = flatbuffers.Builder(0)
1104 x_other_endian = x.byteswap().newbyteorder()
1105 b.CreateNumpyVector(x_other_endian)
1106 self.assertBuilderEquals(
1107 b,
1108 [
1109 3,
1110 0,
1111 0,
1112 0, # vector length
1113 1,
1114 0, # 1
1115 2,
1116 0, # 2
1117 312 - 256,
1118 1, # 312
1119 0,
1120 0 # padding
1121 ])
1122 except ImportError:
1123 b = flatbuffers.Builder(0)
1124 x = 0
1125 assertRaises(self, lambda: b.CreateNumpyVector(x),
1126 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001127
James Kuszmaul8e62b022022-03-22 09:33:25 -07001128 def test_create_numpy_vector_int64(self):
1129 try:
1130 imp.find_module('numpy')
1131 # if numpy exists, then we should be able to get the
1132 # vector as a numpy array
1133 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001134
James Kuszmaul8e62b022022-03-22 09:33:25 -07001135 # Systems endian:
1136 b = flatbuffers.Builder(0)
1137 x = np.array([1, 2, -12], dtype=np.int64)
1138 b.CreateNumpyVector(x)
1139 self.assertBuilderEquals(
1140 b,
1141 [
1142 3,
1143 0,
1144 0,
1145 0, # vector length
1146 1,
1147 0,
1148 0,
1149 0,
1150 0,
1151 0,
1152 0,
1153 0, # 1
1154 2,
1155 0,
1156 0,
1157 0,
1158 0,
1159 0,
1160 0,
1161 0, # 2
1162 256 - 12,
1163 255,
1164 255,
1165 255,
1166 255,
1167 255,
1168 255,
1169 255 # -12
1170 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001171
James Kuszmaul8e62b022022-03-22 09:33:25 -07001172 # Reverse endian:
1173 b = flatbuffers.Builder(0)
1174 x_other_endian = x.byteswap().newbyteorder()
1175 b.CreateNumpyVector(x_other_endian)
1176 self.assertBuilderEquals(
1177 b,
1178 [
1179 3,
1180 0,
1181 0,
1182 0, # vector length
1183 1,
1184 0,
1185 0,
1186 0,
1187 0,
1188 0,
1189 0,
1190 0, # 1
1191 2,
1192 0,
1193 0,
1194 0,
1195 0,
1196 0,
1197 0,
1198 0, # 2
1199 256 - 12,
1200 255,
1201 255,
1202 255,
1203 255,
1204 255,
1205 255,
1206 255 # -12
1207 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001208
James Kuszmaul8e62b022022-03-22 09:33:25 -07001209 except ImportError:
1210 b = flatbuffers.Builder(0)
1211 x = 0
1212 assertRaises(self, lambda: b.CreateNumpyVector(x),
1213 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001214
James Kuszmaul8e62b022022-03-22 09:33:25 -07001215 def test_create_numpy_vector_float32(self):
1216 try:
1217 imp.find_module('numpy')
1218 # if numpy exists, then we should be able to get the
1219 # vector as a numpy array
1220 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001221
James Kuszmaul8e62b022022-03-22 09:33:25 -07001222 # Systems endian:
1223 b = flatbuffers.Builder(0)
1224 x = np.array([1, 2, -12], dtype=np.float32)
1225 b.CreateNumpyVector(x)
1226 self.assertBuilderEquals(
1227 b,
1228 [
1229 3,
1230 0,
1231 0,
1232 0, # vector length
1233 0,
1234 0,
1235 128,
1236 63, # 1
1237 0,
1238 0,
1239 0,
1240 64, # 2
1241 0,
1242 0,
1243 64,
1244 193 # -12
1245 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001246
James Kuszmaul8e62b022022-03-22 09:33:25 -07001247 # Reverse endian:
1248 b = flatbuffers.Builder(0)
1249 x_other_endian = x.byteswap().newbyteorder()
1250 b.CreateNumpyVector(x_other_endian)
1251 self.assertBuilderEquals(
1252 b,
1253 [
1254 3,
1255 0,
1256 0,
1257 0, # vector length
1258 0,
1259 0,
1260 128,
1261 63, # 1
1262 0,
1263 0,
1264 0,
1265 64, # 2
1266 0,
1267 0,
1268 64,
1269 193 # -12
1270 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001271
James Kuszmaul8e62b022022-03-22 09:33:25 -07001272 except ImportError:
1273 b = flatbuffers.Builder(0)
1274 x = 0
1275 assertRaises(self, lambda: b.CreateNumpyVector(x),
1276 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001277
James Kuszmaul8e62b022022-03-22 09:33:25 -07001278 def test_create_numpy_vector_float64(self):
1279 try:
1280 imp.find_module('numpy')
1281 # if numpy exists, then we should be able to get the
1282 # vector as a numpy array
1283 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001284
James Kuszmaul8e62b022022-03-22 09:33:25 -07001285 # Systems endian:
1286 b = flatbuffers.Builder(0)
1287 x = np.array([1, 2, -12], dtype=np.float64)
1288 b.CreateNumpyVector(x)
1289 self.assertBuilderEquals(
1290 b,
1291 [
1292 3,
1293 0,
1294 0,
1295 0, # vector length
1296 0,
1297 0,
1298 0,
1299 0,
1300 0,
1301 0,
1302 240,
1303 63, # 1
1304 0,
1305 0,
1306 0,
1307 0,
1308 0,
1309 0,
1310 0,
1311 64, # 2
1312 0,
1313 0,
1314 0,
1315 0,
1316 0,
1317 0,
1318 40,
1319 192 # -12
1320 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001321
James Kuszmaul8e62b022022-03-22 09:33:25 -07001322 # Reverse endian:
1323 b = flatbuffers.Builder(0)
1324 x_other_endian = x.byteswap().newbyteorder()
1325 b.CreateNumpyVector(x_other_endian)
1326 self.assertBuilderEquals(
1327 b,
1328 [
1329 3,
1330 0,
1331 0,
1332 0, # vector length
1333 0,
1334 0,
1335 0,
1336 0,
1337 0,
1338 0,
1339 240,
1340 63, # 1
1341 0,
1342 0,
1343 0,
1344 0,
1345 0,
1346 0,
1347 0,
1348 64, # 2
1349 0,
1350 0,
1351 0,
1352 0,
1353 0,
1354 0,
1355 40,
1356 192 # -12
1357 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001358
James Kuszmaul8e62b022022-03-22 09:33:25 -07001359 except ImportError:
1360 b = flatbuffers.Builder(0)
1361 x = 0
1362 assertRaises(self, lambda: b.CreateNumpyVector(x),
1363 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001364
James Kuszmaul8e62b022022-03-22 09:33:25 -07001365 def test_create_numpy_vector_bool(self):
1366 try:
1367 imp.find_module('numpy')
1368 # if numpy exists, then we should be able to get the
1369 # vector as a numpy array
1370 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001371
James Kuszmaul8e62b022022-03-22 09:33:25 -07001372 # Systems endian:
1373 b = flatbuffers.Builder(0)
1374 x = np.array([True, False, True], dtype=np.bool)
1375 b.CreateNumpyVector(x)
1376 self.assertBuilderEquals(
1377 b,
1378 [
1379 3,
1380 0,
1381 0,
1382 0, # vector length
1383 1,
1384 0,
1385 1,
1386 0 # vector values + padding
1387 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001388
James Kuszmaul8e62b022022-03-22 09:33:25 -07001389 # Reverse endian:
1390 b = flatbuffers.Builder(0)
1391 x_other_endian = x.byteswap().newbyteorder()
1392 b.CreateNumpyVector(x_other_endian)
1393 self.assertBuilderEquals(
1394 b,
1395 [
1396 3,
1397 0,
1398 0,
1399 0, # vector length
1400 1,
1401 0,
1402 1,
1403 0 # vector values + padding
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_reject_strings(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 # Create String array
1420 b = flatbuffers.Builder(0)
1421 x = np.array(['hello', 'fb', 'testing'])
1422 assertRaises(self, lambda: b.CreateNumpyVector(x), TypeError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001423
James Kuszmaul8e62b022022-03-22 09:33:25 -07001424 except ImportError:
1425 b = flatbuffers.Builder(0)
1426 x = 0
1427 assertRaises(self, lambda: b.CreateNumpyVector(x),
1428 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001429
James Kuszmaul8e62b022022-03-22 09:33:25 -07001430 def test_create_numpy_vector_reject_object(self):
1431 try:
1432 imp.find_module('numpy')
1433 # if numpy exists, then we should be able to get the
1434 # vector as a numpy array
1435 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001436
James Kuszmaul8e62b022022-03-22 09:33:25 -07001437 # Create String array
1438 b = flatbuffers.Builder(0)
1439 x = np.array([{'m': 0}, {'as': -2.1, 'c': 'c'}])
1440 assertRaises(self, lambda: b.CreateNumpyVector(x), TypeError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001441
James Kuszmaul8e62b022022-03-22 09:33:25 -07001442 except ImportError:
1443 b = flatbuffers.Builder(0)
1444 x = 0
1445 assertRaises(self, lambda: b.CreateNumpyVector(x),
1446 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001447
James Kuszmaul8e62b022022-03-22 09:33:25 -07001448 def test_empty_vtable(self):
1449 b = flatbuffers.Builder(0)
1450 b.StartObject(0)
1451 self.assertBuilderEquals(b, [])
1452 b.EndObject()
1453 self.assertBuilderEquals(b, [4, 0, 4, 0, 4, 0, 0, 0])
1454
1455 def test_vtable_with_one_true_bool(self):
1456 b = flatbuffers.Builder(0)
1457 self.assertBuilderEquals(b, [])
1458 b.StartObject(1)
1459 self.assertBuilderEquals(b, [])
1460 b.PrependBoolSlot(0, True, False)
1461 b.EndObject()
1462 self.assertBuilderEquals(
1463 b,
1464 [
1465 6,
1466 0, # vtable bytes
1467 8,
1468 0, # length of object including vtable offset
1469 7,
1470 0, # start of bool value
1471 6,
1472 0,
1473 0,
1474 0, # offset for start of vtable (int32)
1475 0,
1476 0,
1477 0, # padded to 4 bytes
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001478 1, # bool value
1479 ])
1480
James Kuszmaul8e62b022022-03-22 09:33:25 -07001481 def test_vtable_with_one_default_bool(self):
1482 b = flatbuffers.Builder(0)
1483 self.assertBuilderEquals(b, [])
1484 b.StartObject(1)
1485 self.assertBuilderEquals(b, [])
1486 b.PrependBoolSlot(0, False, False)
1487 b.EndObject()
1488 self.assertBuilderEquals(
1489 b,
1490 [
1491 4,
1492 0, # vtable bytes
1493 4,
1494 0, # end of object from here
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001495 # entry 1 is zero and not stored
James Kuszmaul8e62b022022-03-22 09:33:25 -07001496 4,
1497 0,
1498 0,
1499 0, # offset for start of vtable (int32)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001500 ])
1501
James Kuszmaul8e62b022022-03-22 09:33:25 -07001502 def test_vtable_with_one_int16(self):
1503 b = flatbuffers.Builder(0)
1504 b.StartObject(1)
1505 b.PrependInt16Slot(0, 0x789A, 0)
1506 b.EndObject()
1507 self.assertBuilderEquals(
1508 b,
1509 [
1510 6,
1511 0, # vtable bytes
1512 8,
1513 0, # end of object from here
1514 6,
1515 0, # offset to value
1516 6,
1517 0,
1518 0,
1519 0, # offset for start of vtable (int32)
1520 0,
1521 0, # padding to 4 bytes
1522 0x9A,
1523 0x78,
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001524 ])
1525
James Kuszmaul8e62b022022-03-22 09:33:25 -07001526 def test_vtable_with_two_int16(self):
1527 b = flatbuffers.Builder(0)
1528 b.StartObject(2)
1529 b.PrependInt16Slot(0, 0x3456, 0)
1530 b.PrependInt16Slot(1, 0x789A, 0)
1531 b.EndObject()
1532 self.assertBuilderEquals(
1533 b,
1534 [
1535 8,
1536 0, # vtable bytes
1537 8,
1538 0, # end of object from here
1539 6,
1540 0, # offset to value 0
1541 4,
1542 0, # offset to value 1
1543 8,
1544 0,
1545 0,
1546 0, # offset for start of vtable (int32)
1547 0x9A,
1548 0x78, # value 1
1549 0x56,
1550 0x34, # value 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001551 ])
1552
James Kuszmaul8e62b022022-03-22 09:33:25 -07001553 def test_vtable_with_int16_and_bool(self):
1554 b = flatbuffers.Builder(0)
1555 b.StartObject(2)
1556 b.PrependInt16Slot(0, 0x3456, 0)
1557 b.PrependBoolSlot(1, True, False)
1558 b.EndObject()
1559 self.assertBuilderEquals(
1560 b,
1561 [
1562 8,
1563 0, # vtable bytes
1564 8,
1565 0, # end of object from here
1566 6,
1567 0, # offset to value 0
1568 5,
1569 0, # offset to value 1
1570 8,
1571 0,
1572 0,
1573 0, # offset for start of vtable (int32)
1574 0, # padding
1575 1, # value 1
1576 0x56,
1577 0x34, # value 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001578 ])
1579
James Kuszmaul8e62b022022-03-22 09:33:25 -07001580 def test_vtable_with_empty_vector(self):
1581 b = flatbuffers.Builder(0)
1582 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
1583 vecend = b.EndVector()
1584 b.StartObject(1)
1585 b.PrependUOffsetTRelativeSlot(0, vecend, 0)
1586 b.EndObject()
1587 self.assertBuilderEquals(
1588 b,
1589 [
1590 6,
1591 0, # vtable bytes
1592 8,
1593 0,
1594 4,
1595 0, # offset to vector offset
1596 6,
1597 0,
1598 0,
1599 0, # offset for start of vtable (int32)
1600 4,
1601 0,
1602 0,
1603 0,
1604 0,
1605 0,
1606 0,
1607 0, # length of vector (not in struct)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001608 ])
1609
James Kuszmaul8e62b022022-03-22 09:33:25 -07001610 def test_vtable_with_empty_vector_of_byte_and_some_scalars(self):
1611 b = flatbuffers.Builder(0)
1612 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
1613 vecend = b.EndVector()
1614 b.StartObject(2)
1615 b.PrependInt16Slot(0, 55, 0)
1616 b.PrependUOffsetTRelativeSlot(1, vecend, 0)
1617 b.EndObject()
1618 self.assertBuilderEquals(
1619 b,
1620 [
1621 8,
1622 0, # vtable bytes
1623 12,
1624 0,
1625 10,
1626 0, # offset to value 0
1627 4,
1628 0, # offset to vector offset
1629 8,
1630 0,
1631 0,
1632 0, # vtable loc
1633 8,
1634 0,
1635 0,
1636 0, # value 1
1637 0,
1638 0,
1639 55,
1640 0, # value 0
1641 0,
1642 0,
1643 0,
1644 0, # length of vector (not in struct)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001645 ])
1646
James Kuszmaul8e62b022022-03-22 09:33:25 -07001647 def test_vtable_with_1_int16_and_2vector_of_int16(self):
1648 b = flatbuffers.Builder(0)
1649 b.StartVector(flatbuffers.number_types.Int16Flags.bytewidth, 2, 1)
1650 b.PrependInt16(0x1234)
1651 b.PrependInt16(0x5678)
1652 vecend = b.EndVector()
1653 b.StartObject(2)
1654 b.PrependUOffsetTRelativeSlot(1, vecend, 0)
1655 b.PrependInt16Slot(0, 55, 0)
1656 b.EndObject()
1657 self.assertBuilderEquals(
1658 b,
1659 [
1660 8,
1661 0, # vtable bytes
1662 12,
1663 0, # length of object
1664 6,
1665 0, # start of value 0 from end of vtable
1666 8,
1667 0, # start of value 1 from end of buffer
1668 8,
1669 0,
1670 0,
1671 0, # offset for start of vtable (int32)
1672 0,
1673 0, # padding
1674 55,
1675 0, # value 0
1676 4,
1677 0,
1678 0,
1679 0, # vector position from here
1680 2,
1681 0,
1682 0,
1683 0, # length of vector (uint32)
1684 0x78,
1685 0x56, # vector value 1
1686 0x34,
1687 0x12, # vector value 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001688 ])
1689
James Kuszmaul8e62b022022-03-22 09:33:25 -07001690 def test_vtable_with_1_struct_of_1_int8__1_int16__1_int32(self):
1691 b = flatbuffers.Builder(0)
1692 b.StartObject(1)
1693 b.Prep(4 + 4 + 4, 0)
1694 b.PrependInt8(55)
1695 b.Pad(3)
1696 b.PrependInt16(0x1234)
1697 b.Pad(2)
1698 b.PrependInt32(0x12345678)
1699 structStart = b.Offset()
1700 b.PrependStructSlot(0, structStart, 0)
1701 b.EndObject()
1702 self.assertBuilderEquals(
1703 b,
1704 [
1705 6,
1706 0, # vtable bytes
1707 16,
1708 0, # end of object from here
1709 4,
1710 0, # start of struct from here
1711 6,
1712 0,
1713 0,
1714 0, # offset for start of vtable (int32)
1715 0x78,
1716 0x56,
1717 0x34,
1718 0x12, # value 2
1719 0,
1720 0, # padding
1721 0x34,
1722 0x12, # value 1
1723 0,
1724 0,
1725 0, # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001726 55, # value 0
1727 ])
1728
James Kuszmaul8e62b022022-03-22 09:33:25 -07001729 def test_vtable_with_1_vector_of_2_struct_of_2_int8(self):
1730 b = flatbuffers.Builder(0)
1731 b.StartVector(flatbuffers.number_types.Int8Flags.bytewidth * 2, 2, 1)
1732 b.PrependInt8(33)
1733 b.PrependInt8(44)
1734 b.PrependInt8(55)
1735 b.PrependInt8(66)
1736 vecend = b.EndVector()
1737 b.StartObject(1)
1738 b.PrependUOffsetTRelativeSlot(0, vecend, 0)
1739 b.EndObject()
1740 self.assertBuilderEquals(
1741 b,
1742 [
1743 6,
1744 0, # vtable bytes
1745 8,
1746 0,
1747 4,
1748 0, # offset of vector offset
1749 6,
1750 0,
1751 0,
1752 0, # offset for start of vtable (int32)
1753 4,
1754 0,
1755 0,
1756 0, # vector start offset
1757 2,
1758 0,
1759 0,
1760 0, # vector length
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001761 66, # vector value 1,1
1762 55, # vector value 1,0
1763 44, # vector value 0,1
1764 33, # vector value 0,0
1765 ])
1766
James Kuszmaul8e62b022022-03-22 09:33:25 -07001767 def test_table_with_some_elements(self):
1768 b = flatbuffers.Builder(0)
1769 b.StartObject(2)
1770 b.PrependInt8Slot(0, 33, 0)
1771 b.PrependInt16Slot(1, 66, 0)
1772 off = b.EndObject()
1773 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001774
James Kuszmaul8e62b022022-03-22 09:33:25 -07001775 self.assertBuilderEquals(
1776 b,
1777 [
1778 12,
1779 0,
1780 0,
1781 0, # root of table: points to vtable offset
1782 8,
1783 0, # vtable bytes
1784 8,
1785 0, # end of object from here
1786 7,
1787 0, # start of value 0
1788 4,
1789 0, # start of value 1
1790 8,
1791 0,
1792 0,
1793 0, # offset for start of vtable (int32)
1794 66,
1795 0, # value 1
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001796 0, # padding
1797 33, # value 0
1798 ])
1799
James Kuszmaul8e62b022022-03-22 09:33:25 -07001800 def test__one_unfinished_table_and_one_finished_table(self):
1801 b = flatbuffers.Builder(0)
1802 b.StartObject(2)
1803 b.PrependInt8Slot(0, 33, 0)
1804 b.PrependInt8Slot(1, 44, 0)
1805 off = b.EndObject()
1806 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001807
James Kuszmaul8e62b022022-03-22 09:33:25 -07001808 b.StartObject(3)
1809 b.PrependInt8Slot(0, 55, 0)
1810 b.PrependInt8Slot(1, 66, 0)
1811 b.PrependInt8Slot(2, 77, 0)
1812 off = b.EndObject()
1813 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001814
James Kuszmaul8e62b022022-03-22 09:33:25 -07001815 self.assertBuilderEquals(
1816 b,
1817 [
1818 16,
1819 0,
1820 0,
1821 0, # root of table: points to object
1822 0,
1823 0, # padding
1824 10,
1825 0, # vtable bytes
1826 8,
1827 0, # size of object
1828 7,
1829 0, # start of value 0
1830 6,
1831 0, # start of value 1
1832 5,
1833 0, # start of value 2
1834 10,
1835 0,
1836 0,
1837 0, # offset for start of vtable (int32)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001838 0, # padding
1839 77, # value 2
1840 66, # value 1
1841 55, # value 0
James Kuszmaul8e62b022022-03-22 09:33:25 -07001842 12,
1843 0,
1844 0,
1845 0, # root of table: points to object
1846 8,
1847 0, # vtable bytes
1848 8,
1849 0, # size of object
1850 7,
1851 0, # start of value 0
1852 6,
1853 0, # start of value 1
1854 8,
1855 0,
1856 0,
1857 0, # offset for start of vtable (int32)
1858 0,
1859 0, # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001860 44, # value 1
1861 33, # value 0
1862 ])
1863
James Kuszmaul8e62b022022-03-22 09:33:25 -07001864 def test_a_bunch_of_bools(self):
1865 b = flatbuffers.Builder(0)
1866 b.StartObject(8)
1867 b.PrependBoolSlot(0, True, False)
1868 b.PrependBoolSlot(1, True, False)
1869 b.PrependBoolSlot(2, True, False)
1870 b.PrependBoolSlot(3, True, False)
1871 b.PrependBoolSlot(4, True, False)
1872 b.PrependBoolSlot(5, True, False)
1873 b.PrependBoolSlot(6, True, False)
1874 b.PrependBoolSlot(7, True, False)
1875 off = b.EndObject()
1876 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001877
James Kuszmaul8e62b022022-03-22 09:33:25 -07001878 self.assertBuilderEquals(
1879 b,
1880 [
1881 24,
1882 0,
1883 0,
1884 0, # root of table: points to vtable offset
1885 20,
1886 0, # vtable bytes
1887 12,
1888 0, # size of object
1889 11,
1890 0, # start of value 0
1891 10,
1892 0, # start of value 1
1893 9,
1894 0, # start of value 2
1895 8,
1896 0, # start of value 3
1897 7,
1898 0, # start of value 4
1899 6,
1900 0, # start of value 5
1901 5,
1902 0, # start of value 6
1903 4,
1904 0, # start of value 7
1905 20,
1906 0,
1907 0,
1908 0, # vtable offset
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001909 1, # value 7
1910 1, # value 6
1911 1, # value 5
1912 1, # value 4
1913 1, # value 3
1914 1, # value 2
1915 1, # value 1
1916 1, # value 0
1917 ])
1918
James Kuszmaul8e62b022022-03-22 09:33:25 -07001919 def test_three_bools(self):
1920 b = flatbuffers.Builder(0)
1921 b.StartObject(3)
1922 b.PrependBoolSlot(0, True, False)
1923 b.PrependBoolSlot(1, True, False)
1924 b.PrependBoolSlot(2, True, False)
1925 off = b.EndObject()
1926 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001927
James Kuszmaul8e62b022022-03-22 09:33:25 -07001928 self.assertBuilderEquals(
1929 b,
1930 [
1931 16,
1932 0,
1933 0,
1934 0, # root of table: points to vtable offset
1935 0,
1936 0, # padding
1937 10,
1938 0, # vtable bytes
1939 8,
1940 0, # size of object
1941 7,
1942 0, # start of value 0
1943 6,
1944 0, # start of value 1
1945 5,
1946 0, # start of value 2
1947 10,
1948 0,
1949 0,
1950 0, # vtable offset from here
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001951 0, # padding
1952 1, # value 2
1953 1, # value 1
1954 1, # value 0
1955 ])
1956
James Kuszmaul8e62b022022-03-22 09:33:25 -07001957 def test_some_floats(self):
1958 b = flatbuffers.Builder(0)
1959 b.StartObject(1)
1960 b.PrependFloat32Slot(0, 1.0, 0.0)
1961 off = b.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001962
James Kuszmaul8e62b022022-03-22 09:33:25 -07001963 self.assertBuilderEquals(
1964 b,
1965 [
1966 6,
1967 0, # vtable bytes
1968 8,
1969 0, # size of object
1970 4,
1971 0, # start of value 0
1972 6,
1973 0,
1974 0,
1975 0, # vtable offset
1976 0,
1977 0,
1978 128,
1979 63, # value 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001980 ])
1981
1982
James Kuszmaul8e62b022022-03-22 09:33:25 -07001983def make_monster_from_generated_code(sizePrefix=False, file_identifier=None):
1984 """ Use generated code to build the example Monster. """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001985
James Kuszmaul8e62b022022-03-22 09:33:25 -07001986 b = flatbuffers.Builder(0)
1987 string = b.CreateString('MyMonster')
1988 test1 = b.CreateString('test1')
1989 test2 = b.CreateString('test2')
1990 fred = b.CreateString('Fred')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001991
James Kuszmaul8e62b022022-03-22 09:33:25 -07001992 _MONSTER.MonsterStartInventoryVector(b, 5)
1993 b.PrependByte(4)
1994 b.PrependByte(3)
1995 b.PrependByte(2)
1996 b.PrependByte(1)
1997 b.PrependByte(0)
1998 inv = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001999
James Kuszmaul8e62b022022-03-22 09:33:25 -07002000 _MONSTER.MonsterStart(b)
2001 _MONSTER.MonsterAddName(b, fred)
2002 mon2 = _MONSTER.MonsterEnd(b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002003
James Kuszmaul8e62b022022-03-22 09:33:25 -07002004 _MONSTER.MonsterStartTest4Vector(b, 2)
2005 _TEST.CreateTest(b, 10, 20)
2006 _TEST.CreateTest(b, 30, 40)
2007 test4 = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002008
James Kuszmaul8e62b022022-03-22 09:33:25 -07002009 _MONSTER.MonsterStartTestarrayofstringVector(b, 2)
2010 b.PrependUOffsetTRelative(test2)
2011 b.PrependUOffsetTRelative(test1)
2012 testArrayOfString = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002013
James Kuszmaul8e62b022022-03-22 09:33:25 -07002014 _MONSTER.MonsterStartVectorOfLongsVector(b, 5)
2015 b.PrependInt64(100000000)
2016 b.PrependInt64(1000000)
2017 b.PrependInt64(10000)
2018 b.PrependInt64(100)
2019 b.PrependInt64(1)
2020 VectorOfLongs = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002021
James Kuszmaul8e62b022022-03-22 09:33:25 -07002022 _MONSTER.MonsterStartVectorOfDoublesVector(b, 3)
2023 b.PrependFloat64(1.7976931348623157e+308)
2024 b.PrependFloat64(0)
2025 b.PrependFloat64(-1.7976931348623157e+308)
2026 VectorOfDoubles = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002027
James Kuszmaul8e62b022022-03-22 09:33:25 -07002028 _MONSTER.MonsterStart(b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002029
James Kuszmaul8e62b022022-03-22 09:33:25 -07002030 pos = _VEC3.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 2, 5, 6)
2031 _MONSTER.MonsterAddPos(b, pos)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002032
James Kuszmaul8e62b022022-03-22 09:33:25 -07002033 _MONSTER.MonsterAddHp(b, 80)
2034 _MONSTER.MonsterAddName(b, string)
2035 _MONSTER.MonsterAddInventory(b, inv)
2036 _MONSTER.MonsterAddTestType(b, 1)
2037 _MONSTER.MonsterAddTest(b, mon2)
2038 _MONSTER.MonsterAddTest4(b, test4)
2039 _MONSTER.MonsterAddTestarrayofstring(b, testArrayOfString)
2040 _MONSTER.MonsterAddVectorOfLongs(b, VectorOfLongs)
2041 _MONSTER.MonsterAddVectorOfDoubles(b, VectorOfDoubles)
2042 mon = _MONSTER.MonsterEnd(b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002043
James Kuszmaul8e62b022022-03-22 09:33:25 -07002044 if sizePrefix:
2045 b.FinishSizePrefixed(mon, file_identifier)
2046 else:
2047 b.Finish(mon, file_identifier)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002048
James Kuszmaul8e62b022022-03-22 09:33:25 -07002049 return b.Bytes, b.Head()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002050
2051
Austin Schuh272c6132020-11-14 16:37:52 -08002052class TestBuilderForceDefaults(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002053 """Verify that the builder adds default values when forced."""
Austin Schuh272c6132020-11-14 16:37:52 -08002054
James Kuszmaul8e62b022022-03-22 09:33:25 -07002055 test_flags = [N.BoolFlags(), N.Uint8Flags(), N.Uint16Flags(), \
2056 N.Uint32Flags(), N.Uint64Flags(), N.Int8Flags(), \
2057 N.Int16Flags(), N.Int32Flags(), N.Int64Flags(), \
2058 N.Float32Flags(), N.Float64Flags(), N.UOffsetTFlags()]
Austin Schuh272c6132020-11-14 16:37:52 -08002059
James Kuszmaul8e62b022022-03-22 09:33:25 -07002060 def test_default_force_defaults(self):
2061 for flag in self.test_flags:
2062 b = flatbuffers.Builder(0)
2063 b.StartObject(1)
2064 stored_offset = b.Offset()
2065 if flag != N.UOffsetTFlags():
2066 b.PrependSlot(flag, 0, 0, 0)
2067 else:
2068 b.PrependUOffsetTRelativeSlot(0, 0, 0)
2069 end_offset = b.Offset()
2070 b.EndObject()
2071 self.assertEqual(0, end_offset - stored_offset)
2072
2073 def test_force_defaults_true(self):
2074 for flag in self.test_flags:
2075 b = flatbuffers.Builder(0)
2076 b.ForceDefaults(True)
2077 b.StartObject(1)
2078 stored_offset = b.Offset()
2079 if flag != N.UOffsetTFlags():
2080 b.PrependSlot(flag, 0, 0, 0)
2081 else:
2082 b.PrependUOffsetTRelativeSlot(0, 0, 0)
2083 end_offset = b.Offset()
2084 b.EndObject()
2085 self.assertEqual(flag.bytewidth, end_offset - stored_offset)
Austin Schuh272c6132020-11-14 16:37:52 -08002086
2087
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002088class TestAllCodePathsOfExampleSchema(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002089
James Kuszmaul8e62b022022-03-22 09:33:25 -07002090 def setUp(self, *args, **kwargs):
2091 super(TestAllCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002092
James Kuszmaul8e62b022022-03-22 09:33:25 -07002093 b = flatbuffers.Builder(0)
2094 _MONSTER.MonsterStart(b)
2095 gen_mon = _MONSTER.MonsterEnd(b)
2096 b.Finish(gen_mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002097
James Kuszmaul8e62b022022-03-22 09:33:25 -07002098 self.mon = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002099
James Kuszmaul8e62b022022-03-22 09:33:25 -07002100 def test_default_monster_pos(self):
2101 self.assertTrue(self.mon.Pos() is None)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002102
James Kuszmaul8e62b022022-03-22 09:33:25 -07002103 def test_nondefault_monster_mana(self):
2104 b = flatbuffers.Builder(0)
2105 _MONSTER.MonsterStart(b)
2106 _MONSTER.MonsterAddMana(b, 50)
2107 mon = _MONSTER.MonsterEnd(b)
2108 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002109
James Kuszmaul8e62b022022-03-22 09:33:25 -07002110 got_mon = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2111 self.assertEqual(50, got_mon.Mana())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002112
James Kuszmaul8e62b022022-03-22 09:33:25 -07002113 def test_default_monster_hp(self):
2114 self.assertEqual(100, self.mon.Hp())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002115
James Kuszmaul8e62b022022-03-22 09:33:25 -07002116 def test_default_monster_name(self):
2117 self.assertEqual(None, self.mon.Name())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002118
James Kuszmaul8e62b022022-03-22 09:33:25 -07002119 def test_default_monster_inventory_item(self):
2120 self.assertEqual(0, self.mon.Inventory(0))
Austin Schuh272c6132020-11-14 16:37:52 -08002121
James Kuszmaul8e62b022022-03-22 09:33:25 -07002122 def test_default_monster_inventory_length(self):
2123 self.assertEqual(0, self.mon.InventoryLength())
2124 self.assertTrue(self.mon.InventoryIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002125
James Kuszmaul8e62b022022-03-22 09:33:25 -07002126 def test_empty_monster_inventory_vector(self):
2127 b = flatbuffers.Builder(0)
2128 _MONSTER.MonsterStartInventoryVector(b, 0)
2129 inv = b.EndVector()
2130 _MONSTER.MonsterStart(b)
2131 _MONSTER.MonsterAddInventory(b, inv)
2132 mon = _MONSTER.MonsterEnd(b)
2133 b.Finish(mon)
2134 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2135 self.assertFalse(mon2.InventoryIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002136
James Kuszmaul8e62b022022-03-22 09:33:25 -07002137 def test_default_monster_color(self):
2138 self.assertEqual(_COLOR.Color.Blue, self.mon.Color())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002139
James Kuszmaul8e62b022022-03-22 09:33:25 -07002140 def test_nondefault_monster_color(self):
2141 b = flatbuffers.Builder(0)
2142 color = _COLOR.Color.Red
2143 _MONSTER.MonsterStart(b)
2144 _MONSTER.MonsterAddColor(b, color)
2145 mon = _MONSTER.MonsterEnd(b)
2146 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002147
James Kuszmaul8e62b022022-03-22 09:33:25 -07002148 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2149 self.assertEqual(_COLOR.Color.Red, mon2.Color())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002150
James Kuszmaul8e62b022022-03-22 09:33:25 -07002151 def test_default_monster_testtype(self):
2152 self.assertEqual(0, self.mon.TestType())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002153
James Kuszmaul8e62b022022-03-22 09:33:25 -07002154 def test_default_monster_test_field(self):
2155 self.assertEqual(None, self.mon.Test())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002156
James Kuszmaul8e62b022022-03-22 09:33:25 -07002157 def test_default_monster_test4_item(self):
2158 self.assertEqual(None, self.mon.Test4(0))
Austin Schuh272c6132020-11-14 16:37:52 -08002159
James Kuszmaul8e62b022022-03-22 09:33:25 -07002160 def test_default_monster_test4_length(self):
2161 self.assertEqual(0, self.mon.Test4Length())
2162 self.assertTrue(self.mon.Test4IsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002163
James Kuszmaul8e62b022022-03-22 09:33:25 -07002164 def test_empty_monster_test4_vector(self):
2165 b = flatbuffers.Builder(0)
2166 _MONSTER.MonsterStartTest4Vector(b, 0)
2167 test4 = b.EndVector()
2168 _MONSTER.MonsterStart(b)
2169 _MONSTER.MonsterAddTest4(b, test4)
2170 mon = _MONSTER.MonsterEnd(b)
2171 b.Finish(mon)
2172 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2173 self.assertFalse(mon2.Test4IsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002174
James Kuszmaul8e62b022022-03-22 09:33:25 -07002175 def test_default_monster_testarrayofstring(self):
2176 self.assertEqual('', self.mon.Testarrayofstring(0))
Austin Schuh272c6132020-11-14 16:37:52 -08002177
James Kuszmaul8e62b022022-03-22 09:33:25 -07002178 def test_default_monster_testarrayofstring_length(self):
2179 self.assertEqual(0, self.mon.TestarrayofstringLength())
2180 self.assertTrue(self.mon.TestarrayofstringIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002181
James Kuszmaul8e62b022022-03-22 09:33:25 -07002182 def test_empty_monster_testarrayofstring_vector(self):
2183 b = flatbuffers.Builder(0)
2184 _MONSTER.MonsterStartTestarrayofstringVector(b, 0)
2185 testarrayofstring = b.EndVector()
2186 _MONSTER.MonsterStart(b)
2187 _MONSTER.MonsterAddTestarrayofstring(b, testarrayofstring)
2188 mon = _MONSTER.MonsterEnd(b)
2189 b.Finish(mon)
2190 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2191 self.assertFalse(mon2.TestarrayofstringIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002192
James Kuszmaul8e62b022022-03-22 09:33:25 -07002193 def test_default_monster_testarrayoftables(self):
2194 self.assertEqual(None, self.mon.Testarrayoftables(0))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002195
James Kuszmaul8e62b022022-03-22 09:33:25 -07002196 def test_nondefault_monster_testarrayoftables(self):
2197 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002198
James Kuszmaul8e62b022022-03-22 09:33:25 -07002199 # make a child Monster within a vector of Monsters:
2200 _MONSTER.MonsterStart(b)
2201 _MONSTER.MonsterAddHp(b, 99)
2202 sub_monster = _MONSTER.MonsterEnd(b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002203
James Kuszmaul8e62b022022-03-22 09:33:25 -07002204 # build the vector:
2205 _MONSTER.MonsterStartTestarrayoftablesVector(b, 1)
2206 b.PrependUOffsetTRelative(sub_monster)
2207 vec = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002208
James Kuszmaul8e62b022022-03-22 09:33:25 -07002209 # make the parent monster and include the vector of Monster:
2210 _MONSTER.MonsterStart(b)
2211 _MONSTER.MonsterAddTestarrayoftables(b, vec)
2212 mon = _MONSTER.MonsterEnd(b)
2213 b.Finish(mon)
Austin Schuh272c6132020-11-14 16:37:52 -08002214
James Kuszmaul8e62b022022-03-22 09:33:25 -07002215 # inspect the resulting data:
2216 mon2 = _MONSTER.Monster.GetRootAs(b.Output(), 0)
2217 self.assertEqual(99, mon2.Testarrayoftables(0).Hp())
2218 self.assertEqual(1, mon2.TestarrayoftablesLength())
2219 self.assertFalse(mon2.TestarrayoftablesIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -08002220
James Kuszmaul8e62b022022-03-22 09:33:25 -07002221 def test_default_monster_testarrayoftables_length(self):
2222 self.assertEqual(0, self.mon.TestarrayoftablesLength())
2223 self.assertTrue(self.mon.TestarrayoftablesIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002224
James Kuszmaul8e62b022022-03-22 09:33:25 -07002225 def test_empty_monster_testarrayoftables_vector(self):
2226 b = flatbuffers.Builder(0)
2227 _MONSTER.MonsterStartTestarrayoftablesVector(b, 0)
2228 testarrayoftables = b.EndVector()
2229 _MONSTER.MonsterStart(b)
2230 _MONSTER.MonsterAddTestarrayoftables(b, testarrayoftables)
2231 mon = _MONSTER.MonsterEnd(b)
2232 b.Finish(mon)
2233 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2234 self.assertFalse(mon2.TestarrayoftablesIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002235
James Kuszmaul8e62b022022-03-22 09:33:25 -07002236 def test_default_monster_testarrayoftables_length(self):
2237 self.assertEqual(0, self.mon.TestarrayoftablesLength())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002238
James Kuszmaul8e62b022022-03-22 09:33:25 -07002239 def test_nondefault_monster_enemy(self):
2240 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002241
James Kuszmaul8e62b022022-03-22 09:33:25 -07002242 # make an Enemy object:
2243 _MONSTER.MonsterStart(b)
2244 _MONSTER.MonsterAddHp(b, 88)
2245 enemy = _MONSTER.MonsterEnd(b)
2246 b.Finish(enemy)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002247
James Kuszmaul8e62b022022-03-22 09:33:25 -07002248 # make the parent monster and include the vector of Monster:
2249 _MONSTER.MonsterStart(b)
2250 _MONSTER.MonsterAddEnemy(b, enemy)
2251 mon = _MONSTER.MonsterEnd(b)
2252 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002253
James Kuszmaul8e62b022022-03-22 09:33:25 -07002254 # inspect the resulting data:
2255 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2256 self.assertEqual(88, mon2.Enemy().Hp())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002257
James Kuszmaul8e62b022022-03-22 09:33:25 -07002258 def test_default_monster_testnestedflatbuffer(self):
2259 self.assertEqual(0, self.mon.Testnestedflatbuffer(0))
Austin Schuh272c6132020-11-14 16:37:52 -08002260
James Kuszmaul8e62b022022-03-22 09:33:25 -07002261 def test_default_monster_testnestedflatbuffer_length(self):
2262 self.assertEqual(0, self.mon.TestnestedflatbufferLength())
2263 self.assertTrue(self.mon.TestnestedflatbufferIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002264
James Kuszmaul8e62b022022-03-22 09:33:25 -07002265 def test_empty_monster_testnestedflatbuffer_vector(self):
2266 b = flatbuffers.Builder(0)
2267 _MONSTER.MonsterStartTestnestedflatbufferVector(b, 0)
2268 testnestedflatbuffer = b.EndVector()
2269 _MONSTER.MonsterStart(b)
2270 _MONSTER.MonsterAddTestnestedflatbuffer(b, testnestedflatbuffer)
2271 mon = _MONSTER.MonsterEnd(b)
2272 b.Finish(mon)
2273 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2274 self.assertFalse(mon2.TestnestedflatbufferIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002275
James Kuszmaul8e62b022022-03-22 09:33:25 -07002276 def test_nondefault_monster_testnestedflatbuffer(self):
2277 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002278
James Kuszmaul8e62b022022-03-22 09:33:25 -07002279 _MONSTER.MonsterStartTestnestedflatbufferVector(b, 3)
2280 b.PrependByte(4)
2281 b.PrependByte(2)
2282 b.PrependByte(0)
2283 sub_buf = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002284
James Kuszmaul8e62b022022-03-22 09:33:25 -07002285 # make the parent monster and include the vector of Monster:
2286 _MONSTER.MonsterStart(b)
2287 _MONSTER.MonsterAddTestnestedflatbuffer(b, sub_buf)
2288 mon = _MONSTER.MonsterEnd(b)
2289 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002290
James Kuszmaul8e62b022022-03-22 09:33:25 -07002291 # inspect the resulting data:
2292 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2293 self.assertEqual(3, mon2.TestnestedflatbufferLength())
2294 self.assertFalse(mon2.TestnestedflatbufferIsNone())
2295 self.assertEqual(0, mon2.Testnestedflatbuffer(0))
2296 self.assertEqual(2, mon2.Testnestedflatbuffer(1))
2297 self.assertEqual(4, mon2.Testnestedflatbuffer(2))
2298 try:
2299 imp.find_module('numpy')
2300 # if numpy exists, then we should be able to get the
2301 # vector as a numpy array
2302 self.assertEqual([0, 2, 4], mon2.TestnestedflatbufferAsNumpy().tolist())
2303 except ImportError:
2304 assertRaises(self, lambda: mon2.TestnestedflatbufferAsNumpy(),
2305 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002306
James Kuszmaul8e62b022022-03-22 09:33:25 -07002307 def test_nested_monster_testnestedflatbuffer(self):
2308 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002309
James Kuszmaul8e62b022022-03-22 09:33:25 -07002310 # build another monster to nest inside testnestedflatbuffer
2311 nestedB = flatbuffers.Builder(0)
2312 nameStr = nestedB.CreateString('Nested Monster')
2313 _MONSTER.MonsterStart(nestedB)
2314 _MONSTER.MonsterAddHp(nestedB, 30)
2315 _MONSTER.MonsterAddName(nestedB, nameStr)
2316 nestedMon = _MONSTER.MonsterEnd(nestedB)
2317 nestedB.Finish(nestedMon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002318
James Kuszmaul8e62b022022-03-22 09:33:25 -07002319 # write the nested FB bytes
2320 sub_buf = _MONSTER.MonsterMakeTestnestedflatbufferVectorFromBytes(
2321 b, nestedB.Output())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002322
James Kuszmaul8e62b022022-03-22 09:33:25 -07002323 # make the parent monster and include the bytes of the nested monster
2324 _MONSTER.MonsterStart(b)
2325 _MONSTER.MonsterAddTestnestedflatbuffer(b, sub_buf)
2326 mon = _MONSTER.MonsterEnd(b)
2327 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002328
James Kuszmaul8e62b022022-03-22 09:33:25 -07002329 # inspect the resulting data:
2330 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2331 nestedMon2 = mon2.TestnestedflatbufferNestedRoot()
2332 self.assertEqual(b'Nested Monster', nestedMon2.Name())
2333 self.assertEqual(30, nestedMon2.Hp())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002334
James Kuszmaul8e62b022022-03-22 09:33:25 -07002335 def test_nondefault_monster_testempty(self):
2336 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002337
James Kuszmaul8e62b022022-03-22 09:33:25 -07002338 # make a Stat object:
2339 _STAT.StatStart(b)
2340 _STAT.StatAddVal(b, 123)
2341 my_stat = _STAT.StatEnd(b)
2342 b.Finish(my_stat)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002343
James Kuszmaul8e62b022022-03-22 09:33:25 -07002344 # include the stat object in a monster:
2345 _MONSTER.MonsterStart(b)
2346 _MONSTER.MonsterAddTestempty(b, my_stat)
2347 mon = _MONSTER.MonsterEnd(b)
2348 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002349
James Kuszmaul8e62b022022-03-22 09:33:25 -07002350 # inspect the resulting data:
2351 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2352 self.assertEqual(123, mon2.Testempty().Val())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002353
James Kuszmaul8e62b022022-03-22 09:33:25 -07002354 def test_default_monster_testbool(self):
2355 self.assertFalse(self.mon.Testbool())
Austin Schuh272c6132020-11-14 16:37:52 -08002356
James Kuszmaul8e62b022022-03-22 09:33:25 -07002357 def test_nondefault_monster_testbool(self):
2358 b = flatbuffers.Builder(0)
2359 _MONSTER.MonsterStart(b)
2360 _MONSTER.MonsterAddTestbool(b, True)
2361 mon = _MONSTER.MonsterEnd(b)
2362 b.Finish(mon)
Austin Schuh272c6132020-11-14 16:37:52 -08002363
James Kuszmaul8e62b022022-03-22 09:33:25 -07002364 # inspect the resulting data:
2365 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2366 self.assertTrue(mon2.Testbool())
Austin Schuh272c6132020-11-14 16:37:52 -08002367
James Kuszmaul8e62b022022-03-22 09:33:25 -07002368 def test_default_monster_testhashes(self):
2369 self.assertEqual(0, self.mon.Testhashs32Fnv1())
2370 self.assertEqual(0, self.mon.Testhashu32Fnv1())
2371 self.assertEqual(0, self.mon.Testhashs64Fnv1())
2372 self.assertEqual(0, self.mon.Testhashu64Fnv1())
2373 self.assertEqual(0, self.mon.Testhashs32Fnv1a())
2374 self.assertEqual(0, self.mon.Testhashu32Fnv1a())
2375 self.assertEqual(0, self.mon.Testhashs64Fnv1a())
2376 self.assertEqual(0, self.mon.Testhashu64Fnv1a())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002377
James Kuszmaul8e62b022022-03-22 09:33:25 -07002378 def test_nondefault_monster_testhashes(self):
2379 b = flatbuffers.Builder(0)
2380 _MONSTER.MonsterStart(b)
2381 _MONSTER.MonsterAddTesthashs32Fnv1(b, 1)
2382 _MONSTER.MonsterAddTesthashu32Fnv1(b, 2)
2383 _MONSTER.MonsterAddTesthashs64Fnv1(b, 3)
2384 _MONSTER.MonsterAddTesthashu64Fnv1(b, 4)
2385 _MONSTER.MonsterAddTesthashs32Fnv1a(b, 5)
2386 _MONSTER.MonsterAddTesthashu32Fnv1a(b, 6)
2387 _MONSTER.MonsterAddTesthashs64Fnv1a(b, 7)
2388 _MONSTER.MonsterAddTesthashu64Fnv1a(b, 8)
2389 mon = _MONSTER.MonsterEnd(b)
2390 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002391
James Kuszmaul8e62b022022-03-22 09:33:25 -07002392 # inspect the resulting data:
2393 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2394 self.assertEqual(1, mon2.Testhashs32Fnv1())
2395 self.assertEqual(2, mon2.Testhashu32Fnv1())
2396 self.assertEqual(3, mon2.Testhashs64Fnv1())
2397 self.assertEqual(4, mon2.Testhashu64Fnv1())
2398 self.assertEqual(5, mon2.Testhashs32Fnv1a())
2399 self.assertEqual(6, mon2.Testhashu32Fnv1a())
2400 self.assertEqual(7, mon2.Testhashs64Fnv1a())
2401 self.assertEqual(8, mon2.Testhashu64Fnv1a())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002402
James Kuszmaul8e62b022022-03-22 09:33:25 -07002403 def test_default_monster_parent_namespace_test(self):
2404 self.assertEqual(None, self.mon.ParentNamespaceTest())
2405
2406 def test_nondefault_monster_parent_namespace_test(self):
2407 b = flatbuffers.Builder(0)
2408 _IN_PARENT_NAMESPACE.InParentNamespaceStart(b)
2409 parent = _IN_PARENT_NAMESPACE.InParentNamespaceEnd(b)
2410 _MONSTER.MonsterStart(b)
2411 _MONSTER.MonsterAddParentNamespaceTest(b, parent)
2412 mon = _MONSTER.MonsterEnd(b)
2413 b.Finish(mon)
2414
2415 # Inspect the resulting data.
2416 monster = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2417 self.assertTrue(
2418 isinstance(monster.ParentNamespaceTest(),
2419 _IN_PARENT_NAMESPACE.InParentNamespace))
2420
2421 def test_getrootas_for_nonroot_table(self):
2422 b = flatbuffers.Builder(0)
2423 string = b.CreateString('MyStat')
2424
2425 _STAT.StatStart(b)
2426 _STAT.StatAddId(b, string)
2427 _STAT.StatAddVal(b, 12345678)
2428 _STAT.StatAddCount(b, 12345)
2429 stat = _STAT.StatEnd(b)
2430 b.Finish(stat)
2431
2432 stat2 = _STAT.Stat.GetRootAs(b.Bytes, b.Head())
2433
2434 self.assertEqual(b'MyStat', stat2.Id())
2435 self.assertEqual(12345678, stat2.Val())
2436 self.assertEqual(12345, stat2.Count())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002437
2438
2439class TestAllCodePathsOfMonsterExtraSchema(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002440
James Kuszmaul8e62b022022-03-22 09:33:25 -07002441 def setUp(self, *args, **kwargs):
2442 super(TestAllCodePathsOfMonsterExtraSchema, self).setUp(*args, **kwargs)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002443
James Kuszmaul8e62b022022-03-22 09:33:25 -07002444 b = flatbuffers.Builder(0)
2445 MyGame.MonsterExtra.Start(b)
2446 gen_mon = MyGame.MonsterExtra.End(b)
2447 b.Finish(gen_mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002448
James Kuszmaul8e62b022022-03-22 09:33:25 -07002449 self.mon = MyGame.MonsterExtra.MonsterExtra.GetRootAs(b.Bytes, b.Head())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002450
James Kuszmaul8e62b022022-03-22 09:33:25 -07002451 def test_default_nan_inf(self):
2452 self.assertTrue(math.isnan(self.mon.F1()))
2453 self.assertEqual(self.mon.F2(), float('inf'))
2454 self.assertEqual(self.mon.F3(), float('-inf'))
2455
2456 self.assertTrue(math.isnan(self.mon.D1()))
2457 self.assertEqual(self.mon.D2(), float('inf'))
2458 self.assertEqual(self.mon.D3(), float('-inf'))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002459
2460
2461class TestVtableDeduplication(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002462 """ TestVtableDeduplication verifies that vtables are deduplicated. """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002463
James Kuszmaul8e62b022022-03-22 09:33:25 -07002464 def test_vtable_deduplication(self):
2465 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002466
James Kuszmaul8e62b022022-03-22 09:33:25 -07002467 b.StartObject(4)
2468 b.PrependByteSlot(0, 0, 0)
2469 b.PrependByteSlot(1, 11, 0)
2470 b.PrependByteSlot(2, 22, 0)
2471 b.PrependInt16Slot(3, 33, 0)
2472 obj0 = b.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002473
James Kuszmaul8e62b022022-03-22 09:33:25 -07002474 b.StartObject(4)
2475 b.PrependByteSlot(0, 0, 0)
2476 b.PrependByteSlot(1, 44, 0)
2477 b.PrependByteSlot(2, 55, 0)
2478 b.PrependInt16Slot(3, 66, 0)
2479 obj1 = b.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002480
James Kuszmaul8e62b022022-03-22 09:33:25 -07002481 b.StartObject(4)
2482 b.PrependByteSlot(0, 0, 0)
2483 b.PrependByteSlot(1, 77, 0)
2484 b.PrependByteSlot(2, 88, 0)
2485 b.PrependInt16Slot(3, 99, 0)
2486 obj2 = b.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002487
James Kuszmaul8e62b022022-03-22 09:33:25 -07002488 got = b.Bytes[b.Head():]
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002489
James Kuszmaul8e62b022022-03-22 09:33:25 -07002490 want = bytearray([
2491 240,
2492 255,
2493 255,
2494 255, # == -12. offset to dedupped vtable.
2495 99,
2496 0,
2497 88,
2498 77,
2499 248,
2500 255,
2501 255,
2502 255, # == -8. offset to dedupped vtable.
2503 66,
2504 0,
2505 55,
2506 44,
2507 12,
2508 0,
2509 8,
2510 0,
2511 0,
2512 0,
2513 7,
2514 0,
2515 6,
2516 0,
2517 4,
2518 0,
2519 12,
2520 0,
2521 0,
2522 0,
2523 33,
2524 0,
2525 22,
2526 11,
2527 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002528
James Kuszmaul8e62b022022-03-22 09:33:25 -07002529 self.assertEqual((len(want), want), (len(got), got))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002530
James Kuszmaul8e62b022022-03-22 09:33:25 -07002531 table0 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj0)
2532 table1 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj1)
2533 table2 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj2)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002534
James Kuszmaul8e62b022022-03-22 09:33:25 -07002535 def _checkTable(tab, voffsett_value, b, c, d):
2536 # vtable size
2537 got = tab.GetVOffsetTSlot(0, 0)
2538 self.assertEqual(12, got, 'case 0, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002539
James Kuszmaul8e62b022022-03-22 09:33:25 -07002540 # object size
2541 got = tab.GetVOffsetTSlot(2, 0)
2542 self.assertEqual(8, got, 'case 2, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002543
James Kuszmaul8e62b022022-03-22 09:33:25 -07002544 # default value
2545 got = tab.GetVOffsetTSlot(4, 0)
2546 self.assertEqual(voffsett_value, got, 'case 4, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002547
James Kuszmaul8e62b022022-03-22 09:33:25 -07002548 got = tab.GetSlot(6, 0, N.Uint8Flags)
2549 self.assertEqual(b, got, 'case 6, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002550
James Kuszmaul8e62b022022-03-22 09:33:25 -07002551 val = tab.GetSlot(8, 0, N.Uint8Flags)
2552 self.assertEqual(c, val, 'failed 8, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002553
James Kuszmaul8e62b022022-03-22 09:33:25 -07002554 got = tab.GetSlot(10, 0, N.Uint8Flags)
2555 self.assertEqual(d, got, 'failed 10, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002556
James Kuszmaul8e62b022022-03-22 09:33:25 -07002557 _checkTable(table0, 0, 11, 22, 33)
2558 _checkTable(table1, 0, 44, 55, 66)
2559 _checkTable(table2, 0, 77, 88, 99)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002560
2561
2562class TestExceptions(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002563
James Kuszmaul8e62b022022-03-22 09:33:25 -07002564 def test_object_is_nested_error(self):
2565 b = flatbuffers.Builder(0)
2566 b.StartObject(0)
2567 assertRaises(self, lambda: b.StartObject(0),
2568 flatbuffers.builder.IsNestedError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002569
James Kuszmaul8e62b022022-03-22 09:33:25 -07002570 def test_object_is_not_nested_error(self):
2571 b = flatbuffers.Builder(0)
2572 assertRaises(self, lambda: b.EndObject(),
2573 flatbuffers.builder.IsNotNestedError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002574
James Kuszmaul8e62b022022-03-22 09:33:25 -07002575 def test_struct_is_not_inline_error(self):
2576 b = flatbuffers.Builder(0)
2577 b.StartObject(0)
2578 assertRaises(self, lambda: b.PrependStructSlot(0, 1, 0),
2579 flatbuffers.builder.StructIsNotInlineError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002580
James Kuszmaul8e62b022022-03-22 09:33:25 -07002581 def test_unreachable_error(self):
2582 b = flatbuffers.Builder(0)
2583 assertRaises(self, lambda: b.PrependUOffsetTRelative(1),
2584 flatbuffers.builder.OffsetArithmeticError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002585
James Kuszmaul8e62b022022-03-22 09:33:25 -07002586 def test_create_string_is_nested_error(self):
2587 b = flatbuffers.Builder(0)
2588 b.StartObject(0)
2589 s = 'test1'
2590 assertRaises(self, lambda: b.CreateString(s),
2591 flatbuffers.builder.IsNestedError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002592
James Kuszmaul8e62b022022-03-22 09:33:25 -07002593 def test_create_byte_vector_is_nested_error(self):
2594 b = flatbuffers.Builder(0)
2595 b.StartObject(0)
2596 s = b'test1'
2597 assertRaises(self, lambda: b.CreateByteVector(s),
2598 flatbuffers.builder.IsNestedError)
2599
2600 def test_finished_bytes_error(self):
2601 b = flatbuffers.Builder(0)
2602 assertRaises(self, lambda: b.Output(),
2603 flatbuffers.builder.BuilderNotFinishedError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002604
2605
2606class TestFixedLengthArrays(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002607
James Kuszmaul8e62b022022-03-22 09:33:25 -07002608 def test_fixed_length_array(self):
2609 builder = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002610
James Kuszmaul8e62b022022-03-22 09:33:25 -07002611 a = 0.5
2612 b = range(0, 15)
2613 c = 1
2614 d_a = [[1, 2], [3, 4]]
2615 d_b = [MyGame.Example.TestEnum.TestEnum.B, \
2616 MyGame.Example.TestEnum.TestEnum.C]
2617 d_c = [[MyGame.Example.TestEnum.TestEnum.A, \
2618 MyGame.Example.TestEnum.TestEnum.B], \
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002619 [MyGame.Example.TestEnum.TestEnum.C, \
James Kuszmaul8e62b022022-03-22 09:33:25 -07002620 MyGame.Example.TestEnum.TestEnum.B]]
2621 d_d = [[-1, 1], [-2, 2]]
2622 e = 2
2623 f = [-1, 1]
2624
2625 arrayOffset = MyGame.Example.ArrayStruct.CreateArrayStruct(builder, \
2626 a, b, c, d_a, d_b, d_c, d_d, e, f)
2627
2628 # Create a table with the ArrayStruct.
2629 MyGame.Example.ArrayTable.Start(builder)
2630 MyGame.Example.ArrayTable.AddA(builder, arrayOffset)
2631 tableOffset = MyGame.Example.ArrayTable.End(builder)
2632
2633 builder.Finish(tableOffset)
2634
2635 buf = builder.Output()
2636
2637 table = MyGame.Example.ArrayTable.ArrayTable.GetRootAs(buf)
2638
2639 # Verify structure.
2640 nested = MyGame.Example.NestedStruct.NestedStruct()
2641 self.assertEqual(table.A().A(), 0.5)
2642 self.assertEqual(table.A().B(), \
2643 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
2644 self.assertEqual(table.A().C(), 1)
2645 self.assertEqual(table.A().D(nested, 0).A(), [1, 2])
2646 self.assertEqual(table.A().D(nested, 1).A(), [3, 4])
2647 self.assertEqual(table.A().D(nested, 0).B(), \
2648 MyGame.Example.TestEnum.TestEnum.B)
2649 self.assertEqual(table.A().D(nested, 1).B(), \
2650 MyGame.Example.TestEnum.TestEnum.C)
2651 self.assertEqual(table.A().D(nested, 0).C(), \
2652 [MyGame.Example.TestEnum.TestEnum.A, \
2653 MyGame.Example.TestEnum.TestEnum.B])
2654 self.assertEqual(table.A().D(nested, 1).C(), \
2655 [MyGame.Example.TestEnum.TestEnum.C, \
2656 MyGame.Example.TestEnum.TestEnum.B])
2657 self.assertEqual(table.A().D(nested, 0).D(), [-1, 1])
2658 self.assertEqual(table.A().D(nested, 1).D(), [-2, 2])
2659 self.assertEqual(table.A().E(), 2)
2660 self.assertEqual(table.A().F(), [-1, 1])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002661
2662
2663def CheckAgainstGoldDataGo():
James Kuszmaul8e62b022022-03-22 09:33:25 -07002664 try:
2665 gen_buf, gen_off = make_monster_from_generated_code()
2666 fn = 'monsterdata_go_wire.mon'
2667 if not os.path.exists(fn):
2668 print('Go-generated data does not exist, failed.')
2669 return False
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002670
James Kuszmaul8e62b022022-03-22 09:33:25 -07002671 # would like to use a context manager here, but it's less
2672 # backwards-compatible:
2673 f = open(fn, 'rb')
2674 go_wire_data = f.read()
2675 f.close()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002676
James Kuszmaul8e62b022022-03-22 09:33:25 -07002677 CheckReadBuffer(bytearray(go_wire_data), 0)
2678 if not bytearray(gen_buf[gen_off:]) == bytearray(go_wire_data):
2679 raise AssertionError('CheckAgainstGoldDataGo failed')
2680 except:
2681 print('Failed to test against Go-generated test data.')
2682 return False
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002683
James Kuszmaul8e62b022022-03-22 09:33:25 -07002684 print(
2685 'Can read Go-generated test data, and Python generates bytewise identical data.'
2686 )
2687 return True
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002688
2689
2690def CheckAgainstGoldDataJava():
James Kuszmaul8e62b022022-03-22 09:33:25 -07002691 try:
2692 gen_buf, gen_off = make_monster_from_generated_code()
2693 fn = 'monsterdata_java_wire.mon'
2694 if not os.path.exists(fn):
2695 print('Java-generated data does not exist, failed.')
2696 return False
2697 f = open(fn, 'rb')
2698 java_wire_data = f.read()
2699 f.close()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002700
James Kuszmaul8e62b022022-03-22 09:33:25 -07002701 CheckReadBuffer(bytearray(java_wire_data), 0)
2702 except:
2703 print('Failed to read Java-generated test data.')
2704 return False
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002705
James Kuszmaul8e62b022022-03-22 09:33:25 -07002706 print('Can read Java-generated test data.')
2707 return True
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002708
2709
2710class LCG(object):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002711 """ Include simple random number generator to ensure results will be the
2712
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002713 same cross platform.
James Kuszmaul8e62b022022-03-22 09:33:25 -07002714 http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
2715 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002716
James Kuszmaul8e62b022022-03-22 09:33:25 -07002717 __slots__ = ['n']
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002718
James Kuszmaul8e62b022022-03-22 09:33:25 -07002719 InitialLCGSeed = 48271
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002720
James Kuszmaul8e62b022022-03-22 09:33:25 -07002721 def __init__(self):
2722 self.n = self.InitialLCGSeed
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002723
James Kuszmaul8e62b022022-03-22 09:33:25 -07002724 def Reset(self):
2725 self.n = self.InitialLCGSeed
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002726
James Kuszmaul8e62b022022-03-22 09:33:25 -07002727 def Next(self):
2728 self.n = ((self.n * 279470273) % 4294967291) & 0xFFFFFFFF
2729 return self.n
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002730
2731
2732def BenchmarkVtableDeduplication(count):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002733 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002734 BenchmarkVtableDeduplication measures the speed of vtable deduplication
2735 by creating `prePop` vtables, then populating `count` objects with a
2736 different single vtable.
2737
2738 When count is large (as in long benchmarks), memory usage may be high.
James Kuszmaul8e62b022022-03-22 09:33:25 -07002739 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002740
James Kuszmaul8e62b022022-03-22 09:33:25 -07002741 for prePop in (1, 10, 100, 1000):
2742 builder = flatbuffers.Builder(0)
2743 n = 1 + int(math.log(prePop, 1.5))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002744
James Kuszmaul8e62b022022-03-22 09:33:25 -07002745 # generate some layouts:
2746 layouts = set()
2747 r = list(compat_range(n))
2748 while len(layouts) < prePop:
2749 layouts.add(tuple(sorted(random.sample(r, int(max(1, n / 2))))))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002750
James Kuszmaul8e62b022022-03-22 09:33:25 -07002751 layouts = list(layouts)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002752
James Kuszmaul8e62b022022-03-22 09:33:25 -07002753 # pre-populate vtables:
2754 for layout in layouts:
2755 builder.StartObject(n)
2756 for j in layout:
2757 builder.PrependInt16Slot(j, j, 0)
2758 builder.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002759
James Kuszmaul8e62b022022-03-22 09:33:25 -07002760 # benchmark deduplication of a new vtable:
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002761 def f():
James Kuszmaul8e62b022022-03-22 09:33:25 -07002762 layout = random.choice(layouts)
2763 builder.StartObject(n)
2764 for j in layout:
2765 builder.PrependInt16Slot(j, j, 0)
2766 builder.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002767
2768 duration = timeit.timeit(stmt=f, number=count)
2769 rate = float(count) / duration
James Kuszmaul8e62b022022-03-22 09:33:25 -07002770 print(('vtable deduplication rate (n=%d, vtables=%d): %.2f sec' %
2771 (prePop, len(builder.vtables), rate)))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002772
James Kuszmaul8e62b022022-03-22 09:33:25 -07002773
2774def BenchmarkCheckReadBuffer(count, buf, off):
2775 """
2776 BenchmarkCheckReadBuffer measures the speed of flatbuffer reading
2777 by re-using the CheckReadBuffer function with the gold data.
2778 """
2779
2780 def f():
2781 CheckReadBuffer(buf, off)
2782
2783 duration = timeit.timeit(stmt=f, number=count)
2784 rate = float(count) / duration
2785 data = float(len(buf) * count) / float(1024 * 1024)
2786 data_rate = data / float(duration)
2787
2788 print(('traversed %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec') %
2789 (count, len(buf), duration, rate, data_rate))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002790
2791
2792def BenchmarkMakeMonsterFromGeneratedCode(count, length):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002793 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002794 BenchmarkMakeMonsterFromGeneratedCode measures the speed of flatbuffer
2795 creation by re-using the make_monster_from_generated_code function for
2796 generating gold data examples.
James Kuszmaul8e62b022022-03-22 09:33:25 -07002797 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002798
James Kuszmaul8e62b022022-03-22 09:33:25 -07002799 duration = timeit.timeit(stmt=make_monster_from_generated_code, number=count)
2800 rate = float(count) / duration
2801 data = float(length * count) / float(1024 * 1024)
2802 data_rate = data / float(duration)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002803
James Kuszmaul8e62b022022-03-22 09:33:25 -07002804 print(('built %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec' % \
2805 (count, length, duration, rate, data_rate)))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002806
2807
2808def backward_compatible_run_tests(**kwargs):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002809 if PY_VERSION < (2, 6):
2810 sys.stderr.write('Python version less than 2.6 are not supported')
2811 sys.stderr.flush()
2812 return False
2813
2814 # python2.6 has a reduced-functionality unittest.main function:
2815 if PY_VERSION == (2, 6):
2816 try:
2817 unittest.main(**kwargs)
2818 except SystemExit as e:
2819 if not e.code == 0:
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002820 return False
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002821 return True
2822
James Kuszmaul8e62b022022-03-22 09:33:25 -07002823 # python2.7 and above let us not exit once unittest.main is run:
2824 kwargs['exit'] = False
2825 kwargs['verbosity'] = 0
2826 ret = unittest.main(**kwargs)
2827 if ret.result.errors or ret.result.failures:
2828 return False
2829
2830 return True
2831
2832
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002833def main():
James Kuszmaul8e62b022022-03-22 09:33:25 -07002834 import os
2835 import sys
2836 if not len(sys.argv) == 5:
2837 sys.stderr.write('Usage: %s <benchmark vtable count> '
2838 '<benchmark read count> <benchmark build count> '
2839 '<is_onefile>\n' % sys.argv[0])
2840 sys.stderr.write(' Provide COMPARE_GENERATED_TO_GO=1 to check'
2841 'for bytewise comparison to Go data.\n')
2842 sys.stderr.write(' Provide COMPARE_GENERATED_TO_JAVA=1 to check'
2843 'for bytewise comparison to Java data.\n')
2844 sys.stderr.flush()
2845 sys.exit(1)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002846
James Kuszmaul8e62b022022-03-22 09:33:25 -07002847 kwargs = dict(argv=sys.argv[:-4])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002848
James Kuszmaul8e62b022022-03-22 09:33:25 -07002849 create_namespace_shortcut(sys.argv[4].lower() == 'true')
Austin Schuh272c6132020-11-14 16:37:52 -08002850
James Kuszmaul8e62b022022-03-22 09:33:25 -07002851 # show whether numpy is present, as it changes the test logic:
2852 try:
2853 import numpy
2854 print('numpy available')
2855 except ImportError:
2856 print('numpy not available')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002857
James Kuszmaul8e62b022022-03-22 09:33:25 -07002858 # run tests, and run some language comparison checks if needed:
2859 success = backward_compatible_run_tests(**kwargs)
2860 if success and os.environ.get('COMPARE_GENERATED_TO_GO', 0) == '1':
2861 success = success and CheckAgainstGoldDataGo()
2862 if success and os.environ.get('COMPARE_GENERATED_TO_JAVA', 0) == '1':
2863 success = success and CheckAgainstGoldDataJava()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002864
James Kuszmaul8e62b022022-03-22 09:33:25 -07002865 if not success:
2866 sys.stderr.write('Tests failed, skipping benchmarks.\n')
2867 sys.stderr.flush()
2868 sys.exit(1)
2869
2870 # run benchmarks (if 0, they will be a noop):
2871 bench_vtable = int(sys.argv[1])
2872 bench_traverse = int(sys.argv[2])
2873 bench_build = int(sys.argv[3])
2874 if bench_vtable:
2875 BenchmarkVtableDeduplication(bench_vtable)
2876 if bench_traverse:
2877 buf, off = make_monster_from_generated_code()
2878 BenchmarkCheckReadBuffer(bench_traverse, buf, off)
2879 if bench_build:
2880 buf, off = make_monster_from_generated_code()
2881 BenchmarkMakeMonsterFromGeneratedCode(bench_build, len(buf))
2882
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002883
2884if __name__ == '__main__':
James Kuszmaul8e62b022022-03-22 09:33:25 -07002885 main()