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(b=None, sizePrefix=False, file_identifier=None): 2021 """ Use generated code to build the example Monster. """ 2022 if b is None: 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 2770class TestBuilderClear(unittest.TestCase): 2771 2772 def test_consistency(self): 2773 """ Checks if clear resets the state of the builder. """ 2774 b = flatbuffers.Builder(0) 2775 2776 # Add some data to the buffer 2777 off1 = b.CreateString('a' * 1024) 2778 want = b.Bytes[b.Head():] 2779 2780 # Reset the builder 2781 b.Clear() 2782 2783 # Readd the same data into the buffer 2784 off2 = b.CreateString('a' * 1024) 2785 got = b.Bytes[b.Head():] 2786 2787 # Expect to get the same data into the buffer at the same offset 2788 self.assertEqual(off1, off2) 2789 self.assertEqual(want, got) 2790 2791 def test_repeated_clear_after_builder_reuse(self): 2792 init_buf = None 2793 init_off = None 2794 b = flatbuffers.Builder(0) 2795 2796 for i in range(5): 2797 buf, off = make_monster_from_generated_code(b) 2798 b.Clear() 2799 2800 if i > 0: 2801 self.assertEqual(init_buf, buf) 2802 self.assertEqual(init_off, off) 2803 else: 2804 init_buf = buf 2805 init_off = off 2806 2807def CheckAgainstGoldDataGo(): 2808 try: 2809 gen_buf, gen_off = make_monster_from_generated_code() 2810 fn = 'monsterdata_go_wire.mon' 2811 if not os.path.exists(fn): 2812 print('Go-generated data does not exist, failed.') 2813 return False 2814 2815 # would like to use a context manager here, but it's less 2816 # backwards-compatible: 2817 f = open(fn, 'rb') 2818 go_wire_data = f.read() 2819 f.close() 2820 2821 CheckReadBuffer(bytearray(go_wire_data), 0) 2822 if not bytearray(gen_buf[gen_off:]) == bytearray(go_wire_data): 2823 raise AssertionError('CheckAgainstGoldDataGo failed') 2824 except: 2825 print('Failed to test against Go-generated test data.') 2826 return False 2827 2828 print( 2829 'Can read Go-generated test data, and Python generates bytewise identical data.' 2830 ) 2831 return True 2832 2833 2834def CheckAgainstGoldDataJava(): 2835 try: 2836 gen_buf, gen_off = make_monster_from_generated_code() 2837 fn = 'monsterdata_java_wire.mon' 2838 if not os.path.exists(fn): 2839 print('Java-generated data does not exist, failed.') 2840 return False 2841 f = open(fn, 'rb') 2842 java_wire_data = f.read() 2843 f.close() 2844 2845 CheckReadBuffer(bytearray(java_wire_data), 0) 2846 except: 2847 print('Failed to read Java-generated test data.') 2848 return False 2849 2850 print('Can read Java-generated test data.') 2851 return True 2852 2853 2854class LCG(object): 2855 """ Include simple random number generator to ensure results will be the 2856 2857 same cross platform. 2858 http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator 2859 """ 2860 2861 __slots__ = ['n'] 2862 2863 InitialLCGSeed = 48271 2864 2865 def __init__(self): 2866 self.n = self.InitialLCGSeed 2867 2868 def Reset(self): 2869 self.n = self.InitialLCGSeed 2870 2871 def Next(self): 2872 self.n = ((self.n * 279470273) % 4294967291) & 0xFFFFFFFF 2873 return self.n 2874 2875 2876def BenchmarkVtableDeduplication(count): 2877 """ 2878 BenchmarkVtableDeduplication measures the speed of vtable deduplication 2879 by creating `prePop` vtables, then populating `count` objects with a 2880 different single vtable. 2881 2882 When count is large (as in long benchmarks), memory usage may be high. 2883 """ 2884 2885 for prePop in (1, 10, 100, 1000): 2886 builder = flatbuffers.Builder(0) 2887 n = 1 + int(math.log(prePop, 1.5)) 2888 2889 # generate some layouts: 2890 layouts = set() 2891 r = list(compat_range(n)) 2892 while len(layouts) < prePop: 2893 layouts.add(tuple(sorted(random.sample(r, int(max(1, n / 2)))))) 2894 2895 layouts = list(layouts) 2896 2897 # pre-populate vtables: 2898 for layout in layouts: 2899 builder.StartObject(n) 2900 for j in layout: 2901 builder.PrependInt16Slot(j, j, 0) 2902 builder.EndObject() 2903 2904 # benchmark deduplication of a new vtable: 2905 def f(): 2906 layout = random.choice(layouts) 2907 builder.StartObject(n) 2908 for j in layout: 2909 builder.PrependInt16Slot(j, j, 0) 2910 builder.EndObject() 2911 2912 duration = timeit.timeit(stmt=f, number=count) 2913 rate = float(count) / duration 2914 print(('vtable deduplication rate (n=%d, vtables=%d): %.2f sec' % 2915 (prePop, len(builder.vtables), rate))) 2916 2917 2918def BenchmarkCheckReadBuffer(count, buf, off): 2919 """ 2920 BenchmarkCheckReadBuffer measures the speed of flatbuffer reading 2921 by re-using the CheckReadBuffer function with the gold data. 2922 """ 2923 2924 def f(): 2925 CheckReadBuffer(buf, off) 2926 2927 duration = timeit.timeit(stmt=f, number=count) 2928 rate = float(count) / duration 2929 data = float(len(buf) * count) / float(1024 * 1024) 2930 data_rate = data / float(duration) 2931 2932 print(('traversed %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec') % 2933 (count, len(buf), duration, rate, data_rate)) 2934 2935 2936def BenchmarkMakeMonsterFromGeneratedCode(count, length): 2937 """ 2938 BenchmarkMakeMonsterFromGeneratedCode measures the speed of flatbuffer 2939 creation by re-using the make_monster_from_generated_code function for 2940 generating gold data examples. 2941 """ 2942 2943 duration = timeit.timeit(stmt=make_monster_from_generated_code, number=count) 2944 rate = float(count) / duration 2945 data = float(length * count) / float(1024 * 1024) 2946 data_rate = data / float(duration) 2947 2948 print(('built %d %d-byte flatbuffers in %.2fsec: %.2f/sec, %.2fMB/sec' % \ 2949 (count, length, duration, rate, data_rate))) 2950 2951 2952def BenchmarkBuilderClear(count, length): 2953 b = flatbuffers.Builder(length) 2954 duration = timeit.timeit(stmt=lambda: make_monster_from_generated_code(b), 2955 number=count) 2956 rate = float(count) / duration 2957 data = float(length * count) / float(1024 * 1024) 2958 data_rate = data / float(duration) 2959 2960 print(('built %d %d-byte flatbuffers (reused buffer) in %.2fsec:' 2961 ' %.2f/sec, %.2fMB/sec' % (count, length, duration, rate, data_rate))) 2962 2963 2964def backward_compatible_run_tests(**kwargs): 2965 if PY_VERSION < (2, 6): 2966 sys.stderr.write('Python version less than 2.6 are not supported') 2967 sys.stderr.flush() 2968 return False 2969 2970 # python2.6 has a reduced-functionality unittest.main function: 2971 if PY_VERSION == (2, 6): 2972 try: 2973 unittest.main(**kwargs) 2974 except SystemExit as e: 2975 if not e.code == 0: 2976 return False 2977 return True 2978 2979 # python2.7 and above let us not exit once unittest.main is run: 2980 kwargs['exit'] = False 2981 kwargs['verbosity'] = 0 2982 ret = unittest.main(**kwargs) 2983 if ret.result.errors or ret.result.failures: 2984 return False 2985 2986 return True 2987 2988 2989def main(): 2990 import os 2991 import sys 2992 if not len(sys.argv) == 6: 2993 sys.stderr.write('Usage: %s <benchmark vtable count> ' 2994 '<benchmark read count> <benchmark build count> ' 2995 '<benchmark clear builder> <is_onefile>\n' % sys.argv[0]) 2996 sys.stderr.write(' Provide COMPARE_GENERATED_TO_GO=1 to check' 2997 'for bytewise comparison to Go data.\n') 2998 sys.stderr.write(' Provide COMPARE_GENERATED_TO_JAVA=1 to check' 2999 'for bytewise comparison to Java data.\n') 3000 sys.stderr.flush() 3001 sys.exit(1) 3002 3003 kwargs = dict(argv=sys.argv[:-5]) 3004 3005 create_namespace_shortcut(sys.argv[5].lower() == 'true') 3006 3007 # show whether numpy is present, as it changes the test logic: 3008 try: 3009 import numpy 3010 print('numpy available') 3011 except ImportError: 3012 print('numpy not available') 3013 3014 # run tests, and run some language comparison checks if needed: 3015 success = backward_compatible_run_tests(**kwargs) 3016 if success and os.environ.get('COMPARE_GENERATED_TO_GO', 0) == '1': 3017 success = success and CheckAgainstGoldDataGo() 3018 if success and os.environ.get('COMPARE_GENERATED_TO_JAVA', 0) == '1': 3019 success = success and CheckAgainstGoldDataJava() 3020 3021 if not success: 3022 sys.stderr.write('Tests failed, skipping benchmarks.\n') 3023 sys.stderr.flush() 3024 sys.exit(1) 3025 3026 # run benchmarks (if 0, they will be a noop): 3027 bench_vtable = int(sys.argv[1]) 3028 bench_traverse = int(sys.argv[2]) 3029 bench_build = int(sys.argv[3]) 3030 bench_clear = int(sys.argv[4]) 3031 if bench_vtable: 3032 BenchmarkVtableDeduplication(bench_vtable) 3033 if bench_traverse: 3034 buf, off = make_monster_from_generated_code() 3035 BenchmarkCheckReadBuffer(bench_traverse, buf, off) 3036 if bench_build: 3037 buf, off = make_monster_from_generated_code() 3038 BenchmarkMakeMonsterFromGeneratedCode(bench_build, len(buf)) 3039 if bench_clear: 3040 buf, off = make_monster_from_generated_code() 3041 BenchmarkBuilderClear(bench_build, len(buf)) 3042 3043if __name__ == '__main__': 3044 main() 3045