blob: ed966d51dedc8d5db42c4251fc7809adb38900a6 [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
51
52
53def create_namespace_shortcut(is_onefile):
54 # Create shortcut from either the one-file format or the multi-file format
55 global _ANY
56 global _COLOR
57 global _MONSTER
58 global _TEST
59 global _STAT
60 global _VEC3
61 global _IN_PARENT_NAMESPACE
62 if is_onefile:
63 print('Testing with the one-file generated code')
64 _ANY = monster_test_generated
65 _COLOR = monster_test_generated
66 _MONSTER = monster_test_generated
67 _TEST = monster_test_generated
68 _STAT = monster_test_generated
69 _VEC3 = monster_test_generated
70 _IN_PARENT_NAMESPACE = monster_test_generated
71 else:
72 print('Testing with multi-file generated code')
73 _ANY = MyGame.Example.Any
74 _COLOR = MyGame.Example.Color
75 _MONSTER = MyGame.Example.Monster
76 _TEST = MyGame.Example.Test
77 _STAT = MyGame.Example.Stat
78 _VEC3 = MyGame.Example.Vec3
79 _IN_PARENT_NAMESPACE = MyGame.InParentNamespace
80
Austin Schuhe89fa2d2019-08-14 20:24:23 -070081
82def assertRaises(test_case, fn, exception_class):
James Kuszmaul8e62b022022-03-22 09:33:25 -070083 """ Backwards-compatible assertion for exceptions raised. """
Austin Schuhe89fa2d2019-08-14 20:24:23 -070084
James Kuszmaul8e62b022022-03-22 09:33:25 -070085 exc = None
86 try:
87 fn()
88 except Exception as e:
89 exc = e
90 test_case.assertTrue(exc is not None)
91 test_case.assertTrue(isinstance(exc, exception_class))
Austin Schuhe89fa2d2019-08-14 20:24:23 -070092
93
94class TestWireFormat(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -070095
James Kuszmaul8e62b022022-03-22 09:33:25 -070096 def test_wire_format(self):
97 # Verify that using the generated Python code builds a buffer without
98 # returning errors, and is interpreted correctly, for size prefixed
99 # representation and regular:
100 for sizePrefix in [True, False]:
101 for file_identifier in [None, b'MONS']:
102 gen_buf, gen_off = make_monster_from_generated_code(
103 sizePrefix=sizePrefix, file_identifier=file_identifier)
104 CheckReadBuffer(
105 gen_buf,
106 gen_off,
107 sizePrefix=sizePrefix,
108 file_identifier=file_identifier)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700109
James Kuszmaul8e62b022022-03-22 09:33:25 -0700110 # Verify that the canonical flatbuffer file is readable by the
111 # generated Python code. Note that context managers are not part of
112 # Python 2.5, so we use the simpler open/close methods here:
113 f = open('monsterdata_test.mon', 'rb')
114 canonicalWireData = f.read()
115 f.close()
116 CheckReadBuffer(bytearray(canonicalWireData), 0, file_identifier=b'MONS')
117
118 # Write the generated buffer out to a file:
119 f = open('monsterdata_python_wire.mon', 'wb')
120 f.write(gen_buf[gen_off:])
121 f.close()
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700122
123
Austin Schuh272c6132020-11-14 16:37:52 -0800124class TestObjectBasedAPI(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700125 """ Tests the generated object based API."""
Austin Schuh272c6132020-11-14 16:37:52 -0800126
James Kuszmaul8e62b022022-03-22 09:33:25 -0700127 def test_consistenty_with_repeated_pack_and_unpack(self):
128 """ Checks the serialization and deserialization between a buffer and
129
Austin Schuh272c6132020-11-14 16:37:52 -0800130 its python object. It tests in the same way as the C++ object API test,
James Kuszmaul8e62b022022-03-22 09:33:25 -0700131 ObjectFlatBuffersTest in test.cpp.
132 """
Austin Schuh272c6132020-11-14 16:37:52 -0800133
James Kuszmaul8e62b022022-03-22 09:33:25 -0700134 buf, off = make_monster_from_generated_code()
Austin Schuh272c6132020-11-14 16:37:52 -0800135
James Kuszmaul8e62b022022-03-22 09:33:25 -0700136 # Turns a buffer into Python object (T class).
137 monster1 = _MONSTER.Monster.GetRootAs(buf, off)
138 monsterT1 = _MONSTER.MonsterT.InitFromObj(monster1)
Austin Schuh272c6132020-11-14 16:37:52 -0800139
James Kuszmaul8e62b022022-03-22 09:33:25 -0700140 for sizePrefix in [True, False]:
141 # Re-serialize the data into a buffer.
142 b1 = flatbuffers.Builder(0)
143 if sizePrefix:
144 b1.FinishSizePrefixed(monsterT1.Pack(b1))
145 else:
146 b1.Finish(monsterT1.Pack(b1))
147 CheckReadBuffer(b1.Bytes, b1.Head(), sizePrefix)
Austin Schuh272c6132020-11-14 16:37:52 -0800148
James Kuszmaul8e62b022022-03-22 09:33:25 -0700149 # Deserializes the buffer into Python object again.
150 monster2 = _MONSTER.Monster.GetRootAs(b1.Bytes, b1.Head())
151 # Re-serializes the data into a buffer for one more time.
152 monsterT2 = _MONSTER.MonsterT.InitFromObj(monster2)
153 for sizePrefix in [True, False]:
154 # Re-serializes the data into a buffer
155 b2 = flatbuffers.Builder(0)
156 if sizePrefix:
157 b2.FinishSizePrefixed(monsterT2.Pack(b2))
158 else:
159 b2.Finish(monsterT2.Pack(b2))
160 CheckReadBuffer(b2.Bytes, b2.Head(), sizePrefix)
Austin Schuh272c6132020-11-14 16:37:52 -0800161
James Kuszmaul8e62b022022-03-22 09:33:25 -0700162 def test_default_values_with_pack_and_unpack(self):
163 """ Serializes and deserializes between a buffer with default values (no
164
Austin Schuh272c6132020-11-14 16:37:52 -0800165 specific values are filled when the buffer is created) and its python
James Kuszmaul8e62b022022-03-22 09:33:25 -0700166 object.
167 """
168 # Creates a flatbuffer with default values.
169 b1 = flatbuffers.Builder(0)
170 _MONSTER.MonsterStart(b1)
171 gen_mon = _MONSTER.MonsterEnd(b1)
172 b1.Finish(gen_mon)
Austin Schuh272c6132020-11-14 16:37:52 -0800173
James Kuszmaul8e62b022022-03-22 09:33:25 -0700174 # Converts the flatbuffer into the object class.
175 monster1 = _MONSTER.Monster.GetRootAs(b1.Bytes, b1.Head())
176 monsterT1 = _MONSTER.MonsterT.InitFromObj(monster1)
Austin Schuh272c6132020-11-14 16:37:52 -0800177
James Kuszmaul8e62b022022-03-22 09:33:25 -0700178 # Packs the object class into another flatbuffer.
179 b2 = flatbuffers.Builder(0)
180 b2.Finish(monsterT1.Pack(b2))
181 monster2 = _MONSTER.Monster.GetRootAs(b2.Bytes, b2.Head())
182 # Checks the default values.
183 self.assertTrue(monster2.Pos() is None)
184 self.assertEqual(monster2.Mana(), 150)
185 self.assertEqual(monster2.Hp(), 100)
186 self.assertTrue(monster2.Name() is None)
187 self.assertEqual(monster2.Inventory(0), 0)
188 self.assertEqual(monster2.InventoryAsNumpy(), 0)
189 self.assertEqual(monster2.InventoryLength(), 0)
190 self.assertTrue(monster2.InventoryIsNone())
191 self.assertTrue(monster2.Color() is 8)
192 self.assertEqual(monster2.TestType(), 0)
193 self.assertTrue(monster2.Test() is None)
194 self.assertTrue(monster2.Test4(0) is None)
195 self.assertEqual(monster2.Test4Length(), 0)
196 self.assertTrue(monster2.Test4IsNone())
197 self.assertTrue(monster2.Testarrayofstring(0) is '')
198 self.assertEqual(monster2.TestarrayofstringLength(), 0)
199 self.assertTrue(monster2.TestarrayofstringIsNone())
200 self.assertTrue(monster2.Testarrayoftables(0) is None)
201 self.assertEqual(monster2.TestarrayoftablesLength(), 0)
202 self.assertTrue(monster2.TestarrayoftablesIsNone())
203 self.assertTrue(monster2.Enemy() is None)
204 self.assertEqual(monster2.Testnestedflatbuffer(0), 0)
205 self.assertEqual(monster2.TestnestedflatbufferAsNumpy(), 0)
206 self.assertEqual(monster2.TestnestedflatbufferLength(), 0)
207 self.assertTrue(monster2.TestnestedflatbufferIsNone())
208 self.assertTrue(monster2.Testempty() is None)
209 self.assertTrue(monster2.Testbool() is False)
210 self.assertEqual(monster2.Testhashs32Fnv1(), 0)
211 self.assertEqual(monster2.Testhashu32Fnv1(), 0)
212 self.assertEqual(monster2.Testhashs64Fnv1(), 0)
213 self.assertEqual(monster2.Testhashu64Fnv1(), 0)
214 self.assertEqual(monster2.Testhashs32Fnv1a(), 0)
215 self.assertEqual(monster2.Testhashu32Fnv1a(), 0)
216 self.assertEqual(monster2.Testhashs64Fnv1a(), 0)
217 self.assertEqual(monster2.Testhashu64Fnv1a(), 0)
218 self.assertEqual(monster2.Testarrayofbools(0), 0)
219 self.assertEqual(monster2.TestarrayofboolsAsNumpy(), 0)
220 self.assertEqual(monster2.TestarrayofboolsLength(), 0)
221 self.assertTrue(monster2.TestarrayofboolsIsNone())
222 self.assertEqual(monster2.Testf(), 3.14159)
223 self.assertEqual(monster2.Testf2(), 3.0)
224 self.assertEqual(monster2.Testf3(), 0.0)
225 self.assertTrue(monster2.Testarrayofstring2(0) is '')
226 self.assertEqual(monster2.Testarrayofstring2Length(), 0)
227 self.assertTrue(monster2.Testarrayofstring2IsNone())
228 self.assertTrue(monster2.Testarrayofsortedstruct(0) is None)
229 self.assertEqual(monster2.TestarrayofsortedstructLength(), 0)
230 self.assertTrue(monster2.TestarrayofsortedstructIsNone())
231 self.assertEqual(monster2.Flex(0), 0)
232 self.assertEqual(monster2.FlexAsNumpy(), 0)
233 self.assertEqual(monster2.FlexLength(), 0)
234 self.assertTrue(monster2.FlexIsNone())
235 self.assertTrue(monster2.Test5(0) is None)
236 self.assertEqual(monster2.Test5Length(), 0)
237 self.assertTrue(monster2.Test5IsNone())
238 self.assertEqual(monster2.VectorOfLongs(0), 0)
239 self.assertEqual(monster2.VectorOfLongsAsNumpy(), 0)
240 self.assertEqual(monster2.VectorOfLongsLength(), 0)
241 self.assertTrue(monster2.VectorOfLongsIsNone())
242 self.assertEqual(monster2.VectorOfDoubles(0), 0)
243 self.assertEqual(monster2.VectorOfDoublesAsNumpy(), 0)
244 self.assertEqual(monster2.VectorOfDoublesLength(), 0)
245 self.assertTrue(monster2.VectorOfDoublesIsNone())
246 self.assertTrue(monster2.ParentNamespaceTest() is None)
247 self.assertTrue(monster2.VectorOfReferrables(0) is None)
248 self.assertEqual(monster2.VectorOfReferrablesLength(), 0)
249 self.assertTrue(monster2.VectorOfReferrablesIsNone())
250 self.assertEqual(monster2.SingleWeakReference(), 0)
251 self.assertEqual(monster2.VectorOfWeakReferences(0), 0)
252 self.assertEqual(monster2.VectorOfWeakReferencesAsNumpy(), 0)
253 self.assertEqual(monster2.VectorOfWeakReferencesLength(), 0)
254 self.assertTrue(monster2.VectorOfWeakReferencesIsNone())
255 self.assertTrue(monster2.VectorOfStrongReferrables(0) is None)
256 self.assertEqual(monster2.VectorOfStrongReferrablesLength(), 0)
257 self.assertTrue(monster2.VectorOfStrongReferrablesIsNone())
258 self.assertEqual(monster2.CoOwningReference(), 0)
259 self.assertEqual(monster2.VectorOfCoOwningReferences(0), 0)
260 self.assertEqual(monster2.VectorOfCoOwningReferencesAsNumpy(), 0)
261 self.assertEqual(monster2.VectorOfCoOwningReferencesLength(), 0)
262 self.assertTrue(monster2.VectorOfCoOwningReferencesIsNone())
263 self.assertEqual(monster2.NonOwningReference(), 0)
264 self.assertEqual(monster2.VectorOfNonOwningReferences(0), 0)
265 self.assertEqual(monster2.VectorOfNonOwningReferencesAsNumpy(), 0)
266 self.assertEqual(monster2.VectorOfNonOwningReferencesLength(), 0)
267 self.assertTrue(monster2.VectorOfNonOwningReferencesIsNone())
268 self.assertEqual(monster2.AnyUniqueType(), 0)
269 self.assertTrue(monster2.AnyUnique() is None)
270 self.assertEqual(monster2.AnyAmbiguousType(), 0)
271 self.assertTrue(monster2.AnyAmbiguous() is None)
272 self.assertEqual(monster2.VectorOfEnums(0), 0)
273 self.assertEqual(monster2.VectorOfEnumsAsNumpy(), 0)
274 self.assertEqual(monster2.VectorOfEnumsLength(), 0)
275 self.assertTrue(monster2.VectorOfEnumsIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800276
277
278class TestAllMutableCodePathsOfExampleSchema(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700279 """ Tests the object API generated for monster_test.fbs for mutation
280
Austin Schuh272c6132020-11-14 16:37:52 -0800281 purposes. In each test, the default values will be changed through the
282 object API. We'll then pack the object class into the buf class and read
283 the updated values out from it to validate if the values are mutated as
James Kuszmaul8e62b022022-03-22 09:33:25 -0700284 expected.
285 """
Austin Schuh272c6132020-11-14 16:37:52 -0800286
James Kuszmaul8e62b022022-03-22 09:33:25 -0700287 def setUp(self, *args, **kwargs):
288 super(TestAllMutableCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
289 # Creates an empty monster flatbuffer, and loads it into the object
290 # class for future tests.
291 b = flatbuffers.Builder(0)
292 _MONSTER.MonsterStart(b)
293 self.monsterT = self._create_and_load_object_class(b)
Austin Schuh272c6132020-11-14 16:37:52 -0800294
James Kuszmaul8e62b022022-03-22 09:33:25 -0700295 def _pack_and_load_buf_class(self, monsterT):
296 """ Packs the object class into a flatbuffer and loads it into a buf
Austin Schuh272c6132020-11-14 16:37:52 -0800297
James Kuszmaul8e62b022022-03-22 09:33:25 -0700298 class.
299 """
300 b = flatbuffers.Builder(0)
301 b.Finish(monsterT.Pack(b))
302 monster = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
303 return monster
Austin Schuh272c6132020-11-14 16:37:52 -0800304
James Kuszmaul8e62b022022-03-22 09:33:25 -0700305 def _create_and_load_object_class(self, b):
306 """ Finishs the creation of a monster flatbuffer and loads it into an
Austin Schuh272c6132020-11-14 16:37:52 -0800307
James Kuszmaul8e62b022022-03-22 09:33:25 -0700308 object class.
309 """
310 gen_mon = _MONSTER.MonsterEnd(b)
311 b.Finish(gen_mon)
312 monster = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
313 monsterT = _MONSTER.MonsterT()
314 monsterT.InitFromObj(monster)
315 return monsterT
Austin Schuh272c6132020-11-14 16:37:52 -0800316
James Kuszmaul8e62b022022-03-22 09:33:25 -0700317 def test_mutate_pos(self):
318 posT = _VEC3.Vec3T()
319 posT.x = 4.0
320 posT.y = 5.0
321 posT.z = 6.0
322 posT.test1 = 6.0
323 posT.test2 = 7
324 test3T = _TEST.TestT()
325 test3T.a = 8
326 test3T.b = 9
327 posT.test3 = test3T
328 self.monsterT.pos = posT
Austin Schuh272c6132020-11-14 16:37:52 -0800329
James Kuszmaul8e62b022022-03-22 09:33:25 -0700330 # Packs the updated values.
331 monster = self._pack_and_load_buf_class(self.monsterT)
Austin Schuh272c6132020-11-14 16:37:52 -0800332
James Kuszmaul8e62b022022-03-22 09:33:25 -0700333 # Checks if values are loaded correctly into the object class.
334 pos = monster.Pos()
Austin Schuh272c6132020-11-14 16:37:52 -0800335
James Kuszmaul8e62b022022-03-22 09:33:25 -0700336 # Verifies the properties of the Vec3.
337 self.assertEqual(pos.X(), 4.0)
338 self.assertEqual(pos.Y(), 5.0)
339 self.assertEqual(pos.Z(), 6.0)
340 self.assertEqual(pos.Test1(), 6.0)
341 self.assertEqual(pos.Test2(), 7)
342 t3 = _TEST.Test()
343 t3 = pos.Test3(t3)
344 self.assertEqual(t3.A(), 8)
345 self.assertEqual(t3.B(), 9)
Austin Schuh272c6132020-11-14 16:37:52 -0800346
James Kuszmaul8e62b022022-03-22 09:33:25 -0700347 def test_mutate_mana(self):
348 self.monsterT.mana = 200
349 monster = self._pack_and_load_buf_class(self.monsterT)
350 self.assertEqual(monster.Mana(), 200)
Austin Schuh272c6132020-11-14 16:37:52 -0800351
James Kuszmaul8e62b022022-03-22 09:33:25 -0700352 def test_mutate_hp(self):
353 self.monsterT.hp = 200
354 monster = self._pack_and_load_buf_class(self.monsterT)
355 self.assertEqual(monster.Hp(), 200)
Austin Schuh272c6132020-11-14 16:37:52 -0800356
James Kuszmaul8e62b022022-03-22 09:33:25 -0700357 def test_mutate_name(self):
358 self.monsterT.name = 'MyMonster'
359 monster = self._pack_and_load_buf_class(self.monsterT)
360 self.assertEqual(monster.Name(), b'MyMonster')
Austin Schuh272c6132020-11-14 16:37:52 -0800361
James Kuszmaul8e62b022022-03-22 09:33:25 -0700362 def test_mutate_inventory(self):
363 self.monsterT.inventory = [1, 7, 8]
364 monster = self._pack_and_load_buf_class(self.monsterT)
365 self.assertEqual(monster.Inventory(0), 1)
366 self.assertEqual(monster.Inventory(1), 7)
367 self.assertEqual(monster.Inventory(2), 8)
Austin Schuh272c6132020-11-14 16:37:52 -0800368
James Kuszmaul8e62b022022-03-22 09:33:25 -0700369 def test_empty_inventory(self):
370 self.monsterT.inventory = []
371 monster = self._pack_and_load_buf_class(self.monsterT)
372 self.assertFalse(monster.InventoryIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800373
James Kuszmaul8e62b022022-03-22 09:33:25 -0700374 def test_mutate_color(self):
375 self.monsterT.color = _COLOR.Color.Red
376 monster = self._pack_and_load_buf_class(self.monsterT)
377 self.assertEqual(monster.Color(), _COLOR.Color.Red)
Austin Schuh272c6132020-11-14 16:37:52 -0800378
James Kuszmaul8e62b022022-03-22 09:33:25 -0700379 def test_mutate_testtype(self):
380 self.monsterT.testType = _ANY.Any.Monster
381 monster = self._pack_and_load_buf_class(self.monsterT)
382 self.assertEqual(monster.TestType(), _ANY.Any.Monster)
Austin Schuh272c6132020-11-14 16:37:52 -0800383
James Kuszmaul8e62b022022-03-22 09:33:25 -0700384 def test_mutate_test(self):
385 testT = _MONSTER.MonsterT()
386 testT.hp = 200
387 self.monsterT.test = testT
388 monster = self._pack_and_load_buf_class(self.monsterT)
389 # Initializes a Table from a union field Test(...).
390 table = monster.Test()
Austin Schuh272c6132020-11-14 16:37:52 -0800391
James Kuszmaul8e62b022022-03-22 09:33:25 -0700392 # Initializes a Monster from the Table from the union.
393 test_monster = _MONSTER.Monster()
394 test_monster.Init(table.Bytes, table.Pos)
395 self.assertEqual(test_monster.Hp(), 200)
Austin Schuh272c6132020-11-14 16:37:52 -0800396
James Kuszmaul8e62b022022-03-22 09:33:25 -0700397 def test_mutate_test4(self):
398 test0T = _TEST.TestT()
399 test0T.a = 10
400 test0T.b = 20
401 test1T = _TEST.TestT()
402 test1T.a = 30
403 test1T.b = 40
404 self.monsterT.test4 = [test0T, test1T]
Austin Schuh272c6132020-11-14 16:37:52 -0800405
James Kuszmaul8e62b022022-03-22 09:33:25 -0700406 monster = self._pack_and_load_buf_class(self.monsterT)
407 test0 = monster.Test4(0)
408 self.assertEqual(test0.A(), 10)
409 self.assertEqual(test0.B(), 20)
410 test1 = monster.Test4(1)
411 self.assertEqual(test1.A(), 30)
412 self.assertEqual(test1.B(), 40)
Austin Schuh272c6132020-11-14 16:37:52 -0800413
James Kuszmaul8e62b022022-03-22 09:33:25 -0700414 def test_empty_test4(self):
415 self.monsterT.test4 = []
416 monster = self._pack_and_load_buf_class(self.monsterT)
417 self.assertFalse(monster.Test4IsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800418
James Kuszmaul8e62b022022-03-22 09:33:25 -0700419 def test_mutate_testarrayofstring(self):
420 self.monsterT.testarrayofstring = []
421 self.monsterT.testarrayofstring.append('test1')
422 self.monsterT.testarrayofstring.append('test2')
423 monster = self._pack_and_load_buf_class(self.monsterT)
424 self.assertEqual(monster.Testarrayofstring(0), b'test1')
425 self.assertEqual(monster.Testarrayofstring(1), b'test2')
Austin Schuh272c6132020-11-14 16:37:52 -0800426
James Kuszmaul8e62b022022-03-22 09:33:25 -0700427 def test_empty_testarrayofstring(self):
428 self.monsterT.testarrayofstring = []
429 monster = self._pack_and_load_buf_class(self.monsterT)
430 self.assertFalse(monster.TestarrayofstringIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800431
James Kuszmaul8e62b022022-03-22 09:33:25 -0700432 def test_mutate_testarrayoftables(self):
433 monsterT0 = _MONSTER.MonsterT()
434 monsterT0.hp = 200
435 monsterT1 = _MONSTER.MonsterT()
436 monsterT1.hp = 400
437 self.monsterT.testarrayoftables = []
438 self.monsterT.testarrayoftables.append(monsterT0)
439 self.monsterT.testarrayoftables.append(monsterT1)
440 monster = self._pack_and_load_buf_class(self.monsterT)
441 self.assertEqual(monster.Testarrayoftables(0).Hp(), 200)
442 self.assertEqual(monster.Testarrayoftables(1).Hp(), 400)
Austin Schuh272c6132020-11-14 16:37:52 -0800443
James Kuszmaul8e62b022022-03-22 09:33:25 -0700444 def test_empty_testarrayoftables(self):
445 self.monsterT.testarrayoftables = []
446 monster = self._pack_and_load_buf_class(self.monsterT)
447 self.assertFalse(monster.TestarrayoftablesIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800448
James Kuszmaul8e62b022022-03-22 09:33:25 -0700449 def test_mutate_enemy(self):
450 monsterT = _MONSTER.MonsterT()
451 monsterT.hp = 200
452 self.monsterT.enemy = monsterT
453 monster = self._pack_and_load_buf_class(self.monsterT)
454 self.assertEqual(monster.Enemy().Hp(), 200)
Austin Schuh272c6132020-11-14 16:37:52 -0800455
James Kuszmaul8e62b022022-03-22 09:33:25 -0700456 def test_mutate_testnestedflatbuffer(self):
457 self.monsterT.testnestedflatbuffer = [8, 2, 4]
458 monster = self._pack_and_load_buf_class(self.monsterT)
459 self.assertEqual(monster.Testnestedflatbuffer(0), 8)
460 self.assertEqual(monster.Testnestedflatbuffer(1), 2)
461 self.assertEqual(monster.Testnestedflatbuffer(2), 4)
Austin Schuh272c6132020-11-14 16:37:52 -0800462
James Kuszmaul8e62b022022-03-22 09:33:25 -0700463 def test_empty_testnestedflatbuffer(self):
464 self.monsterT.testnestedflatbuffer = []
465 monster = self._pack_and_load_buf_class(self.monsterT)
466 self.assertFalse(monster.TestnestedflatbufferIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800467
James Kuszmaul8e62b022022-03-22 09:33:25 -0700468 def test_mutate_testbool(self):
469 self.monsterT.testbool = True
470 monster = self._pack_and_load_buf_class(self.monsterT)
471 self.assertTrue(monster.Testbool())
Austin Schuh272c6132020-11-14 16:37:52 -0800472
James Kuszmaul8e62b022022-03-22 09:33:25 -0700473 def test_mutate_testhashes(self):
474 self.monsterT.testhashs32Fnv1 = 1
475 self.monsterT.testhashu32Fnv1 = 2
476 self.monsterT.testhashs64Fnv1 = 3
477 self.monsterT.testhashu64Fnv1 = 4
478 self.monsterT.testhashs32Fnv1a = 5
479 self.monsterT.testhashu32Fnv1a = 6
480 self.monsterT.testhashs64Fnv1a = 7
481 self.monsterT.testhashu64Fnv1a = 8
482 monster = self._pack_and_load_buf_class(self.monsterT)
483 self.assertEqual(monster.Testhashs32Fnv1(), 1)
484 self.assertEqual(monster.Testhashu32Fnv1(), 2)
485 self.assertEqual(monster.Testhashs64Fnv1(), 3)
486 self.assertEqual(monster.Testhashu64Fnv1(), 4)
487 self.assertEqual(monster.Testhashs32Fnv1a(), 5)
488 self.assertEqual(monster.Testhashu32Fnv1a(), 6)
489 self.assertEqual(monster.Testhashs64Fnv1a(), 7)
490 self.assertEqual(monster.Testhashu64Fnv1a(), 8)
Austin Schuh272c6132020-11-14 16:37:52 -0800491
James Kuszmaul8e62b022022-03-22 09:33:25 -0700492 def test_mutate_testarrayofbools(self):
493 self.monsterT.testarrayofbools = []
494 self.monsterT.testarrayofbools.append(True)
495 self.monsterT.testarrayofbools.append(True)
496 self.monsterT.testarrayofbools.append(False)
497 monster = self._pack_and_load_buf_class(self.monsterT)
498 self.assertEqual(monster.Testarrayofbools(0), True)
499 self.assertEqual(monster.Testarrayofbools(1), True)
500 self.assertEqual(monster.Testarrayofbools(2), False)
Austin Schuh272c6132020-11-14 16:37:52 -0800501
James Kuszmaul8e62b022022-03-22 09:33:25 -0700502 def test_empty_testarrayofbools(self):
503 self.monsterT.testarrayofbools = []
504 monster = self._pack_and_load_buf_class(self.monsterT)
505 self.assertFalse(monster.TestarrayofboolsIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800506
James Kuszmaul8e62b022022-03-22 09:33:25 -0700507 def test_mutate_testf(self):
508 self.monsterT.testf = 2.0
509 monster = self._pack_and_load_buf_class(self.monsterT)
510 self.assertEqual(monster.Testf(), 2.0)
Austin Schuh272c6132020-11-14 16:37:52 -0800511
James Kuszmaul8e62b022022-03-22 09:33:25 -0700512 def test_mutate_vectoroflongs(self):
513 self.monsterT.vectorOfLongs = []
514 self.monsterT.vectorOfLongs.append(1)
515 self.monsterT.vectorOfLongs.append(100)
516 self.monsterT.vectorOfLongs.append(10000)
517 self.monsterT.vectorOfLongs.append(1000000)
518 self.monsterT.vectorOfLongs.append(100000000)
519 monster = self._pack_and_load_buf_class(self.monsterT)
520 self.assertEqual(monster.VectorOfLongs(0), 1)
521 self.assertEqual(monster.VectorOfLongs(1), 100)
522 self.assertEqual(monster.VectorOfLongs(2), 10000)
523 self.assertEqual(monster.VectorOfLongs(3), 1000000)
524 self.assertEqual(monster.VectorOfLongs(4), 100000000)
Austin Schuh272c6132020-11-14 16:37:52 -0800525
James Kuszmaul8e62b022022-03-22 09:33:25 -0700526 def test_empty_vectoroflongs(self):
527 self.monsterT.vectorOfLongs = []
528 monster = self._pack_and_load_buf_class(self.monsterT)
529 self.assertFalse(monster.VectorOfLongsIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800530
James Kuszmaul8e62b022022-03-22 09:33:25 -0700531 def test_mutate_vectorofdoubles(self):
532 self.monsterT.vectorOfDoubles = []
533 self.monsterT.vectorOfDoubles.append(-1.7976931348623157e+308)
534 self.monsterT.vectorOfDoubles.append(0)
535 self.monsterT.vectorOfDoubles.append(1.7976931348623157e+308)
536 monster = self._pack_and_load_buf_class(self.monsterT)
537 self.assertEqual(monster.VectorOfDoubles(0), -1.7976931348623157e+308)
538 self.assertEqual(monster.VectorOfDoubles(1), 0)
539 self.assertEqual(monster.VectorOfDoubles(2), 1.7976931348623157e+308)
Austin Schuh272c6132020-11-14 16:37:52 -0800540
James Kuszmaul8e62b022022-03-22 09:33:25 -0700541 def test_empty_vectorofdoubles(self):
542 self.monsterT.vectorOfDoubles = []
543 monster = self._pack_and_load_buf_class(self.monsterT)
544 self.assertFalse(monster.VectorOfDoublesIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800545
James Kuszmaul8e62b022022-03-22 09:33:25 -0700546 def test_mutate_parentnamespacetest(self):
547 self.monsterT.parentNamespaceTest = _IN_PARENT_NAMESPACE.InParentNamespaceT(
548 )
549 monster = self._pack_and_load_buf_class(self.monsterT)
550 self.assertTrue(
551 isinstance(monster.ParentNamespaceTest(),
552 _IN_PARENT_NAMESPACE.InParentNamespace))
553
554 def test_mutate_vectorofEnums(self):
555 self.monsterT.vectorOfEnums = []
556 self.monsterT.vectorOfEnums.append(_COLOR.Color.Red)
557 self.monsterT.vectorOfEnums.append(_COLOR.Color.Blue)
558 self.monsterT.vectorOfEnums.append(_COLOR.Color.Red)
559 monster = self._pack_and_load_buf_class(self.monsterT)
560 self.assertEqual(monster.VectorOfEnums(0), _COLOR.Color.Red)
561 self.assertEqual(monster.VectorOfEnums(1), _COLOR.Color.Blue)
562 self.assertEqual(monster.VectorOfEnums(2), _COLOR.Color.Red)
563
564 def test_empty_vectorofEnums(self):
565 self.monsterT.vectorOfEnums = []
566 monster = self._pack_and_load_buf_class(self.monsterT)
567 self.assertFalse(monster.VectorOfEnumsIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -0800568
569
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700570def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700571 """ CheckReadBuffer checks that the given buffer is evaluated correctly
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700572
James Kuszmaul8e62b022022-03-22 09:33:25 -0700573 as the example Monster.
574 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700575
James Kuszmaul8e62b022022-03-22 09:33:25 -0700576 def asserter(stmt):
577 """ An assertion helper that is separated from TestCase classes. """
578 if not stmt:
579 raise AssertionError('CheckReadBuffer case failed')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700580
James Kuszmaul8e62b022022-03-22 09:33:25 -0700581 if file_identifier:
582 # test prior to removal of size_prefix
583 asserter(
584 util.GetBufferIdentifier(buf, offset, size_prefixed=sizePrefix) ==
585 file_identifier)
586 asserter(
587 util.BufferHasIdentifier(
588 buf,
589 offset,
590 file_identifier=file_identifier,
591 size_prefixed=sizePrefix))
592 asserter(
593 _MONSTER.Monster.MonsterBufferHasIdentifier(
594 buf, offset, size_prefixed=sizePrefix))
595 if sizePrefix:
596 size = util.GetSizePrefix(buf, offset)
597 asserter(size == len(buf[offset:]) - 4)
598 buf, offset = util.RemoveSizePrefix(buf, offset)
599 if file_identifier:
600 asserter(_MONSTER.Monster.MonsterBufferHasIdentifier(buf, offset))
601 else:
602 asserter(not _MONSTER.Monster.MonsterBufferHasIdentifier(buf, offset))
603 monster = _MONSTER.Monster.GetRootAs(buf, offset)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700604
James Kuszmaul8e62b022022-03-22 09:33:25 -0700605 asserter(monster.Hp() == 80)
606 asserter(monster.Mana() == 150)
607 asserter(monster.Name() == b'MyMonster')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700608
James Kuszmaul8e62b022022-03-22 09:33:25 -0700609 # initialize a Vec3 from Pos()
610 vec = monster.Pos()
611 asserter(vec is not None)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700612
James Kuszmaul8e62b022022-03-22 09:33:25 -0700613 # verify the properties of the Vec3
614 asserter(vec.X() == 1.0)
615 asserter(vec.Y() == 2.0)
616 asserter(vec.Z() == 3.0)
617 asserter(vec.Test1() == 3.0)
618 asserter(vec.Test2() == 2)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700619
James Kuszmaul8e62b022022-03-22 09:33:25 -0700620 # initialize a Test from Test3(...)
621 t = _TEST.Test()
622 t = vec.Test3(t)
623 asserter(t is not None)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700624
James Kuszmaul8e62b022022-03-22 09:33:25 -0700625 # verify the properties of the Test
626 asserter(t.A() == 5)
627 asserter(t.B() == 6)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700628
James Kuszmaul8e62b022022-03-22 09:33:25 -0700629 # verify that the enum code matches the enum declaration:
630 union_type = _ANY.Any
631 asserter(monster.TestType() == union_type.Monster)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700632
James Kuszmaul8e62b022022-03-22 09:33:25 -0700633 # initialize a Table from a union field Test(...)
634 table2 = monster.Test()
635 asserter(type(table2) is flatbuffers.table.Table)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700636
James Kuszmaul8e62b022022-03-22 09:33:25 -0700637 # initialize a Monster from the Table from the union
638 monster2 = _MONSTER.Monster()
639 monster2.Init(table2.Bytes, table2.Pos)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700640
James Kuszmaul8e62b022022-03-22 09:33:25 -0700641 asserter(monster2.Name() == b'Fred')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700642
James Kuszmaul8e62b022022-03-22 09:33:25 -0700643 # iterate through the first monster's inventory:
644 asserter(monster.InventoryLength() == 5)
645 asserter(not monster.InventoryIsNone())
646
647 invsum = 0
648 for i in compat_range(monster.InventoryLength()):
649 v = monster.Inventory(i)
650 invsum += int(v)
651 asserter(invsum == 10)
652
653 for i in range(5):
654 asserter(monster.VectorOfLongs(i) == 10**(i * 2))
655
656 asserter(not monster.VectorOfDoublesIsNone())
657 asserter(([-1.7976931348623157e+308, 0, 1.7976931348623157e+308] == [
658 monster.VectorOfDoubles(i) for i in range(monster.VectorOfDoublesLength())
659 ]))
660
661 try:
662 imp.find_module('numpy')
663 # if numpy exists, then we should be able to get the
664 # vector as a numpy array
665 import numpy as np
666
667 asserter(monster.InventoryAsNumpy().sum() == 10)
668 asserter(monster.InventoryAsNumpy().dtype == np.dtype('uint8'))
669
670 VectorOfLongs = monster.VectorOfLongsAsNumpy()
671 asserter(VectorOfLongs.dtype == np.dtype('int64'))
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700672 for i in range(5):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700673 asserter(VectorOfLongs[i] == 10**(i * 2))
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700674
James Kuszmaul8e62b022022-03-22 09:33:25 -0700675 VectorOfDoubles = monster.VectorOfDoublesAsNumpy()
676 asserter(VectorOfDoubles.dtype == np.dtype('float64'))
677 asserter(VectorOfDoubles[0] == np.finfo('float64').min)
678 asserter(VectorOfDoubles[1] == 0.0)
679 asserter(VectorOfDoubles[2] == np.finfo('float64').max)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700680
James Kuszmaul8e62b022022-03-22 09:33:25 -0700681 except ImportError:
682 # If numpy does not exist, trying to get vector as numpy
683 # array should raise NumpyRequiredForThisFeature. The way
684 # assertRaises has been implemented prevents us from
685 # asserting this error is raised outside of a test case.
686 pass
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700687
James Kuszmaul8e62b022022-03-22 09:33:25 -0700688 asserter(monster.Test4Length() == 2)
689 asserter(not monster.Test4IsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700690
James Kuszmaul8e62b022022-03-22 09:33:25 -0700691 # create a 'Test' object and populate it:
692 test0 = monster.Test4(0)
693 asserter(type(test0) is _TEST.Test)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700694
James Kuszmaul8e62b022022-03-22 09:33:25 -0700695 test1 = monster.Test4(1)
696 asserter(type(test1) is _TEST.Test)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700697
James Kuszmaul8e62b022022-03-22 09:33:25 -0700698 # the position of test0 and test1 are swapped in monsterdata_java_wire
699 # and monsterdata_test_wire, so ignore ordering
700 v0 = test0.A()
701 v1 = test0.B()
702 v2 = test1.A()
703 v3 = test1.B()
704 sumtest12 = int(v0) + int(v1) + int(v2) + int(v3)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700705
James Kuszmaul8e62b022022-03-22 09:33:25 -0700706 asserter(sumtest12 == 100)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700707
James Kuszmaul8e62b022022-03-22 09:33:25 -0700708 asserter(not monster.TestarrayofstringIsNone())
709 asserter(monster.TestarrayofstringLength() == 2)
710 asserter(monster.Testarrayofstring(0) == b'test1')
711 asserter(monster.Testarrayofstring(1) == b'test2')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700712
James Kuszmaul8e62b022022-03-22 09:33:25 -0700713 asserter(monster.TestarrayoftablesIsNone())
714 asserter(monster.TestarrayoftablesLength() == 0)
715 asserter(monster.TestnestedflatbufferIsNone())
716 asserter(monster.TestnestedflatbufferLength() == 0)
717 asserter(monster.Testempty() is None)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700718
719
720class TestFuzz(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700721 """ Low level stress/fuzz test: serialize/deserialize a variety of
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700722
James Kuszmaul8e62b022022-03-22 09:33:25 -0700723 different kinds of data in different combinations
724 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700725
James Kuszmaul8e62b022022-03-22 09:33:25 -0700726 binary_type = compat.binary_types[0] # this will always exist
727 ofInt32Bytes = binary_type([0x83, 0x33, 0x33, 0x33])
728 ofInt64Bytes = binary_type([0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44])
729 overflowingInt32Val = flatbuffers.encode.Get(flatbuffers.packer.int32,
730 ofInt32Bytes, 0)
731 overflowingInt64Val = flatbuffers.encode.Get(flatbuffers.packer.int64,
732 ofInt64Bytes, 0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700733
James Kuszmaul8e62b022022-03-22 09:33:25 -0700734 # Values we're testing against: chosen to ensure no bits get chopped
735 # off anywhere, and also be different from eachother.
736 boolVal = True
737 int8Val = N.Int8Flags.py_type(-127) # 0x81
738 uint8Val = N.Uint8Flags.py_type(0xFF)
739 int16Val = N.Int16Flags.py_type(-32222) # 0x8222
740 uint16Val = N.Uint16Flags.py_type(0xFEEE)
741 int32Val = N.Int32Flags.py_type(overflowingInt32Val)
742 uint32Val = N.Uint32Flags.py_type(0xFDDDDDDD)
743 int64Val = N.Int64Flags.py_type(overflowingInt64Val)
744 uint64Val = N.Uint64Flags.py_type(0xFCCCCCCCCCCCCCCC)
745 # Python uses doubles, so force it here
746 float32Val = N.Float32Flags.py_type(ctypes.c_float(3.14159).value)
747 float64Val = N.Float64Flags.py_type(3.14159265359)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700748
James Kuszmaul8e62b022022-03-22 09:33:25 -0700749 def test_fuzz(self):
750 return self.check_once(11, 100)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700751
James Kuszmaul8e62b022022-03-22 09:33:25 -0700752 def check_once(self, fuzzFields, fuzzObjects):
753 testValuesMax = 11 # hardcoded to the number of scalar types
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700754
James Kuszmaul8e62b022022-03-22 09:33:25 -0700755 builder = flatbuffers.Builder(0)
756 l = LCG()
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700757
James Kuszmaul8e62b022022-03-22 09:33:25 -0700758 objects = [0 for _ in compat_range(fuzzObjects)]
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700759
James Kuszmaul8e62b022022-03-22 09:33:25 -0700760 # Generate fuzzObjects random objects each consisting of
761 # fuzzFields fields, each of a random type.
762 for i in compat_range(fuzzObjects):
763 builder.StartObject(fuzzFields)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700764
James Kuszmaul8e62b022022-03-22 09:33:25 -0700765 for j in compat_range(fuzzFields):
766 choice = int(l.Next()) % testValuesMax
767 if choice == 0:
768 builder.PrependBoolSlot(int(j), self.boolVal, False)
769 elif choice == 1:
770 builder.PrependInt8Slot(int(j), self.int8Val, 0)
771 elif choice == 2:
772 builder.PrependUint8Slot(int(j), self.uint8Val, 0)
773 elif choice == 3:
774 builder.PrependInt16Slot(int(j), self.int16Val, 0)
775 elif choice == 4:
776 builder.PrependUint16Slot(int(j), self.uint16Val, 0)
777 elif choice == 5:
778 builder.PrependInt32Slot(int(j), self.int32Val, 0)
779 elif choice == 6:
780 builder.PrependUint32Slot(int(j), self.uint32Val, 0)
781 elif choice == 7:
782 builder.PrependInt64Slot(int(j), self.int64Val, 0)
783 elif choice == 8:
784 builder.PrependUint64Slot(int(j), self.uint64Val, 0)
785 elif choice == 9:
786 builder.PrependFloat32Slot(int(j), self.float32Val, 0)
787 elif choice == 10:
788 builder.PrependFloat64Slot(int(j), self.float64Val, 0)
789 else:
790 raise RuntimeError('unreachable')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700791
James Kuszmaul8e62b022022-03-22 09:33:25 -0700792 off = builder.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700793
James Kuszmaul8e62b022022-03-22 09:33:25 -0700794 # store the offset from the end of the builder buffer,
795 # since it will keep growing:
796 objects[i] = off
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700797
James Kuszmaul8e62b022022-03-22 09:33:25 -0700798 # Do some bookkeeping to generate stats on fuzzes:
799 stats = defaultdict(int)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700800
James Kuszmaul8e62b022022-03-22 09:33:25 -0700801 def check(table, desc, want, got):
802 stats[desc] += 1
803 self.assertEqual(want, got, '%s != %s, %s' % (want, got, desc))
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700804
James Kuszmaul8e62b022022-03-22 09:33:25 -0700805 l = LCG() # Reset.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700806
James Kuszmaul8e62b022022-03-22 09:33:25 -0700807 # Test that all objects we generated are readable and return the
808 # expected values. We generate random objects in the same order
809 # so this is deterministic.
810 for i in compat_range(fuzzObjects):
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700811
James Kuszmaul8e62b022022-03-22 09:33:25 -0700812 table = flatbuffers.table.Table(builder.Bytes,
813 len(builder.Bytes) - objects[i])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700814
James Kuszmaul8e62b022022-03-22 09:33:25 -0700815 for j in compat_range(fuzzFields):
816 field_count = flatbuffers.builder.VtableMetadataFields + j
817 f = N.VOffsetTFlags.py_type(field_count * N.VOffsetTFlags.bytewidth)
818 choice = int(l.Next()) % testValuesMax
819
820 if choice == 0:
821 check(table, 'bool', self.boolVal,
822 table.GetSlot(f, False, N.BoolFlags))
823 elif choice == 1:
824 check(table, 'int8', self.int8Val, table.GetSlot(f, 0, N.Int8Flags))
825 elif choice == 2:
826 check(table, 'uint8', self.uint8Val,
827 table.GetSlot(f, 0, N.Uint8Flags))
828 elif choice == 3:
829 check(table, 'int16', self.int16Val,
830 table.GetSlot(f, 0, N.Int16Flags))
831 elif choice == 4:
832 check(table, 'uint16', self.uint16Val,
833 table.GetSlot(f, 0, N.Uint16Flags))
834 elif choice == 5:
835 check(table, 'int32', self.int32Val,
836 table.GetSlot(f, 0, N.Int32Flags))
837 elif choice == 6:
838 check(table, 'uint32', self.uint32Val,
839 table.GetSlot(f, 0, N.Uint32Flags))
840 elif choice == 7:
841 check(table, 'int64', self.int64Val,
842 table.GetSlot(f, 0, N.Int64Flags))
843 elif choice == 8:
844 check(table, 'uint64', self.uint64Val,
845 table.GetSlot(f, 0, N.Uint64Flags))
846 elif choice == 9:
847 check(table, 'float32', self.float32Val,
848 table.GetSlot(f, 0, N.Float32Flags))
849 elif choice == 10:
850 check(table, 'float64', self.float64Val,
851 table.GetSlot(f, 0, N.Float64Flags))
852 else:
853 raise RuntimeError('unreachable')
854
855 # If enough checks were made, verify that all scalar types were used:
856 self.assertEqual(testValuesMax, len(stats),
857 'fuzzing failed to test all scalar types: %s' % stats)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700858
859
860class TestByteLayout(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -0700861 """ TestByteLayout checks the bytes of a Builder in various scenarios. """
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700862
James Kuszmaul8e62b022022-03-22 09:33:25 -0700863 def assertBuilderEquals(self, builder, want_chars_or_ints):
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700864
James Kuszmaul8e62b022022-03-22 09:33:25 -0700865 def integerize(x):
866 if isinstance(x, compat.string_types):
867 return ord(x)
868 return x
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700869
James Kuszmaul8e62b022022-03-22 09:33:25 -0700870 want_ints = list(map(integerize, want_chars_or_ints))
871 want = bytearray(want_ints)
872 got = builder.Bytes[builder.Head():] # use the buffer directly
873 self.assertEqual(want, got)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700874
James Kuszmaul8e62b022022-03-22 09:33:25 -0700875 def test_numbers(self):
876 b = flatbuffers.Builder(0)
877 self.assertBuilderEquals(b, [])
878 b.PrependBool(True)
879 self.assertBuilderEquals(b, [1])
880 b.PrependInt8(-127)
881 self.assertBuilderEquals(b, [129, 1])
882 b.PrependUint8(255)
883 self.assertBuilderEquals(b, [255, 129, 1])
884 b.PrependInt16(-32222)
885 self.assertBuilderEquals(b, [0x22, 0x82, 0, 255, 129, 1]) # first pad
886 b.PrependUint16(0xFEEE)
887 # no pad this time:
888 self.assertBuilderEquals(b, [0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1])
889 b.PrependInt32(-53687092)
890 self.assertBuilderEquals(
891 b, [204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1])
892 b.PrependUint32(0x98765432)
893 self.assertBuilderEquals(b, [
894 0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0,
895 255, 129, 1
896 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700897
James Kuszmaul8e62b022022-03-22 09:33:25 -0700898 def test_numbers64(self):
899 b = flatbuffers.Builder(0)
900 b.PrependUint64(0x1122334455667788)
901 self.assertBuilderEquals(b,
902 [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700903
James Kuszmaul8e62b022022-03-22 09:33:25 -0700904 b = flatbuffers.Builder(0)
905 b.PrependInt64(0x1122334455667788)
906 self.assertBuilderEquals(b,
907 [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700908
James Kuszmaul8e62b022022-03-22 09:33:25 -0700909 def test_1xbyte_vector(self):
910 b = flatbuffers.Builder(0)
911 self.assertBuilderEquals(b, [])
912 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 1, 1)
913 self.assertBuilderEquals(b, [0, 0, 0]) # align to 4bytes
914 b.PrependByte(1)
915 self.assertBuilderEquals(b, [1, 0, 0, 0])
916 b.EndVector()
917 self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700918
James Kuszmaul8e62b022022-03-22 09:33:25 -0700919 def test_2xbyte_vector(self):
920 b = flatbuffers.Builder(0)
921 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 2, 1)
922 self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
923 b.PrependByte(1)
924 self.assertBuilderEquals(b, [1, 0, 0])
925 b.PrependByte(2)
926 self.assertBuilderEquals(b, [2, 1, 0, 0])
927 b.EndVector()
928 self.assertBuilderEquals(b, [2, 0, 0, 0, 2, 1, 0, 0]) # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700929
James Kuszmaul8e62b022022-03-22 09:33:25 -0700930 def test_1xuint16_vector(self):
931 b = flatbuffers.Builder(0)
932 b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 1, 1)
933 self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
934 b.PrependUint16(1)
935 self.assertBuilderEquals(b, [1, 0, 0, 0])
936 b.EndVector()
937 self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700938
James Kuszmaul8e62b022022-03-22 09:33:25 -0700939 def test_2xuint16_vector(self):
940 b = flatbuffers.Builder(0)
941 b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 2, 1)
942 self.assertBuilderEquals(b, []) # align to 4bytes
943 b.PrependUint16(0xABCD)
944 self.assertBuilderEquals(b, [0xCD, 0xAB])
945 b.PrependUint16(0xDCBA)
946 self.assertBuilderEquals(b, [0xBA, 0xDC, 0xCD, 0xAB])
947 b.EndVector()
948 self.assertBuilderEquals(b, [2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700949
James Kuszmaul8e62b022022-03-22 09:33:25 -0700950 def test_create_ascii_string(self):
951 b = flatbuffers.Builder(0)
952 b.CreateString(u'foo', encoding='ascii')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700953
James Kuszmaul8e62b022022-03-22 09:33:25 -0700954 # 0-terminated, no pad:
955 self.assertBuilderEquals(b, [3, 0, 0, 0, 'f', 'o', 'o', 0])
956 b.CreateString(u'moop', encoding='ascii')
957 # 0-terminated, 3-byte pad:
958 self.assertBuilderEquals(b, [
959 4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, 3, 0, 0, 0, 'f', 'o', 'o', 0
960 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700961
James Kuszmaul8e62b022022-03-22 09:33:25 -0700962 def test_create_utf8_string(self):
963 b = flatbuffers.Builder(0)
964 b.CreateString(u'Цлїςσδε')
965 self.assertBuilderEquals(b, '\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97' \
966 '\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700967
James Kuszmaul8e62b022022-03-22 09:33:25 -0700968 b.CreateString(u'フムアムカモケモ')
969 self.assertBuilderEquals(b, '\x18\x00\x00\x00\xef\xbe\x8c\xef\xbe\x91' \
970 '\xef\xbd\xb1\xef\xbe\x91\xef\xbd\xb6\xef\xbe\x93\xef\xbd\xb9\xef' \
971 '\xbe\x93\x00\x00\x00\x00\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97' \
972 '\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00')
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700973
James Kuszmaul8e62b022022-03-22 09:33:25 -0700974 def test_create_arbitrary_string(self):
975 b = flatbuffers.Builder(0)
976 s = '\x01\x02\x03'
977 b.CreateString(s) # Default encoding is utf-8.
978 # 0-terminated, no pad:
979 self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
980 s2 = '\x04\x05\x06\x07'
981 b.CreateString(s2) # Default encoding is utf-8.
982 # 0-terminated, 3-byte pad:
983 self.assertBuilderEquals(
984 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 -0700985
James Kuszmaul8e62b022022-03-22 09:33:25 -0700986 def test_create_byte_vector(self):
987 b = flatbuffers.Builder(0)
988 b.CreateByteVector(b'')
989 # 0-byte pad:
990 self.assertBuilderEquals(b, [0, 0, 0, 0])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700991
James Kuszmaul8e62b022022-03-22 09:33:25 -0700992 b = flatbuffers.Builder(0)
993 b.CreateByteVector(b'\x01\x02\x03')
994 # 1-byte pad:
995 self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700996
James Kuszmaul8e62b022022-03-22 09:33:25 -0700997 def test_create_numpy_vector_int8(self):
998 try:
999 imp.find_module('numpy')
1000 # if numpy exists, then we should be able to get the
1001 # vector as a numpy array
1002 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001003
James Kuszmaul8e62b022022-03-22 09:33:25 -07001004 # Systems endian:
1005 b = flatbuffers.Builder(0)
1006 x = np.array([1, 2, -3], dtype=np.int8)
1007 b.CreateNumpyVector(x)
1008 self.assertBuilderEquals(
1009 b,
1010 [
1011 3,
1012 0,
1013 0,
1014 0, # vector length
1015 1,
1016 2,
1017 256 - 3,
1018 0 # vector value + padding
1019 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001020
James Kuszmaul8e62b022022-03-22 09:33:25 -07001021 # Reverse endian:
1022 b = flatbuffers.Builder(0)
1023 x_other_endian = x.byteswap().newbyteorder()
1024 b.CreateNumpyVector(x_other_endian)
1025 self.assertBuilderEquals(
1026 b,
1027 [
1028 3,
1029 0,
1030 0,
1031 0, # vector length
1032 1,
1033 2,
1034 256 - 3,
1035 0 # vector value + padding
1036 ])
1037 except ImportError:
1038 b = flatbuffers.Builder(0)
1039 x = 0
1040 assertRaises(self, lambda: b.CreateNumpyVector(x),
1041 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001042
James Kuszmaul8e62b022022-03-22 09:33:25 -07001043 def test_create_numpy_vector_uint16(self):
1044 try:
1045 imp.find_module('numpy')
1046 # if numpy exists, then we should be able to get the
1047 # vector as a numpy array
1048 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001049
James Kuszmaul8e62b022022-03-22 09:33:25 -07001050 # Systems endian:
1051 b = flatbuffers.Builder(0)
1052 x = np.array([1, 2, 312], dtype=np.uint16)
1053 b.CreateNumpyVector(x)
1054 self.assertBuilderEquals(
1055 b,
1056 [
1057 3,
1058 0,
1059 0,
1060 0, # vector length
1061 1,
1062 0, # 1
1063 2,
1064 0, # 2
1065 312 - 256,
1066 1, # 312
1067 0,
1068 0 # padding
1069 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001070
James Kuszmaul8e62b022022-03-22 09:33:25 -07001071 # Reverse endian:
1072 b = flatbuffers.Builder(0)
1073 x_other_endian = x.byteswap().newbyteorder()
1074 b.CreateNumpyVector(x_other_endian)
1075 self.assertBuilderEquals(
1076 b,
1077 [
1078 3,
1079 0,
1080 0,
1081 0, # vector length
1082 1,
1083 0, # 1
1084 2,
1085 0, # 2
1086 312 - 256,
1087 1, # 312
1088 0,
1089 0 # padding
1090 ])
1091 except ImportError:
1092 b = flatbuffers.Builder(0)
1093 x = 0
1094 assertRaises(self, lambda: b.CreateNumpyVector(x),
1095 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001096
James Kuszmaul8e62b022022-03-22 09:33:25 -07001097 def test_create_numpy_vector_int64(self):
1098 try:
1099 imp.find_module('numpy')
1100 # if numpy exists, then we should be able to get the
1101 # vector as a numpy array
1102 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001103
James Kuszmaul8e62b022022-03-22 09:33:25 -07001104 # Systems endian:
1105 b = flatbuffers.Builder(0)
1106 x = np.array([1, 2, -12], dtype=np.int64)
1107 b.CreateNumpyVector(x)
1108 self.assertBuilderEquals(
1109 b,
1110 [
1111 3,
1112 0,
1113 0,
1114 0, # vector length
1115 1,
1116 0,
1117 0,
1118 0,
1119 0,
1120 0,
1121 0,
1122 0, # 1
1123 2,
1124 0,
1125 0,
1126 0,
1127 0,
1128 0,
1129 0,
1130 0, # 2
1131 256 - 12,
1132 255,
1133 255,
1134 255,
1135 255,
1136 255,
1137 255,
1138 255 # -12
1139 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001140
James Kuszmaul8e62b022022-03-22 09:33:25 -07001141 # Reverse endian:
1142 b = flatbuffers.Builder(0)
1143 x_other_endian = x.byteswap().newbyteorder()
1144 b.CreateNumpyVector(x_other_endian)
1145 self.assertBuilderEquals(
1146 b,
1147 [
1148 3,
1149 0,
1150 0,
1151 0, # vector length
1152 1,
1153 0,
1154 0,
1155 0,
1156 0,
1157 0,
1158 0,
1159 0, # 1
1160 2,
1161 0,
1162 0,
1163 0,
1164 0,
1165 0,
1166 0,
1167 0, # 2
1168 256 - 12,
1169 255,
1170 255,
1171 255,
1172 255,
1173 255,
1174 255,
1175 255 # -12
1176 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001177
James Kuszmaul8e62b022022-03-22 09:33:25 -07001178 except ImportError:
1179 b = flatbuffers.Builder(0)
1180 x = 0
1181 assertRaises(self, lambda: b.CreateNumpyVector(x),
1182 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001183
James Kuszmaul8e62b022022-03-22 09:33:25 -07001184 def test_create_numpy_vector_float32(self):
1185 try:
1186 imp.find_module('numpy')
1187 # if numpy exists, then we should be able to get the
1188 # vector as a numpy array
1189 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001190
James Kuszmaul8e62b022022-03-22 09:33:25 -07001191 # Systems endian:
1192 b = flatbuffers.Builder(0)
1193 x = np.array([1, 2, -12], dtype=np.float32)
1194 b.CreateNumpyVector(x)
1195 self.assertBuilderEquals(
1196 b,
1197 [
1198 3,
1199 0,
1200 0,
1201 0, # vector length
1202 0,
1203 0,
1204 128,
1205 63, # 1
1206 0,
1207 0,
1208 0,
1209 64, # 2
1210 0,
1211 0,
1212 64,
1213 193 # -12
1214 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001215
James Kuszmaul8e62b022022-03-22 09:33:25 -07001216 # Reverse endian:
1217 b = flatbuffers.Builder(0)
1218 x_other_endian = x.byteswap().newbyteorder()
1219 b.CreateNumpyVector(x_other_endian)
1220 self.assertBuilderEquals(
1221 b,
1222 [
1223 3,
1224 0,
1225 0,
1226 0, # vector length
1227 0,
1228 0,
1229 128,
1230 63, # 1
1231 0,
1232 0,
1233 0,
1234 64, # 2
1235 0,
1236 0,
1237 64,
1238 193 # -12
1239 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001240
James Kuszmaul8e62b022022-03-22 09:33:25 -07001241 except ImportError:
1242 b = flatbuffers.Builder(0)
1243 x = 0
1244 assertRaises(self, lambda: b.CreateNumpyVector(x),
1245 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001246
James Kuszmaul8e62b022022-03-22 09:33:25 -07001247 def test_create_numpy_vector_float64(self):
1248 try:
1249 imp.find_module('numpy')
1250 # if numpy exists, then we should be able to get the
1251 # vector as a numpy array
1252 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001253
James Kuszmaul8e62b022022-03-22 09:33:25 -07001254 # Systems endian:
1255 b = flatbuffers.Builder(0)
1256 x = np.array([1, 2, -12], dtype=np.float64)
1257 b.CreateNumpyVector(x)
1258 self.assertBuilderEquals(
1259 b,
1260 [
1261 3,
1262 0,
1263 0,
1264 0, # vector length
1265 0,
1266 0,
1267 0,
1268 0,
1269 0,
1270 0,
1271 240,
1272 63, # 1
1273 0,
1274 0,
1275 0,
1276 0,
1277 0,
1278 0,
1279 0,
1280 64, # 2
1281 0,
1282 0,
1283 0,
1284 0,
1285 0,
1286 0,
1287 40,
1288 192 # -12
1289 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001290
James Kuszmaul8e62b022022-03-22 09:33:25 -07001291 # Reverse endian:
1292 b = flatbuffers.Builder(0)
1293 x_other_endian = x.byteswap().newbyteorder()
1294 b.CreateNumpyVector(x_other_endian)
1295 self.assertBuilderEquals(
1296 b,
1297 [
1298 3,
1299 0,
1300 0,
1301 0, # vector length
1302 0,
1303 0,
1304 0,
1305 0,
1306 0,
1307 0,
1308 240,
1309 63, # 1
1310 0,
1311 0,
1312 0,
1313 0,
1314 0,
1315 0,
1316 0,
1317 64, # 2
1318 0,
1319 0,
1320 0,
1321 0,
1322 0,
1323 0,
1324 40,
1325 192 # -12
1326 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001327
James Kuszmaul8e62b022022-03-22 09:33:25 -07001328 except ImportError:
1329 b = flatbuffers.Builder(0)
1330 x = 0
1331 assertRaises(self, lambda: b.CreateNumpyVector(x),
1332 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001333
James Kuszmaul8e62b022022-03-22 09:33:25 -07001334 def test_create_numpy_vector_bool(self):
1335 try:
1336 imp.find_module('numpy')
1337 # if numpy exists, then we should be able to get the
1338 # vector as a numpy array
1339 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001340
James Kuszmaul8e62b022022-03-22 09:33:25 -07001341 # Systems endian:
1342 b = flatbuffers.Builder(0)
1343 x = np.array([True, False, True], dtype=np.bool)
1344 b.CreateNumpyVector(x)
1345 self.assertBuilderEquals(
1346 b,
1347 [
1348 3,
1349 0,
1350 0,
1351 0, # vector length
1352 1,
1353 0,
1354 1,
1355 0 # vector values + padding
1356 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001357
James Kuszmaul8e62b022022-03-22 09:33:25 -07001358 # Reverse endian:
1359 b = flatbuffers.Builder(0)
1360 x_other_endian = x.byteswap().newbyteorder()
1361 b.CreateNumpyVector(x_other_endian)
1362 self.assertBuilderEquals(
1363 b,
1364 [
1365 3,
1366 0,
1367 0,
1368 0, # vector length
1369 1,
1370 0,
1371 1,
1372 0 # vector values + padding
1373 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001374
James Kuszmaul8e62b022022-03-22 09:33:25 -07001375 except ImportError:
1376 b = flatbuffers.Builder(0)
1377 x = 0
1378 assertRaises(self, lambda: b.CreateNumpyVector(x),
1379 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001380
James Kuszmaul8e62b022022-03-22 09:33:25 -07001381 def test_create_numpy_vector_reject_strings(self):
1382 try:
1383 imp.find_module('numpy')
1384 # if numpy exists, then we should be able to get the
1385 # vector as a numpy array
1386 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001387
James Kuszmaul8e62b022022-03-22 09:33:25 -07001388 # Create String array
1389 b = flatbuffers.Builder(0)
1390 x = np.array(['hello', 'fb', 'testing'])
1391 assertRaises(self, lambda: b.CreateNumpyVector(x), TypeError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001392
James Kuszmaul8e62b022022-03-22 09:33:25 -07001393 except ImportError:
1394 b = flatbuffers.Builder(0)
1395 x = 0
1396 assertRaises(self, lambda: b.CreateNumpyVector(x),
1397 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001398
James Kuszmaul8e62b022022-03-22 09:33:25 -07001399 def test_create_numpy_vector_reject_object(self):
1400 try:
1401 imp.find_module('numpy')
1402 # if numpy exists, then we should be able to get the
1403 # vector as a numpy array
1404 import numpy as np
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001405
James Kuszmaul8e62b022022-03-22 09:33:25 -07001406 # Create String array
1407 b = flatbuffers.Builder(0)
1408 x = np.array([{'m': 0}, {'as': -2.1, 'c': 'c'}])
1409 assertRaises(self, lambda: b.CreateNumpyVector(x), TypeError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001410
James Kuszmaul8e62b022022-03-22 09:33:25 -07001411 except ImportError:
1412 b = flatbuffers.Builder(0)
1413 x = 0
1414 assertRaises(self, lambda: b.CreateNumpyVector(x),
1415 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001416
James Kuszmaul8e62b022022-03-22 09:33:25 -07001417 def test_empty_vtable(self):
1418 b = flatbuffers.Builder(0)
1419 b.StartObject(0)
1420 self.assertBuilderEquals(b, [])
1421 b.EndObject()
1422 self.assertBuilderEquals(b, [4, 0, 4, 0, 4, 0, 0, 0])
1423
1424 def test_vtable_with_one_true_bool(self):
1425 b = flatbuffers.Builder(0)
1426 self.assertBuilderEquals(b, [])
1427 b.StartObject(1)
1428 self.assertBuilderEquals(b, [])
1429 b.PrependBoolSlot(0, True, False)
1430 b.EndObject()
1431 self.assertBuilderEquals(
1432 b,
1433 [
1434 6,
1435 0, # vtable bytes
1436 8,
1437 0, # length of object including vtable offset
1438 7,
1439 0, # start of bool value
1440 6,
1441 0,
1442 0,
1443 0, # offset for start of vtable (int32)
1444 0,
1445 0,
1446 0, # padded to 4 bytes
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001447 1, # bool value
1448 ])
1449
James Kuszmaul8e62b022022-03-22 09:33:25 -07001450 def test_vtable_with_one_default_bool(self):
1451 b = flatbuffers.Builder(0)
1452 self.assertBuilderEquals(b, [])
1453 b.StartObject(1)
1454 self.assertBuilderEquals(b, [])
1455 b.PrependBoolSlot(0, False, False)
1456 b.EndObject()
1457 self.assertBuilderEquals(
1458 b,
1459 [
1460 4,
1461 0, # vtable bytes
1462 4,
1463 0, # end of object from here
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001464 # entry 1 is zero and not stored
James Kuszmaul8e62b022022-03-22 09:33:25 -07001465 4,
1466 0,
1467 0,
1468 0, # offset for start of vtable (int32)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001469 ])
1470
James Kuszmaul8e62b022022-03-22 09:33:25 -07001471 def test_vtable_with_one_int16(self):
1472 b = flatbuffers.Builder(0)
1473 b.StartObject(1)
1474 b.PrependInt16Slot(0, 0x789A, 0)
1475 b.EndObject()
1476 self.assertBuilderEquals(
1477 b,
1478 [
1479 6,
1480 0, # vtable bytes
1481 8,
1482 0, # end of object from here
1483 6,
1484 0, # offset to value
1485 6,
1486 0,
1487 0,
1488 0, # offset for start of vtable (int32)
1489 0,
1490 0, # padding to 4 bytes
1491 0x9A,
1492 0x78,
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001493 ])
1494
James Kuszmaul8e62b022022-03-22 09:33:25 -07001495 def test_vtable_with_two_int16(self):
1496 b = flatbuffers.Builder(0)
1497 b.StartObject(2)
1498 b.PrependInt16Slot(0, 0x3456, 0)
1499 b.PrependInt16Slot(1, 0x789A, 0)
1500 b.EndObject()
1501 self.assertBuilderEquals(
1502 b,
1503 [
1504 8,
1505 0, # vtable bytes
1506 8,
1507 0, # end of object from here
1508 6,
1509 0, # offset to value 0
1510 4,
1511 0, # offset to value 1
1512 8,
1513 0,
1514 0,
1515 0, # offset for start of vtable (int32)
1516 0x9A,
1517 0x78, # value 1
1518 0x56,
1519 0x34, # value 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001520 ])
1521
James Kuszmaul8e62b022022-03-22 09:33:25 -07001522 def test_vtable_with_int16_and_bool(self):
1523 b = flatbuffers.Builder(0)
1524 b.StartObject(2)
1525 b.PrependInt16Slot(0, 0x3456, 0)
1526 b.PrependBoolSlot(1, True, False)
1527 b.EndObject()
1528 self.assertBuilderEquals(
1529 b,
1530 [
1531 8,
1532 0, # vtable bytes
1533 8,
1534 0, # end of object from here
1535 6,
1536 0, # offset to value 0
1537 5,
1538 0, # offset to value 1
1539 8,
1540 0,
1541 0,
1542 0, # offset for start of vtable (int32)
1543 0, # padding
1544 1, # value 1
1545 0x56,
1546 0x34, # value 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001547 ])
1548
James Kuszmaul8e62b022022-03-22 09:33:25 -07001549 def test_vtable_with_empty_vector(self):
1550 b = flatbuffers.Builder(0)
1551 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
1552 vecend = b.EndVector()
1553 b.StartObject(1)
1554 b.PrependUOffsetTRelativeSlot(0, vecend, 0)
1555 b.EndObject()
1556 self.assertBuilderEquals(
1557 b,
1558 [
1559 6,
1560 0, # vtable bytes
1561 8,
1562 0,
1563 4,
1564 0, # offset to vector offset
1565 6,
1566 0,
1567 0,
1568 0, # offset for start of vtable (int32)
1569 4,
1570 0,
1571 0,
1572 0,
1573 0,
1574 0,
1575 0,
1576 0, # length of vector (not in struct)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001577 ])
1578
James Kuszmaul8e62b022022-03-22 09:33:25 -07001579 def test_vtable_with_empty_vector_of_byte_and_some_scalars(self):
1580 b = flatbuffers.Builder(0)
1581 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
1582 vecend = b.EndVector()
1583 b.StartObject(2)
1584 b.PrependInt16Slot(0, 55, 0)
1585 b.PrependUOffsetTRelativeSlot(1, vecend, 0)
1586 b.EndObject()
1587 self.assertBuilderEquals(
1588 b,
1589 [
1590 8,
1591 0, # vtable bytes
1592 12,
1593 0,
1594 10,
1595 0, # offset to value 0
1596 4,
1597 0, # offset to vector offset
1598 8,
1599 0,
1600 0,
1601 0, # vtable loc
1602 8,
1603 0,
1604 0,
1605 0, # value 1
1606 0,
1607 0,
1608 55,
1609 0, # value 0
1610 0,
1611 0,
1612 0,
1613 0, # length of vector (not in struct)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001614 ])
1615
James Kuszmaul8e62b022022-03-22 09:33:25 -07001616 def test_vtable_with_1_int16_and_2vector_of_int16(self):
1617 b = flatbuffers.Builder(0)
1618 b.StartVector(flatbuffers.number_types.Int16Flags.bytewidth, 2, 1)
1619 b.PrependInt16(0x1234)
1620 b.PrependInt16(0x5678)
1621 vecend = b.EndVector()
1622 b.StartObject(2)
1623 b.PrependUOffsetTRelativeSlot(1, vecend, 0)
1624 b.PrependInt16Slot(0, 55, 0)
1625 b.EndObject()
1626 self.assertBuilderEquals(
1627 b,
1628 [
1629 8,
1630 0, # vtable bytes
1631 12,
1632 0, # length of object
1633 6,
1634 0, # start of value 0 from end of vtable
1635 8,
1636 0, # start of value 1 from end of buffer
1637 8,
1638 0,
1639 0,
1640 0, # offset for start of vtable (int32)
1641 0,
1642 0, # padding
1643 55,
1644 0, # value 0
1645 4,
1646 0,
1647 0,
1648 0, # vector position from here
1649 2,
1650 0,
1651 0,
1652 0, # length of vector (uint32)
1653 0x78,
1654 0x56, # vector value 1
1655 0x34,
1656 0x12, # vector value 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001657 ])
1658
James Kuszmaul8e62b022022-03-22 09:33:25 -07001659 def test_vtable_with_1_struct_of_1_int8__1_int16__1_int32(self):
1660 b = flatbuffers.Builder(0)
1661 b.StartObject(1)
1662 b.Prep(4 + 4 + 4, 0)
1663 b.PrependInt8(55)
1664 b.Pad(3)
1665 b.PrependInt16(0x1234)
1666 b.Pad(2)
1667 b.PrependInt32(0x12345678)
1668 structStart = b.Offset()
1669 b.PrependStructSlot(0, structStart, 0)
1670 b.EndObject()
1671 self.assertBuilderEquals(
1672 b,
1673 [
1674 6,
1675 0, # vtable bytes
1676 16,
1677 0, # end of object from here
1678 4,
1679 0, # start of struct from here
1680 6,
1681 0,
1682 0,
1683 0, # offset for start of vtable (int32)
1684 0x78,
1685 0x56,
1686 0x34,
1687 0x12, # value 2
1688 0,
1689 0, # padding
1690 0x34,
1691 0x12, # value 1
1692 0,
1693 0,
1694 0, # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001695 55, # value 0
1696 ])
1697
James Kuszmaul8e62b022022-03-22 09:33:25 -07001698 def test_vtable_with_1_vector_of_2_struct_of_2_int8(self):
1699 b = flatbuffers.Builder(0)
1700 b.StartVector(flatbuffers.number_types.Int8Flags.bytewidth * 2, 2, 1)
1701 b.PrependInt8(33)
1702 b.PrependInt8(44)
1703 b.PrependInt8(55)
1704 b.PrependInt8(66)
1705 vecend = b.EndVector()
1706 b.StartObject(1)
1707 b.PrependUOffsetTRelativeSlot(0, vecend, 0)
1708 b.EndObject()
1709 self.assertBuilderEquals(
1710 b,
1711 [
1712 6,
1713 0, # vtable bytes
1714 8,
1715 0,
1716 4,
1717 0, # offset of vector offset
1718 6,
1719 0,
1720 0,
1721 0, # offset for start of vtable (int32)
1722 4,
1723 0,
1724 0,
1725 0, # vector start offset
1726 2,
1727 0,
1728 0,
1729 0, # vector length
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001730 66, # vector value 1,1
1731 55, # vector value 1,0
1732 44, # vector value 0,1
1733 33, # vector value 0,0
1734 ])
1735
James Kuszmaul8e62b022022-03-22 09:33:25 -07001736 def test_table_with_some_elements(self):
1737 b = flatbuffers.Builder(0)
1738 b.StartObject(2)
1739 b.PrependInt8Slot(0, 33, 0)
1740 b.PrependInt16Slot(1, 66, 0)
1741 off = b.EndObject()
1742 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001743
James Kuszmaul8e62b022022-03-22 09:33:25 -07001744 self.assertBuilderEquals(
1745 b,
1746 [
1747 12,
1748 0,
1749 0,
1750 0, # root of table: points to vtable offset
1751 8,
1752 0, # vtable bytes
1753 8,
1754 0, # end of object from here
1755 7,
1756 0, # start of value 0
1757 4,
1758 0, # start of value 1
1759 8,
1760 0,
1761 0,
1762 0, # offset for start of vtable (int32)
1763 66,
1764 0, # value 1
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001765 0, # padding
1766 33, # value 0
1767 ])
1768
James Kuszmaul8e62b022022-03-22 09:33:25 -07001769 def test__one_unfinished_table_and_one_finished_table(self):
1770 b = flatbuffers.Builder(0)
1771 b.StartObject(2)
1772 b.PrependInt8Slot(0, 33, 0)
1773 b.PrependInt8Slot(1, 44, 0)
1774 off = b.EndObject()
1775 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001776
James Kuszmaul8e62b022022-03-22 09:33:25 -07001777 b.StartObject(3)
1778 b.PrependInt8Slot(0, 55, 0)
1779 b.PrependInt8Slot(1, 66, 0)
1780 b.PrependInt8Slot(2, 77, 0)
1781 off = b.EndObject()
1782 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001783
James Kuszmaul8e62b022022-03-22 09:33:25 -07001784 self.assertBuilderEquals(
1785 b,
1786 [
1787 16,
1788 0,
1789 0,
1790 0, # root of table: points to object
1791 0,
1792 0, # padding
1793 10,
1794 0, # vtable bytes
1795 8,
1796 0, # size of object
1797 7,
1798 0, # start of value 0
1799 6,
1800 0, # start of value 1
1801 5,
1802 0, # start of value 2
1803 10,
1804 0,
1805 0,
1806 0, # offset for start of vtable (int32)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001807 0, # padding
1808 77, # value 2
1809 66, # value 1
1810 55, # value 0
James Kuszmaul8e62b022022-03-22 09:33:25 -07001811 12,
1812 0,
1813 0,
1814 0, # root of table: points to object
1815 8,
1816 0, # vtable bytes
1817 8,
1818 0, # size of object
1819 7,
1820 0, # start of value 0
1821 6,
1822 0, # start of value 1
1823 8,
1824 0,
1825 0,
1826 0, # offset for start of vtable (int32)
1827 0,
1828 0, # padding
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001829 44, # value 1
1830 33, # value 0
1831 ])
1832
James Kuszmaul8e62b022022-03-22 09:33:25 -07001833 def test_a_bunch_of_bools(self):
1834 b = flatbuffers.Builder(0)
1835 b.StartObject(8)
1836 b.PrependBoolSlot(0, True, False)
1837 b.PrependBoolSlot(1, True, False)
1838 b.PrependBoolSlot(2, True, False)
1839 b.PrependBoolSlot(3, True, False)
1840 b.PrependBoolSlot(4, True, False)
1841 b.PrependBoolSlot(5, True, False)
1842 b.PrependBoolSlot(6, True, False)
1843 b.PrependBoolSlot(7, True, False)
1844 off = b.EndObject()
1845 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001846
James Kuszmaul8e62b022022-03-22 09:33:25 -07001847 self.assertBuilderEquals(
1848 b,
1849 [
1850 24,
1851 0,
1852 0,
1853 0, # root of table: points to vtable offset
1854 20,
1855 0, # vtable bytes
1856 12,
1857 0, # size of object
1858 11,
1859 0, # start of value 0
1860 10,
1861 0, # start of value 1
1862 9,
1863 0, # start of value 2
1864 8,
1865 0, # start of value 3
1866 7,
1867 0, # start of value 4
1868 6,
1869 0, # start of value 5
1870 5,
1871 0, # start of value 6
1872 4,
1873 0, # start of value 7
1874 20,
1875 0,
1876 0,
1877 0, # vtable offset
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001878 1, # value 7
1879 1, # value 6
1880 1, # value 5
1881 1, # value 4
1882 1, # value 3
1883 1, # value 2
1884 1, # value 1
1885 1, # value 0
1886 ])
1887
James Kuszmaul8e62b022022-03-22 09:33:25 -07001888 def test_three_bools(self):
1889 b = flatbuffers.Builder(0)
1890 b.StartObject(3)
1891 b.PrependBoolSlot(0, True, False)
1892 b.PrependBoolSlot(1, True, False)
1893 b.PrependBoolSlot(2, True, False)
1894 off = b.EndObject()
1895 b.Finish(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001896
James Kuszmaul8e62b022022-03-22 09:33:25 -07001897 self.assertBuilderEquals(
1898 b,
1899 [
1900 16,
1901 0,
1902 0,
1903 0, # root of table: points to vtable offset
1904 0,
1905 0, # padding
1906 10,
1907 0, # vtable bytes
1908 8,
1909 0, # size of object
1910 7,
1911 0, # start of value 0
1912 6,
1913 0, # start of value 1
1914 5,
1915 0, # start of value 2
1916 10,
1917 0,
1918 0,
1919 0, # vtable offset from here
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001920 0, # padding
1921 1, # value 2
1922 1, # value 1
1923 1, # value 0
1924 ])
1925
James Kuszmaul8e62b022022-03-22 09:33:25 -07001926 def test_some_floats(self):
1927 b = flatbuffers.Builder(0)
1928 b.StartObject(1)
1929 b.PrependFloat32Slot(0, 1.0, 0.0)
1930 off = b.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001931
James Kuszmaul8e62b022022-03-22 09:33:25 -07001932 self.assertBuilderEquals(
1933 b,
1934 [
1935 6,
1936 0, # vtable bytes
1937 8,
1938 0, # size of object
1939 4,
1940 0, # start of value 0
1941 6,
1942 0,
1943 0,
1944 0, # vtable offset
1945 0,
1946 0,
1947 128,
1948 63, # value 0
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001949 ])
1950
1951
James Kuszmaul8e62b022022-03-22 09:33:25 -07001952def make_monster_from_generated_code(sizePrefix=False, file_identifier=None):
1953 """ Use generated code to build the example Monster. """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001954
James Kuszmaul8e62b022022-03-22 09:33:25 -07001955 b = flatbuffers.Builder(0)
1956 string = b.CreateString('MyMonster')
1957 test1 = b.CreateString('test1')
1958 test2 = b.CreateString('test2')
1959 fred = b.CreateString('Fred')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001960
James Kuszmaul8e62b022022-03-22 09:33:25 -07001961 _MONSTER.MonsterStartInventoryVector(b, 5)
1962 b.PrependByte(4)
1963 b.PrependByte(3)
1964 b.PrependByte(2)
1965 b.PrependByte(1)
1966 b.PrependByte(0)
1967 inv = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001968
James Kuszmaul8e62b022022-03-22 09:33:25 -07001969 _MONSTER.MonsterStart(b)
1970 _MONSTER.MonsterAddName(b, fred)
1971 mon2 = _MONSTER.MonsterEnd(b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001972
James Kuszmaul8e62b022022-03-22 09:33:25 -07001973 _MONSTER.MonsterStartTest4Vector(b, 2)
1974 _TEST.CreateTest(b, 10, 20)
1975 _TEST.CreateTest(b, 30, 40)
1976 test4 = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001977
James Kuszmaul8e62b022022-03-22 09:33:25 -07001978 _MONSTER.MonsterStartTestarrayofstringVector(b, 2)
1979 b.PrependUOffsetTRelative(test2)
1980 b.PrependUOffsetTRelative(test1)
1981 testArrayOfString = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001982
James Kuszmaul8e62b022022-03-22 09:33:25 -07001983 _MONSTER.MonsterStartVectorOfLongsVector(b, 5)
1984 b.PrependInt64(100000000)
1985 b.PrependInt64(1000000)
1986 b.PrependInt64(10000)
1987 b.PrependInt64(100)
1988 b.PrependInt64(1)
1989 VectorOfLongs = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001990
James Kuszmaul8e62b022022-03-22 09:33:25 -07001991 _MONSTER.MonsterStartVectorOfDoublesVector(b, 3)
1992 b.PrependFloat64(1.7976931348623157e+308)
1993 b.PrependFloat64(0)
1994 b.PrependFloat64(-1.7976931348623157e+308)
1995 VectorOfDoubles = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001996
James Kuszmaul8e62b022022-03-22 09:33:25 -07001997 _MONSTER.MonsterStart(b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001998
James Kuszmaul8e62b022022-03-22 09:33:25 -07001999 pos = _VEC3.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 2, 5, 6)
2000 _MONSTER.MonsterAddPos(b, pos)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002001
James Kuszmaul8e62b022022-03-22 09:33:25 -07002002 _MONSTER.MonsterAddHp(b, 80)
2003 _MONSTER.MonsterAddName(b, string)
2004 _MONSTER.MonsterAddInventory(b, inv)
2005 _MONSTER.MonsterAddTestType(b, 1)
2006 _MONSTER.MonsterAddTest(b, mon2)
2007 _MONSTER.MonsterAddTest4(b, test4)
2008 _MONSTER.MonsterAddTestarrayofstring(b, testArrayOfString)
2009 _MONSTER.MonsterAddVectorOfLongs(b, VectorOfLongs)
2010 _MONSTER.MonsterAddVectorOfDoubles(b, VectorOfDoubles)
2011 mon = _MONSTER.MonsterEnd(b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002012
James Kuszmaul8e62b022022-03-22 09:33:25 -07002013 if sizePrefix:
2014 b.FinishSizePrefixed(mon, file_identifier)
2015 else:
2016 b.Finish(mon, file_identifier)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002017
James Kuszmaul8e62b022022-03-22 09:33:25 -07002018 return b.Bytes, b.Head()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002019
2020
Austin Schuh272c6132020-11-14 16:37:52 -08002021class TestBuilderForceDefaults(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002022 """Verify that the builder adds default values when forced."""
Austin Schuh272c6132020-11-14 16:37:52 -08002023
James Kuszmaul8e62b022022-03-22 09:33:25 -07002024 test_flags = [N.BoolFlags(), N.Uint8Flags(), N.Uint16Flags(), \
2025 N.Uint32Flags(), N.Uint64Flags(), N.Int8Flags(), \
2026 N.Int16Flags(), N.Int32Flags(), N.Int64Flags(), \
2027 N.Float32Flags(), N.Float64Flags(), N.UOffsetTFlags()]
Austin Schuh272c6132020-11-14 16:37:52 -08002028
James Kuszmaul8e62b022022-03-22 09:33:25 -07002029 def test_default_force_defaults(self):
2030 for flag in self.test_flags:
2031 b = flatbuffers.Builder(0)
2032 b.StartObject(1)
2033 stored_offset = b.Offset()
2034 if flag != N.UOffsetTFlags():
2035 b.PrependSlot(flag, 0, 0, 0)
2036 else:
2037 b.PrependUOffsetTRelativeSlot(0, 0, 0)
2038 end_offset = b.Offset()
2039 b.EndObject()
2040 self.assertEqual(0, end_offset - stored_offset)
2041
2042 def test_force_defaults_true(self):
2043 for flag in self.test_flags:
2044 b = flatbuffers.Builder(0)
2045 b.ForceDefaults(True)
2046 b.StartObject(1)
2047 stored_offset = b.Offset()
2048 if flag != N.UOffsetTFlags():
2049 b.PrependSlot(flag, 0, 0, 0)
2050 else:
2051 b.PrependUOffsetTRelativeSlot(0, 0, 0)
2052 end_offset = b.Offset()
2053 b.EndObject()
2054 self.assertEqual(flag.bytewidth, end_offset - stored_offset)
Austin Schuh272c6132020-11-14 16:37:52 -08002055
2056
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002057class TestAllCodePathsOfExampleSchema(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002058
James Kuszmaul8e62b022022-03-22 09:33:25 -07002059 def setUp(self, *args, **kwargs):
2060 super(TestAllCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002061
James Kuszmaul8e62b022022-03-22 09:33:25 -07002062 b = flatbuffers.Builder(0)
2063 _MONSTER.MonsterStart(b)
2064 gen_mon = _MONSTER.MonsterEnd(b)
2065 b.Finish(gen_mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002066
James Kuszmaul8e62b022022-03-22 09:33:25 -07002067 self.mon = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002068
James Kuszmaul8e62b022022-03-22 09:33:25 -07002069 def test_default_monster_pos(self):
2070 self.assertTrue(self.mon.Pos() is None)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002071
James Kuszmaul8e62b022022-03-22 09:33:25 -07002072 def test_nondefault_monster_mana(self):
2073 b = flatbuffers.Builder(0)
2074 _MONSTER.MonsterStart(b)
2075 _MONSTER.MonsterAddMana(b, 50)
2076 mon = _MONSTER.MonsterEnd(b)
2077 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002078
James Kuszmaul8e62b022022-03-22 09:33:25 -07002079 got_mon = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2080 self.assertEqual(50, got_mon.Mana())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002081
James Kuszmaul8e62b022022-03-22 09:33:25 -07002082 def test_default_monster_hp(self):
2083 self.assertEqual(100, self.mon.Hp())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002084
James Kuszmaul8e62b022022-03-22 09:33:25 -07002085 def test_default_monster_name(self):
2086 self.assertEqual(None, self.mon.Name())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002087
James Kuszmaul8e62b022022-03-22 09:33:25 -07002088 def test_default_monster_inventory_item(self):
2089 self.assertEqual(0, self.mon.Inventory(0))
Austin Schuh272c6132020-11-14 16:37:52 -08002090
James Kuszmaul8e62b022022-03-22 09:33:25 -07002091 def test_default_monster_inventory_length(self):
2092 self.assertEqual(0, self.mon.InventoryLength())
2093 self.assertTrue(self.mon.InventoryIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002094
James Kuszmaul8e62b022022-03-22 09:33:25 -07002095 def test_empty_monster_inventory_vector(self):
2096 b = flatbuffers.Builder(0)
2097 _MONSTER.MonsterStartInventoryVector(b, 0)
2098 inv = b.EndVector()
2099 _MONSTER.MonsterStart(b)
2100 _MONSTER.MonsterAddInventory(b, inv)
2101 mon = _MONSTER.MonsterEnd(b)
2102 b.Finish(mon)
2103 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2104 self.assertFalse(mon2.InventoryIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002105
James Kuszmaul8e62b022022-03-22 09:33:25 -07002106 def test_default_monster_color(self):
2107 self.assertEqual(_COLOR.Color.Blue, self.mon.Color())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002108
James Kuszmaul8e62b022022-03-22 09:33:25 -07002109 def test_nondefault_monster_color(self):
2110 b = flatbuffers.Builder(0)
2111 color = _COLOR.Color.Red
2112 _MONSTER.MonsterStart(b)
2113 _MONSTER.MonsterAddColor(b, color)
2114 mon = _MONSTER.MonsterEnd(b)
2115 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002116
James Kuszmaul8e62b022022-03-22 09:33:25 -07002117 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2118 self.assertEqual(_COLOR.Color.Red, mon2.Color())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002119
James Kuszmaul8e62b022022-03-22 09:33:25 -07002120 def test_default_monster_testtype(self):
2121 self.assertEqual(0, self.mon.TestType())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002122
James Kuszmaul8e62b022022-03-22 09:33:25 -07002123 def test_default_monster_test_field(self):
2124 self.assertEqual(None, self.mon.Test())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002125
James Kuszmaul8e62b022022-03-22 09:33:25 -07002126 def test_default_monster_test4_item(self):
2127 self.assertEqual(None, self.mon.Test4(0))
Austin Schuh272c6132020-11-14 16:37:52 -08002128
James Kuszmaul8e62b022022-03-22 09:33:25 -07002129 def test_default_monster_test4_length(self):
2130 self.assertEqual(0, self.mon.Test4Length())
2131 self.assertTrue(self.mon.Test4IsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002132
James Kuszmaul8e62b022022-03-22 09:33:25 -07002133 def test_empty_monster_test4_vector(self):
2134 b = flatbuffers.Builder(0)
2135 _MONSTER.MonsterStartTest4Vector(b, 0)
2136 test4 = b.EndVector()
2137 _MONSTER.MonsterStart(b)
2138 _MONSTER.MonsterAddTest4(b, test4)
2139 mon = _MONSTER.MonsterEnd(b)
2140 b.Finish(mon)
2141 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2142 self.assertFalse(mon2.Test4IsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002143
James Kuszmaul8e62b022022-03-22 09:33:25 -07002144 def test_default_monster_testarrayofstring(self):
2145 self.assertEqual('', self.mon.Testarrayofstring(0))
Austin Schuh272c6132020-11-14 16:37:52 -08002146
James Kuszmaul8e62b022022-03-22 09:33:25 -07002147 def test_default_monster_testarrayofstring_length(self):
2148 self.assertEqual(0, self.mon.TestarrayofstringLength())
2149 self.assertTrue(self.mon.TestarrayofstringIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002150
James Kuszmaul8e62b022022-03-22 09:33:25 -07002151 def test_empty_monster_testarrayofstring_vector(self):
2152 b = flatbuffers.Builder(0)
2153 _MONSTER.MonsterStartTestarrayofstringVector(b, 0)
2154 testarrayofstring = b.EndVector()
2155 _MONSTER.MonsterStart(b)
2156 _MONSTER.MonsterAddTestarrayofstring(b, testarrayofstring)
2157 mon = _MONSTER.MonsterEnd(b)
2158 b.Finish(mon)
2159 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2160 self.assertFalse(mon2.TestarrayofstringIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002161
James Kuszmaul8e62b022022-03-22 09:33:25 -07002162 def test_default_monster_testarrayoftables(self):
2163 self.assertEqual(None, self.mon.Testarrayoftables(0))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002164
James Kuszmaul8e62b022022-03-22 09:33:25 -07002165 def test_nondefault_monster_testarrayoftables(self):
2166 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002167
James Kuszmaul8e62b022022-03-22 09:33:25 -07002168 # make a child Monster within a vector of Monsters:
2169 _MONSTER.MonsterStart(b)
2170 _MONSTER.MonsterAddHp(b, 99)
2171 sub_monster = _MONSTER.MonsterEnd(b)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002172
James Kuszmaul8e62b022022-03-22 09:33:25 -07002173 # build the vector:
2174 _MONSTER.MonsterStartTestarrayoftablesVector(b, 1)
2175 b.PrependUOffsetTRelative(sub_monster)
2176 vec = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002177
James Kuszmaul8e62b022022-03-22 09:33:25 -07002178 # make the parent monster and include the vector of Monster:
2179 _MONSTER.MonsterStart(b)
2180 _MONSTER.MonsterAddTestarrayoftables(b, vec)
2181 mon = _MONSTER.MonsterEnd(b)
2182 b.Finish(mon)
Austin Schuh272c6132020-11-14 16:37:52 -08002183
James Kuszmaul8e62b022022-03-22 09:33:25 -07002184 # inspect the resulting data:
2185 mon2 = _MONSTER.Monster.GetRootAs(b.Output(), 0)
2186 self.assertEqual(99, mon2.Testarrayoftables(0).Hp())
2187 self.assertEqual(1, mon2.TestarrayoftablesLength())
2188 self.assertFalse(mon2.TestarrayoftablesIsNone())
Austin Schuh272c6132020-11-14 16:37:52 -08002189
James Kuszmaul8e62b022022-03-22 09:33:25 -07002190 def test_default_monster_testarrayoftables_length(self):
2191 self.assertEqual(0, self.mon.TestarrayoftablesLength())
2192 self.assertTrue(self.mon.TestarrayoftablesIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002193
James Kuszmaul8e62b022022-03-22 09:33:25 -07002194 def test_empty_monster_testarrayoftables_vector(self):
2195 b = flatbuffers.Builder(0)
2196 _MONSTER.MonsterStartTestarrayoftablesVector(b, 0)
2197 testarrayoftables = b.EndVector()
2198 _MONSTER.MonsterStart(b)
2199 _MONSTER.MonsterAddTestarrayoftables(b, testarrayoftables)
2200 mon = _MONSTER.MonsterEnd(b)
2201 b.Finish(mon)
2202 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2203 self.assertFalse(mon2.TestarrayoftablesIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002204
James Kuszmaul8e62b022022-03-22 09:33:25 -07002205 def test_default_monster_testarrayoftables_length(self):
2206 self.assertEqual(0, self.mon.TestarrayoftablesLength())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002207
James Kuszmaul8e62b022022-03-22 09:33:25 -07002208 def test_nondefault_monster_enemy(self):
2209 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002210
James Kuszmaul8e62b022022-03-22 09:33:25 -07002211 # make an Enemy object:
2212 _MONSTER.MonsterStart(b)
2213 _MONSTER.MonsterAddHp(b, 88)
2214 enemy = _MONSTER.MonsterEnd(b)
2215 b.Finish(enemy)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002216
James Kuszmaul8e62b022022-03-22 09:33:25 -07002217 # make the parent monster and include the vector of Monster:
2218 _MONSTER.MonsterStart(b)
2219 _MONSTER.MonsterAddEnemy(b, enemy)
2220 mon = _MONSTER.MonsterEnd(b)
2221 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002222
James Kuszmaul8e62b022022-03-22 09:33:25 -07002223 # inspect the resulting data:
2224 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2225 self.assertEqual(88, mon2.Enemy().Hp())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002226
James Kuszmaul8e62b022022-03-22 09:33:25 -07002227 def test_default_monster_testnestedflatbuffer(self):
2228 self.assertEqual(0, self.mon.Testnestedflatbuffer(0))
Austin Schuh272c6132020-11-14 16:37:52 -08002229
James Kuszmaul8e62b022022-03-22 09:33:25 -07002230 def test_default_monster_testnestedflatbuffer_length(self):
2231 self.assertEqual(0, self.mon.TestnestedflatbufferLength())
2232 self.assertTrue(self.mon.TestnestedflatbufferIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002233
James Kuszmaul8e62b022022-03-22 09:33:25 -07002234 def test_empty_monster_testnestedflatbuffer_vector(self):
2235 b = flatbuffers.Builder(0)
2236 _MONSTER.MonsterStartTestnestedflatbufferVector(b, 0)
2237 testnestedflatbuffer = b.EndVector()
2238 _MONSTER.MonsterStart(b)
2239 _MONSTER.MonsterAddTestnestedflatbuffer(b, testnestedflatbuffer)
2240 mon = _MONSTER.MonsterEnd(b)
2241 b.Finish(mon)
2242 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2243 self.assertFalse(mon2.TestnestedflatbufferIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002244
James Kuszmaul8e62b022022-03-22 09:33:25 -07002245 def test_nondefault_monster_testnestedflatbuffer(self):
2246 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002247
James Kuszmaul8e62b022022-03-22 09:33:25 -07002248 _MONSTER.MonsterStartTestnestedflatbufferVector(b, 3)
2249 b.PrependByte(4)
2250 b.PrependByte(2)
2251 b.PrependByte(0)
2252 sub_buf = b.EndVector()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002253
James Kuszmaul8e62b022022-03-22 09:33:25 -07002254 # make the parent monster and include the vector of Monster:
2255 _MONSTER.MonsterStart(b)
2256 _MONSTER.MonsterAddTestnestedflatbuffer(b, sub_buf)
2257 mon = _MONSTER.MonsterEnd(b)
2258 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002259
James Kuszmaul8e62b022022-03-22 09:33:25 -07002260 # inspect the resulting data:
2261 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2262 self.assertEqual(3, mon2.TestnestedflatbufferLength())
2263 self.assertFalse(mon2.TestnestedflatbufferIsNone())
2264 self.assertEqual(0, mon2.Testnestedflatbuffer(0))
2265 self.assertEqual(2, mon2.Testnestedflatbuffer(1))
2266 self.assertEqual(4, mon2.Testnestedflatbuffer(2))
2267 try:
2268 imp.find_module('numpy')
2269 # if numpy exists, then we should be able to get the
2270 # vector as a numpy array
2271 self.assertEqual([0, 2, 4], mon2.TestnestedflatbufferAsNumpy().tolist())
2272 except ImportError:
2273 assertRaises(self, lambda: mon2.TestnestedflatbufferAsNumpy(),
2274 NumpyRequiredForThisFeature)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002275
James Kuszmaul8e62b022022-03-22 09:33:25 -07002276 def test_nested_monster_testnestedflatbuffer(self):
2277 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002278
James Kuszmaul8e62b022022-03-22 09:33:25 -07002279 # build another monster to nest inside testnestedflatbuffer
2280 nestedB = flatbuffers.Builder(0)
2281 nameStr = nestedB.CreateString('Nested Monster')
2282 _MONSTER.MonsterStart(nestedB)
2283 _MONSTER.MonsterAddHp(nestedB, 30)
2284 _MONSTER.MonsterAddName(nestedB, nameStr)
2285 nestedMon = _MONSTER.MonsterEnd(nestedB)
2286 nestedB.Finish(nestedMon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002287
James Kuszmaul8e62b022022-03-22 09:33:25 -07002288 # write the nested FB bytes
2289 sub_buf = _MONSTER.MonsterMakeTestnestedflatbufferVectorFromBytes(
2290 b, nestedB.Output())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002291
James Kuszmaul8e62b022022-03-22 09:33:25 -07002292 # make the parent monster and include the bytes of the nested monster
2293 _MONSTER.MonsterStart(b)
2294 _MONSTER.MonsterAddTestnestedflatbuffer(b, sub_buf)
2295 mon = _MONSTER.MonsterEnd(b)
2296 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002297
James Kuszmaul8e62b022022-03-22 09:33:25 -07002298 # inspect the resulting data:
2299 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2300 nestedMon2 = mon2.TestnestedflatbufferNestedRoot()
2301 self.assertEqual(b'Nested Monster', nestedMon2.Name())
2302 self.assertEqual(30, nestedMon2.Hp())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002303
James Kuszmaul8e62b022022-03-22 09:33:25 -07002304 def test_nondefault_monster_testempty(self):
2305 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002306
James Kuszmaul8e62b022022-03-22 09:33:25 -07002307 # make a Stat object:
2308 _STAT.StatStart(b)
2309 _STAT.StatAddVal(b, 123)
2310 my_stat = _STAT.StatEnd(b)
2311 b.Finish(my_stat)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002312
James Kuszmaul8e62b022022-03-22 09:33:25 -07002313 # include the stat object in a monster:
2314 _MONSTER.MonsterStart(b)
2315 _MONSTER.MonsterAddTestempty(b, my_stat)
2316 mon = _MONSTER.MonsterEnd(b)
2317 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002318
James Kuszmaul8e62b022022-03-22 09:33:25 -07002319 # inspect the resulting data:
2320 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2321 self.assertEqual(123, mon2.Testempty().Val())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002322
James Kuszmaul8e62b022022-03-22 09:33:25 -07002323 def test_default_monster_testbool(self):
2324 self.assertFalse(self.mon.Testbool())
Austin Schuh272c6132020-11-14 16:37:52 -08002325
James Kuszmaul8e62b022022-03-22 09:33:25 -07002326 def test_nondefault_monster_testbool(self):
2327 b = flatbuffers.Builder(0)
2328 _MONSTER.MonsterStart(b)
2329 _MONSTER.MonsterAddTestbool(b, True)
2330 mon = _MONSTER.MonsterEnd(b)
2331 b.Finish(mon)
Austin Schuh272c6132020-11-14 16:37:52 -08002332
James Kuszmaul8e62b022022-03-22 09:33:25 -07002333 # inspect the resulting data:
2334 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2335 self.assertTrue(mon2.Testbool())
Austin Schuh272c6132020-11-14 16:37:52 -08002336
James Kuszmaul8e62b022022-03-22 09:33:25 -07002337 def test_default_monster_testhashes(self):
2338 self.assertEqual(0, self.mon.Testhashs32Fnv1())
2339 self.assertEqual(0, self.mon.Testhashu32Fnv1())
2340 self.assertEqual(0, self.mon.Testhashs64Fnv1())
2341 self.assertEqual(0, self.mon.Testhashu64Fnv1())
2342 self.assertEqual(0, self.mon.Testhashs32Fnv1a())
2343 self.assertEqual(0, self.mon.Testhashu32Fnv1a())
2344 self.assertEqual(0, self.mon.Testhashs64Fnv1a())
2345 self.assertEqual(0, self.mon.Testhashu64Fnv1a())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002346
James Kuszmaul8e62b022022-03-22 09:33:25 -07002347 def test_nondefault_monster_testhashes(self):
2348 b = flatbuffers.Builder(0)
2349 _MONSTER.MonsterStart(b)
2350 _MONSTER.MonsterAddTesthashs32Fnv1(b, 1)
2351 _MONSTER.MonsterAddTesthashu32Fnv1(b, 2)
2352 _MONSTER.MonsterAddTesthashs64Fnv1(b, 3)
2353 _MONSTER.MonsterAddTesthashu64Fnv1(b, 4)
2354 _MONSTER.MonsterAddTesthashs32Fnv1a(b, 5)
2355 _MONSTER.MonsterAddTesthashu32Fnv1a(b, 6)
2356 _MONSTER.MonsterAddTesthashs64Fnv1a(b, 7)
2357 _MONSTER.MonsterAddTesthashu64Fnv1a(b, 8)
2358 mon = _MONSTER.MonsterEnd(b)
2359 b.Finish(mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002360
James Kuszmaul8e62b022022-03-22 09:33:25 -07002361 # inspect the resulting data:
2362 mon2 = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2363 self.assertEqual(1, mon2.Testhashs32Fnv1())
2364 self.assertEqual(2, mon2.Testhashu32Fnv1())
2365 self.assertEqual(3, mon2.Testhashs64Fnv1())
2366 self.assertEqual(4, mon2.Testhashu64Fnv1())
2367 self.assertEqual(5, mon2.Testhashs32Fnv1a())
2368 self.assertEqual(6, mon2.Testhashu32Fnv1a())
2369 self.assertEqual(7, mon2.Testhashs64Fnv1a())
2370 self.assertEqual(8, mon2.Testhashu64Fnv1a())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002371
James Kuszmaul8e62b022022-03-22 09:33:25 -07002372 def test_default_monster_parent_namespace_test(self):
2373 self.assertEqual(None, self.mon.ParentNamespaceTest())
2374
2375 def test_nondefault_monster_parent_namespace_test(self):
2376 b = flatbuffers.Builder(0)
2377 _IN_PARENT_NAMESPACE.InParentNamespaceStart(b)
2378 parent = _IN_PARENT_NAMESPACE.InParentNamespaceEnd(b)
2379 _MONSTER.MonsterStart(b)
2380 _MONSTER.MonsterAddParentNamespaceTest(b, parent)
2381 mon = _MONSTER.MonsterEnd(b)
2382 b.Finish(mon)
2383
2384 # Inspect the resulting data.
2385 monster = _MONSTER.Monster.GetRootAs(b.Bytes, b.Head())
2386 self.assertTrue(
2387 isinstance(monster.ParentNamespaceTest(),
2388 _IN_PARENT_NAMESPACE.InParentNamespace))
2389
2390 def test_getrootas_for_nonroot_table(self):
2391 b = flatbuffers.Builder(0)
2392 string = b.CreateString('MyStat')
2393
2394 _STAT.StatStart(b)
2395 _STAT.StatAddId(b, string)
2396 _STAT.StatAddVal(b, 12345678)
2397 _STAT.StatAddCount(b, 12345)
2398 stat = _STAT.StatEnd(b)
2399 b.Finish(stat)
2400
2401 stat2 = _STAT.Stat.GetRootAs(b.Bytes, b.Head())
2402
2403 self.assertEqual(b'MyStat', stat2.Id())
2404 self.assertEqual(12345678, stat2.Val())
2405 self.assertEqual(12345, stat2.Count())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002406
2407
2408class TestAllCodePathsOfMonsterExtraSchema(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002409
James Kuszmaul8e62b022022-03-22 09:33:25 -07002410 def setUp(self, *args, **kwargs):
2411 super(TestAllCodePathsOfMonsterExtraSchema, self).setUp(*args, **kwargs)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002412
James Kuszmaul8e62b022022-03-22 09:33:25 -07002413 b = flatbuffers.Builder(0)
2414 MyGame.MonsterExtra.Start(b)
2415 gen_mon = MyGame.MonsterExtra.End(b)
2416 b.Finish(gen_mon)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002417
James Kuszmaul8e62b022022-03-22 09:33:25 -07002418 self.mon = MyGame.MonsterExtra.MonsterExtra.GetRootAs(b.Bytes, b.Head())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002419
James Kuszmaul8e62b022022-03-22 09:33:25 -07002420 def test_default_nan_inf(self):
2421 self.assertTrue(math.isnan(self.mon.F1()))
2422 self.assertEqual(self.mon.F2(), float('inf'))
2423 self.assertEqual(self.mon.F3(), float('-inf'))
2424
2425 self.assertTrue(math.isnan(self.mon.D1()))
2426 self.assertEqual(self.mon.D2(), float('inf'))
2427 self.assertEqual(self.mon.D3(), float('-inf'))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002428
2429
2430class TestVtableDeduplication(unittest.TestCase):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002431 """ TestVtableDeduplication verifies that vtables are deduplicated. """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002432
James Kuszmaul8e62b022022-03-22 09:33:25 -07002433 def test_vtable_deduplication(self):
2434 b = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002435
James Kuszmaul8e62b022022-03-22 09:33:25 -07002436 b.StartObject(4)
2437 b.PrependByteSlot(0, 0, 0)
2438 b.PrependByteSlot(1, 11, 0)
2439 b.PrependByteSlot(2, 22, 0)
2440 b.PrependInt16Slot(3, 33, 0)
2441 obj0 = b.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002442
James Kuszmaul8e62b022022-03-22 09:33:25 -07002443 b.StartObject(4)
2444 b.PrependByteSlot(0, 0, 0)
2445 b.PrependByteSlot(1, 44, 0)
2446 b.PrependByteSlot(2, 55, 0)
2447 b.PrependInt16Slot(3, 66, 0)
2448 obj1 = b.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002449
James Kuszmaul8e62b022022-03-22 09:33:25 -07002450 b.StartObject(4)
2451 b.PrependByteSlot(0, 0, 0)
2452 b.PrependByteSlot(1, 77, 0)
2453 b.PrependByteSlot(2, 88, 0)
2454 b.PrependInt16Slot(3, 99, 0)
2455 obj2 = b.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002456
James Kuszmaul8e62b022022-03-22 09:33:25 -07002457 got = b.Bytes[b.Head():]
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002458
James Kuszmaul8e62b022022-03-22 09:33:25 -07002459 want = bytearray([
2460 240,
2461 255,
2462 255,
2463 255, # == -12. offset to dedupped vtable.
2464 99,
2465 0,
2466 88,
2467 77,
2468 248,
2469 255,
2470 255,
2471 255, # == -8. offset to dedupped vtable.
2472 66,
2473 0,
2474 55,
2475 44,
2476 12,
2477 0,
2478 8,
2479 0,
2480 0,
2481 0,
2482 7,
2483 0,
2484 6,
2485 0,
2486 4,
2487 0,
2488 12,
2489 0,
2490 0,
2491 0,
2492 33,
2493 0,
2494 22,
2495 11,
2496 ])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002497
James Kuszmaul8e62b022022-03-22 09:33:25 -07002498 self.assertEqual((len(want), want), (len(got), got))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002499
James Kuszmaul8e62b022022-03-22 09:33:25 -07002500 table0 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj0)
2501 table1 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj1)
2502 table2 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj2)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002503
James Kuszmaul8e62b022022-03-22 09:33:25 -07002504 def _checkTable(tab, voffsett_value, b, c, d):
2505 # vtable size
2506 got = tab.GetVOffsetTSlot(0, 0)
2507 self.assertEqual(12, got, 'case 0, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002508
James Kuszmaul8e62b022022-03-22 09:33:25 -07002509 # object size
2510 got = tab.GetVOffsetTSlot(2, 0)
2511 self.assertEqual(8, got, 'case 2, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002512
James Kuszmaul8e62b022022-03-22 09:33:25 -07002513 # default value
2514 got = tab.GetVOffsetTSlot(4, 0)
2515 self.assertEqual(voffsett_value, got, 'case 4, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002516
James Kuszmaul8e62b022022-03-22 09:33:25 -07002517 got = tab.GetSlot(6, 0, N.Uint8Flags)
2518 self.assertEqual(b, got, 'case 6, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002519
James Kuszmaul8e62b022022-03-22 09:33:25 -07002520 val = tab.GetSlot(8, 0, N.Uint8Flags)
2521 self.assertEqual(c, val, 'failed 8, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002522
James Kuszmaul8e62b022022-03-22 09:33:25 -07002523 got = tab.GetSlot(10, 0, N.Uint8Flags)
2524 self.assertEqual(d, got, 'failed 10, 0')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002525
James Kuszmaul8e62b022022-03-22 09:33:25 -07002526 _checkTable(table0, 0, 11, 22, 33)
2527 _checkTable(table1, 0, 44, 55, 66)
2528 _checkTable(table2, 0, 77, 88, 99)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002529
2530
2531class TestExceptions(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002532
James Kuszmaul8e62b022022-03-22 09:33:25 -07002533 def test_object_is_nested_error(self):
2534 b = flatbuffers.Builder(0)
2535 b.StartObject(0)
2536 assertRaises(self, lambda: b.StartObject(0),
2537 flatbuffers.builder.IsNestedError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002538
James Kuszmaul8e62b022022-03-22 09:33:25 -07002539 def test_object_is_not_nested_error(self):
2540 b = flatbuffers.Builder(0)
2541 assertRaises(self, lambda: b.EndObject(),
2542 flatbuffers.builder.IsNotNestedError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002543
James Kuszmaul8e62b022022-03-22 09:33:25 -07002544 def test_struct_is_not_inline_error(self):
2545 b = flatbuffers.Builder(0)
2546 b.StartObject(0)
2547 assertRaises(self, lambda: b.PrependStructSlot(0, 1, 0),
2548 flatbuffers.builder.StructIsNotInlineError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002549
James Kuszmaul8e62b022022-03-22 09:33:25 -07002550 def test_unreachable_error(self):
2551 b = flatbuffers.Builder(0)
2552 assertRaises(self, lambda: b.PrependUOffsetTRelative(1),
2553 flatbuffers.builder.OffsetArithmeticError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002554
James Kuszmaul8e62b022022-03-22 09:33:25 -07002555 def test_create_string_is_nested_error(self):
2556 b = flatbuffers.Builder(0)
2557 b.StartObject(0)
2558 s = 'test1'
2559 assertRaises(self, lambda: b.CreateString(s),
2560 flatbuffers.builder.IsNestedError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002561
James Kuszmaul8e62b022022-03-22 09:33:25 -07002562 def test_create_byte_vector_is_nested_error(self):
2563 b = flatbuffers.Builder(0)
2564 b.StartObject(0)
2565 s = b'test1'
2566 assertRaises(self, lambda: b.CreateByteVector(s),
2567 flatbuffers.builder.IsNestedError)
2568
2569 def test_finished_bytes_error(self):
2570 b = flatbuffers.Builder(0)
2571 assertRaises(self, lambda: b.Output(),
2572 flatbuffers.builder.BuilderNotFinishedError)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002573
2574
2575class TestFixedLengthArrays(unittest.TestCase):
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002576
James Kuszmaul8e62b022022-03-22 09:33:25 -07002577 def test_fixed_length_array(self):
2578 builder = flatbuffers.Builder(0)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002579
James Kuszmaul8e62b022022-03-22 09:33:25 -07002580 a = 0.5
2581 b = range(0, 15)
2582 c = 1
2583 d_a = [[1, 2], [3, 4]]
2584 d_b = [MyGame.Example.TestEnum.TestEnum.B, \
2585 MyGame.Example.TestEnum.TestEnum.C]
2586 d_c = [[MyGame.Example.TestEnum.TestEnum.A, \
2587 MyGame.Example.TestEnum.TestEnum.B], \
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002588 [MyGame.Example.TestEnum.TestEnum.C, \
James Kuszmaul8e62b022022-03-22 09:33:25 -07002589 MyGame.Example.TestEnum.TestEnum.B]]
2590 d_d = [[-1, 1], [-2, 2]]
2591 e = 2
2592 f = [-1, 1]
2593
2594 arrayOffset = MyGame.Example.ArrayStruct.CreateArrayStruct(builder, \
2595 a, b, c, d_a, d_b, d_c, d_d, e, f)
2596
2597 # Create a table with the ArrayStruct.
2598 MyGame.Example.ArrayTable.Start(builder)
2599 MyGame.Example.ArrayTable.AddA(builder, arrayOffset)
2600 tableOffset = MyGame.Example.ArrayTable.End(builder)
2601
2602 builder.Finish(tableOffset)
2603
2604 buf = builder.Output()
2605
2606 table = MyGame.Example.ArrayTable.ArrayTable.GetRootAs(buf)
2607
2608 # Verify structure.
2609 nested = MyGame.Example.NestedStruct.NestedStruct()
2610 self.assertEqual(table.A().A(), 0.5)
2611 self.assertEqual(table.A().B(), \
2612 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
2613 self.assertEqual(table.A().C(), 1)
2614 self.assertEqual(table.A().D(nested, 0).A(), [1, 2])
2615 self.assertEqual(table.A().D(nested, 1).A(), [3, 4])
2616 self.assertEqual(table.A().D(nested, 0).B(), \
2617 MyGame.Example.TestEnum.TestEnum.B)
2618 self.assertEqual(table.A().D(nested, 1).B(), \
2619 MyGame.Example.TestEnum.TestEnum.C)
2620 self.assertEqual(table.A().D(nested, 0).C(), \
2621 [MyGame.Example.TestEnum.TestEnum.A, \
2622 MyGame.Example.TestEnum.TestEnum.B])
2623 self.assertEqual(table.A().D(nested, 1).C(), \
2624 [MyGame.Example.TestEnum.TestEnum.C, \
2625 MyGame.Example.TestEnum.TestEnum.B])
2626 self.assertEqual(table.A().D(nested, 0).D(), [-1, 1])
2627 self.assertEqual(table.A().D(nested, 1).D(), [-2, 2])
2628 self.assertEqual(table.A().E(), 2)
2629 self.assertEqual(table.A().F(), [-1, 1])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002630
2631
2632def CheckAgainstGoldDataGo():
James Kuszmaul8e62b022022-03-22 09:33:25 -07002633 try:
2634 gen_buf, gen_off = make_monster_from_generated_code()
2635 fn = 'monsterdata_go_wire.mon'
2636 if not os.path.exists(fn):
2637 print('Go-generated data does not exist, failed.')
2638 return False
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002639
James Kuszmaul8e62b022022-03-22 09:33:25 -07002640 # would like to use a context manager here, but it's less
2641 # backwards-compatible:
2642 f = open(fn, 'rb')
2643 go_wire_data = f.read()
2644 f.close()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002645
James Kuszmaul8e62b022022-03-22 09:33:25 -07002646 CheckReadBuffer(bytearray(go_wire_data), 0)
2647 if not bytearray(gen_buf[gen_off:]) == bytearray(go_wire_data):
2648 raise AssertionError('CheckAgainstGoldDataGo failed')
2649 except:
2650 print('Failed to test against Go-generated test data.')
2651 return False
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002652
James Kuszmaul8e62b022022-03-22 09:33:25 -07002653 print(
2654 'Can read Go-generated test data, and Python generates bytewise identical data.'
2655 )
2656 return True
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002657
2658
2659def CheckAgainstGoldDataJava():
James Kuszmaul8e62b022022-03-22 09:33:25 -07002660 try:
2661 gen_buf, gen_off = make_monster_from_generated_code()
2662 fn = 'monsterdata_java_wire.mon'
2663 if not os.path.exists(fn):
2664 print('Java-generated data does not exist, failed.')
2665 return False
2666 f = open(fn, 'rb')
2667 java_wire_data = f.read()
2668 f.close()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002669
James Kuszmaul8e62b022022-03-22 09:33:25 -07002670 CheckReadBuffer(bytearray(java_wire_data), 0)
2671 except:
2672 print('Failed to read Java-generated test data.')
2673 return False
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002674
James Kuszmaul8e62b022022-03-22 09:33:25 -07002675 print('Can read Java-generated test data.')
2676 return True
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002677
2678
2679class LCG(object):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002680 """ Include simple random number generator to ensure results will be the
2681
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002682 same cross platform.
James Kuszmaul8e62b022022-03-22 09:33:25 -07002683 http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
2684 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002685
James Kuszmaul8e62b022022-03-22 09:33:25 -07002686 __slots__ = ['n']
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002687
James Kuszmaul8e62b022022-03-22 09:33:25 -07002688 InitialLCGSeed = 48271
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002689
James Kuszmaul8e62b022022-03-22 09:33:25 -07002690 def __init__(self):
2691 self.n = self.InitialLCGSeed
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002692
James Kuszmaul8e62b022022-03-22 09:33:25 -07002693 def Reset(self):
2694 self.n = self.InitialLCGSeed
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002695
James Kuszmaul8e62b022022-03-22 09:33:25 -07002696 def Next(self):
2697 self.n = ((self.n * 279470273) % 4294967291) & 0xFFFFFFFF
2698 return self.n
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002699
2700
2701def BenchmarkVtableDeduplication(count):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002702 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002703 BenchmarkVtableDeduplication measures the speed of vtable deduplication
2704 by creating `prePop` vtables, then populating `count` objects with a
2705 different single vtable.
2706
2707 When count is large (as in long benchmarks), memory usage may be high.
James Kuszmaul8e62b022022-03-22 09:33:25 -07002708 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002709
James Kuszmaul8e62b022022-03-22 09:33:25 -07002710 for prePop in (1, 10, 100, 1000):
2711 builder = flatbuffers.Builder(0)
2712 n = 1 + int(math.log(prePop, 1.5))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002713
James Kuszmaul8e62b022022-03-22 09:33:25 -07002714 # generate some layouts:
2715 layouts = set()
2716 r = list(compat_range(n))
2717 while len(layouts) < prePop:
2718 layouts.add(tuple(sorted(random.sample(r, int(max(1, n / 2))))))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002719
James Kuszmaul8e62b022022-03-22 09:33:25 -07002720 layouts = list(layouts)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002721
James Kuszmaul8e62b022022-03-22 09:33:25 -07002722 # pre-populate vtables:
2723 for layout in layouts:
2724 builder.StartObject(n)
2725 for j in layout:
2726 builder.PrependInt16Slot(j, j, 0)
2727 builder.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002728
James Kuszmaul8e62b022022-03-22 09:33:25 -07002729 # benchmark deduplication of a new vtable:
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002730 def f():
James Kuszmaul8e62b022022-03-22 09:33:25 -07002731 layout = random.choice(layouts)
2732 builder.StartObject(n)
2733 for j in layout:
2734 builder.PrependInt16Slot(j, j, 0)
2735 builder.EndObject()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002736
2737 duration = timeit.timeit(stmt=f, number=count)
2738 rate = float(count) / duration
James Kuszmaul8e62b022022-03-22 09:33:25 -07002739 print(('vtable deduplication rate (n=%d, vtables=%d): %.2f sec' %
2740 (prePop, len(builder.vtables), rate)))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002741
James Kuszmaul8e62b022022-03-22 09:33:25 -07002742
2743def BenchmarkCheckReadBuffer(count, buf, off):
2744 """
2745 BenchmarkCheckReadBuffer measures the speed of flatbuffer reading
2746 by re-using the CheckReadBuffer function with the gold data.
2747 """
2748
2749 def f():
2750 CheckReadBuffer(buf, off)
2751
2752 duration = timeit.timeit(stmt=f, number=count)
2753 rate = float(count) / duration
2754 data = float(len(buf) * count) / float(1024 * 1024)
2755 data_rate = data / float(duration)
2756
2757 print(('traversed %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec') %
2758 (count, len(buf), duration, rate, data_rate))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002759
2760
2761def BenchmarkMakeMonsterFromGeneratedCode(count, length):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002762 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002763 BenchmarkMakeMonsterFromGeneratedCode measures the speed of flatbuffer
2764 creation by re-using the make_monster_from_generated_code function for
2765 generating gold data examples.
James Kuszmaul8e62b022022-03-22 09:33:25 -07002766 """
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002767
James Kuszmaul8e62b022022-03-22 09:33:25 -07002768 duration = timeit.timeit(stmt=make_monster_from_generated_code, number=count)
2769 rate = float(count) / duration
2770 data = float(length * count) / float(1024 * 1024)
2771 data_rate = data / float(duration)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002772
James Kuszmaul8e62b022022-03-22 09:33:25 -07002773 print(('built %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec' % \
2774 (count, length, duration, rate, data_rate)))
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002775
2776
2777def backward_compatible_run_tests(**kwargs):
James Kuszmaul8e62b022022-03-22 09:33:25 -07002778 if PY_VERSION < (2, 6):
2779 sys.stderr.write('Python version less than 2.6 are not supported')
2780 sys.stderr.flush()
2781 return False
2782
2783 # python2.6 has a reduced-functionality unittest.main function:
2784 if PY_VERSION == (2, 6):
2785 try:
2786 unittest.main(**kwargs)
2787 except SystemExit as e:
2788 if not e.code == 0:
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002789 return False
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002790 return True
2791
James Kuszmaul8e62b022022-03-22 09:33:25 -07002792 # python2.7 and above let us not exit once unittest.main is run:
2793 kwargs['exit'] = False
2794 kwargs['verbosity'] = 0
2795 ret = unittest.main(**kwargs)
2796 if ret.result.errors or ret.result.failures:
2797 return False
2798
2799 return True
2800
2801
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002802def main():
James Kuszmaul8e62b022022-03-22 09:33:25 -07002803 import os
2804 import sys
2805 if not len(sys.argv) == 5:
2806 sys.stderr.write('Usage: %s <benchmark vtable count> '
2807 '<benchmark read count> <benchmark build count> '
2808 '<is_onefile>\n' % sys.argv[0])
2809 sys.stderr.write(' Provide COMPARE_GENERATED_TO_GO=1 to check'
2810 'for bytewise comparison to Go data.\n')
2811 sys.stderr.write(' Provide COMPARE_GENERATED_TO_JAVA=1 to check'
2812 'for bytewise comparison to Java data.\n')
2813 sys.stderr.flush()
2814 sys.exit(1)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002815
James Kuszmaul8e62b022022-03-22 09:33:25 -07002816 kwargs = dict(argv=sys.argv[:-4])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002817
James Kuszmaul8e62b022022-03-22 09:33:25 -07002818 create_namespace_shortcut(sys.argv[4].lower() == 'true')
Austin Schuh272c6132020-11-14 16:37:52 -08002819
James Kuszmaul8e62b022022-03-22 09:33:25 -07002820 # show whether numpy is present, as it changes the test logic:
2821 try:
2822 import numpy
2823 print('numpy available')
2824 except ImportError:
2825 print('numpy not available')
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002826
James Kuszmaul8e62b022022-03-22 09:33:25 -07002827 # run tests, and run some language comparison checks if needed:
2828 success = backward_compatible_run_tests(**kwargs)
2829 if success and os.environ.get('COMPARE_GENERATED_TO_GO', 0) == '1':
2830 success = success and CheckAgainstGoldDataGo()
2831 if success and os.environ.get('COMPARE_GENERATED_TO_JAVA', 0) == '1':
2832 success = success and CheckAgainstGoldDataJava()
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002833
James Kuszmaul8e62b022022-03-22 09:33:25 -07002834 if not success:
2835 sys.stderr.write('Tests failed, skipping benchmarks.\n')
2836 sys.stderr.flush()
2837 sys.exit(1)
2838
2839 # run benchmarks (if 0, they will be a noop):
2840 bench_vtable = int(sys.argv[1])
2841 bench_traverse = int(sys.argv[2])
2842 bench_build = int(sys.argv[3])
2843 if bench_vtable:
2844 BenchmarkVtableDeduplication(bench_vtable)
2845 if bench_traverse:
2846 buf, off = make_monster_from_generated_code()
2847 BenchmarkCheckReadBuffer(bench_traverse, buf, off)
2848 if bench_build:
2849 buf, off = make_monster_from_generated_code()
2850 BenchmarkMakeMonsterFromGeneratedCode(bench_build, len(buf))
2851
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002852
2853if __name__ == '__main__':
James Kuszmaul8e62b022022-03-22 09:33:25 -07002854 main()