146 lines
4.4 KiB
Lua
146 lines
4.4 KiB
Lua
|
--
|
||
|
-- Set verbose to 0 for quiet output (either the first assertion failure or
|
||
|
-- "All tests OK"), to 1 to see the events ("SEND", "SENT", "CHECK") without
|
||
|
-- the actual bytes, or to 2 to see the events with the bytes.
|
||
|
--
|
||
|
local verbose = 0
|
||
|
|
||
|
local vprint = (verbose > 0) and print or function() end
|
||
|
|
||
|
--
|
||
|
-- Mock up enough of the nodemcu tmr structure, but pretend that nothing
|
||
|
-- happens between ticks. This won't exercise the optimistic corking logic,
|
||
|
-- but that's probably fine.
|
||
|
-- luacheck: push ignore
|
||
|
tmr = {}
|
||
|
tmr.ALARM_SINGLE = 0
|
||
|
function tmr.create()
|
||
|
local r = {}
|
||
|
function r:alarm(_i, _t, cb) vprint("TMR") cb() end
|
||
|
return r
|
||
|
end
|
||
|
-- luacheck: pop
|
||
|
|
||
|
--
|
||
|
-- Mock up enough of the nodemcu net.socket type; have it log all the sends
|
||
|
-- into this "outs" array so that we can later check against it.
|
||
|
--
|
||
|
local outs = {}
|
||
|
local fakesock = {
|
||
|
cb = nil,
|
||
|
on = function(this, _, cb) this.cb = cb end,
|
||
|
send = function(this, s) vprint("SEND", (verbose > 1) and s) table.insert(outs, s) end -- luacheck: no unused
|
||
|
}
|
||
|
local function sent() vprint("SENT") fakesock.cb() end
|
||
|
|
||
|
-- And wrap a fifosock around this fake socket
|
||
|
local fsend = (require "fifosock").wrap(fakesock)
|
||
|
|
||
|
-- Verify that the next unconsumed output is as indicated
|
||
|
local function fcheck(x)
|
||
|
vprint ("CHECK", (verbose > 1) and x)
|
||
|
assert (#outs > 0)
|
||
|
assert (x == outs[1])
|
||
|
table.remove(outs, 1)
|
||
|
end
|
||
|
|
||
|
-- Enqueue an empty function to prevent coalescing within the fifosock
|
||
|
local function nocoal() fsend(function() return nil end) end
|
||
|
|
||
|
-- Send and check, for when the string should be sent exactly as is
|
||
|
local function fsendc(x) fsend(x) fcheck(x) end
|
||
|
|
||
|
-- Check that there are no more outputs
|
||
|
local function fchecke() vprint("CHECKE") assert (#outs == 0) end
|
||
|
|
||
|
--
|
||
|
-- And now for the tests, which start easy and grow in complexity
|
||
|
--
|
||
|
|
||
|
fsendc("abracadabra none")
|
||
|
sent() ; fchecke()
|
||
|
|
||
|
fsendc("abracadabra three")
|
||
|
fsend("short")
|
||
|
fsend("string")
|
||
|
fsend("build")
|
||
|
sent() ; fcheck("shortstringbuild")
|
||
|
sent() ; fchecke()
|
||
|
|
||
|
-- Hit default FSMALLLIM while building up
|
||
|
fsendc("abracadabra lots small")
|
||
|
for i = 1, 32 do fsend("a") end -- luacheck: no unused
|
||
|
nocoal()
|
||
|
for i = 1, 4 do fsend("a") end -- luacheck: no unused
|
||
|
sent() ; fcheck(string.rep("a", 32))
|
||
|
sent() ; fcheck(string.rep("a", 4))
|
||
|
sent() ; fchecke()
|
||
|
|
||
|
-- Hit string length while building up
|
||
|
fsendc("abracadabra overlong")
|
||
|
for i = 1, 10 do fsend(string.rep("a",32)) end -- luacheck: no unused
|
||
|
sent() ; fcheck(string.rep("a", 320))
|
||
|
sent() ; fchecke()
|
||
|
|
||
|
-- Hit neither before sending a big string
|
||
|
fsendc("abracadabra mid long")
|
||
|
for i = 1, 6 do fsend(string.rep("a",32)) end -- luacheck: no unused
|
||
|
fsend(string.rep("b", 256))
|
||
|
nocoal()
|
||
|
for i = 1, 6 do fsend(string.rep("c",32)) end -- luacheck: no unused
|
||
|
sent() ; fcheck(string.rep("a", 192) .. string.rep("b", 256))
|
||
|
sent() ; fcheck(string.rep("c", 192))
|
||
|
sent() ; fchecke()
|
||
|
|
||
|
-- send a huge string, verify that it coalesces
|
||
|
fsendc(string.rep("a",256) .. string.rep("b", 256) .. string.rep("c", 260))
|
||
|
sent() ; fchecke()
|
||
|
|
||
|
-- send a huge string, verify that it coalesces save for the short bit at the end
|
||
|
fsend(string.rep("a",256) .. string.rep("b", 256) .. string.rep("c", 256) .. string.rep("d",256))
|
||
|
fsend("e")
|
||
|
fcheck(string.rep("a",256) .. string.rep("b", 256) .. string.rep("c", 256))
|
||
|
sent() ; fcheck(string.rep("d",256) .. "e")
|
||
|
sent() ; fchecke()
|
||
|
|
||
|
-- send enough that our 4x lookahead still leaves something in the queue
|
||
|
fsend(string.rep("a",512) .. string.rep("b", 512) .. string.rep("c", 512))
|
||
|
fcheck(string.rep("a",512) .. string.rep("b", 512))
|
||
|
sent() ; fcheck(string.rep("c",512))
|
||
|
sent() ; fchecke()
|
||
|
|
||
|
-- test a lazy generator
|
||
|
do
|
||
|
local ix = 0
|
||
|
local function gen() vprint("GEN", ix); ix = ix + 1; return ("a" .. ix), ix < 3 and gen end
|
||
|
fsend(gen)
|
||
|
fsend("b")
|
||
|
fcheck("a1")
|
||
|
sent() ; fcheck("a2")
|
||
|
sent() ; fcheck("a3")
|
||
|
sent() ; fcheck("b")
|
||
|
sent() ; fchecke()
|
||
|
end
|
||
|
-- test a completion-like callback that does send text
|
||
|
do
|
||
|
local ix = 0
|
||
|
local function gen() vprint("GEN"); ix = 1; return "efgh", nil end
|
||
|
fsend("abcd"); fsend(gen); fsend("ijkl")
|
||
|
assert (ix == 0)
|
||
|
fcheck("abcd"); assert (ix == 0)
|
||
|
sent() ; fcheck("efgh"); assert (ix == 1); ix = 0
|
||
|
sent() ; fcheck("ijkl"); assert (ix == 0)
|
||
|
sent() ; fchecke()
|
||
|
end
|
||
|
-- and one that doesn't
|
||
|
do
|
||
|
local ix = 0
|
||
|
local function gen() vprint("GEN"); ix = 1; return nil, nil end
|
||
|
fsend("abcd"); fsend(gen); fsend("ijkl")
|
||
|
assert (ix == 0)
|
||
|
fcheck("abcd"); assert (ix == 0)
|
||
|
sent() ; fcheck("ijkl"); assert (ix == 1); ix = 0
|
||
|
sent() ; fchecke() ; assert (ix == 0)
|
||
|
end
|
||
|
print("All tests OK")
|