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