mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 20:38:22 +01:00
Testes reformulados.
This commit is contained in:
parent
af181244d9
commit
7b99195649
@ -1,112 +1,327 @@
|
|||||||
-----------------------------------------------------------------------------
|
|
||||||
-- LuaSocket automated test module
|
|
||||||
-- testclnt.lua
|
|
||||||
-- This is the client module. It connects with the server module and executes
|
|
||||||
-- all tests.
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Read command definitions
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
HOST = HOST or "localhost"
|
HOST = HOST or "localhost"
|
||||||
assert(dofile("testcmd.lua"))
|
PORT = PORT or "8080"
|
||||||
test_debug_mode()
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
function pass(...)
|
||||||
-- Start control connection
|
local s = call(format, arg)
|
||||||
-----------------------------------------------------------------------------
|
write(s, "\n")
|
||||||
new_test("initializing...")
|
end
|
||||||
while control == nil do
|
|
||||||
print("client: trying control connection...")
|
function fail(...)
|
||||||
control, err = connect(HOST, PORT)
|
local s = call(format, arg)
|
||||||
if control then
|
write("ERROR: ", s, "!\n")
|
||||||
print("client: control connection stablished!")
|
exit()
|
||||||
|
end
|
||||||
|
|
||||||
|
function warn(...)
|
||||||
|
local s = call(format, arg)
|
||||||
|
write("WARNING: ", s, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
function remote(...)
|
||||||
|
local s = call(format, arg)
|
||||||
|
s = gsub(s, "\n", ";")
|
||||||
|
s = gsub(s, "%s+", " ")
|
||||||
|
s = gsub(s, "^%s*", "")
|
||||||
|
control:send(s, "\n")
|
||||||
|
control:receive()
|
||||||
|
end
|
||||||
|
|
||||||
|
function test(test)
|
||||||
|
write("----------------------------------------------\n",
|
||||||
|
"testing: ", test, "\n",
|
||||||
|
"----------------------------------------------\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
function check_timeout(tm, sl, elapsed, err, opp, mode, alldone)
|
||||||
|
if tm < sl then
|
||||||
|
if opp == "send" then
|
||||||
|
if not err then warn("must be buffered")
|
||||||
|
elseif err == "timeout" then pass("proper timeout")
|
||||||
|
else fail("unexpected error '%s'", err) end
|
||||||
else
|
else
|
||||||
_sleep(2)
|
if err ~= "timeout" then fail("should have timed out")
|
||||||
|
else pass("proper timeout") end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if mode == "return" then
|
||||||
|
if elapsed > tm then
|
||||||
|
if err ~= "timeout" then fail("should have timed out")
|
||||||
|
else pass("proper timeout") end
|
||||||
|
elseif elapsed < tm then
|
||||||
|
if err then fail(err)
|
||||||
|
else pass("ok") end
|
||||||
|
else
|
||||||
|
if alldone then
|
||||||
|
if err then fail("unexpected error '%s'", err)
|
||||||
|
else pass("ok") end
|
||||||
|
else
|
||||||
|
if err ~= "timeout" then fail(err)
|
||||||
|
else pass("proper timeoutk") end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if err then fail(err)
|
||||||
|
else pass("ok") end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
write("----------------------------------------------\n",
|
||||||
-- Make sure server is ready for data transmission
|
"LuaSocket Test Procedures\n",
|
||||||
-----------------------------------------------------------------------------
|
"----------------------------------------------\n")
|
||||||
function sync()
|
|
||||||
send_command(SYNC)
|
|
||||||
get_command()
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
if not _time or not _sleep then fail("not compiled with _DEBUG") end
|
||||||
-- Close and reopen data connection, to get rid of any unread blocks
|
|
||||||
-----------------------------------------------------------------------------
|
start = _time()
|
||||||
function reconnect()
|
|
||||||
if data then
|
function tcpreconnect()
|
||||||
data:close()
|
write("attempting data connection... ")
|
||||||
send_command(CLOSE)
|
if data then data:close() end
|
||||||
data = nil
|
remote [[
|
||||||
|
if data then data:close() data = nil end
|
||||||
|
data = server:accept()
|
||||||
|
]]
|
||||||
|
data, error = connect(HOST, PORT)
|
||||||
|
if not data then fail(error)
|
||||||
|
else pass("connected!") end
|
||||||
end
|
end
|
||||||
while data == nil do
|
reconnect = tcpreconnect
|
||||||
send_command(CONNECT)
|
|
||||||
data = connect(HOST, PORT)
|
pass("attempting control connection...")
|
||||||
|
control, error = connect(HOST, PORT)
|
||||||
|
if error then fail(error)
|
||||||
|
else pass("connected!") end
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
test("bugs")
|
||||||
|
|
||||||
|
write("empty host connect: ")
|
||||||
|
function empty_connect()
|
||||||
|
if data then data:close() data = nil end
|
||||||
|
remote [[
|
||||||
|
if data then data:close() data = nil end
|
||||||
|
data = server:accept()
|
||||||
|
]]
|
||||||
|
data, err = connect("", PORT)
|
||||||
if not data then
|
if not data then
|
||||||
print("client: waiting for data connection.")
|
pass("ok")
|
||||||
_sleep(1)
|
data = connect(HOST, PORT)
|
||||||
end
|
else fail("should not have connected!") end
|
||||||
end
|
|
||||||
sync()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
empty_connect()
|
||||||
-- Tests the command connection
|
|
||||||
-----------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
function test_command(cmd, par)
|
test("method registration")
|
||||||
local cmd_back, par_back
|
|
||||||
|
function test_methods(sock, methods)
|
||||||
|
for _, v in methods do
|
||||||
|
if type(sock[v]) ~= "function" then
|
||||||
|
fail(type(sock) .. " method " .. v .. "not registered")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
pass(type(sock) .. " methods are ok")
|
||||||
|
end
|
||||||
|
|
||||||
|
test_methods(control, {
|
||||||
|
"close",
|
||||||
|
"timeout",
|
||||||
|
"send",
|
||||||
|
"receive",
|
||||||
|
"getpeername",
|
||||||
|
"getsockname"
|
||||||
|
})
|
||||||
|
|
||||||
|
if udpsocket then
|
||||||
|
test_methods(udpsocket(), {
|
||||||
|
"close",
|
||||||
|
"timeout",
|
||||||
|
"send",
|
||||||
|
"sendto",
|
||||||
|
"receive",
|
||||||
|
"receivefrom",
|
||||||
|
"getpeername",
|
||||||
|
"getsockname",
|
||||||
|
"setsockname",
|
||||||
|
"setpeername"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
test_methods(bind("*", 0), {
|
||||||
|
"close",
|
||||||
|
"timeout",
|
||||||
|
"accept"
|
||||||
|
})
|
||||||
|
|
||||||
|
if pipe then
|
||||||
|
local p1, p2 = pipe()
|
||||||
|
test_methods(p1, {
|
||||||
|
"close",
|
||||||
|
"timeout",
|
||||||
|
"send",
|
||||||
|
"receive"
|
||||||
|
})
|
||||||
|
test_methods(p2, {
|
||||||
|
"close",
|
||||||
|
"timeout",
|
||||||
|
"send",
|
||||||
|
"receive"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
if filesocket then
|
||||||
|
test_methods(filesocket(0), {
|
||||||
|
"close",
|
||||||
|
"timeout",
|
||||||
|
"send",
|
||||||
|
"receive"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
test("select function")
|
||||||
|
function test_selectbugs()
|
||||||
|
local r, s, e = select(nil, nil, 0.1)
|
||||||
|
assert(type(r) == "table" and type(s) == "table" and e == "timeout")
|
||||||
|
pass("both nil: ok")
|
||||||
|
local udp = udpsocket()
|
||||||
|
udp:close()
|
||||||
|
r, s, e = select({ data }, { data }, 0.1)
|
||||||
|
assert(type(r) == "table" and type(s) == "table" and e == "timeout")
|
||||||
|
pass("closed sockets: ok")
|
||||||
|
e = call(select, {"wrong", 1, 0.1}, "x", nil)
|
||||||
|
assert(e == nil)
|
||||||
|
pass("invalid input: ok")
|
||||||
|
end
|
||||||
|
|
||||||
|
test_selectbugs()
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
test("character line")
|
||||||
reconnect()
|
reconnect()
|
||||||
send_command(COMMAND)
|
|
||||||
write("testing command ")
|
|
||||||
print_command(cmd, par)
|
|
||||||
send_command(cmd, par)
|
|
||||||
cmd_back, par_back = get_command()
|
|
||||||
if cmd_back ~= cmd or par_back ~= par then
|
|
||||||
fail(cmd)
|
|
||||||
else
|
|
||||||
pass()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Tests ASCII line transmission
|
|
||||||
-- Input
|
|
||||||
-- len: length of line to be tested
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
function test_asciiline(len)
|
function test_asciiline(len)
|
||||||
local str, str10, back, err
|
local str, str10, back, err
|
||||||
reconnect()
|
|
||||||
send_command(ECHO_LINE)
|
|
||||||
str = strrep("x", mod(len, 10))
|
str = strrep("x", mod(len, 10))
|
||||||
str10 = strrep("aZb.c#dAe?", floor(len/10))
|
str10 = strrep("aZb.c#dAe?", floor(len/10))
|
||||||
str = str .. str10
|
str = str .. str10
|
||||||
write("testing ", len, " byte(s) line\n")
|
pass(len .. " byte(s) line")
|
||||||
|
remote "str = data:receive()"
|
||||||
err = data:send(str, "\n")
|
err = data:send(str, "\n")
|
||||||
if err then fail(err) end
|
if err then fail(err) end
|
||||||
|
remote "data:send(str, '\\n')"
|
||||||
back, err = data:receive()
|
back, err = data:receive()
|
||||||
if err then fail(err) end
|
if err then fail(err) end
|
||||||
if back == str then pass("lines match")
|
if back == str then pass("lines match")
|
||||||
else fail("lines don't match") end
|
else fail("lines don't match") end
|
||||||
end
|
end
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
test_asciiline(1)
|
||||||
-- Tests multiple pattern transmission
|
test_asciiline(17)
|
||||||
-- Input
|
test_asciiline(200)
|
||||||
-- len: length of line to be tested
|
test_asciiline(4091)
|
||||||
-----------------------------------------------------------------------------
|
test_asciiline(80199)
|
||||||
function test_multiple()
|
test_asciiline(800000)
|
||||||
local p1 = "unix line\n"
|
|
||||||
local p2 = "dos line\r\n"
|
------------------------------------------------------------------------
|
||||||
local p3 = "raw bytes"
|
test("binary line")
|
||||||
local bp1, bp2, bp3
|
|
||||||
reconnect()
|
reconnect()
|
||||||
send_command(ECHO_BLOCK, strlen(p1)+strlen(p2)+strlen(p3))
|
|
||||||
|
function test_rawline(len)
|
||||||
|
local str, str10, back, err
|
||||||
|
str = strrep(strchar(47), mod(len, 10))
|
||||||
|
str10 = strrep(strchar(120,21,77,4,5,0,7,36,44,100), floor(len/10))
|
||||||
|
str = str .. str10
|
||||||
|
pass(len .. " byte(s) line")
|
||||||
|
remote "str = data:receive()"
|
||||||
|
err = data:send(str, "\n")
|
||||||
|
if err then fail(err) end
|
||||||
|
remote "data:send(str, '\\n')"
|
||||||
|
back, err = data:receive()
|
||||||
|
if err then fail(err) end
|
||||||
|
if back == str then pass("lines match")
|
||||||
|
else fail("lines don't match") end
|
||||||
|
end
|
||||||
|
|
||||||
|
test_rawline(1)
|
||||||
|
test_rawline(17)
|
||||||
|
test_rawline(200)
|
||||||
|
test_rawline(4091)
|
||||||
|
test_rawline(80199)
|
||||||
|
test_rawline(800000)
|
||||||
|
test_rawline(80199)
|
||||||
|
test_rawline(4091)
|
||||||
|
test_rawline(200)
|
||||||
|
test_rawline(17)
|
||||||
|
test_rawline(1)
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
test("raw transfer")
|
||||||
|
reconnect()
|
||||||
|
|
||||||
|
function test_raw(len)
|
||||||
|
local half = floor(len/2)
|
||||||
|
local s1, s2, back, err
|
||||||
|
s1 = strrep("x", half)
|
||||||
|
s2 = strrep("y", len-half)
|
||||||
|
pass(len .. " byte(s) block")
|
||||||
|
remote (format("str = data:receive(%d)", len))
|
||||||
|
err = data:send(s1)
|
||||||
|
if err then fail(err) end
|
||||||
|
err = data:send(s2)
|
||||||
|
if err then fail(err) end
|
||||||
|
remote "data:send(str)"
|
||||||
|
back, err = data:receive(len)
|
||||||
|
if err then fail(err) end
|
||||||
|
if back == s1..s2 then pass("blocks match")
|
||||||
|
else fail("blocks don't match") end
|
||||||
|
end
|
||||||
|
|
||||||
|
test_raw(1)
|
||||||
|
test_raw(17)
|
||||||
|
test_raw(200)
|
||||||
|
test_raw(4091)
|
||||||
|
test_raw(80199)
|
||||||
|
test_raw(800000)
|
||||||
|
test_raw(80199)
|
||||||
|
test_raw(4091)
|
||||||
|
test_raw(200)
|
||||||
|
test_raw(17)
|
||||||
|
test_raw(1)
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
test("non-blocking transfer")
|
||||||
|
reconnect()
|
||||||
|
|
||||||
|
-- the value is not important, we only want
|
||||||
|
-- to test non-blockin I/O anyways
|
||||||
|
data:timeout(200)
|
||||||
|
test_raw(1)
|
||||||
|
test_raw(17)
|
||||||
|
test_raw(200)
|
||||||
|
test_raw(4091)
|
||||||
|
test_raw(80199)
|
||||||
|
test_raw(800000)
|
||||||
|
test_raw(80199)
|
||||||
|
test_raw(4091)
|
||||||
|
test_raw(200)
|
||||||
|
test_raw(17)
|
||||||
|
test_raw(1)
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
test("mixed patterns")
|
||||||
|
reconnect()
|
||||||
|
|
||||||
|
function test_mixed(len)
|
||||||
|
local inter = floor(len/3)
|
||||||
|
local p1 = "unix " .. strrep("x", inter) .. "line\n"
|
||||||
|
local p2 = "dos " .. strrep("y", inter) .. "line\r\n"
|
||||||
|
local p3 = "raw " .. strrep("z", inter) .. "bytes"
|
||||||
|
local bp1, bp2, bp3
|
||||||
|
pass(len .. " byte(s) patterns")
|
||||||
|
remote (format("str = data:receive(%d)", strlen(p1)+strlen(p2)+strlen(p3)))
|
||||||
err = data:send(p1, p2, p3)
|
err = data:send(p1, p2, p3)
|
||||||
if err then fail(err) end
|
if err then fail(err) end
|
||||||
|
remote "data:send(str)"
|
||||||
bp1, bp2, bp3, err = data:receive("*lu", "*l", strlen(p3))
|
bp1, bp2, bp3, err = data:receive("*lu", "*l", strlen(p3))
|
||||||
if err then fail(err) end
|
if err then fail(err) end
|
||||||
if bp1.."\n" == p1 and bp2.."\r\n" == p2 and bp3 == p3 then
|
if bp1.."\n" == p1 and bp2.."\r\n" == p2 and bp3 == p3 then
|
||||||
@ -114,354 +329,156 @@ function test_multiple()
|
|||||||
else fail("patterns don't match") end
|
else fail("patterns don't match") end
|
||||||
end
|
end
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
test_mixed(1)
|
||||||
-- Tests closed connection detection
|
test_mixed(17)
|
||||||
-----------------------------------------------------------------------------
|
test_mixed(200)
|
||||||
|
test_mixed(4091)
|
||||||
|
test_mixed(80199)
|
||||||
|
test_mixed(800000)
|
||||||
|
test_mixed(80199)
|
||||||
|
test_mixed(4091)
|
||||||
|
test_mixed(200)
|
||||||
|
test_mixed(17)
|
||||||
|
test_mixed(1)
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
test("closed connection detection")
|
||||||
|
|
||||||
function test_closed()
|
function test_closed()
|
||||||
local str = "This is our little test line"
|
local back, err
|
||||||
local len = strlen(str)
|
local str = 'little string'
|
||||||
local back, err, total
|
|
||||||
reconnect()
|
reconnect()
|
||||||
print("testing close while reading line")
|
pass("trying read detection")
|
||||||
send_command(ECHO_BLOCK, len)
|
remote (format ([[
|
||||||
data:send(str)
|
data:send('%s')
|
||||||
send_command(CLOSE)
|
|
||||||
-- try to get a line
|
|
||||||
back, err = data:receive()
|
|
||||||
if not err then fail("shold have gotten 'closed'.")
|
|
||||||
elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.")
|
|
||||||
elseif str ~= back then fail("didn't receive what i should 'closed'.")
|
|
||||||
else pass("rightfull 'closed' received") end
|
|
||||||
reconnect()
|
|
||||||
print("testing close while reading block")
|
|
||||||
send_command(ECHO_BLOCK, len)
|
|
||||||
data:send(str)
|
|
||||||
send_command(CLOSE)
|
|
||||||
-- try to get a line
|
|
||||||
back, err = data:receive(2*len)
|
|
||||||
if not err then fail("shold have gotten 'closed'.")
|
|
||||||
elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.")
|
|
||||||
elseif str ~= back then fail("didn't receive what I should.")
|
|
||||||
else pass("rightfull 'closed' received") end
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Tests binary line transmission
|
|
||||||
-- Input
|
|
||||||
-- len: length of line to be tested
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
function test_rawline(len)
|
|
||||||
local str, str10, back, err
|
|
||||||
reconnect()
|
|
||||||
send_command(ECHO_LINE)
|
|
||||||
str = strrep(strchar(47), mod(len, 10))
|
|
||||||
str10 = strrep(strchar(120,21,77,4,5,0,7,36,44,100), floor(len/10))
|
|
||||||
str = str .. str10
|
|
||||||
write("testing ", len, " byte(s) line\n")
|
|
||||||
err = data:send(str, "\n")
|
|
||||||
if err then fail(err) end
|
|
||||||
back, err = data:receive()
|
|
||||||
if err then fail(err) end
|
|
||||||
if back == str then pass("lines match")
|
|
||||||
else fail("lines don't match") end
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Tests block transmission
|
|
||||||
-- Input
|
|
||||||
-- len: length of block to be tested
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
function test_block(len)
|
|
||||||
local half = floor(len/2)
|
|
||||||
local s1, s2, back, err
|
|
||||||
reconnect()
|
|
||||||
send_command(ECHO_BLOCK, len)
|
|
||||||
write("testing ", len, " byte(s) block\n")
|
|
||||||
s1 = strrep("x", half)
|
|
||||||
err = data:send(s1)
|
|
||||||
if err then fail(err) end
|
|
||||||
s2 = strrep("y", len-half)
|
|
||||||
err = data:send(s2)
|
|
||||||
if err then fail(err) end
|
|
||||||
back, err = data:receive(len)
|
|
||||||
if err then fail(err) end
|
|
||||||
if back == s1..s2 then pass("blocks match")
|
|
||||||
else fail("blocks don't match") end
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Tests if return-timeout was respected
|
|
||||||
-- delta: time elapsed during transfer
|
|
||||||
-- t: timeout value
|
|
||||||
-- s: time server slept
|
|
||||||
-- err: error code returned by I/O operation
|
|
||||||
-- o: operation being executed
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
function blockedtimed_out(t, s, err, o)
|
|
||||||
if err == "timeout" then
|
|
||||||
if s >= t then
|
|
||||||
pass("got rightfull forced timeout")
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
pass("got natural cause timeout")
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
elseif s > t then
|
|
||||||
if o == "send" then
|
|
||||||
pass("must have been buffered (may be wrong)")
|
|
||||||
else
|
|
||||||
fail("should have gotten timeout")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Tests blocked-timeout conformance
|
|
||||||
-- Input
|
|
||||||
-- len: length of block to be tested
|
|
||||||
-- t: timeout value
|
|
||||||
-- s: server sleep between transfers
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
function test_blockedtimeout(len, t, s)
|
|
||||||
local str, err, back, total
|
|
||||||
reconnect()
|
|
||||||
send_command(RECEIVE_BLOCK, len)
|
|
||||||
send_command(SLEEP, s)
|
|
||||||
send_command(RECEIVE_BLOCK, len)
|
|
||||||
write("testing ", len, " bytes, ", t,
|
|
||||||
"s block timeout, ", s, "s sleep\n")
|
|
||||||
data:timeout(t)
|
|
||||||
str = strrep("a", 2*len)
|
|
||||||
err, total = data:send(str)
|
|
||||||
if blockedtimed_out(t, s, err, "send") then return end
|
|
||||||
if err then fail(err) end
|
|
||||||
send_command(SEND_BLOCK)
|
|
||||||
send_command(SLEEP, s)
|
|
||||||
send_command(SEND_BLOCK)
|
|
||||||
back, err = data:receive(2*len)
|
|
||||||
if blockedtimed_out(t, s, err, "receive") then return end
|
|
||||||
if err then fail(err) end
|
|
||||||
if back == str then pass("blocks match")
|
|
||||||
else fail("blocks don't match") end
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Tests if return-timeout was respected
|
|
||||||
-- delta: time elapsed during transfer
|
|
||||||
-- t: timeout value
|
|
||||||
-- err: error code returned by I/O operation
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
function returntimed_out(delta, t, err)
|
|
||||||
if err == "timeout" then
|
|
||||||
if delta >= t then
|
|
||||||
pass("got rightfull timeout")
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
fail("shouldn't have gotten timeout")
|
|
||||||
end
|
|
||||||
elseif delta > t then
|
|
||||||
pass(format("but took %fs longer than should have", delta - t))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Tests return-timeout conformance
|
|
||||||
-- Input
|
|
||||||
-- len: length of block to be tested
|
|
||||||
-- t: timeout value
|
|
||||||
-- s: server sleep between transfers
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
function test_returntimeout(len, t, s)
|
|
||||||
local str, err, back, delta, total
|
|
||||||
reconnect()
|
|
||||||
send_command(RECEIVE_BLOCK, len)
|
|
||||||
send_command(SLEEP, s)
|
|
||||||
send_command(RECEIVE_BLOCK, len)
|
|
||||||
write("testing ", len, " bytes, ", t,
|
|
||||||
"s return timeout, ", s, "s sleep\n")
|
|
||||||
data:timeout(t, "return")
|
|
||||||
str = strrep("a", 2*len)
|
|
||||||
err, total, delta = data:send(str)
|
|
||||||
print("sent in " .. delta .. "s")
|
|
||||||
if returntimed_out(delta, t, err) then return end
|
|
||||||
if err then fail("unexpected error: " .. err) end
|
|
||||||
send_command(SEND_BLOCK)
|
|
||||||
send_command(SLEEP, s)
|
|
||||||
send_command(SEND_BLOCK)
|
|
||||||
back, err, delta = data:receive(2*len)
|
|
||||||
print("received in " .. delta .. "s")
|
|
||||||
if returntimed_out(delta, t, err) then return end
|
|
||||||
if err then fail("unexpected error: " .. err) end
|
|
||||||
if back == str then pass("blocks match")
|
|
||||||
else fail("blocks don't match") end
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Tests read patterns
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
function test_word()
|
|
||||||
local b1 = " \t one two three \n this_is_a_very"
|
|
||||||
local b2 = "_big_word "
|
|
||||||
send_command(ECHO_BLOCK, strlen(b1)+strlen(b2))
|
|
||||||
err = data:send(b1, b2)
|
|
||||||
local a1, a2, a3, a4
|
|
||||||
a1, a2, a3, a4, err = data:receive("*w", "*w", "*w", "*w")
|
|
||||||
if err then fail(err) end
|
|
||||||
_, err = data:receive(1) -- get last space
|
|
||||||
if err then fail(err) end
|
|
||||||
if a1 ~= "one" or a2 ~= "two" or a3 ~= "three" or
|
|
||||||
a4 ~= "this_is_a_very_big_word" then fail("'*w' failed") end
|
|
||||||
pass("'*w' is ok")
|
|
||||||
end
|
|
||||||
|
|
||||||
function test_patterns()
|
|
||||||
local dos_line1 = "this the first dos line"
|
|
||||||
local dos_line2 = "this is another dos line"
|
|
||||||
local unix_line1 = "this the first unix line"
|
|
||||||
local unix_line2 = "this is another unix line"
|
|
||||||
local block = dos_line1 .. "\r\n" .. dos_line2 .. "\r\n"
|
|
||||||
reconnect()
|
|
||||||
block = block .. unix_line1 .. "\n" .. unix_line2 .. "\n"
|
|
||||||
block = block .. block
|
|
||||||
send_command(ECHO_BLOCK, strlen(block))
|
|
||||||
err = data:send(block)
|
|
||||||
if err then fail(err) end
|
|
||||||
local back = data:receive("*l")
|
|
||||||
if back ~= dos_line1 then fail("'*l' failed") end
|
|
||||||
back = data:receive("*l")
|
|
||||||
if back ~= dos_line2 then fail("'*l' failed") end
|
|
||||||
back = data:receive("*lu")
|
|
||||||
if back ~= unix_line1 then fail("'*lu' failed") end
|
|
||||||
back = data:receive("*lu")
|
|
||||||
if back ~= unix_line2 then fail("'*lu' failed") end
|
|
||||||
back = data:receive()
|
|
||||||
if back ~= dos_line1 then fail("default failed") end
|
|
||||||
back = data:receive()
|
|
||||||
if back ~= dos_line2 then fail("default failed") end
|
|
||||||
back = data:receive("*lu")
|
|
||||||
if back ~= unix_line1 then fail("'*lu' failed") end
|
|
||||||
back = data:receive("*lu")
|
|
||||||
if back ~= unix_line2 then fail("'*lu' failed") end
|
|
||||||
pass("line patterns are ok")
|
|
||||||
send_command(ECHO_BLOCK, strlen(block))
|
|
||||||
err = data:send(block)
|
|
||||||
if err then fail(err) end
|
|
||||||
back = data:receive(strlen(block))
|
|
||||||
if back ~= block then fail("number failed") end
|
|
||||||
pass("number is ok")
|
|
||||||
test_word()
|
|
||||||
send_command(ECHO_BLOCK, strlen(block))
|
|
||||||
send_command(SLEEP, 1)
|
|
||||||
send_command(CLOSE)
|
|
||||||
err = data:send(block)
|
|
||||||
if err then fail(err) end
|
|
||||||
back = data:receive("*a")
|
|
||||||
if back ~= block then fail("'*a' failed") end
|
|
||||||
pass("'*a' is ok")
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Test for select bugs
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
function test_select()
|
|
||||||
local r, s, e = select(nil, nil, 0.1)
|
|
||||||
assert(type(r) == "table" and type(s) == "table" and e == "timeout")
|
|
||||||
pass("both nil")
|
|
||||||
data:close()
|
data:close()
|
||||||
r, s, e = select({ data }, { data }, 0.1)
|
data = nil
|
||||||
assert(type(r) == "table" and type(s) == "table" and e == "timeout")
|
]], str))
|
||||||
pass("closed sockets")
|
-- try to get a line
|
||||||
e = call(select, {"wrong", 1, 0.1}, "x", nil)
|
back, err = data:receive()
|
||||||
assert(e == nil)
|
if not err then fail("shold have gotten 'closed'.")
|
||||||
pass("invalid input")
|
elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.")
|
||||||
|
elseif str ~= back then fail("didn't receive partial result.")
|
||||||
|
else pass("graceful 'closed' received") end
|
||||||
|
reconnect()
|
||||||
|
pass("trying write detection")
|
||||||
|
remote [[
|
||||||
|
data:close()
|
||||||
|
data = nil
|
||||||
|
]]
|
||||||
|
err, total = data:send(strrep("ugauga", 100000))
|
||||||
|
if not err then
|
||||||
|
pass("failed: output buffer is at least %d bytes long!", total)
|
||||||
|
elseif err ~= "closed" then
|
||||||
|
fail("got '"..err.."' instead of 'closed'.")
|
||||||
|
else
|
||||||
|
pass("graceful 'closed' received after %d bytes were sent", total)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Execute all tests
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
start = _time()
|
|
||||||
|
|
||||||
new_test("control connection test")
|
|
||||||
test_command(EXIT)
|
|
||||||
test_command(CONNECT)
|
|
||||||
test_command(CLOSE)
|
|
||||||
test_command(ECHO_BLOCK, 12234)
|
|
||||||
test_command(SLEEP, 1111)
|
|
||||||
test_command(ECHO_LINE)
|
|
||||||
|
|
||||||
new_test("testing for select bugs")
|
|
||||||
test_select()
|
|
||||||
|
|
||||||
new_test("connection close test")
|
|
||||||
test_closed()
|
test_closed()
|
||||||
|
|
||||||
new_test("read pattern test")
|
------------------------------------------------------------------------
|
||||||
test_patterns()
|
test("return timeout on receive")
|
||||||
|
function test_blockingtimeoutreceive(len, tm, sl)
|
||||||
|
local str, err, total
|
||||||
|
reconnect()
|
||||||
|
pass("%d bytes, %ds return timeout, %ds pause", len, tm, sl)
|
||||||
|
remote (format ([[
|
||||||
|
data:timeout(%d)
|
||||||
|
str = strrep('a', %d)
|
||||||
|
data:send(str)
|
||||||
|
print('server: sleeping for %ds')
|
||||||
|
_sleep(%d)
|
||||||
|
print('server: woke up')
|
||||||
|
data:send(str)
|
||||||
|
]], 2*tm, len, sl, sl))
|
||||||
|
data:timeout(tm, "return")
|
||||||
|
str, err, elapsed = data:receive(2*len)
|
||||||
|
check_timeout(tm, sl, elapsed, err, "receive", "return",
|
||||||
|
strlen(str) == 2*len)
|
||||||
|
end
|
||||||
|
test_blockingtimeoutreceive(800091, 1, 3)
|
||||||
|
test_blockingtimeoutreceive(800091, 2, 3)
|
||||||
|
test_blockingtimeoutreceive(800091, 3, 2)
|
||||||
|
test_blockingtimeoutreceive(800091, 3, 1)
|
||||||
|
|
||||||
new_test("multiple pattern test")
|
------------------------------------------------------------------------
|
||||||
test_multiple()
|
test("return timeout on send")
|
||||||
|
function test_returntimeoutsend(len, tm, sl)
|
||||||
|
local str, err, total
|
||||||
|
reconnect()
|
||||||
|
pass("%d bytes, %ds return timeout, %ds pause", len, tm, sl)
|
||||||
|
remote (format ([[
|
||||||
|
data:timeout(%d)
|
||||||
|
str = data:receive(%d)
|
||||||
|
print('server: sleeping for %ds')
|
||||||
|
_sleep(%d)
|
||||||
|
print('server: woke up')
|
||||||
|
str = data:receive(%d)
|
||||||
|
]], 2*tm, len, sl, sl, len))
|
||||||
|
data:timeout(tm, "return")
|
||||||
|
str = strrep("a", 2*len)
|
||||||
|
err, total, elapsed = data:send(str)
|
||||||
|
check_timeout(tm, sl, elapsed, err, "send", "return",
|
||||||
|
total == 2*len)
|
||||||
|
end
|
||||||
|
test_returntimeoutsend(800091, 1, 3)
|
||||||
|
test_returntimeoutsend(800091, 2, 3)
|
||||||
|
test_returntimeoutsend(800091, 3, 2)
|
||||||
|
test_returntimeoutsend(800091, 3, 1)
|
||||||
|
|
||||||
new_test("character string test")
|
|
||||||
test_asciiline(1)
|
|
||||||
test_asciiline(17)
|
|
||||||
test_asciiline(200)
|
|
||||||
test_asciiline(3000)
|
|
||||||
test_asciiline(80000)
|
|
||||||
test_asciiline(800000)
|
|
||||||
|
|
||||||
new_test("binary string test")
|
------------------------------------------------------------------------
|
||||||
test_rawline(1)
|
test("blocking timeout on receive")
|
||||||
test_rawline(17)
|
function test_blockingtimeoutreceive(len, tm, sl)
|
||||||
test_rawline(200)
|
local str, err, total
|
||||||
test_rawline(3000)
|
reconnect()
|
||||||
test_rawline(8000)
|
pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl)
|
||||||
test_rawline(80000)
|
remote (format ([[
|
||||||
test_rawline(800000)
|
data:timeout(%d)
|
||||||
|
str = strrep('a', %d)
|
||||||
|
data:send(str)
|
||||||
|
print('server: sleeping for %ds')
|
||||||
|
_sleep(%d)
|
||||||
|
print('server: woke up')
|
||||||
|
data:send(str)
|
||||||
|
]], 2*tm, len, sl, sl))
|
||||||
|
data:timeout(tm)
|
||||||
|
str, err, elapsed = data:receive(2*len)
|
||||||
|
check_timeout(tm, sl, elapsed, err, "receive", "blocking",
|
||||||
|
strlen(str) == 2*len)
|
||||||
|
end
|
||||||
|
test_blockingtimeoutreceive(800091, 1, 3)
|
||||||
|
test_blockingtimeoutreceive(800091, 2, 3)
|
||||||
|
test_blockingtimeoutreceive(800091, 3, 2)
|
||||||
|
test_blockingtimeoutreceive(800091, 3, 1)
|
||||||
|
|
||||||
new_test("blocking transfer test")
|
|
||||||
test_block(1)
|
|
||||||
test_block(17)
|
|
||||||
test_block(200)
|
|
||||||
test_block(3000)
|
|
||||||
test_block(80000)
|
|
||||||
test_block(800000)
|
|
||||||
|
|
||||||
new_test("non-blocking transfer test")
|
------------------------------------------------------------------------
|
||||||
-- the value is not important, we only want
|
test("blocking timeout on send")
|
||||||
-- to test non-blockin I/O anyways
|
function test_blockingtimeoutsend(len, tm, sl)
|
||||||
data:timeout(200)
|
local str, err, total
|
||||||
test_block(1)
|
reconnect()
|
||||||
test_block(17)
|
pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl)
|
||||||
test_block(200)
|
remote (format ([[
|
||||||
test_block(3000)
|
data:timeout(%d)
|
||||||
test_block(80000)
|
str = data:receive(%d)
|
||||||
test_block(800000)
|
print('server: sleeping for %ds')
|
||||||
|
_sleep(%d)
|
||||||
|
print('server: woke up')
|
||||||
|
str = data:receive(%d)
|
||||||
|
]], 2*tm, len, sl, sl, len))
|
||||||
|
data:timeout(tm)
|
||||||
|
str = strrep("a", 2*len)
|
||||||
|
err, total, elapsed = data:send(str)
|
||||||
|
check_timeout(tm, sl, elapsed, err, "send", "blocking",
|
||||||
|
total == 2*len)
|
||||||
|
end
|
||||||
|
test_blockingtimeoutsend(800091, 1, 3)
|
||||||
|
test_blockingtimeoutsend(800091, 2, 3)
|
||||||
|
test_blockingtimeoutsend(800091, 3, 2)
|
||||||
|
test_blockingtimeoutsend(800091, 3, 1)
|
||||||
|
|
||||||
new_test("blocked timeout test")
|
------------------------------------------------------------------------
|
||||||
test_blockedtimeout(80, 1, 2)
|
test(format("done in %.2fs", _time() - start))
|
||||||
test_blockedtimeout(80, 2, 2)
|
|
||||||
test_blockedtimeout(80, 3, 2)
|
|
||||||
test_blockedtimeout(800, 1, 0)
|
|
||||||
test_blockedtimeout(8000, 2, 3)
|
|
||||||
test_blockedtimeout(80000, 2, 1)
|
|
||||||
test_blockedtimeout(800000, 0.01, 0)
|
|
||||||
|
|
||||||
new_test("return timeout test")
|
|
||||||
test_returntimeout(80, 2, 1)
|
|
||||||
test_returntimeout(80, 1, 2)
|
|
||||||
test_returntimeout(8000, 1, 2)
|
|
||||||
test_returntimeout(80000, 2, 1)
|
|
||||||
test_returntimeout(800000, 0.1, 0)
|
|
||||||
test_returntimeout(800000, 2, 1)
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Close connection and exit server. We are done.
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
new_test("the library has passed all tests")
|
|
||||||
print("client: closing connection with server")
|
|
||||||
send_command(CLOSE)
|
|
||||||
send_command(EXIT)
|
|
||||||
control:close()
|
|
||||||
print(format("time elapsed: %6.2fs", _time() - start))
|
|
||||||
print("client: exiting...")
|
|
||||||
exit()
|
|
||||||
|
@ -1,96 +1,24 @@
|
|||||||
-----------------------------------------------------------------------------
|
HOST = HOST or "localhost"
|
||||||
-- LuaSocket automated test module
|
PORT = PORT or "8080"
|
||||||
-- testsrvr.lua
|
|
||||||
-- This is the server module. It's completely controled by the client module
|
|
||||||
-- by the use of a control connection.
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
server, error = bind(HOST, PORT)
|
||||||
-- Read command definitions
|
if not server then print("server: " .. tostring(error)) exit() end
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
HOST = HOST or "*"
|
|
||||||
assert(dofile("testcmd.lua"))
|
|
||||||
test_debug_mode()
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Start control connection
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
server, err = bind(HOST, PORT)
|
|
||||||
if not server then
|
|
||||||
fail(err)
|
|
||||||
exit(1)
|
|
||||||
end
|
|
||||||
print("server: waiting for control connection...")
|
|
||||||
control = server:accept()
|
|
||||||
print("server: control connection stablished!")
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Executes a command, detecting any possible failures
|
|
||||||
-- Input
|
|
||||||
-- cmd: command to be executed
|
|
||||||
-- par: command parameters, if needed
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
function execute_command(cmd, par)
|
|
||||||
if cmd == CONNECT then
|
|
||||||
print("server: waiting for data connection...")
|
|
||||||
data = server:accept()
|
|
||||||
data:timeout(10)
|
|
||||||
if not data then
|
|
||||||
fail("server: unable to start data connection!")
|
|
||||||
else
|
|
||||||
print("server: data connection stablished!")
|
|
||||||
end
|
|
||||||
elseif cmd == CLOSE then
|
|
||||||
print("server: closing connection with client...")
|
|
||||||
if data then
|
|
||||||
data:close()
|
|
||||||
data = nil
|
|
||||||
end
|
|
||||||
elseif cmd == ECHO_LINE then
|
|
||||||
str, err = data:receive()
|
|
||||||
if err then fail("server: " .. err) end
|
|
||||||
err = data:send(str, "\n")
|
|
||||||
if err then fail("server: " .. err) end
|
|
||||||
elseif cmd == ECHO_BLOCK then
|
|
||||||
str, err = data:receive(par)
|
|
||||||
print(format("server: received %d bytes", strlen(str)))
|
|
||||||
if err then fail("server: " .. err) end
|
|
||||||
print(format("server: sending %d bytes", strlen(str)))
|
|
||||||
err = data:send(str)
|
|
||||||
if err then fail("server: " .. err) end
|
|
||||||
elseif cmd == RECEIVE_BLOCK then
|
|
||||||
str, err = data:receive(par)
|
|
||||||
print(format("server: received %d bytes", strlen(str)))
|
|
||||||
elseif cmd == SEND_BLOCK then
|
|
||||||
print(format("server: sending %d bytes", strlen(str)))
|
|
||||||
err = data:send(str)
|
|
||||||
elseif cmd == ECHO_TIMEOUT then
|
|
||||||
str, err = data:receive(par)
|
|
||||||
if err then fail("server: " .. err) end
|
|
||||||
err = data:send(str)
|
|
||||||
if err then fail("server: " .. err) end
|
|
||||||
elseif cmd == COMMAND then
|
|
||||||
cmd, par = get_command()
|
|
||||||
send_command(cmd, par)
|
|
||||||
elseif cmd == EXIT then
|
|
||||||
print("server: exiting...")
|
|
||||||
exit(0)
|
|
||||||
elseif cmd == SYNC then
|
|
||||||
print("server: synchronizing...")
|
|
||||||
send_command(SYNC)
|
|
||||||
elseif cmd == SLEEP then
|
|
||||||
print("server: sleeping for " .. par .. " seconds...")
|
|
||||||
_sleep(par)
|
|
||||||
print("server: woke up!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
-- Loop forever, accepting and executing commands
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
while 1 do
|
while 1 do
|
||||||
cmd, par = get_command()
|
print("server: waiting for client connection...");
|
||||||
if not cmd then fail("server: " .. par) end
|
control = server:accept()
|
||||||
print_command(cmd, par)
|
while 1 do
|
||||||
execute_command(cmd, par)
|
command, error = control:receive()
|
||||||
|
if error then
|
||||||
|
control:close()
|
||||||
|
print("server: closing connection...")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
error = control:send("\n")
|
||||||
|
if error then
|
||||||
|
control:close()
|
||||||
|
print("server: closing connection...")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
dostring(command)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user