luasocket/test/testclnt.lua

468 lines
14 KiB
Lua
Raw Normal View History

-----------------------------------------------------------------------------
-- 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"
assert(dofile("testcmd.lua"))
test_debug_mode()
-----------------------------------------------------------------------------
-- Start control connection
-----------------------------------------------------------------------------
new_test("initializing...")
while control == nil do
print("client: trying control connection...")
control, err = connect(HOST, PORT)
if control then
print("client: control connection stablished!")
else
_sleep(2)
end
end
-----------------------------------------------------------------------------
-- Make sure server is ready for data transmission
-----------------------------------------------------------------------------
function sync()
send_command(SYNC)
get_command()
end
-----------------------------------------------------------------------------
-- Close and reopen data connection, to get rid of any unread blocks
-----------------------------------------------------------------------------
function reconnect()
if data then
data:close()
send_command(CLOSE)
data = nil
end
while data == nil do
send_command(CONNECT)
data = connect(HOST, PORT)
if not data then
print("client: waiting for data connection.")
_sleep(1)
end
end
sync()
end
-----------------------------------------------------------------------------
-- Tests the command connection
-----------------------------------------------------------------------------
function test_command(cmd, par)
local cmd_back, par_back
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)
local str, str10, back, err
reconnect()
send_command(ECHO_LINE)
str = strrep("x", mod(len, 10))
str10 = strrep("aZb.c#dAe?", 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 multiple pattern transmission
-- Input
-- len: length of line to be tested
-----------------------------------------------------------------------------
function test_multiple()
local p1 = "unix line\n"
local p2 = "dos line\r\n"
local p3 = "raw bytes"
local bp1, bp2, bp3
reconnect()
send_command(ECHO_BLOCK, strlen(p1)+strlen(p2)+strlen(p3))
err = data:send(p1, p2, p3)
if err then fail(err) end
bp1, bp2, bp3, err = data:receive("*lu", "*l", strlen(p3))
if err then fail(err) end
if bp1.."\n" == p1 and bp2.."\r\n" == p2 and bp3 == p3 then
pass("patterns match")
else fail("patterns don't match") end
end
-----------------------------------------------------------------------------
-- Tests closed connection detection
-----------------------------------------------------------------------------
function test_closed()
local str = "This is our little test line"
local len = strlen(str)
local back, err, total
reconnect()
print("testing close while reading line")
send_command(ECHO_BLOCK, len)
data:send(str)
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
2001-01-28 03:18:24 +01:00
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
2001-01-28 03:18:24 +01:00
if delta >= t then
pass("got rightfull timeout")
return 1
else
fail("shouldn't have gotten timeout")
end
2001-01-28 03:18:24 +01:00
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()
r, s, e = select({ data }, { data }, 0.1)
assert(type(r) == "table" and type(s) == "table" and e == "timeout")
pass("closed sockets")
e = call(select, {"wrong", 1, 0.1}, "x", nil)
assert(e == nil)
pass("invalid input")
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()
new_test("read pattern test")
test_patterns()
new_test("multiple pattern test")
test_multiple()
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_rawline(17)
test_rawline(200)
test_rawline(3000)
test_rawline(8000)
test_rawline(80000)
test_rawline(800000)
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
-- to test non-blockin I/O anyways
data:timeout(200)
test_block(1)
test_block(17)
test_block(200)
test_block(3000)
test_block(80000)
test_block(800000)
new_test("blocked timeout test")
2001-01-28 03:18:24 +01:00
test_blockedtimeout(80, 1, 2)
test_blockedtimeout(80, 2, 2)
test_blockedtimeout(80, 3, 2)
test_blockedtimeout(800, 1, 0)
2001-01-28 03:18:24 +01:00
test_blockedtimeout(8000, 2, 3)
test_blockedtimeout(80000, 2, 1)
test_blockedtimeout(800000, 0.01, 0)
new_test("return timeout test")
2001-01-28 03:18:24 +01:00
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()