From 7b991956498fece58bc9beacfd64fe9eb73520a5 Mon Sep 17 00:00:00 2001 From: Diego Nehab Date: Mon, 8 Jul 2002 21:56:01 +0000 Subject: [PATCH] Testes reformulados. --- test/testclnt.lua | 871 +++++++++++++++++++++++----------------------- test/testsrvr.lua | 114 ++---- 2 files changed, 465 insertions(+), 520 deletions(-) diff --git a/test/testclnt.lua b/test/testclnt.lua index 4ee2c48..73c10de 100644 --- a/test/testclnt.lua +++ b/test/testclnt.lua @@ -1,467 +1,484 @@ ------------------------------------------------------------------------------ --- 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() +PORT = PORT or "8080" ------------------------------------------------------------------------------ --- 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 +function pass(...) + local s = call(format, arg) + write(s, "\n") end ------------------------------------------------------------------------------ --- Make sure server is ready for data transmission ------------------------------------------------------------------------------ -function sync() - send_command(SYNC) - get_command() +function fail(...) + local s = call(format, arg) + write("ERROR: ", s, "!\n") + exit() 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() +function warn(...) + local s = call(format, arg) + write("WARNING: ", s, "\n") 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 +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 ------------------------------------------------------------------------------ --- 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 +function test(test) + write("----------------------------------------------\n", + "testing: ", test, "\n", + "----------------------------------------------\n") 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 +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 + 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 ------------------------------------------------------------------------------ --- 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 +write("----------------------------------------------\n", +"LuaSocket Test Procedures\n", +"----------------------------------------------\n") ------------------------------------------------------------------------------ --- 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 +if not _time or not _sleep then fail("not compiled with _DEBUG") 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() - 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) +function tcpreconnect() + write("attempting data connection... ") + if data then data:close() end + 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 +reconnect = tcpreconnect -new_test("testing for select bugs") -test_select() +pass("attempting control connection...") +control, error = connect(HOST, PORT) +if error then fail(error) +else pass("connected!") end -new_test("connection close test") -test_closed() +------------------------------------------------------------------------ +test("bugs") -new_test("read pattern test") -test_patterns() +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 + pass("ok") + data = connect(HOST, PORT) + else fail("should not have connected!") end +end -new_test("multiple pattern test") -test_multiple() +empty_connect() + +------------------------------------------------------------------------ +test("method registration") + +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() + +function test_asciiline(len) + local str, str10, back, err + str = strrep("x", mod(len, 10)) + str10 = strrep("aZb.c#dAe?", 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 -new_test("character string test") test_asciiline(1) test_asciiline(17) test_asciiline(200) -test_asciiline(3000) -test_asciiline(80000) +test_asciiline(4091) +test_asciiline(80199) test_asciiline(800000) -new_test("binary string test") +------------------------------------------------------------------------ +test("binary line") +reconnect() + +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(3000) -test_rawline(8000) -test_rawline(80000) +test_rawline(4091) +test_rawline(80199) test_rawline(800000) +test_rawline(80199) +test_rawline(4091) +test_rawline(200) +test_rawline(17) +test_rawline(1) -new_test("blocking transfer test") -test_block(1) -test_block(17) -test_block(200) -test_block(3000) -test_block(80000) -test_block(800000) +------------------------------------------------------------------------ +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() -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) +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) -new_test("blocked timeout test") -test_blockedtimeout(80, 1, 2) -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) +------------------------------------------------------------------------ +test("mixed patterns") +reconnect() -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) +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) + if err then fail(err) end +remote "data:send(str)" + 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 ------------------------------------------------------------------------------ --- 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() +test_mixed(1) +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() + local back, err + local str = 'little string' + reconnect() + pass("trying read detection") + remote (format ([[ + data:send('%s') + data:close() + data = nil + ]], str)) + -- 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 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 + +test_closed() + +------------------------------------------------------------------------ +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) + +------------------------------------------------------------------------ +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) + + +------------------------------------------------------------------------ +test("blocking timeout on receive") +function test_blockingtimeoutreceive(len, tm, sl) + local str, err, total + reconnect() + pass("%d bytes, %ds blocking 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) + 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) + + +------------------------------------------------------------------------ +test("blocking timeout on send") +function test_blockingtimeoutsend(len, tm, sl) + local str, err, total + reconnect() + pass("%d bytes, %ds blocking 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) + 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) + +------------------------------------------------------------------------ +test(format("done in %.2fs", _time() - start)) diff --git a/test/testsrvr.lua b/test/testsrvr.lua index 7b89987..227e341 100644 --- a/test/testsrvr.lua +++ b/test/testsrvr.lua @@ -1,96 +1,24 @@ ------------------------------------------------------------------------------ --- LuaSocket automated test module --- testsrvr.lua --- This is the server module. It's completely controled by the client module --- by the use of a control connection. ------------------------------------------------------------------------------ +HOST = HOST or "localhost" +PORT = PORT or "8080" ------------------------------------------------------------------------------ --- Read command definitions ------------------------------------------------------------------------------ -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 ------------------------------------------------------------------------------ +server, error = bind(HOST, PORT) +if not server then print("server: " .. tostring(error)) exit() end while 1 do - cmd, par = get_command() - if not cmd then fail("server: " .. par) end - print_command(cmd, par) - execute_command(cmd, par) + print("server: waiting for client connection..."); + control = server:accept() + while 1 do + 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