blob: 9b31f6083de6a193e52ac922e9ac2b97d79f428c [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
Austin Schuh272c6132020-11-14 16:37:52 -080045import 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
50
51def assertRaises(test_case, fn, exception_class):
52 ''' Backwards-compatible assertion for exceptions raised. '''
53
54 exc = None
55 try:
56 fn()
57 except Exception as e:
58 exc = e
59 test_case.assertTrue(exc is not None)
60 test_case.assertTrue(isinstance(exc, exception_class))
61
62
63class TestWireFormat(unittest.TestCase):
64 def test_wire_format(self):
65 # Verify that using the generated Python code builds a buffer without
66 # returning errors, and is interpreted correctly, for size prefixed
67 # representation and regular:
68 for sizePrefix in [True, False]:
69 for file_identifier in [None, b"MONS"]:
70 gen_buf, gen_off = make_monster_from_generated_code(sizePrefix=sizePrefix, file_identifier=file_identifier)
71 CheckReadBuffer(gen_buf, gen_off, sizePrefix=sizePrefix, file_identifier=file_identifier)
72
73 # Verify that the canonical flatbuffer file is readable by the
74 # generated Python code. Note that context managers are not part of
75 # Python 2.5, so we use the simpler open/close methods here:
76 f = open('monsterdata_test.mon', 'rb')
77 canonicalWireData = f.read()
78 f.close()
79 CheckReadBuffer(bytearray(canonicalWireData), 0, file_identifier=b'MONS')
80
81 # Write the generated buffer out to a file:
82 f = open('monsterdata_python_wire.mon', 'wb')
83 f.write(gen_buf[gen_off:])
84 f.close()
85
86
Austin Schuh272c6132020-11-14 16:37:52 -080087class TestObjectBasedAPI(unittest.TestCase):
88 ''' Tests the generated object based API.'''
89
90 def test_consistenty_with_repeated_pack_and_unpack(self):
91 ''' Checks the serialization and deserialization between a buffer and
92 its python object. It tests in the same way as the C++ object API test,
93 ObjectFlatBuffersTest in test.cpp. '''
94
95 buf, off = make_monster_from_generated_code()
96
97 # Turns a buffer into Python object (T class).
98 monster1 = MyGame.Example.Monster.Monster.GetRootAsMonster(buf, off)
99 monsterT1 = MyGame.Example.Monster.MonsterT.InitFromObj(monster1)
100
101 for sizePrefix in [True, False]:
102 # Re-serialize the data into a buffer.
103 b1 = flatbuffers.Builder(0)
104 if sizePrefix:
105 b1.FinishSizePrefixed(monsterT1.Pack(b1))
106 else:
107 b1.Finish(monsterT1.Pack(b1))
108 CheckReadBuffer(b1.Bytes, b1.Head(), sizePrefix)
109
110 # Deserializes the buffer into Python object again.
111 monster2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b1.Bytes,
112 b1.Head())
113 # Re-serializes the data into a buffer for one more time.
114 monsterT2 = MyGame.Example.Monster.MonsterT.InitFromObj(monster2)
115 for sizePrefix in [True, False]:
116 # Re-serializes the data into a buffer
117 b2 = flatbuffers.Builder(0)
118 if sizePrefix:
119 b2.FinishSizePrefixed(monsterT2.Pack(b2))
120 else:
121 b2.Finish(monsterT2.Pack(b2))
122 CheckReadBuffer(b2.Bytes, b2.Head(), sizePrefix)
123
124 def test_default_values_with_pack_and_unpack(self):
125 ''' Serializes and deserializes between a buffer with default values (no
126 specific values are filled when the buffer is created) and its python
127 object. '''
128 # Creates a flatbuffer with default values.
129 b1 = flatbuffers.Builder(0)
130 MyGame.Example.Monster.MonsterStart(b1)
131 gen_mon = MyGame.Example.Monster.MonsterEnd(b1)
132 b1.Finish(gen_mon)
133
134 # Converts the flatbuffer into the object class.
135 monster1 = MyGame.Example.Monster.Monster.GetRootAsMonster(b1.Bytes,
136 b1.Head())
137 monsterT1 = MyGame.Example.Monster.MonsterT.InitFromObj(monster1)
138
139 # Packs the object class into another flatbuffer.
140 b2 = flatbuffers.Builder(0)
141 b2.Finish(monsterT1.Pack(b2))
142 monster2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b2.Bytes,
143 b2.Head())
144 # Checks the default values.
145 self.assertTrue(monster2.Pos() is None)
146 self.assertEqual(monster2.Mana(),150)
147 self.assertEqual(monster2.Hp(), 100)
148 self.assertTrue(monster2.Name() is None)
149 self.assertEqual(monster2.Inventory(0), 0)
150 self.assertEqual(monster2.InventoryAsNumpy(), 0)
151 self.assertEqual(monster2.InventoryLength(), 0)
152 self.assertTrue(monster2.InventoryIsNone())
153 self.assertTrue(monster2.Color() is 8)
154 self.assertEqual(monster2.TestType(), 0)
155 self.assertTrue(monster2.Test() is None)
156 self.assertTrue(monster2.Test4(0) is None)
157 self.assertEqual(monster2.Test4Length(), 0)
158 self.assertTrue(monster2.Test4IsNone())
159 self.assertTrue(monster2.Testarrayofstring(0) is "")
160 self.assertEqual(monster2.TestarrayofstringLength(), 0)
161 self.assertTrue(monster2.TestarrayofstringIsNone())
162 self.assertTrue(monster2.Testarrayoftables(0) is None)
163 self.assertEqual(monster2.TestarrayoftablesLength(), 0)
164 self.assertTrue(monster2.TestarrayoftablesIsNone())
165 self.assertTrue(monster2.Enemy() is None)
166 self.assertEqual(monster2.Testnestedflatbuffer(0), 0)
167 self.assertEqual(monster2.TestnestedflatbufferAsNumpy(), 0)
168 self.assertEqual(monster2.TestnestedflatbufferLength(), 0)
169 self.assertTrue(monster2.TestnestedflatbufferIsNone())
170 self.assertTrue(monster2.Testempty() is None)
171 self.assertTrue(monster2.Testbool() is False)
172 self.assertEqual(monster2.Testhashs32Fnv1(), 0)
173 self.assertEqual(monster2.Testhashu32Fnv1(), 0)
174 self.assertEqual(monster2.Testhashs64Fnv1(), 0)
175 self.assertEqual(monster2.Testhashu64Fnv1(), 0)
176 self.assertEqual(monster2.Testhashs32Fnv1a(), 0)
177 self.assertEqual(monster2.Testhashu32Fnv1a(), 0)
178 self.assertEqual(monster2.Testhashs64Fnv1a(), 0)
179 self.assertEqual(monster2.Testhashu64Fnv1a(), 0)
180 self.assertEqual(monster2.Testarrayofbools(0), 0)
181 self.assertEqual(monster2.TestarrayofboolsAsNumpy(), 0)
182 self.assertEqual(monster2.TestarrayofboolsLength(), 0)
183 self.assertTrue(monster2.TestarrayofboolsIsNone())
184 self.assertEqual(monster2.Testf(), 3.14159)
185 self.assertEqual(monster2.Testf2(), 3.0)
186 self.assertEqual(monster2.Testf3(), 0.0)
187 self.assertTrue(monster2.Testarrayofstring2(0) is "")
188 self.assertEqual(monster2.Testarrayofstring2Length(), 0)
189 self.assertTrue(monster2.Testarrayofstring2IsNone())
190 self.assertTrue(monster2.Testarrayofsortedstruct(0) is None)
191 self.assertEqual(monster2.TestarrayofsortedstructLength(), 0)
192 self.assertTrue(monster2.TestarrayofsortedstructIsNone())
193 self.assertEqual(monster2.Flex(0), 0)
194 self.assertEqual(monster2.FlexAsNumpy(), 0)
195 self.assertEqual(monster2.FlexLength(), 0)
196 self.assertTrue(monster2.FlexIsNone())
197 self.assertTrue(monster2.Test5(0) is None)
198 self.assertEqual(monster2.Test5Length(), 0)
199 self.assertTrue(monster2.Test5IsNone())
200 self.assertEqual(monster2.VectorOfLongs(0), 0)
201 self.assertEqual(monster2.VectorOfLongsAsNumpy(), 0)
202 self.assertEqual(monster2.VectorOfLongsLength(), 0)
203 self.assertTrue(monster2.VectorOfLongsIsNone())
204 self.assertEqual(monster2.VectorOfDoubles(0), 0)
205 self.assertEqual(monster2.VectorOfDoublesAsNumpy(), 0)
206 self.assertEqual(monster2.VectorOfDoublesLength(), 0)
207 self.assertTrue(monster2.VectorOfDoublesIsNone())
208 self.assertTrue(monster2.ParentNamespaceTest() is None)
209 self.assertTrue(monster2.VectorOfReferrables(0) is None)
210 self.assertEqual(monster2.VectorOfReferrablesLength(), 0)
211 self.assertTrue(monster2.VectorOfReferrablesIsNone())
212 self.assertEqual(monster2.SingleWeakReference(), 0)
213 self.assertEqual(monster2.VectorOfWeakReferences(0), 0)
214 self.assertEqual(monster2.VectorOfWeakReferencesAsNumpy(), 0)
215 self.assertEqual(monster2.VectorOfWeakReferencesLength(), 0)
216 self.assertTrue(monster2.VectorOfWeakReferencesIsNone())
217 self.assertTrue(monster2.VectorOfStrongReferrables(0) is None)
218 self.assertEqual(monster2.VectorOfStrongReferrablesLength(), 0)
219 self.assertTrue(monster2.VectorOfStrongReferrablesIsNone())
220 self.assertEqual(monster2.CoOwningReference(), 0)
221 self.assertEqual(monster2.VectorOfCoOwningReferences(0), 0)
222 self.assertEqual(monster2.VectorOfCoOwningReferencesAsNumpy(), 0)
223 self.assertEqual(monster2.VectorOfCoOwningReferencesLength(), 0)
224 self.assertTrue(monster2.VectorOfCoOwningReferencesIsNone())
225 self.assertEqual(monster2.NonOwningReference(), 0)
226 self.assertEqual(monster2.VectorOfNonOwningReferences(0), 0)
227 self.assertEqual(monster2.VectorOfNonOwningReferencesAsNumpy(), 0)
228 self.assertEqual(monster2.VectorOfNonOwningReferencesLength(), 0)
229 self.assertTrue(monster2.VectorOfNonOwningReferencesIsNone())
230 self.assertEqual(monster2.AnyUniqueType(), 0)
231 self.assertTrue(monster2.AnyUnique() is None)
232 self.assertEqual(monster2.AnyAmbiguousType(), 0)
233 self.assertTrue(monster2.AnyAmbiguous() is None)
234 self.assertEqual(monster2.VectorOfEnums(0), 0)
235 self.assertEqual(monster2.VectorOfEnumsAsNumpy(), 0)
236 self.assertEqual(monster2.VectorOfEnumsLength(), 0)
237 self.assertTrue(monster2.VectorOfEnumsIsNone())
238
239
240class TestAllMutableCodePathsOfExampleSchema(unittest.TestCase):
241 ''' Tests the object API generated for monster_test.fbs for mutation
242 purposes. In each test, the default values will be changed through the
243 object API. We'll then pack the object class into the buf class and read
244 the updated values out from it to validate if the values are mutated as
245 expected.'''
246
247 def setUp(self, *args, **kwargs):
248 super(TestAllMutableCodePathsOfExampleSchema, self).setUp(*args,
249 **kwargs)
250 # Creates an empty monster flatbuffer, and loads it into the object
251 # class for future tests.
252 b = flatbuffers.Builder(0)
253 MyGame.Example.Monster.MonsterStart(b)
254 self.monsterT = self._create_and_load_object_class(b)
255
256 def _pack_and_load_buf_class(self, monsterT):
257 ''' Packs the object class into a flatbuffer and loads it into a buf
258 class.'''
259 b = flatbuffers.Builder(0)
260 b.Finish(monsterT.Pack(b))
261 monster = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
262 b.Head())
263 return monster
264
265 def _create_and_load_object_class(self, b):
266 ''' Finishs the creation of a monster flatbuffer and loads it into an
267 object class.'''
268 gen_mon = MyGame.Example.Monster.MonsterEnd(b)
269 b.Finish(gen_mon)
270 monster = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
271 b.Head())
272 monsterT = MyGame.Example.Monster.MonsterT()
273 monsterT.InitFromObj(monster)
274 return monsterT
275
276 def test_mutate_pos(self):
277 posT = MyGame.Example.Vec3.Vec3T()
278 posT.x = 4.0
279 posT.y = 5.0
280 posT.z = 6.0
281 posT.test1 = 6.0
282 posT.test2 = 7
283 test3T = MyGame.Example.Test.TestT()
284 test3T.a = 8
285 test3T.b = 9
286 posT.test3 = test3T
287 self.monsterT.pos = posT
288
289 # Packs the updated values.
290 monster = self._pack_and_load_buf_class(self.monsterT)
291
292 # Checks if values are loaded correctly into the object class.
293 pos = monster.Pos()
294
295 # Verifies the properties of the Vec3.
296 self.assertEqual(pos.X(), 4.0)
297 self.assertEqual(pos.Y(), 5.0)
298 self.assertEqual(pos.Z(), 6.0)
299 self.assertEqual(pos.Test1(), 6.0)
300 self.assertEqual(pos.Test2(), 7)
301 t3 = MyGame.Example.Test.Test()
302 t3 = pos.Test3(t3)
303 self.assertEqual(t3.A(), 8)
304 self.assertEqual(t3.B(), 9)
305
306 def test_mutate_mana(self):
307 self.monsterT.mana = 200
308 monster = self._pack_and_load_buf_class(self.monsterT)
309 self.assertEqual(monster.Mana(), 200)
310
311 def test_mutate_hp(self):
312 self.monsterT.hp = 200
313 monster = self._pack_and_load_buf_class(self.monsterT)
314 self.assertEqual(monster.Hp(), 200)
315
316 def test_mutate_name(self):
317 self.monsterT.name = "MyMonster"
318 monster = self._pack_and_load_buf_class(self.monsterT)
319 self.assertEqual(monster.Name(), b"MyMonster")
320
321 def test_mutate_inventory(self):
322 self.monsterT.inventory = [1, 7, 8]
323 monster = self._pack_and_load_buf_class(self.monsterT)
324 self.assertEqual(monster.Inventory(0), 1)
325 self.assertEqual(monster.Inventory(1), 7)
326 self.assertEqual(monster.Inventory(2), 8)
327
328 def test_empty_inventory(self):
329 self.monsterT.inventory = []
330 monster = self._pack_and_load_buf_class(self.monsterT)
331 self.assertFalse(monster.InventoryIsNone())
332
333 def test_mutate_color(self):
334 self.monsterT.color = MyGame.Example.Color.Color.Red
335 monster = self._pack_and_load_buf_class(self.monsterT)
336 self.assertEqual(monster.Color(), MyGame.Example.Color.Color.Red)
337
338 def test_mutate_testtype(self):
339 self.monsterT.testType = MyGame.Example.Any.Any.Monster
340 monster = self._pack_and_load_buf_class(self.monsterT)
341 self.assertEqual(monster.TestType(), MyGame.Example.Any.Any.Monster)
342
343 def test_mutate_test(self):
344 testT = MyGame.Example.Monster.MonsterT()
345 testT.hp = 200
346 self.monsterT.test = testT
347 monster = self._pack_and_load_buf_class(self.monsterT)
348 # Initializes a Table from a union field Test(...).
349 table = monster.Test()
350
351 # Initializes a Monster from the Table from the union.
352 test_monster = MyGame.Example.Monster.Monster()
353 test_monster.Init(table.Bytes, table.Pos)
354 self.assertEqual(test_monster.Hp(), 200)
355
356 def test_mutate_test4(self):
357 test0T = MyGame.Example.Test.TestT()
358 test0T.a = 10
359 test0T.b = 20
360 test1T = MyGame.Example.Test.TestT()
361 test1T.a = 30
362 test1T.b = 40
363 self.monsterT.test4 = [test0T, test1T]
364
365 monster = self._pack_and_load_buf_class(self.monsterT)
366 test0 = monster.Test4(0)
367 self.assertEqual(test0.A(), 10)
368 self.assertEqual(test0.B(), 20)
369 test1 = monster.Test4(1)
370 self.assertEqual(test1.A(), 30)
371 self.assertEqual(test1.B(), 40)
372
373 def test_empty_test4(self):
374 self.monsterT.test4 = []
375 monster = self._pack_and_load_buf_class(self.monsterT)
376 self.assertFalse(monster.Test4IsNone())
377
378 def test_mutate_testarrayofstring(self):
379 self.monsterT.testarrayofstring = []
380 self.monsterT.testarrayofstring.append("test1")
381 self.monsterT.testarrayofstring.append("test2")
382 monster = self._pack_and_load_buf_class(self.monsterT)
383 self.assertEqual(monster.Testarrayofstring(0), b"test1")
384 self.assertEqual(monster.Testarrayofstring(1), b"test2")
385
386 def test_empty_testarrayofstring(self):
387 self.monsterT.testarrayofstring = []
388 monster = self._pack_and_load_buf_class(self.monsterT)
389 self.assertFalse(monster.TestarrayofstringIsNone())
390
391 def test_mutate_testarrayoftables(self):
392 monsterT0 = MyGame.Example.Monster.MonsterT()
393 monsterT0.hp = 200
394 monsterT1 = MyGame.Example.Monster.MonsterT()
395 monsterT1.hp = 400
396 self.monsterT.testarrayoftables = []
397 self.monsterT.testarrayoftables.append(monsterT0)
398 self.monsterT.testarrayoftables.append(monsterT1)
399 monster = self._pack_and_load_buf_class(self.monsterT)
400 self.assertEqual(monster.Testarrayoftables(0).Hp(), 200)
401 self.assertEqual(monster.Testarrayoftables(1).Hp(), 400)
402
403 def test_empty_testarrayoftables(self):
404 self.monsterT.testarrayoftables = []
405 monster = self._pack_and_load_buf_class(self.monsterT)
406 self.assertFalse(monster.TestarrayoftablesIsNone())
407
408 def test_mutate_enemy(self):
409 monsterT = MyGame.Example.Monster.MonsterT()
410 monsterT.hp = 200
411 self.monsterT.enemy = monsterT
412 monster = self._pack_and_load_buf_class(self.monsterT)
413 self.assertEqual(monster.Enemy().Hp(), 200)
414
415 def test_mutate_testnestedflatbuffer(self):
416 self.monsterT.testnestedflatbuffer = [8, 2, 4]
417 monster = self._pack_and_load_buf_class(self.monsterT)
418 self.assertEqual(monster.Testnestedflatbuffer(0), 8)
419 self.assertEqual(monster.Testnestedflatbuffer(1), 2)
420 self.assertEqual(monster.Testnestedflatbuffer(2), 4)
421
422 def test_empty_testnestedflatbuffer(self):
423 self.monsterT.testnestedflatbuffer = []
424 monster = self._pack_and_load_buf_class(self.monsterT)
425 self.assertFalse(monster.TestnestedflatbufferIsNone())
426
427 def test_mutate_testbool(self):
428 self.monsterT.testbool = True
429 monster = self._pack_and_load_buf_class(self.monsterT)
430 self.assertTrue(monster.Testbool())
431
432 def test_mutate_testhashes(self):
433 self.monsterT.testhashs32Fnv1 = 1
434 self.monsterT.testhashu32Fnv1 = 2
435 self.monsterT.testhashs64Fnv1 = 3
436 self.monsterT.testhashu64Fnv1 = 4
437 self.monsterT.testhashs32Fnv1a = 5
438 self.monsterT.testhashu32Fnv1a = 6
439 self.monsterT.testhashs64Fnv1a = 7
440 self.monsterT.testhashu64Fnv1a = 8
441 monster = self._pack_and_load_buf_class(self.monsterT)
442 self.assertEqual(monster.Testhashs32Fnv1(), 1)
443 self.assertEqual(monster.Testhashu32Fnv1(), 2)
444 self.assertEqual(monster.Testhashs64Fnv1(), 3)
445 self.assertEqual(monster.Testhashu64Fnv1(), 4)
446 self.assertEqual(monster.Testhashs32Fnv1a(), 5)
447 self.assertEqual(monster.Testhashu32Fnv1a(), 6)
448 self.assertEqual(monster.Testhashs64Fnv1a(), 7)
449 self.assertEqual(monster.Testhashu64Fnv1a(), 8)
450
451 def test_mutate_testarrayofbools(self):
452 self.monsterT.testarrayofbools = []
453 self.monsterT.testarrayofbools.append(True)
454 self.monsterT.testarrayofbools.append(True)
455 self.monsterT.testarrayofbools.append(False)
456 monster = self._pack_and_load_buf_class(self.monsterT)
457 self.assertEqual(monster.Testarrayofbools(0), True)
458 self.assertEqual(monster.Testarrayofbools(1), True)
459 self.assertEqual(monster.Testarrayofbools(2), False)
460
461 def test_empty_testarrayofbools(self):
462 self.monsterT.testarrayofbools = []
463 monster = self._pack_and_load_buf_class(self.monsterT)
464 self.assertFalse(monster.TestarrayofboolsIsNone())
465
466 def test_mutate_testf(self):
467 self.monsterT.testf = 2.0
468 monster = self._pack_and_load_buf_class(self.monsterT)
469 self.assertEqual(monster.Testf(), 2.0)
470
471 def test_mutate_vectoroflongs(self):
472 self.monsterT.vectorOfLongs = []
473 self.monsterT.vectorOfLongs.append(1)
474 self.monsterT.vectorOfLongs.append(100)
475 self.monsterT.vectorOfLongs.append(10000)
476 self.monsterT.vectorOfLongs.append(1000000)
477 self.monsterT.vectorOfLongs.append(100000000)
478 monster = self._pack_and_load_buf_class(self.monsterT)
479 self.assertEqual(monster.VectorOfLongs(0), 1)
480 self.assertEqual(monster.VectorOfLongs(1), 100)
481 self.assertEqual(monster.VectorOfLongs(2), 10000)
482 self.assertEqual(monster.VectorOfLongs(3), 1000000)
483 self.assertEqual(monster.VectorOfLongs(4), 100000000)
484
485 def test_empty_vectoroflongs(self):
486 self.monsterT.vectorOfLongs = []
487 monster = self._pack_and_load_buf_class(self.monsterT)
488 self.assertFalse(monster.VectorOfLongsIsNone())
489
490 def test_mutate_vectorofdoubles(self):
491 self.monsterT.vectorOfDoubles = []
492 self.monsterT.vectorOfDoubles.append(-1.7976931348623157e+308)
493 self.monsterT.vectorOfDoubles.append(0)
494 self.monsterT.vectorOfDoubles.append(1.7976931348623157e+308)
495 monster = self._pack_and_load_buf_class(self.monsterT)
496 self.assertEqual(monster.VectorOfDoubles(0), -1.7976931348623157e+308)
497 self.assertEqual(monster.VectorOfDoubles(1), 0)
498 self.assertEqual(monster.VectorOfDoubles(2), 1.7976931348623157e+308)
499
500 def test_empty_vectorofdoubles(self):
501 self.monsterT.vectorOfDoubles = []
502 monster = self._pack_and_load_buf_class(self.monsterT)
503 self.assertFalse(monster.VectorOfDoublesIsNone())
504
505 def test_mutate_parentnamespacetest(self):
506 self.monsterT.parentNamespaceTest = MyGame.InParentNamespace.InParentNamespaceT()
507 monster = self._pack_and_load_buf_class(self.monsterT)
508 self.assertTrue(isinstance(monster.ParentNamespaceTest(),
509 MyGame.InParentNamespace.InParentNamespace))
510
511 def test_mutate_vectorofEnums(self):
512 self.monsterT.vectorOfEnums = []
513 self.monsterT.vectorOfEnums.append(MyGame.Example.Color.Color.Red)
514 self.monsterT.vectorOfEnums.append(MyGame.Example.Color.Color.Blue)
515 self.monsterT.vectorOfEnums.append(MyGame.Example.Color.Color.Red)
516 monster = self._pack_and_load_buf_class(self.monsterT)
517 self.assertEqual(monster.VectorOfEnums(0),
518 MyGame.Example.Color.Color.Red)
519 self.assertEqual(monster.VectorOfEnums(1),
520 MyGame.Example.Color.Color.Blue)
521 self.assertEqual(monster.VectorOfEnums(2),
522 MyGame.Example.Color.Color.Red)
523
524 def test_empty_vectorofEnums(self):
525 self.monsterT.vectorOfEnums = []
526 monster = self._pack_and_load_buf_class(self.monsterT)
527 self.assertFalse(monster.VectorOfEnumsIsNone())
528
529
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700530def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
531 ''' CheckReadBuffer checks that the given buffer is evaluated correctly
532 as the example Monster. '''
533
534 def asserter(stmt):
535 ''' An assertion helper that is separated from TestCase classes. '''
536 if not stmt:
537 raise AssertionError('CheckReadBuffer case failed')
538 if file_identifier:
539 # test prior to removal of size_prefix
540 asserter(util.GetBufferIdentifier(buf, offset, size_prefixed=sizePrefix) == file_identifier)
541 asserter(util.BufferHasIdentifier(buf, offset, file_identifier=file_identifier, size_prefixed=sizePrefix))
Austin Schuh272c6132020-11-14 16:37:52 -0800542 asserter(MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset, size_prefixed=sizePrefix))
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700543 if sizePrefix:
544 size = util.GetSizePrefix(buf, offset)
545 asserter(size == len(buf[offset:])-4)
546 buf, offset = util.RemoveSizePrefix(buf, offset)
547 if file_identifier:
548 asserter(MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset))
549 else:
550 asserter(not MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset))
551 monster = MyGame.Example.Monster.Monster.GetRootAsMonster(buf, offset)
552
553 asserter(monster.Hp() == 80)
554 asserter(monster.Mana() == 150)
555 asserter(monster.Name() == b'MyMonster')
556
557 # initialize a Vec3 from Pos()
558 vec = monster.Pos()
559 asserter(vec is not None)
560
561 # verify the properties of the Vec3
562 asserter(vec.X() == 1.0)
563 asserter(vec.Y() == 2.0)
564 asserter(vec.Z() == 3.0)
565 asserter(vec.Test1() == 3.0)
566 asserter(vec.Test2() == 2)
567
568 # initialize a Test from Test3(...)
569 t = MyGame.Example.Test.Test()
570 t = vec.Test3(t)
571 asserter(t is not None)
572
573 # verify the properties of the Test
574 asserter(t.A() == 5)
575 asserter(t.B() == 6)
576
577 # verify that the enum code matches the enum declaration:
578 union_type = MyGame.Example.Any.Any
579 asserter(monster.TestType() == union_type.Monster)
580
581 # initialize a Table from a union field Test(...)
582 table2 = monster.Test()
583 asserter(type(table2) is flatbuffers.table.Table)
584
585 # initialize a Monster from the Table from the union
586 monster2 = MyGame.Example.Monster.Monster()
587 monster2.Init(table2.Bytes, table2.Pos)
588
589 asserter(monster2.Name() == b"Fred")
590
591 # iterate through the first monster's inventory:
592 asserter(monster.InventoryLength() == 5)
Austin Schuh272c6132020-11-14 16:37:52 -0800593 asserter(not monster.InventoryIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700594
595 invsum = 0
596 for i in compat_range(monster.InventoryLength()):
597 v = monster.Inventory(i)
598 invsum += int(v)
599 asserter(invsum == 10)
600
601 for i in range(5):
602 asserter(monster.VectorOfLongs(i) == 10 ** (i * 2))
603
Austin Schuh272c6132020-11-14 16:37:52 -0800604 asserter(not monster.VectorOfDoublesIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700605 asserter(([-1.7976931348623157e+308, 0, 1.7976931348623157e+308]
606 == [monster.VectorOfDoubles(i)
607 for i in range(monster.VectorOfDoublesLength())]))
608
609 try:
610 imp.find_module('numpy')
611 # if numpy exists, then we should be able to get the
612 # vector as a numpy array
613 import numpy as np
614
615 asserter(monster.InventoryAsNumpy().sum() == 10)
616 asserter(monster.InventoryAsNumpy().dtype == np.dtype('uint8'))
617
618 VectorOfLongs = monster.VectorOfLongsAsNumpy()
619 asserter(VectorOfLongs.dtype == np.dtype('int64'))
620 for i in range(5):
621 asserter(VectorOfLongs[i] == 10 ** (i * 2))
622
623 VectorOfDoubles = monster.VectorOfDoublesAsNumpy()
624 asserter(VectorOfDoubles.dtype == np.dtype('float64'))
625 asserter(VectorOfDoubles[0] == np.finfo('float64').min)
626 asserter(VectorOfDoubles[1] == 0.0)
627 asserter(VectorOfDoubles[2] == np.finfo('float64').max)
628
629 except ImportError:
630 # If numpy does not exist, trying to get vector as numpy
631 # array should raise NumpyRequiredForThisFeature. The way
632 # assertRaises has been implemented prevents us from
633 # asserting this error is raised outside of a test case.
634 pass
635
636 asserter(monster.Test4Length() == 2)
Austin Schuh272c6132020-11-14 16:37:52 -0800637 asserter(not monster.Test4IsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700638
639 # create a 'Test' object and populate it:
640 test0 = monster.Test4(0)
641 asserter(type(test0) is MyGame.Example.Test.Test)
642
643 test1 = monster.Test4(1)
644 asserter(type(test1) is MyGame.Example.Test.Test)
645
646 # the position of test0 and test1 are swapped in monsterdata_java_wire
647 # and monsterdata_test_wire, so ignore ordering
648 v0 = test0.A()
649 v1 = test0.B()
650 v2 = test1.A()
651 v3 = test1.B()
652 sumtest12 = int(v0) + int(v1) + int(v2) + int(v3)
653
654 asserter(sumtest12 == 100)
655
Austin Schuh272c6132020-11-14 16:37:52 -0800656 asserter(not monster.TestarrayofstringIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700657 asserter(monster.TestarrayofstringLength() == 2)
658 asserter(monster.Testarrayofstring(0) == b"test1")
659 asserter(monster.Testarrayofstring(1) == b"test2")
660
Austin Schuh272c6132020-11-14 16:37:52 -0800661 asserter(monster.TestarrayoftablesIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700662 asserter(monster.TestarrayoftablesLength() == 0)
Austin Schuh272c6132020-11-14 16:37:52 -0800663 asserter(monster.TestnestedflatbufferIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700664 asserter(monster.TestnestedflatbufferLength() == 0)
665 asserter(monster.Testempty() is None)
666
667
668class TestFuzz(unittest.TestCase):
669 ''' Low level stress/fuzz test: serialize/deserialize a variety of
670 different kinds of data in different combinations '''
671
672 binary_type = compat.binary_types[0] # this will always exist
673 ofInt32Bytes = binary_type([0x83, 0x33, 0x33, 0x33])
674 ofInt64Bytes = binary_type([0x84, 0x44, 0x44, 0x44,
675 0x44, 0x44, 0x44, 0x44])
676 overflowingInt32Val = flatbuffers.encode.Get(flatbuffers.packer.int32,
677 ofInt32Bytes, 0)
678 overflowingInt64Val = flatbuffers.encode.Get(flatbuffers.packer.int64,
679 ofInt64Bytes, 0)
680
681 # Values we're testing against: chosen to ensure no bits get chopped
682 # off anywhere, and also be different from eachother.
683 boolVal = True
684 int8Val = N.Int8Flags.py_type(-127) # 0x81
685 uint8Val = N.Uint8Flags.py_type(0xFF)
686 int16Val = N.Int16Flags.py_type(-32222) # 0x8222
687 uint16Val = N.Uint16Flags.py_type(0xFEEE)
688 int32Val = N.Int32Flags.py_type(overflowingInt32Val)
689 uint32Val = N.Uint32Flags.py_type(0xFDDDDDDD)
690 int64Val = N.Int64Flags.py_type(overflowingInt64Val)
691 uint64Val = N.Uint64Flags.py_type(0xFCCCCCCCCCCCCCCC)
692 # Python uses doubles, so force it here
693 float32Val = N.Float32Flags.py_type(ctypes.c_float(3.14159).value)
694 float64Val = N.Float64Flags.py_type(3.14159265359)
695
696 def test_fuzz(self):
697 return self.check_once(11, 100)
698
699 def check_once(self, fuzzFields, fuzzObjects):
700 testValuesMax = 11 # hardcoded to the number of scalar types
701
702 builder = flatbuffers.Builder(0)
703 l = LCG()
704
705 objects = [0 for _ in compat_range(fuzzObjects)]
706
707 # Generate fuzzObjects random objects each consisting of
708 # fuzzFields fields, each of a random type.
709 for i in compat_range(fuzzObjects):
710 builder.StartObject(fuzzFields)
711
712 for j in compat_range(fuzzFields):
713 choice = int(l.Next()) % testValuesMax
714 if choice == 0:
715 builder.PrependBoolSlot(int(j), self.boolVal, False)
716 elif choice == 1:
717 builder.PrependInt8Slot(int(j), self.int8Val, 0)
718 elif choice == 2:
719 builder.PrependUint8Slot(int(j), self.uint8Val, 0)
720 elif choice == 3:
721 builder.PrependInt16Slot(int(j), self.int16Val, 0)
722 elif choice == 4:
723 builder.PrependUint16Slot(int(j), self.uint16Val, 0)
724 elif choice == 5:
725 builder.PrependInt32Slot(int(j), self.int32Val, 0)
726 elif choice == 6:
727 builder.PrependUint32Slot(int(j), self.uint32Val, 0)
728 elif choice == 7:
729 builder.PrependInt64Slot(int(j), self.int64Val, 0)
730 elif choice == 8:
731 builder.PrependUint64Slot(int(j), self.uint64Val, 0)
732 elif choice == 9:
733 builder.PrependFloat32Slot(int(j), self.float32Val, 0)
734 elif choice == 10:
735 builder.PrependFloat64Slot(int(j), self.float64Val, 0)
736 else:
737 raise RuntimeError('unreachable')
738
739 off = builder.EndObject()
740
741 # store the offset from the end of the builder buffer,
742 # since it will keep growing:
743 objects[i] = off
744
745 # Do some bookkeeping to generate stats on fuzzes:
746 stats = defaultdict(int)
747 def check(table, desc, want, got):
748 stats[desc] += 1
749 self.assertEqual(want, got, "%s != %s, %s" % (want, got, desc))
750
751 l = LCG() # Reset.
752
753 # Test that all objects we generated are readable and return the
754 # expected values. We generate random objects in the same order
755 # so this is deterministic.
756 for i in compat_range(fuzzObjects):
757
758 table = flatbuffers.table.Table(builder.Bytes,
759 len(builder.Bytes) - objects[i])
760
761 for j in compat_range(fuzzFields):
762 field_count = flatbuffers.builder.VtableMetadataFields + j
763 f = N.VOffsetTFlags.py_type(field_count *
764 N.VOffsetTFlags.bytewidth)
765 choice = int(l.Next()) % testValuesMax
766
767 if choice == 0:
768 check(table, "bool", self.boolVal,
769 table.GetSlot(f, False, N.BoolFlags))
770 elif choice == 1:
771 check(table, "int8", self.int8Val,
772 table.GetSlot(f, 0, N.Int8Flags))
773 elif choice == 2:
774 check(table, "uint8", self.uint8Val,
775 table.GetSlot(f, 0, N.Uint8Flags))
776 elif choice == 3:
777 check(table, "int16", self.int16Val,
778 table.GetSlot(f, 0, N.Int16Flags))
779 elif choice == 4:
780 check(table, "uint16", self.uint16Val,
781 table.GetSlot(f, 0, N.Uint16Flags))
782 elif choice == 5:
783 check(table, "int32", self.int32Val,
784 table.GetSlot(f, 0, N.Int32Flags))
785 elif choice == 6:
786 check(table, "uint32", self.uint32Val,
787 table.GetSlot(f, 0, N.Uint32Flags))
788 elif choice == 7:
789 check(table, "int64", self.int64Val,
790 table.GetSlot(f, 0, N.Int64Flags))
791 elif choice == 8:
792 check(table, "uint64", self.uint64Val,
793 table.GetSlot(f, 0, N.Uint64Flags))
794 elif choice == 9:
795 check(table, "float32", self.float32Val,
796 table.GetSlot(f, 0, N.Float32Flags))
797 elif choice == 10:
798 check(table, "float64", self.float64Val,
799 table.GetSlot(f, 0, N.Float64Flags))
800 else:
801 raise RuntimeError('unreachable')
802
803 # If enough checks were made, verify that all scalar types were used:
804 self.assertEqual(testValuesMax, len(stats),
805 "fuzzing failed to test all scalar types: %s" % stats)
806
807
808class TestByteLayout(unittest.TestCase):
809 ''' TestByteLayout checks the bytes of a Builder in various scenarios. '''
810
811 def assertBuilderEquals(self, builder, want_chars_or_ints):
812 def integerize(x):
813 if isinstance(x, compat.string_types):
814 return ord(x)
815 return x
816
817 want_ints = list(map(integerize, want_chars_or_ints))
818 want = bytearray(want_ints)
819 got = builder.Bytes[builder.Head():] # use the buffer directly
820 self.assertEqual(want, got)
821
822 def test_numbers(self):
823 b = flatbuffers.Builder(0)
824 self.assertBuilderEquals(b, [])
825 b.PrependBool(True)
826 self.assertBuilderEquals(b, [1])
827 b.PrependInt8(-127)
828 self.assertBuilderEquals(b, [129, 1])
829 b.PrependUint8(255)
830 self.assertBuilderEquals(b, [255, 129, 1])
831 b.PrependInt16(-32222)
832 self.assertBuilderEquals(b, [0x22, 0x82, 0, 255, 129, 1]) # first pad
833 b.PrependUint16(0xFEEE)
834 # no pad this time:
835 self.assertBuilderEquals(b, [0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1])
836 b.PrependInt32(-53687092)
837 self.assertBuilderEquals(b, [204, 204, 204, 252, 0xEE, 0xFE,
838 0x22, 0x82, 0, 255, 129, 1])
839 b.PrependUint32(0x98765432)
840 self.assertBuilderEquals(b, [0x32, 0x54, 0x76, 0x98,
841 204, 204, 204, 252,
842 0xEE, 0xFE, 0x22, 0x82,
843 0, 255, 129, 1])
844
845 def test_numbers64(self):
846 b = flatbuffers.Builder(0)
847 b.PrependUint64(0x1122334455667788)
848 self.assertBuilderEquals(b, [0x88, 0x77, 0x66, 0x55,
849 0x44, 0x33, 0x22, 0x11])
850
851 b = flatbuffers.Builder(0)
852 b.PrependInt64(0x1122334455667788)
853 self.assertBuilderEquals(b, [0x88, 0x77, 0x66, 0x55,
854 0x44, 0x33, 0x22, 0x11])
855
856 def test_1xbyte_vector(self):
857 b = flatbuffers.Builder(0)
858 self.assertBuilderEquals(b, [])
859 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 1, 1)
860 self.assertBuilderEquals(b, [0, 0, 0]) # align to 4bytes
861 b.PrependByte(1)
862 self.assertBuilderEquals(b, [1, 0, 0, 0])
863 b.EndVector(1)
864 self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
865
866 def test_2xbyte_vector(self):
867 b = flatbuffers.Builder(0)
868 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 2, 1)
869 self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
870 b.PrependByte(1)
871 self.assertBuilderEquals(b, [1, 0, 0])
872 b.PrependByte(2)
873 self.assertBuilderEquals(b, [2, 1, 0, 0])
874 b.EndVector(2)
875 self.assertBuilderEquals(b, [2, 0, 0, 0, 2, 1, 0, 0]) # padding
876
877 def test_1xuint16_vector(self):
878 b = flatbuffers.Builder(0)
879 b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 1, 1)
880 self.assertBuilderEquals(b, [0, 0]) # align to 4bytes
881 b.PrependUint16(1)
882 self.assertBuilderEquals(b, [1, 0, 0, 0])
883 b.EndVector(1)
884 self.assertBuilderEquals(b, [1, 0, 0, 0, 1, 0, 0, 0]) # padding
885
886 def test_2xuint16_vector(self):
887 b = flatbuffers.Builder(0)
888 b.StartVector(flatbuffers.number_types.Uint16Flags.bytewidth, 2, 1)
889 self.assertBuilderEquals(b, []) # align to 4bytes
890 b.PrependUint16(0xABCD)
891 self.assertBuilderEquals(b, [0xCD, 0xAB])
892 b.PrependUint16(0xDCBA)
893 self.assertBuilderEquals(b, [0xBA, 0xDC, 0xCD, 0xAB])
894 b.EndVector(2)
895 self.assertBuilderEquals(b, [2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB])
896
897 def test_create_ascii_string(self):
898 b = flatbuffers.Builder(0)
899 b.CreateString(u"foo", encoding='ascii')
900
901 # 0-terminated, no pad:
902 self.assertBuilderEquals(b, [3, 0, 0, 0, 'f', 'o', 'o', 0])
903 b.CreateString(u"moop", encoding='ascii')
904 # 0-terminated, 3-byte pad:
905 self.assertBuilderEquals(b, [4, 0, 0, 0, 'm', 'o', 'o', 'p',
906 0, 0, 0, 0,
907 3, 0, 0, 0, 'f', 'o', 'o', 0])
908
909 def test_create_utf8_string(self):
910 b = flatbuffers.Builder(0)
911 b.CreateString(u"Цлїςσδε")
912 self.assertBuilderEquals(b, "\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97" \
913 "\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00")
914
915 b.CreateString(u"フムアムカモケモ")
916 self.assertBuilderEquals(b, "\x18\x00\x00\x00\xef\xbe\x8c\xef\xbe\x91" \
917 "\xef\xbd\xb1\xef\xbe\x91\xef\xbd\xb6\xef\xbe\x93\xef\xbd\xb9\xef" \
918 "\xbe\x93\x00\x00\x00\x00\x0e\x00\x00\x00\xd0\xa6\xd0\xbb\xd1\x97" \
919 "\xcf\x82\xcf\x83\xce\xb4\xce\xb5\x00\x00")
920
921 def test_create_arbitrary_string(self):
922 b = flatbuffers.Builder(0)
923 s = "\x01\x02\x03"
924 b.CreateString(s) # Default encoding is utf-8.
925 # 0-terminated, no pad:
926 self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
927 s2 = "\x04\x05\x06\x07"
928 b.CreateString(s2) # Default encoding is utf-8.
929 # 0-terminated, 3-byte pad:
930 self.assertBuilderEquals(b, [4, 0, 0, 0, 4, 5, 6, 7, 0, 0, 0, 0,
931 3, 0, 0, 0, 1, 2, 3, 0])
932
933 def test_create_byte_vector(self):
934 b = flatbuffers.Builder(0)
935 b.CreateByteVector(b"")
936 # 0-byte pad:
937 self.assertBuilderEquals(b, [0, 0, 0, 0])
938
939 b = flatbuffers.Builder(0)
940 b.CreateByteVector(b"\x01\x02\x03")
941 # 1-byte pad:
942 self.assertBuilderEquals(b, [3, 0, 0, 0, 1, 2, 3, 0])
943
944 def test_create_numpy_vector_int8(self):
945 try:
946 imp.find_module('numpy')
947 # if numpy exists, then we should be able to get the
948 # vector as a numpy array
949 import numpy as np
950
951 # Systems endian:
952 b = flatbuffers.Builder(0)
953 x = np.array([1, 2, -3], dtype=np.int8)
954 b.CreateNumpyVector(x)
955 self.assertBuilderEquals(b, [
956 3, 0, 0, 0, # vector length
957 1, 2, 256 - 3, 0 # vector value + padding
958 ])
959
960 # Reverse endian:
961 b = flatbuffers.Builder(0)
962 x_other_endian = x.byteswap().newbyteorder()
963 b.CreateNumpyVector(x_other_endian)
964 self.assertBuilderEquals(b, [
965 3, 0, 0, 0, # vector length
966 1, 2, 256 - 3, 0 # vector value + padding
967 ])
968 except ImportError:
969 b = flatbuffers.Builder(0)
970 x = 0
971 assertRaises(
972 self,
973 lambda: b.CreateNumpyVector(x),
974 NumpyRequiredForThisFeature)
975
976 def test_create_numpy_vector_uint16(self):
977 try:
978 imp.find_module('numpy')
979 # if numpy exists, then we should be able to get the
980 # vector as a numpy array
981 import numpy as np
982
983 # Systems endian:
984 b = flatbuffers.Builder(0)
985 x = np.array([1, 2, 312], dtype=np.uint16)
986 b.CreateNumpyVector(x)
987 self.assertBuilderEquals(b, [
988 3, 0, 0, 0, # vector length
989 1, 0, # 1
990 2, 0, # 2
991 312 - 256, 1, # 312
992 0, 0 # padding
993 ])
994
995 # Reverse endian:
996 b = flatbuffers.Builder(0)
997 x_other_endian = x.byteswap().newbyteorder()
998 b.CreateNumpyVector(x_other_endian)
999 self.assertBuilderEquals(b, [
1000 3, 0, 0, 0, # vector length
1001 1, 0, # 1
1002 2, 0, # 2
1003 312 - 256, 1, # 312
1004 0, 0 # padding
1005 ])
1006 except ImportError:
1007 b = flatbuffers.Builder(0)
1008 x = 0
1009 assertRaises(
1010 self,
1011 lambda: b.CreateNumpyVector(x),
1012 NumpyRequiredForThisFeature)
1013
1014 def test_create_numpy_vector_int64(self):
1015 try:
1016 imp.find_module('numpy')
1017 # if numpy exists, then we should be able to get the
1018 # vector as a numpy array
1019 import numpy as np
1020
1021 # Systems endian:
1022 b = flatbuffers.Builder(0)
1023 x = np.array([1, 2, -12], dtype=np.int64)
1024 b.CreateNumpyVector(x)
1025 self.assertBuilderEquals(b, [
1026 3, 0, 0, 0, # vector length
1027 1, 0, 0, 0, 0, 0, 0, 0, # 1
1028 2, 0, 0, 0, 0, 0, 0, 0, # 2
1029 256 - 12, 255, 255, 255, 255, 255, 255, 255 # -12
1030 ])
1031
1032 # Reverse endian:
1033 b = flatbuffers.Builder(0)
1034 x_other_endian = x.byteswap().newbyteorder()
1035 b.CreateNumpyVector(x_other_endian)
1036 self.assertBuilderEquals(b, [
1037 3, 0, 0, 0, # vector length
1038 1, 0, 0, 0, 0, 0, 0, 0, # 1
1039 2, 0, 0, 0, 0, 0, 0, 0, # 2
1040 256 - 12, 255, 255, 255, 255, 255, 255, 255 # -12
1041 ])
1042
1043 except ImportError:
1044 b = flatbuffers.Builder(0)
1045 x = 0
1046 assertRaises(
1047 self,
1048 lambda: b.CreateNumpyVector(x),
1049 NumpyRequiredForThisFeature)
1050
1051 def test_create_numpy_vector_float32(self):
1052 try:
1053 imp.find_module('numpy')
1054 # if numpy exists, then we should be able to get the
1055 # vector as a numpy array
1056 import numpy as np
1057
1058 # Systems endian:
1059 b = flatbuffers.Builder(0)
1060 x = np.array([1, 2, -12], dtype=np.float32)
1061 b.CreateNumpyVector(x)
1062 self.assertBuilderEquals(b, [
1063 3, 0, 0, 0, # vector length
1064 0, 0, 128, 63, # 1
1065 0, 0, 0, 64, # 2
1066 0, 0, 64, 193 # -12
1067 ])
1068
1069 # Reverse endian:
1070 b = flatbuffers.Builder(0)
1071 x_other_endian = x.byteswap().newbyteorder()
1072 b.CreateNumpyVector(x_other_endian)
1073 self.assertBuilderEquals(b, [
1074 3, 0, 0, 0, # vector length
1075 0, 0, 128, 63, # 1
1076 0, 0, 0, 64, # 2
1077 0, 0, 64, 193 # -12
1078 ])
1079
1080 except ImportError:
1081 b = flatbuffers.Builder(0)
1082 x = 0
1083 assertRaises(
1084 self,
1085 lambda: b.CreateNumpyVector(x),
1086 NumpyRequiredForThisFeature)
1087
1088 def test_create_numpy_vector_float64(self):
1089 try:
1090 imp.find_module('numpy')
1091 # if numpy exists, then we should be able to get the
1092 # vector as a numpy array
1093 import numpy as np
1094
1095 # Systems endian:
1096 b = flatbuffers.Builder(0)
1097 x = np.array([1, 2, -12], dtype=np.float64)
1098 b.CreateNumpyVector(x)
1099 self.assertBuilderEquals(b, [
1100 3, 0, 0, 0, # vector length
1101 0, 0, 0, 0, 0, 0, 240, 63, # 1
1102 0, 0, 0, 0, 0, 0, 0, 64, # 2
1103 0, 0, 0, 0, 0, 0, 40, 192 # -12
1104 ])
1105
1106 # Reverse endian:
1107 b = flatbuffers.Builder(0)
1108 x_other_endian = x.byteswap().newbyteorder()
1109 b.CreateNumpyVector(x_other_endian)
1110 self.assertBuilderEquals(b, [
1111 3, 0, 0, 0, # vector length
1112 0, 0, 0, 0, 0, 0, 240, 63, # 1
1113 0, 0, 0, 0, 0, 0, 0, 64, # 2
1114 0, 0, 0, 0, 0, 0, 40, 192 # -12
1115 ])
1116
1117 except ImportError:
1118 b = flatbuffers.Builder(0)
1119 x = 0
1120 assertRaises(
1121 self,
1122 lambda: b.CreateNumpyVector(x),
1123 NumpyRequiredForThisFeature)
1124
1125 def test_create_numpy_vector_bool(self):
1126 try:
1127 imp.find_module('numpy')
1128 # if numpy exists, then we should be able to get the
1129 # vector as a numpy array
1130 import numpy as np
1131
1132 # Systems endian:
1133 b = flatbuffers.Builder(0)
1134 x = np.array([True, False, True], dtype=np.bool)
1135 b.CreateNumpyVector(x)
1136 self.assertBuilderEquals(b, [
1137 3, 0, 0, 0, # vector length
1138 1, 0, 1, 0 # vector values + padding
1139 ])
1140
1141 # Reverse endian:
1142 b = flatbuffers.Builder(0)
1143 x_other_endian = x.byteswap().newbyteorder()
1144 b.CreateNumpyVector(x_other_endian)
1145 self.assertBuilderEquals(b, [
1146 3, 0, 0, 0, # vector length
1147 1, 0, 1, 0 # vector values + padding
1148 ])
1149
1150 except ImportError:
1151 b = flatbuffers.Builder(0)
1152 x = 0
1153 assertRaises(
1154 self,
1155 lambda: b.CreateNumpyVector(x),
1156 NumpyRequiredForThisFeature)
1157
1158 def test_create_numpy_vector_reject_strings(self):
1159 try:
1160 imp.find_module('numpy')
1161 # if numpy exists, then we should be able to get the
1162 # vector as a numpy array
1163 import numpy as np
1164
1165 # Create String array
1166 b = flatbuffers.Builder(0)
1167 x = np.array(["hello", "fb", "testing"])
1168 assertRaises(
1169 self,
1170 lambda: b.CreateNumpyVector(x),
1171 TypeError)
1172
1173 except ImportError:
1174 b = flatbuffers.Builder(0)
1175 x = 0
1176 assertRaises(
1177 self,
1178 lambda: b.CreateNumpyVector(x),
1179 NumpyRequiredForThisFeature)
1180
1181 def test_create_numpy_vector_reject_object(self):
1182 try:
1183 imp.find_module('numpy')
1184 # if numpy exists, then we should be able to get the
1185 # vector as a numpy array
1186 import numpy as np
1187
1188 # Create String array
1189 b = flatbuffers.Builder(0)
1190 x = np.array([{"m": 0}, {"as": -2.1, 'c': 'c'}])
1191 assertRaises(
1192 self,
1193 lambda: b.CreateNumpyVector(x),
1194 TypeError)
1195
1196 except ImportError:
1197 b = flatbuffers.Builder(0)
1198 x = 0
1199 assertRaises(
1200 self,
1201 lambda: b.CreateNumpyVector(x),
1202 NumpyRequiredForThisFeature)
1203
1204 def test_empty_vtable(self):
1205 b = flatbuffers.Builder(0)
1206 b.StartObject(0)
1207 self.assertBuilderEquals(b, [])
1208 b.EndObject()
1209 self.assertBuilderEquals(b, [4, 0, 4, 0, 4, 0, 0, 0])
1210
1211 def test_vtable_with_one_true_bool(self):
1212 b = flatbuffers.Builder(0)
1213 self.assertBuilderEquals(b, [])
1214 b.StartObject(1)
1215 self.assertBuilderEquals(b, [])
1216 b.PrependBoolSlot(0, True, False)
1217 b.EndObject()
1218 self.assertBuilderEquals(b, [
1219 6, 0, # vtable bytes
1220 8, 0, # length of object including vtable offset
1221 7, 0, # start of bool value
1222 6, 0, 0, 0, # offset for start of vtable (int32)
1223 0, 0, 0, # padded to 4 bytes
1224 1, # bool value
1225 ])
1226
1227 def test_vtable_with_one_default_bool(self):
1228 b = flatbuffers.Builder(0)
1229 self.assertBuilderEquals(b, [])
1230 b.StartObject(1)
1231 self.assertBuilderEquals(b, [])
1232 b.PrependBoolSlot(0, False, False)
1233 b.EndObject()
1234 self.assertBuilderEquals(b, [
1235 4, 0, # vtable bytes
1236 4, 0, # end of object from here
1237 # entry 1 is zero and not stored
1238 4, 0, 0, 0, # offset for start of vtable (int32)
1239 ])
1240
1241 def test_vtable_with_one_int16(self):
1242 b = flatbuffers.Builder(0)
1243 b.StartObject(1)
1244 b.PrependInt16Slot(0, 0x789A, 0)
1245 b.EndObject()
1246 self.assertBuilderEquals(b, [
1247 6, 0, # vtable bytes
1248 8, 0, # end of object from here
1249 6, 0, # offset to value
1250 6, 0, 0, 0, # offset for start of vtable (int32)
1251 0, 0, # padding to 4 bytes
1252 0x9A, 0x78,
1253 ])
1254
1255 def test_vtable_with_two_int16(self):
1256 b = flatbuffers.Builder(0)
1257 b.StartObject(2)
1258 b.PrependInt16Slot(0, 0x3456, 0)
1259 b.PrependInt16Slot(1, 0x789A, 0)
1260 b.EndObject()
1261 self.assertBuilderEquals(b, [
1262 8, 0, # vtable bytes
1263 8, 0, # end of object from here
1264 6, 0, # offset to value 0
1265 4, 0, # offset to value 1
1266 8, 0, 0, 0, # offset for start of vtable (int32)
1267 0x9A, 0x78, # value 1
1268 0x56, 0x34, # value 0
1269 ])
1270
1271 def test_vtable_with_int16_and_bool(self):
1272 b = flatbuffers.Builder(0)
1273 b.StartObject(2)
1274 b.PrependInt16Slot(0, 0x3456, 0)
1275 b.PrependBoolSlot(1, True, False)
1276 b.EndObject()
1277 self.assertBuilderEquals(b, [
1278 8, 0, # vtable bytes
1279 8, 0, # end of object from here
1280 6, 0, # offset to value 0
1281 5, 0, # offset to value 1
1282 8, 0, 0, 0, # offset for start of vtable (int32)
1283 0, # padding
1284 1, # value 1
1285 0x56, 0x34, # value 0
1286 ])
1287
1288 def test_vtable_with_empty_vector(self):
1289 b = flatbuffers.Builder(0)
1290 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
1291 vecend = b.EndVector(0)
1292 b.StartObject(1)
1293 b.PrependUOffsetTRelativeSlot(0, vecend, 0)
1294 b.EndObject()
1295 self.assertBuilderEquals(b, [
1296 6, 0, # vtable bytes
1297 8, 0,
1298 4, 0, # offset to vector offset
1299 6, 0, 0, 0, # offset for start of vtable (int32)
1300 4, 0, 0, 0,
1301 0, 0, 0, 0, # length of vector (not in struct)
1302 ])
1303
1304 def test_vtable_with_empty_vector_of_byte_and_some_scalars(self):
1305 b = flatbuffers.Builder(0)
1306 b.StartVector(flatbuffers.number_types.Uint8Flags.bytewidth, 0, 1)
1307 vecend = b.EndVector(0)
1308 b.StartObject(2)
1309 b.PrependInt16Slot(0, 55, 0)
1310 b.PrependUOffsetTRelativeSlot(1, vecend, 0)
1311 b.EndObject()
1312 self.assertBuilderEquals(b, [
1313 8, 0, # vtable bytes
1314 12, 0,
1315 10, 0, # offset to value 0
1316 4, 0, # offset to vector offset
1317 8, 0, 0, 0, # vtable loc
1318 8, 0, 0, 0, # value 1
1319 0, 0, 55, 0, # value 0
1320
1321 0, 0, 0, 0, # length of vector (not in struct)
1322 ])
1323
1324 def test_vtable_with_1_int16_and_2vector_of_int16(self):
1325 b = flatbuffers.Builder(0)
1326 b.StartVector(flatbuffers.number_types.Int16Flags.bytewidth, 2, 1)
1327 b.PrependInt16(0x1234)
1328 b.PrependInt16(0x5678)
1329 vecend = b.EndVector(2)
1330 b.StartObject(2)
1331 b.PrependUOffsetTRelativeSlot(1, vecend, 0)
1332 b.PrependInt16Slot(0, 55, 0)
1333 b.EndObject()
1334 self.assertBuilderEquals(b, [
1335 8, 0, # vtable bytes
1336 12, 0, # length of object
1337 6, 0, # start of value 0 from end of vtable
1338 8, 0, # start of value 1 from end of buffer
1339 8, 0, 0, 0, # offset for start of vtable (int32)
1340 0, 0, # padding
1341 55, 0, # value 0
1342 4, 0, 0, 0, # vector position from here
1343 2, 0, 0, 0, # length of vector (uint32)
1344 0x78, 0x56, # vector value 1
1345 0x34, 0x12, # vector value 0
1346 ])
1347
1348 def test_vtable_with_1_struct_of_1_int8__1_int16__1_int32(self):
1349 b = flatbuffers.Builder(0)
1350 b.StartObject(1)
1351 b.Prep(4+4+4, 0)
1352 b.PrependInt8(55)
1353 b.Pad(3)
1354 b.PrependInt16(0x1234)
1355 b.Pad(2)
1356 b.PrependInt32(0x12345678)
1357 structStart = b.Offset()
1358 b.PrependStructSlot(0, structStart, 0)
1359 b.EndObject()
1360 self.assertBuilderEquals(b, [
1361 6, 0, # vtable bytes
1362 16, 0, # end of object from here
1363 4, 0, # start of struct from here
1364 6, 0, 0, 0, # offset for start of vtable (int32)
1365 0x78, 0x56, 0x34, 0x12, # value 2
1366 0, 0, # padding
1367 0x34, 0x12, # value 1
1368 0, 0, 0, # padding
1369 55, # value 0
1370 ])
1371
1372 def test_vtable_with_1_vector_of_2_struct_of_2_int8(self):
1373 b = flatbuffers.Builder(0)
1374 b.StartVector(flatbuffers.number_types.Int8Flags.bytewidth*2, 2, 1)
1375 b.PrependInt8(33)
1376 b.PrependInt8(44)
1377 b.PrependInt8(55)
1378 b.PrependInt8(66)
1379 vecend = b.EndVector(2)
1380 b.StartObject(1)
1381 b.PrependUOffsetTRelativeSlot(0, vecend, 0)
1382 b.EndObject()
1383 self.assertBuilderEquals(b, [
1384 6, 0, # vtable bytes
1385 8, 0,
1386 4, 0, # offset of vector offset
1387 6, 0, 0, 0, # offset for start of vtable (int32)
1388 4, 0, 0, 0, # vector start offset
1389
1390 2, 0, 0, 0, # vector length
1391 66, # vector value 1,1
1392 55, # vector value 1,0
1393 44, # vector value 0,1
1394 33, # vector value 0,0
1395 ])
1396
1397 def test_table_with_some_elements(self):
1398 b = flatbuffers.Builder(0)
1399 b.StartObject(2)
1400 b.PrependInt8Slot(0, 33, 0)
1401 b.PrependInt16Slot(1, 66, 0)
1402 off = b.EndObject()
1403 b.Finish(off)
1404
1405 self.assertBuilderEquals(b, [
1406 12, 0, 0, 0, # root of table: points to vtable offset
1407
1408 8, 0, # vtable bytes
1409 8, 0, # end of object from here
1410 7, 0, # start of value 0
1411 4, 0, # start of value 1
1412
1413 8, 0, 0, 0, # offset for start of vtable (int32)
1414
1415 66, 0, # value 1
1416 0, # padding
1417 33, # value 0
1418 ])
1419
1420 def test__one_unfinished_table_and_one_finished_table(self):
1421 b = flatbuffers.Builder(0)
1422 b.StartObject(2)
1423 b.PrependInt8Slot(0, 33, 0)
1424 b.PrependInt8Slot(1, 44, 0)
1425 off = b.EndObject()
1426 b.Finish(off)
1427
1428 b.StartObject(3)
1429 b.PrependInt8Slot(0, 55, 0)
1430 b.PrependInt8Slot(1, 66, 0)
1431 b.PrependInt8Slot(2, 77, 0)
1432 off = b.EndObject()
1433 b.Finish(off)
1434
1435 self.assertBuilderEquals(b, [
1436 16, 0, 0, 0, # root of table: points to object
1437 0, 0, # padding
1438
1439 10, 0, # vtable bytes
1440 8, 0, # size of object
1441 7, 0, # start of value 0
1442 6, 0, # start of value 1
1443 5, 0, # start of value 2
1444 10, 0, 0, 0, # offset for start of vtable (int32)
1445 0, # padding
1446 77, # value 2
1447 66, # value 1
1448 55, # value 0
1449
1450 12, 0, 0, 0, # root of table: points to object
1451
1452 8, 0, # vtable bytes
1453 8, 0, # size of object
1454 7, 0, # start of value 0
1455 6, 0, # start of value 1
1456 8, 0, 0, 0, # offset for start of vtable (int32)
1457 0, 0, # padding
1458 44, # value 1
1459 33, # value 0
1460 ])
1461
1462 def test_a_bunch_of_bools(self):
1463 b = flatbuffers.Builder(0)
1464 b.StartObject(8)
1465 b.PrependBoolSlot(0, True, False)
1466 b.PrependBoolSlot(1, True, False)
1467 b.PrependBoolSlot(2, True, False)
1468 b.PrependBoolSlot(3, True, False)
1469 b.PrependBoolSlot(4, True, False)
1470 b.PrependBoolSlot(5, True, False)
1471 b.PrependBoolSlot(6, True, False)
1472 b.PrependBoolSlot(7, True, False)
1473 off = b.EndObject()
1474 b.Finish(off)
1475
1476 self.assertBuilderEquals(b, [
1477 24, 0, 0, 0, # root of table: points to vtable offset
1478
1479 20, 0, # vtable bytes
1480 12, 0, # size of object
1481 11, 0, # start of value 0
1482 10, 0, # start of value 1
1483 9, 0, # start of value 2
1484 8, 0, # start of value 3
1485 7, 0, # start of value 4
1486 6, 0, # start of value 5
1487 5, 0, # start of value 6
1488 4, 0, # start of value 7
1489 20, 0, 0, 0, # vtable offset
1490
1491 1, # value 7
1492 1, # value 6
1493 1, # value 5
1494 1, # value 4
1495 1, # value 3
1496 1, # value 2
1497 1, # value 1
1498 1, # value 0
1499 ])
1500
1501 def test_three_bools(self):
1502 b = flatbuffers.Builder(0)
1503 b.StartObject(3)
1504 b.PrependBoolSlot(0, True, False)
1505 b.PrependBoolSlot(1, True, False)
1506 b.PrependBoolSlot(2, True, False)
1507 off = b.EndObject()
1508 b.Finish(off)
1509
1510 self.assertBuilderEquals(b, [
1511 16, 0, 0, 0, # root of table: points to vtable offset
1512
1513 0, 0, # padding
1514
1515 10, 0, # vtable bytes
1516 8, 0, # size of object
1517 7, 0, # start of value 0
1518 6, 0, # start of value 1
1519 5, 0, # start of value 2
1520 10, 0, 0, 0, # vtable offset from here
1521
1522 0, # padding
1523 1, # value 2
1524 1, # value 1
1525 1, # value 0
1526 ])
1527
1528 def test_some_floats(self):
1529 b = flatbuffers.Builder(0)
1530 b.StartObject(1)
1531 b.PrependFloat32Slot(0, 1.0, 0.0)
1532 off = b.EndObject()
1533
1534 self.assertBuilderEquals(b, [
1535 6, 0, # vtable bytes
1536 8, 0, # size of object
1537 4, 0, # start of value 0
1538 6, 0, 0, 0, # vtable offset
1539
1540 0, 0, 128, 63, # value 0
1541 ])
1542
1543
1544def make_monster_from_generated_code(sizePrefix = False, file_identifier=None):
1545 ''' Use generated code to build the example Monster. '''
1546
1547 b = flatbuffers.Builder(0)
1548 string = b.CreateString("MyMonster")
1549 test1 = b.CreateString("test1")
1550 test2 = b.CreateString("test2")
1551 fred = b.CreateString("Fred")
1552
1553 MyGame.Example.Monster.MonsterStartInventoryVector(b, 5)
1554 b.PrependByte(4)
1555 b.PrependByte(3)
1556 b.PrependByte(2)
1557 b.PrependByte(1)
1558 b.PrependByte(0)
1559 inv = b.EndVector(5)
1560
1561 MyGame.Example.Monster.MonsterStart(b)
1562 MyGame.Example.Monster.MonsterAddName(b, fred)
1563 mon2 = MyGame.Example.Monster.MonsterEnd(b)
1564
1565 MyGame.Example.Monster.MonsterStartTest4Vector(b, 2)
1566 MyGame.Example.Test.CreateTest(b, 10, 20)
1567 MyGame.Example.Test.CreateTest(b, 30, 40)
1568 test4 = b.EndVector(2)
1569
1570 MyGame.Example.Monster.MonsterStartTestarrayofstringVector(b, 2)
1571 b.PrependUOffsetTRelative(test2)
1572 b.PrependUOffsetTRelative(test1)
1573 testArrayOfString = b.EndVector(2)
1574
1575 MyGame.Example.Monster.MonsterStartVectorOfLongsVector(b, 5)
1576 b.PrependInt64(100000000)
1577 b.PrependInt64(1000000)
1578 b.PrependInt64(10000)
1579 b.PrependInt64(100)
1580 b.PrependInt64(1)
1581 VectorOfLongs = b.EndVector(5)
1582
1583 MyGame.Example.Monster.MonsterStartVectorOfDoublesVector(b, 3)
1584 b.PrependFloat64(1.7976931348623157e+308)
1585 b.PrependFloat64(0)
1586 b.PrependFloat64(-1.7976931348623157e+308)
1587 VectorOfDoubles = b.EndVector(3)
1588
1589 MyGame.Example.Monster.MonsterStart(b)
1590
1591 pos = MyGame.Example.Vec3.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 2, 5, 6)
1592 MyGame.Example.Monster.MonsterAddPos(b, pos)
1593
1594 MyGame.Example.Monster.MonsterAddHp(b, 80)
1595 MyGame.Example.Monster.MonsterAddName(b, string)
1596 MyGame.Example.Monster.MonsterAddInventory(b, inv)
1597 MyGame.Example.Monster.MonsterAddTestType(b, 1)
1598 MyGame.Example.Monster.MonsterAddTest(b, mon2)
1599 MyGame.Example.Monster.MonsterAddTest4(b, test4)
1600 MyGame.Example.Monster.MonsterAddTestarrayofstring(b, testArrayOfString)
1601 MyGame.Example.Monster.MonsterAddVectorOfLongs(b, VectorOfLongs)
1602 MyGame.Example.Monster.MonsterAddVectorOfDoubles(b, VectorOfDoubles)
1603 mon = MyGame.Example.Monster.MonsterEnd(b)
1604
1605 if sizePrefix:
1606 b.FinishSizePrefixed(mon, file_identifier)
1607 else:
1608 b.Finish(mon, file_identifier)
1609
1610 return b.Bytes, b.Head()
1611
1612
Austin Schuh272c6132020-11-14 16:37:52 -08001613class TestBuilderForceDefaults(unittest.TestCase):
1614 """Verify that the builder adds default values when forced."""
1615
1616 test_flags = [N.BoolFlags(), N.Uint8Flags(), N.Uint16Flags(), \
1617 N.Uint32Flags(), N.Uint64Flags(), N.Int8Flags(), \
1618 N.Int16Flags(), N.Int32Flags(), N.Int64Flags(), \
1619 N.Float32Flags(), N.Float64Flags(), N.UOffsetTFlags()]
1620 def test_default_force_defaults(self):
1621 for flag in self.test_flags:
1622 b = flatbuffers.Builder(0)
1623 b.StartObject(1)
1624 stored_offset = b.Offset()
1625 if flag != N.UOffsetTFlags():
1626 b.PrependSlot(flag, 0, 0, 0)
1627 else:
1628 b.PrependUOffsetTRelativeSlot(0, 0, 0)
1629 end_offset = b.Offset()
1630 b.EndObject()
1631 self.assertEqual(0, end_offset - stored_offset)
1632
1633 def test_force_defaults_true(self):
1634 for flag in self.test_flags:
1635 b = flatbuffers.Builder(0)
1636 b.ForceDefaults(True)
1637 b.StartObject(1)
1638 stored_offset = b.Offset()
1639 if flag != N.UOffsetTFlags():
1640 b.PrependSlot(flag, 0, 0, 0)
1641 else:
1642 b.PrependUOffsetTRelativeSlot(0, 0, 0)
1643 end_offset = b.Offset()
1644 b.EndObject()
1645 self.assertEqual(flag.bytewidth, end_offset - stored_offset)
1646
1647
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001648class TestAllCodePathsOfExampleSchema(unittest.TestCase):
1649 def setUp(self, *args, **kwargs):
1650 super(TestAllCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
1651
1652 b = flatbuffers.Builder(0)
1653 MyGame.Example.Monster.MonsterStart(b)
1654 gen_mon = MyGame.Example.Monster.MonsterEnd(b)
1655 b.Finish(gen_mon)
1656
1657 self.mon = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1658 b.Head())
1659
1660 def test_default_monster_pos(self):
1661 self.assertTrue(self.mon.Pos() is None)
1662
1663 def test_nondefault_monster_mana(self):
1664 b = flatbuffers.Builder(0)
1665 MyGame.Example.Monster.MonsterStart(b)
1666 MyGame.Example.Monster.MonsterAddMana(b, 50)
1667 mon = MyGame.Example.Monster.MonsterEnd(b)
1668 b.Finish(mon)
1669
1670 got_mon = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1671 b.Head())
1672 self.assertEqual(50, got_mon.Mana())
1673
1674 def test_default_monster_hp(self):
1675 self.assertEqual(100, self.mon.Hp())
1676
1677 def test_default_monster_name(self):
1678 self.assertEqual(None, self.mon.Name())
1679
1680 def test_default_monster_inventory_item(self):
1681 self.assertEqual(0, self.mon.Inventory(0))
1682
1683 def test_default_monster_inventory_length(self):
1684 self.assertEqual(0, self.mon.InventoryLength())
Austin Schuh272c6132020-11-14 16:37:52 -08001685 self.assertTrue(self.mon.InventoryIsNone())
1686
1687 def test_empty_monster_inventory_vector(self):
1688 b = flatbuffers.Builder(0)
1689 MyGame.Example.Monster.MonsterStartInventoryVector(b, 0)
1690 inv = b.EndVector(0)
1691 MyGame.Example.Monster.MonsterStart(b)
1692 MyGame.Example.Monster.MonsterAddInventory(b, inv)
1693 mon = MyGame.Example.Monster.MonsterEnd(b)
1694 b.Finish(mon)
1695 mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1696 b.Head())
1697 self.assertFalse(mon2.InventoryIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001698
1699 def test_default_monster_color(self):
1700 self.assertEqual(MyGame.Example.Color.Color.Blue, self.mon.Color())
1701
1702 def test_nondefault_monster_color(self):
1703 b = flatbuffers.Builder(0)
1704 color = MyGame.Example.Color.Color.Red
1705 MyGame.Example.Monster.MonsterStart(b)
1706 MyGame.Example.Monster.MonsterAddColor(b, color)
1707 mon = MyGame.Example.Monster.MonsterEnd(b)
1708 b.Finish(mon)
1709
1710 mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1711 b.Head())
1712 self.assertEqual(MyGame.Example.Color.Color.Red, mon2.Color())
1713
1714 def test_default_monster_testtype(self):
1715 self.assertEqual(0, self.mon.TestType())
1716
1717 def test_default_monster_test_field(self):
1718 self.assertEqual(None, self.mon.Test())
1719
1720 def test_default_monster_test4_item(self):
1721 self.assertEqual(None, self.mon.Test4(0))
1722
1723 def test_default_monster_test4_length(self):
1724 self.assertEqual(0, self.mon.Test4Length())
Austin Schuh272c6132020-11-14 16:37:52 -08001725 self.assertTrue(self.mon.Test4IsNone())
1726
1727 def test_empty_monster_test4_vector(self):
1728 b = flatbuffers.Builder(0)
1729 MyGame.Example.Monster.MonsterStartTest4Vector(b, 0)
1730 test4 = b.EndVector(0)
1731 MyGame.Example.Monster.MonsterStart(b)
1732 MyGame.Example.Monster.MonsterAddTest4(b, test4)
1733 mon = MyGame.Example.Monster.MonsterEnd(b)
1734 b.Finish(mon)
1735 mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1736 b.Head())
1737 self.assertFalse(mon2.Test4IsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001738
1739 def test_default_monster_testarrayofstring(self):
1740 self.assertEqual("", self.mon.Testarrayofstring(0))
1741
1742 def test_default_monster_testarrayofstring_length(self):
1743 self.assertEqual(0, self.mon.TestarrayofstringLength())
Austin Schuh272c6132020-11-14 16:37:52 -08001744 self.assertTrue(self.mon.TestarrayofstringIsNone())
1745
1746 def test_empty_monster_testarrayofstring_vector(self):
1747 b = flatbuffers.Builder(0)
1748 MyGame.Example.Monster.MonsterStartTestarrayofstringVector(b, 0)
1749 testarrayofstring = b.EndVector(0)
1750 MyGame.Example.Monster.MonsterStart(b)
1751 MyGame.Example.Monster.MonsterAddTestarrayofstring(b, testarrayofstring)
1752 mon = MyGame.Example.Monster.MonsterEnd(b)
1753 b.Finish(mon)
1754 mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1755 b.Head())
1756 self.assertFalse(mon2.TestarrayofstringIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001757
1758 def test_default_monster_testarrayoftables(self):
1759 self.assertEqual(None, self.mon.Testarrayoftables(0))
1760
1761 def test_nondefault_monster_testarrayoftables(self):
1762 b = flatbuffers.Builder(0)
1763
1764 # make a child Monster within a vector of Monsters:
1765 MyGame.Example.Monster.MonsterStart(b)
1766 MyGame.Example.Monster.MonsterAddHp(b, 99)
1767 sub_monster = MyGame.Example.Monster.MonsterEnd(b)
1768
1769 # build the vector:
1770 MyGame.Example.Monster.MonsterStartTestarrayoftablesVector(b, 1)
1771 b.PrependUOffsetTRelative(sub_monster)
1772 vec = b.EndVector(1)
1773
1774 # make the parent monster and include the vector of Monster:
1775 MyGame.Example.Monster.MonsterStart(b)
1776 MyGame.Example.Monster.MonsterAddTestarrayoftables(b, vec)
1777 mon = MyGame.Example.Monster.MonsterEnd(b)
1778 b.Finish(mon)
1779
1780 # inspect the resulting data:
1781 mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Output(), 0)
1782 self.assertEqual(99, mon2.Testarrayoftables(0).Hp())
1783 self.assertEqual(1, mon2.TestarrayoftablesLength())
Austin Schuh272c6132020-11-14 16:37:52 -08001784 self.assertFalse(mon2.TestarrayoftablesIsNone())
1785
1786 def test_default_monster_testarrayoftables_length(self):
1787 self.assertEqual(0, self.mon.TestarrayoftablesLength())
1788 self.assertTrue(self.mon.TestarrayoftablesIsNone())
1789
1790 def test_empty_monster_testarrayoftables_vector(self):
1791 b = flatbuffers.Builder(0)
1792 MyGame.Example.Monster.MonsterStartTestarrayoftablesVector(b, 0)
1793 testarrayoftables = b.EndVector(0)
1794 MyGame.Example.Monster.MonsterStart(b)
1795 MyGame.Example.Monster.MonsterAddTestarrayoftables(b, testarrayoftables)
1796 mon = MyGame.Example.Monster.MonsterEnd(b)
1797 b.Finish(mon)
1798 mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1799 b.Head())
1800 self.assertFalse(mon2.TestarrayoftablesIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001801
1802 def test_default_monster_testarrayoftables_length(self):
1803 self.assertEqual(0, self.mon.TestarrayoftablesLength())
1804
1805 def test_nondefault_monster_enemy(self):
1806 b = flatbuffers.Builder(0)
1807
1808 # make an Enemy object:
1809 MyGame.Example.Monster.MonsterStart(b)
1810 MyGame.Example.Monster.MonsterAddHp(b, 88)
1811 enemy = MyGame.Example.Monster.MonsterEnd(b)
1812 b.Finish(enemy)
1813
1814 # make the parent monster and include the vector of Monster:
1815 MyGame.Example.Monster.MonsterStart(b)
1816 MyGame.Example.Monster.MonsterAddEnemy(b, enemy)
1817 mon = MyGame.Example.Monster.MonsterEnd(b)
1818 b.Finish(mon)
1819
1820 # inspect the resulting data:
1821 mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1822 b.Head())
1823 self.assertEqual(88, mon2.Enemy().Hp())
1824
1825 def test_default_monster_testnestedflatbuffer(self):
1826 self.assertEqual(0, self.mon.Testnestedflatbuffer(0))
1827
1828 def test_default_monster_testnestedflatbuffer_length(self):
1829 self.assertEqual(0, self.mon.TestnestedflatbufferLength())
Austin Schuh272c6132020-11-14 16:37:52 -08001830 self.assertTrue(self.mon.TestnestedflatbufferIsNone())
1831
1832 def test_empty_monster_testnestedflatbuffer_vector(self):
1833 b = flatbuffers.Builder(0)
1834 MyGame.Example.Monster.MonsterStartTestnestedflatbufferVector(b, 0)
1835 testnestedflatbuffer = b.EndVector(0)
1836 MyGame.Example.Monster.MonsterStart(b)
1837 MyGame.Example.Monster.MonsterAddTestnestedflatbuffer(b, testnestedflatbuffer)
1838 mon = MyGame.Example.Monster.MonsterEnd(b)
1839 b.Finish(mon)
1840 mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1841 b.Head())
1842 self.assertFalse(mon2.TestnestedflatbufferIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001843
1844 def test_nondefault_monster_testnestedflatbuffer(self):
1845 b = flatbuffers.Builder(0)
1846
1847 MyGame.Example.Monster.MonsterStartTestnestedflatbufferVector(b, 3)
1848 b.PrependByte(4)
1849 b.PrependByte(2)
1850 b.PrependByte(0)
1851 sub_buf = b.EndVector(3)
1852
1853 # make the parent monster and include the vector of Monster:
1854 MyGame.Example.Monster.MonsterStart(b)
1855 MyGame.Example.Monster.MonsterAddTestnestedflatbuffer(b, sub_buf)
1856 mon = MyGame.Example.Monster.MonsterEnd(b)
1857 b.Finish(mon)
1858
1859 # inspect the resulting data:
1860 mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1861 b.Head())
1862 self.assertEqual(3, mon2.TestnestedflatbufferLength())
Austin Schuh272c6132020-11-14 16:37:52 -08001863 self.assertFalse(mon2.TestnestedflatbufferIsNone())
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001864 self.assertEqual(0, mon2.Testnestedflatbuffer(0))
1865 self.assertEqual(2, mon2.Testnestedflatbuffer(1))
1866 self.assertEqual(4, mon2.Testnestedflatbuffer(2))
1867 try:
1868 imp.find_module('numpy')
1869 # if numpy exists, then we should be able to get the
1870 # vector as a numpy array
1871 self.assertEqual([0, 2, 4], mon2.TestnestedflatbufferAsNumpy().tolist())
1872 except ImportError:
1873 assertRaises(self,
1874 lambda: mon2.TestnestedflatbufferAsNumpy(),
1875 NumpyRequiredForThisFeature)
1876
1877 def test_nondefault_monster_testempty(self):
1878 b = flatbuffers.Builder(0)
1879
1880 # make a Stat object:
1881 MyGame.Example.Stat.StatStart(b)
1882 MyGame.Example.Stat.StatAddVal(b, 123)
1883 my_stat = MyGame.Example.Stat.StatEnd(b)
1884 b.Finish(my_stat)
1885
1886 # include the stat object in a monster:
1887 MyGame.Example.Monster.MonsterStart(b)
1888 MyGame.Example.Monster.MonsterAddTestempty(b, my_stat)
1889 mon = MyGame.Example.Monster.MonsterEnd(b)
1890 b.Finish(mon)
1891
1892 # inspect the resulting data:
1893 mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1894 b.Head())
1895 self.assertEqual(123, mon2.Testempty().Val())
1896
1897 def test_default_monster_testbool(self):
1898 self.assertFalse(self.mon.Testbool())
1899
1900 def test_nondefault_monster_testbool(self):
1901 b = flatbuffers.Builder(0)
1902 MyGame.Example.Monster.MonsterStart(b)
1903 MyGame.Example.Monster.MonsterAddTestbool(b, True)
1904 mon = MyGame.Example.Monster.MonsterEnd(b)
1905 b.Finish(mon)
1906
1907 # inspect the resulting data:
1908 mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1909 b.Head())
1910 self.assertTrue(mon2.Testbool())
1911
1912 def test_default_monster_testhashes(self):
1913 self.assertEqual(0, self.mon.Testhashs32Fnv1())
1914 self.assertEqual(0, self.mon.Testhashu32Fnv1())
1915 self.assertEqual(0, self.mon.Testhashs64Fnv1())
1916 self.assertEqual(0, self.mon.Testhashu64Fnv1())
1917 self.assertEqual(0, self.mon.Testhashs32Fnv1a())
1918 self.assertEqual(0, self.mon.Testhashu32Fnv1a())
1919 self.assertEqual(0, self.mon.Testhashs64Fnv1a())
1920 self.assertEqual(0, self.mon.Testhashu64Fnv1a())
1921
1922 def test_nondefault_monster_testhashes(self):
1923 b = flatbuffers.Builder(0)
1924 MyGame.Example.Monster.MonsterStart(b)
1925 MyGame.Example.Monster.MonsterAddTesthashs32Fnv1(b, 1)
1926 MyGame.Example.Monster.MonsterAddTesthashu32Fnv1(b, 2)
1927 MyGame.Example.Monster.MonsterAddTesthashs64Fnv1(b, 3)
1928 MyGame.Example.Monster.MonsterAddTesthashu64Fnv1(b, 4)
1929 MyGame.Example.Monster.MonsterAddTesthashs32Fnv1a(b, 5)
1930 MyGame.Example.Monster.MonsterAddTesthashu32Fnv1a(b, 6)
1931 MyGame.Example.Monster.MonsterAddTesthashs64Fnv1a(b, 7)
1932 MyGame.Example.Monster.MonsterAddTesthashu64Fnv1a(b, 8)
1933 mon = MyGame.Example.Monster.MonsterEnd(b)
1934 b.Finish(mon)
1935
1936 # inspect the resulting data:
1937 mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1938 b.Head())
1939 self.assertEqual(1, mon2.Testhashs32Fnv1())
1940 self.assertEqual(2, mon2.Testhashu32Fnv1())
1941 self.assertEqual(3, mon2.Testhashs64Fnv1())
1942 self.assertEqual(4, mon2.Testhashu64Fnv1())
1943 self.assertEqual(5, mon2.Testhashs32Fnv1a())
1944 self.assertEqual(6, mon2.Testhashu32Fnv1a())
1945 self.assertEqual(7, mon2.Testhashs64Fnv1a())
1946 self.assertEqual(8, mon2.Testhashu64Fnv1a())
1947
Austin Schuh272c6132020-11-14 16:37:52 -08001948 def test_default_monster_parent_namespace_test(self):
1949 self.assertEqual(None, self.mon.ParentNamespaceTest())
1950
1951 def test_nondefault_monster_parent_namespace_test(self):
1952 b = flatbuffers.Builder(0)
1953 MyGame.InParentNamespace.InParentNamespaceStart(b)
1954 parent = MyGame.InParentNamespace.InParentNamespaceEnd(b)
1955 MyGame.Example.Monster.MonsterStart(b)
1956 MyGame.Example.Monster.MonsterAddParentNamespaceTest(b, parent)
1957 mon = MyGame.Example.Monster.MonsterEnd(b)
1958 b.Finish(mon)
1959
1960 # Inspect the resulting data.
1961 monster = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
1962 b.Head())
1963 self.assertTrue(isinstance(monster.ParentNamespaceTest(),
1964 MyGame.InParentNamespace.InParentNamespace))
1965
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001966 def test_getrootas_for_nonroot_table(self):
1967 b = flatbuffers.Builder(0)
1968 string = b.CreateString("MyStat")
1969
1970 MyGame.Example.Stat.StatStart(b)
1971 MyGame.Example.Stat.StatAddId(b, string)
1972 MyGame.Example.Stat.StatAddVal(b, 12345678)
1973 MyGame.Example.Stat.StatAddCount(b, 12345)
1974 stat = MyGame.Example.Stat.StatEnd(b)
1975 b.Finish(stat)
1976
1977 stat2 = MyGame.Example.Stat.Stat.GetRootAsStat(b.Bytes, b.Head())
1978
1979 self.assertEqual(b"MyStat", stat2.Id())
1980 self.assertEqual(12345678, stat2.Val())
1981 self.assertEqual(12345, stat2.Count())
1982
1983
1984class TestAllCodePathsOfMonsterExtraSchema(unittest.TestCase):
1985 def setUp(self, *args, **kwargs):
1986 super(TestAllCodePathsOfMonsterExtraSchema, self).setUp(*args, **kwargs)
1987
1988 b = flatbuffers.Builder(0)
1989 MyGame.MonsterExtra.MonsterExtraStart(b)
1990 gen_mon = MyGame.MonsterExtra.MonsterExtraEnd(b)
1991 b.Finish(gen_mon)
1992
1993 self.mon = MyGame.MonsterExtra.MonsterExtra.GetRootAsMonsterExtra(b.Bytes, b.Head())
1994
1995 def test_default_nan_inf(self):
1996 self.assertTrue(math.isnan(self.mon.F1()))
1997 self.assertEqual(self.mon.F2(), float("inf"))
1998 self.assertEqual(self.mon.F3(), float("-inf"))
1999
2000 self.assertTrue(math.isnan(self.mon.D1()))
2001 self.assertEqual(self.mon.D2(), float("inf"))
2002 self.assertEqual(self.mon.D3(), float("-inf"))
2003
2004
2005class TestVtableDeduplication(unittest.TestCase):
2006 ''' TestVtableDeduplication verifies that vtables are deduplicated. '''
2007
2008 def test_vtable_deduplication(self):
2009 b = flatbuffers.Builder(0)
2010
2011 b.StartObject(4)
2012 b.PrependByteSlot(0, 0, 0)
2013 b.PrependByteSlot(1, 11, 0)
2014 b.PrependByteSlot(2, 22, 0)
2015 b.PrependInt16Slot(3, 33, 0)
2016 obj0 = b.EndObject()
2017
2018 b.StartObject(4)
2019 b.PrependByteSlot(0, 0, 0)
2020 b.PrependByteSlot(1, 44, 0)
2021 b.PrependByteSlot(2, 55, 0)
2022 b.PrependInt16Slot(3, 66, 0)
2023 obj1 = b.EndObject()
2024
2025 b.StartObject(4)
2026 b.PrependByteSlot(0, 0, 0)
2027 b.PrependByteSlot(1, 77, 0)
2028 b.PrependByteSlot(2, 88, 0)
2029 b.PrependInt16Slot(3, 99, 0)
2030 obj2 = b.EndObject()
2031
2032 got = b.Bytes[b.Head():]
2033
2034 want = bytearray([
2035 240, 255, 255, 255, # == -12. offset to dedupped vtable.
2036 99, 0,
2037 88,
2038 77,
2039 248, 255, 255, 255, # == -8. offset to dedupped vtable.
2040 66, 0,
2041 55,
2042 44,
2043 12, 0,
2044 8, 0,
2045 0, 0,
2046 7, 0,
2047 6, 0,
2048 4, 0,
2049 12, 0, 0, 0,
2050 33, 0,
2051 22,
2052 11,
2053 ])
2054
2055 self.assertEqual((len(want), want), (len(got), got))
2056
2057 table0 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj0)
2058 table1 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj1)
2059 table2 = flatbuffers.table.Table(b.Bytes, len(b.Bytes) - obj2)
2060
2061 def _checkTable(tab, voffsett_value, b, c, d):
2062 # vtable size
2063 got = tab.GetVOffsetTSlot(0, 0)
2064 self.assertEqual(12, got, 'case 0, 0')
2065
2066 # object size
2067 got = tab.GetVOffsetTSlot(2, 0)
2068 self.assertEqual(8, got, 'case 2, 0')
2069
2070 # default value
2071 got = tab.GetVOffsetTSlot(4, 0)
2072 self.assertEqual(voffsett_value, got, 'case 4, 0')
2073
2074 got = tab.GetSlot(6, 0, N.Uint8Flags)
2075 self.assertEqual(b, got, 'case 6, 0')
2076
2077 val = tab.GetSlot(8, 0, N.Uint8Flags)
2078 self.assertEqual(c, val, 'failed 8, 0')
2079
2080 got = tab.GetSlot(10, 0, N.Uint8Flags)
2081 self.assertEqual(d, got, 'failed 10, 0')
2082
2083 _checkTable(table0, 0, 11, 22, 33)
2084 _checkTable(table1, 0, 44, 55, 66)
2085 _checkTable(table2, 0, 77, 88, 99)
2086
2087
2088class TestExceptions(unittest.TestCase):
2089 def test_object_is_nested_error(self):
2090 b = flatbuffers.Builder(0)
2091 b.StartObject(0)
2092 assertRaises(self, lambda: b.StartObject(0),
2093 flatbuffers.builder.IsNestedError)
2094
2095 def test_object_is_not_nested_error(self):
2096 b = flatbuffers.Builder(0)
2097 assertRaises(self, lambda: b.EndObject(),
2098 flatbuffers.builder.IsNotNestedError)
2099
2100 def test_struct_is_not_inline_error(self):
2101 b = flatbuffers.Builder(0)
2102 b.StartObject(0)
2103 assertRaises(self, lambda: b.PrependStructSlot(0, 1, 0),
2104 flatbuffers.builder.StructIsNotInlineError)
2105
2106 def test_unreachable_error(self):
2107 b = flatbuffers.Builder(0)
2108 assertRaises(self, lambda: b.PrependUOffsetTRelative(1),
2109 flatbuffers.builder.OffsetArithmeticError)
2110
2111 def test_create_string_is_nested_error(self):
2112 b = flatbuffers.Builder(0)
2113 b.StartObject(0)
2114 s = 'test1'
2115 assertRaises(self, lambda: b.CreateString(s),
2116 flatbuffers.builder.IsNestedError)
2117
2118 def test_create_byte_vector_is_nested_error(self):
2119 b = flatbuffers.Builder(0)
2120 b.StartObject(0)
2121 s = b'test1'
2122 assertRaises(self, lambda: b.CreateByteVector(s),
2123 flatbuffers.builder.IsNestedError)
2124
2125 def test_finished_bytes_error(self):
2126 b = flatbuffers.Builder(0)
2127 assertRaises(self, lambda: b.Output(),
2128 flatbuffers.builder.BuilderNotFinishedError)
2129
2130
2131class TestFixedLengthArrays(unittest.TestCase):
2132 def test_fixed_length_array(self):
2133 builder = flatbuffers.Builder(0)
2134
2135 a = 0.5
2136 b = range(0, 15)
2137 c = 1
2138 d_a = [[1, 2], [3, 4]]
2139 d_b = [MyGame.Example.TestEnum.TestEnum.B, \
2140 MyGame.Example.TestEnum.TestEnum.C]
2141 d_c = [[MyGame.Example.TestEnum.TestEnum.A, \
2142 MyGame.Example.TestEnum.TestEnum.B], \
2143 [MyGame.Example.TestEnum.TestEnum.C, \
2144 MyGame.Example.TestEnum.TestEnum.B]]
Austin Schuh272c6132020-11-14 16:37:52 -08002145 d_d = [[-1, 1], [-2, 2]]
2146 e = 2
2147 f = [-1, 1]
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002148
2149 arrayOffset = MyGame.Example.ArrayStruct.CreateArrayStruct(builder, \
Austin Schuh272c6132020-11-14 16:37:52 -08002150 a, b, c, d_a, d_b, d_c, d_d, e, f)
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002151
2152 # Create a table with the ArrayStruct.
2153 MyGame.Example.ArrayTable.ArrayTableStart(builder)
2154 MyGame.Example.ArrayTable.ArrayTableAddA(builder, arrayOffset)
2155 tableOffset = MyGame.Example.ArrayTable.ArrayTableEnd(builder)
2156
2157 builder.Finish(tableOffset)
2158
2159 buf = builder.Output()
2160
2161 table = MyGame.Example.ArrayTable.ArrayTable.GetRootAsArrayTable(buf, 0)
2162
2163 # Verify structure.
2164 nested = MyGame.Example.NestedStruct.NestedStruct()
2165 self.assertEqual(table.A().A(), 0.5)
2166 self.assertEqual(table.A().B(), \
2167 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
2168 self.assertEqual(table.A().C(), 1)
2169 self.assertEqual(table.A().D(nested, 0).A(), [1, 2])
2170 self.assertEqual(table.A().D(nested, 1).A(), [3, 4])
2171 self.assertEqual(table.A().D(nested, 0).B(), \
2172 MyGame.Example.TestEnum.TestEnum.B)
2173 self.assertEqual(table.A().D(nested, 1).B(), \
2174 MyGame.Example.TestEnum.TestEnum.C)
2175 self.assertEqual(table.A().D(nested, 0).C(), \
2176 [MyGame.Example.TestEnum.TestEnum.A, \
2177 MyGame.Example.TestEnum.TestEnum.B])
2178 self.assertEqual(table.A().D(nested, 1).C(), \
2179 [MyGame.Example.TestEnum.TestEnum.C, \
2180 MyGame.Example.TestEnum.TestEnum.B])
Austin Schuh272c6132020-11-14 16:37:52 -08002181 self.assertEqual(table.A().D(nested, 0).D(), [-1, 1])
2182 self.assertEqual(table.A().D(nested, 1).D(), [-2, 2])
2183 self.assertEqual(table.A().E(), 2)
2184 self.assertEqual(table.A().F(), [-1, 1])
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002185
2186
2187def CheckAgainstGoldDataGo():
2188 try:
2189 gen_buf, gen_off = make_monster_from_generated_code()
2190 fn = 'monsterdata_go_wire.mon'
2191 if not os.path.exists(fn):
2192 print('Go-generated data does not exist, failed.')
2193 return False
2194
2195 # would like to use a context manager here, but it's less
2196 # backwards-compatible:
2197 f = open(fn, 'rb')
2198 go_wire_data = f.read()
2199 f.close()
2200
2201 CheckReadBuffer(bytearray(go_wire_data), 0)
2202 if not bytearray(gen_buf[gen_off:]) == bytearray(go_wire_data):
2203 raise AssertionError('CheckAgainstGoldDataGo failed')
2204 except:
2205 print('Failed to test against Go-generated test data.')
2206 return False
2207
2208 print('Can read Go-generated test data, and Python generates bytewise identical data.')
2209 return True
2210
2211
2212def CheckAgainstGoldDataJava():
2213 try:
2214 gen_buf, gen_off = make_monster_from_generated_code()
2215 fn = 'monsterdata_java_wire.mon'
2216 if not os.path.exists(fn):
2217 print('Java-generated data does not exist, failed.')
2218 return False
2219 f = open(fn, 'rb')
2220 java_wire_data = f.read()
2221 f.close()
2222
2223 CheckReadBuffer(bytearray(java_wire_data), 0)
2224 except:
2225 print('Failed to read Java-generated test data.')
2226 return False
2227
2228 print('Can read Java-generated test data.')
2229 return True
2230
2231
2232class LCG(object):
2233 ''' Include simple random number generator to ensure results will be the
2234 same cross platform.
2235 http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator '''
2236
2237 __slots__ = ['n']
2238
2239 InitialLCGSeed = 48271
2240
2241 def __init__(self):
2242 self.n = self.InitialLCGSeed
2243
2244 def Reset(self):
2245 self.n = self.InitialLCGSeed
2246
2247 def Next(self):
2248 self.n = ((self.n * 279470273) % 4294967291) & 0xFFFFFFFF
2249 return self.n
2250
2251
2252def BenchmarkVtableDeduplication(count):
2253 '''
2254 BenchmarkVtableDeduplication measures the speed of vtable deduplication
2255 by creating `prePop` vtables, then populating `count` objects with a
2256 different single vtable.
2257
2258 When count is large (as in long benchmarks), memory usage may be high.
2259 '''
2260
2261 for prePop in (1, 10, 100, 1000):
2262 builder = flatbuffers.Builder(0)
2263 n = 1 + int(math.log(prePop, 1.5))
2264
2265 # generate some layouts:
2266 layouts = set()
2267 r = list(compat_range(n))
2268 while len(layouts) < prePop:
2269 layouts.add(tuple(sorted(random.sample(r, int(max(1, n / 2))))))
2270
2271 layouts = list(layouts)
2272
2273 # pre-populate vtables:
2274 for layout in layouts:
2275 builder.StartObject(n)
2276 for j in layout:
2277 builder.PrependInt16Slot(j, j, 0)
2278 builder.EndObject()
2279
2280 # benchmark deduplication of a new vtable:
2281 def f():
2282 layout = random.choice(layouts)
2283 builder.StartObject(n)
2284 for j in layout:
2285 builder.PrependInt16Slot(j, j, 0)
2286 builder.EndObject()
2287
2288 duration = timeit.timeit(stmt=f, number=count)
2289 rate = float(count) / duration
2290 print(('vtable deduplication rate (n=%d, vtables=%d): %.2f sec' % (
2291 prePop,
2292 len(builder.vtables),
2293 rate))
2294 )
2295
2296
2297def BenchmarkCheckReadBuffer(count, buf, off):
2298 '''
2299 BenchmarkCheckReadBuffer measures the speed of flatbuffer reading
2300 by re-using the CheckReadBuffer function with the gold data.
2301 '''
2302
2303 def f():
2304 CheckReadBuffer(buf, off)
2305
2306 duration = timeit.timeit(stmt=f, number=count)
2307 rate = float(count) / duration
2308 data = float(len(buf) * count) / float(1024 * 1024)
2309 data_rate = data / float(duration)
2310
2311 print(('traversed %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec')
2312 % (count, len(buf), duration, rate, data_rate))
2313
2314
2315def BenchmarkMakeMonsterFromGeneratedCode(count, length):
2316 '''
2317 BenchmarkMakeMonsterFromGeneratedCode measures the speed of flatbuffer
2318 creation by re-using the make_monster_from_generated_code function for
2319 generating gold data examples.
2320 '''
2321
2322 duration = timeit.timeit(stmt=make_monster_from_generated_code,
2323 number=count)
2324 rate = float(count) / duration
2325 data = float(length * count) / float(1024 * 1024)
2326 data_rate = data / float(duration)
2327
2328 print(('built %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec' % \
2329 (count, length, duration, rate, data_rate)))
2330
2331
2332def backward_compatible_run_tests(**kwargs):
2333 if PY_VERSION < (2, 6):
2334 sys.stderr.write("Python version less than 2.6 are not supported")
2335 sys.stderr.flush()
2336 return False
2337
2338 # python2.6 has a reduced-functionality unittest.main function:
2339 if PY_VERSION == (2, 6):
2340 try:
2341 unittest.main(**kwargs)
2342 except SystemExit as e:
2343 if not e.code == 0:
2344 return False
2345 return True
2346
2347 # python2.7 and above let us not exit once unittest.main is run:
2348 kwargs['exit'] = False
2349 kwargs['verbosity'] = 0
2350 ret = unittest.main(**kwargs)
2351 if ret.result.errors or ret.result.failures:
2352 return False
2353
2354 return True
2355
2356def main():
2357 import os
2358 import sys
2359 if not len(sys.argv) == 4:
2360 sys.stderr.write('Usage: %s <benchmark vtable count>'
2361 '<benchmark read count> <benchmark build count>\n'
2362 % sys.argv[0])
2363 sys.stderr.write(' Provide COMPARE_GENERATED_TO_GO=1 to check'
2364 'for bytewise comparison to Go data.\n')
2365 sys.stderr.write(' Provide COMPARE_GENERATED_TO_JAVA=1 to check'
2366 'for bytewise comparison to Java data.\n')
2367 sys.stderr.flush()
2368 sys.exit(1)
2369
2370 kwargs = dict(argv=sys.argv[:-3])
2371
Austin Schuh272c6132020-11-14 16:37:52 -08002372 # show whether numpy is present, as it changes the test logic:
2373 try:
2374 import numpy
2375 print('numpy available')
2376 except ImportError:
2377 print('numpy not available')
2378
Austin Schuhe89fa2d2019-08-14 20:24:23 -07002379 # run tests, and run some language comparison checks if needed:
2380 success = backward_compatible_run_tests(**kwargs)
2381 if success and os.environ.get('COMPARE_GENERATED_TO_GO', 0) == "1":
2382 success = success and CheckAgainstGoldDataGo()
2383 if success and os.environ.get('COMPARE_GENERATED_TO_JAVA', 0) == "1":
2384 success = success and CheckAgainstGoldDataJava()
2385
2386 if not success:
2387 sys.stderr.write('Tests failed, skipping benchmarks.\n')
2388 sys.stderr.flush()
2389 sys.exit(1)
2390
2391 # run benchmarks (if 0, they will be a noop):
2392 bench_vtable = int(sys.argv[1])
2393 bench_traverse = int(sys.argv[2])
2394 bench_build = int(sys.argv[3])
2395 if bench_vtable:
2396 BenchmarkVtableDeduplication(bench_vtable)
2397 if bench_traverse:
2398 buf, off = make_monster_from_generated_code()
2399 BenchmarkCheckReadBuffer(bench_traverse, buf, off)
2400 if bench_build:
2401 buf, off = make_monster_from_generated_code()
2402 BenchmarkMakeMonsterFromGeneratedCode(bench_build, len(buf))
2403
2404if __name__ == '__main__':
2405 main()