• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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