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