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