1package.path = string.format("../lua/?.lua;./?.lua;%s",package.path) 2 3local function checkReadBuffer(buf, offset, sizePrefix) 4 offset = offset or 0 5 6 if type(buf) == "string" then 7 buf = flatbuffers.binaryArray.New(buf) 8 end 9 10 if sizePrefix then 11 local size = flatbuffers.N.Int32:Unpack(buf, offset) 12 -- no longer matches python tests, but the latest 'monsterdata_test.mon' 13 -- is 448 bytes, minus 4 to arrive at the 444 14 assert(size == 444) 15 offset = offset + flatbuffers.N.Int32.bytewidth 16 end 17 18 local mon = monster.GetRootAsMonster(buf, offset) 19 assert(mon:Hp() == 80, "Monster Hp is not 80") 20 assert(mon:Mana() == 150, "Monster Mana is not 150") 21 assert(mon:Name() == "MyMonster", "Monster Name is not MyMonster") 22 23 local vec = assert(mon:Pos(), "Monster Position is nil") 24 assert(vec:X() == 1.0) 25 assert(vec:Y() == 2.0) 26 assert(vec:Z() == 3.0) 27 assert(vec:Test1() == 3.0) 28 assert(vec:Test2() == 2) 29 30 local t = require("MyGame.Example.Test").New() 31 t = assert(vec:Test3(t)) 32 33 assert(t:A() == 5) 34 assert(t:B() == 6) 35 36 local ut = require("MyGame.Example.Any") 37 assert(mon:TestType() == ut.Monster) 38 39 local table2 = mon:Test() 40 assert(getmetatable(table2) == "flatbuffers.view.mt") 41 42 local mon2 = monster.New() 43 mon2:Init(table2.bytes, table2.pos) 44 45 assert(mon2:Name() == "Fred") 46 47 assert(mon:InventoryLength() == 5) 48 local invsum = 0 49 for i=1,mon:InventoryLength() do 50 local v = mon:Inventory(i) 51 invsum = invsum + v 52 end 53 assert(invsum == 10) 54 55 for i=1,5 do 56 assert(mon:VectorOfLongs(i) == 10^((i-1)*2)) 57 end 58 59 local dbls = { -1.7976931348623157e+308, 0, 1.7976931348623157e+308} 60 for i=1,mon:VectorOfDoublesLength() do 61 assert(mon:VectorOfDoubles(i) == dbls[i]) 62 end 63 64 assert(mon:Test4Length() == 2) 65 66 local test0 = mon:Test4(1) 67 local test1 = mon:Test4(2) 68 69 local v0 = test0:A() 70 local v1 = test0:B() 71 local v2 = test1:A() 72 local v3 = test1:B() 73 74 local sumtest12 = v0 + v1 + v2 + v3 75 assert(sumtest12 == 100) 76 77 assert(mon:TestarrayofstringLength() == 2) 78 assert(mon:Testarrayofstring(1) == "test1") 79 assert(mon:Testarrayofstring(2) == "test2") 80 81 assert(mon:TestarrayoftablesLength() == 0) 82 assert(mon:TestnestedflatbufferLength() == 0) 83 assert(mon:Testempty() == nil) 84end 85 86local function generateMonster(sizePrefix) 87 local b = flatbuffers.Builder(0) 88 local str = b:CreateString("MyMonster") 89 local test1 = b:CreateString("test1") 90 local test2 = b:CreateString("test2") 91 local fred = b:CreateString("Fred") 92 93 monster.StartInventoryVector(b, 5) 94 b:PrependByte(4) 95 b:PrependByte(3) 96 b:PrependByte(2) 97 b:PrependByte(1) 98 b:PrependByte(0) 99 local inv = b:EndVector(5) 100 101 monster.Start(b) 102 monster.AddName(b, fred) 103 local mon2 = monster.End(b) 104 105 monster.StartTest4Vector(b, 2) 106 test.CreateTest(b, 10, 20) 107 test.CreateTest(b, 30, 40) 108 local test4 = b:EndVector(2) 109 110 monster.StartTestarrayofstringVector(b, 2) 111 b:PrependUOffsetTRelative(test2) 112 b:PrependUOffsetTRelative(test1) 113 local testArrayOfString = b:EndVector(2) 114 115 monster.StartVectorOfLongsVector(b, 5) 116 b:PrependInt64(100000000) 117 b:PrependInt64(1000000) 118 b:PrependInt64(10000) 119 b:PrependInt64(100) 120 b:PrependInt64(1) 121 local vectorOfLongs = b:EndVector(5) 122 123 monster.StartVectorOfDoublesVector(b, 3) 124 b:PrependFloat64(1.7976931348623157e+308) 125 b:PrependFloat64(0) 126 b:PrependFloat64(-1.7976931348623157e+308) 127 local vectorOfDoubles = b:EndVector(3) 128 129 monster.Start(b) 130 local pos = vec3.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 2, 5, 6) 131 monster.AddPos(b, pos) 132 133 monster.AddHp(b, 80) 134 monster.AddName(b, str) 135 monster.AddInventory(b, inv) 136 monster.AddTestType(b, 1) 137 monster.AddTest(b, mon2) 138 monster.AddTest4(b, test4) 139 monster.AddTestarrayofstring(b, testArrayOfString) 140 monster.AddVectorOfLongs(b, vectorOfLongs) 141 monster.AddVectorOfDoubles(b, vectorOfDoubles) 142 local mon = monster.End(b) 143 144 if sizePrefix then 145 b:FinishSizePrefixed(mon) 146 else 147 b:Finish(mon) 148 end 149 return b:Output(true), b:Head() 150end 151 152local function sizePrefix(sizePrefix) 153 local buf,offset = generateMonster(sizePrefix) 154 checkReadBuffer(buf, offset, sizePrefix) 155end 156 157local function testCanonicalData() 158 local f = assert(io.open('monsterdata_test.mon', 'rb')) 159 local wireData = f:read("*a") 160 f:close() 161 checkReadBuffer(wireData) 162end 163 164local function benchmarkMakeMonster(count) 165 local length = #(generateMonster()) 166 167 --require("flatbuffers.profiler") 168 --profiler = newProfiler("call") 169 --profiler:start() 170 171 local s = os.clock() 172 for i=1,count do 173 generateMonster() 174 end 175 local e = os.clock() 176 177 --profiler:stop() 178 179 --local outfile = io.open( "profile.txt", "w+" ) 180 --profiler:report( outfile, true) 181 --outfile:close() 182 183 184 local dur = (e - s) 185 local rate = count / (dur * 1000) 186 local data = (length * count) / (1024 * 1024) 187 local dataRate = data / dur 188 189 print(string.format('built %d %d-byte flatbuffers in %.2fsec: %.2f/msec, %.2fMB/sec', 190 count, length, dur, rate, dataRate)) 191end 192 193local function benchmarkReadBuffer(count) 194 local f = assert(io.open('monsterdata_test.mon', 'rb')) 195 local buf = f:read("*a") 196 f:close() 197 198 local s = os.clock() 199 for i=1,count do 200 checkReadBuffer(buf) 201 end 202 local e = os.clock() 203 204 local dur = (e - s) 205 local rate = count / (dur * 1000) 206 local data = (#buf * count) / (1024 * 1024) 207 local dataRate = data / dur 208 209 print(string.format('traversed %d %d-byte flatbuffers in %.2fsec: %.2f/msec, %.2fMB/sec', 210 count, #buf, dur, rate, dataRate)) 211end 212 213local tests = 214{ 215 { 216 f = sizePrefix, 217 d = "Test size prefix", 218 args = {{true}, {false}} 219 }, 220 { 221 f = testCanonicalData, 222 d = "Tests Canonical flatbuffer file included in repo" 223 }, 224 { 225 f = benchmarkMakeMonster, 226 d = "Benchmark making monsters", 227 args = { 228 {100}, 229 {1000}, 230 {10000}, 231 } 232 }, 233 { 234 f = benchmarkReadBuffer, 235 d = "Benchmark reading monsters", 236 args = { 237 {100}, 238 {1000}, 239 {10000}, 240 -- uncomment following to run 1 million to compare. 241 -- Took ~141 seconds on my machine 242 --{1000000}, 243 } 244 }, 245} 246 247local result, err = xpcall(function() 248 flatbuffers = assert(require("flatbuffers")) 249 monster = assert(require("MyGame.Example.Monster")) 250 test = assert(require("MyGame.Example.Test")) 251 vec3 = assert(require("MyGame.Example.Vec3")) 252 253 local function buildArgList(tbl) 254 local s = "" 255 for _,item in ipairs(tbl) do 256 s = s .. tostring(item) .. "," 257 end 258 return s:sub(1,-2) 259 end 260 261 local testsPassed, testsFailed = 0,0 262 for _,test in ipairs(tests) do 263 local allargs = test.args or {{}} 264 for _,args in ipairs(allargs) do 265 local results, err = xpcall(test.f,debug.traceback, table.unpack(args)) 266 if results then 267 testsPassed = testsPassed + 1 268 else 269 testsFailed = testsFailed + 1 270 print(string.format(" Test [%s](%s) failed: \n\t%s", 271 test.d or "", 272 buildArgList(args), 273 err)) 274 end 275 end 276 end 277 278 local totalTests = testsPassed + testsFailed 279 print(string.format("# of test passed: %d / %d (%.2f%%)", 280 testsPassed, 281 totalTests, 282 totalTests ~= 0 283 and 100 * (testsPassed / totalTests) 284 or 0) 285 ) 286 287 return 0 288end, debug.traceback) 289 290if not result then 291 print("Unable to run tests due to test framework error: ",err) 292end 293 294os.exit(result or -1) 295