diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2002-07-08 21:56:01 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2002-07-08 21:56:01 +0000 |
| commit | 7b991956498fece58bc9beacfd64fe9eb73520a5 (patch) | |
| tree | e0666b9c422caefe230a6b4296d3fa9959f1017a | |
| parent | af181244d9670ec8f6ef83c3548060c35fa9bf0e (diff) | |
| download | luasocket-7b991956498fece58bc9beacfd64fe9eb73520a5.tar.gz luasocket-7b991956498fece58bc9beacfd64fe9eb73520a5.tar.bz2 luasocket-7b991956498fece58bc9beacfd64fe9eb73520a5.zip | |
Testes reformulados.
| -rw-r--r-- | test/testclnt.lua | 857 | ||||
| -rw-r--r-- | test/testsrvr.lua | 114 |
2 files changed, 458 insertions, 513 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 @@ | |||
| 1 | ----------------------------------------------------------------------------- | ||
| 2 | -- LuaSocket automated test module | ||
| 3 | -- testclnt.lua | ||
| 4 | -- This is the client module. It connects with the server module and executes | ||
| 5 | -- all tests. | ||
| 6 | ----------------------------------------------------------------------------- | ||
| 7 | |||
| 8 | ----------------------------------------------------------------------------- | ||
| 9 | -- Read command definitions | ||
| 10 | ----------------------------------------------------------------------------- | ||
| 11 | HOST = HOST or "localhost" | 1 | HOST = HOST or "localhost" |
| 12 | assert(dofile("testcmd.lua")) | 2 | PORT = PORT or "8080" |
| 13 | test_debug_mode() | ||
| 14 | |||
| 15 | ----------------------------------------------------------------------------- | ||
| 16 | -- Start control connection | ||
| 17 | ----------------------------------------------------------------------------- | ||
| 18 | new_test("initializing...") | ||
| 19 | while control == nil do | ||
| 20 | print("client: trying control connection...") | ||
| 21 | control, err = connect(HOST, PORT) | ||
| 22 | if control then | ||
| 23 | print("client: control connection stablished!") | ||
| 24 | else | ||
| 25 | _sleep(2) | ||
| 26 | end | ||
| 27 | end | ||
| 28 | 3 | ||
| 29 | ----------------------------------------------------------------------------- | 4 | function pass(...) |
| 30 | -- Make sure server is ready for data transmission | 5 | local s = call(format, arg) |
| 31 | ----------------------------------------------------------------------------- | 6 | write(s, "\n") |
| 32 | function sync() | ||
| 33 | send_command(SYNC) | ||
| 34 | get_command() | ||
| 35 | end | 7 | end |
| 36 | 8 | ||
| 37 | ----------------------------------------------------------------------------- | 9 | function fail(...) |
| 38 | -- Close and reopen data connection, to get rid of any unread blocks | 10 | local s = call(format, arg) |
| 39 | ----------------------------------------------------------------------------- | 11 | write("ERROR: ", s, "!\n") |
| 40 | function reconnect() | 12 | exit() |
| 41 | if data then | ||
| 42 | data:close() | ||
| 43 | send_command(CLOSE) | ||
| 44 | data = nil | ||
| 45 | end | ||
| 46 | while data == nil do | ||
| 47 | send_command(CONNECT) | ||
| 48 | data = connect(HOST, PORT) | ||
| 49 | if not data then | ||
| 50 | print("client: waiting for data connection.") | ||
| 51 | _sleep(1) | ||
| 52 | end | ||
| 53 | end | ||
| 54 | sync() | ||
| 55 | end | 13 | end |
| 56 | 14 | ||
| 57 | ----------------------------------------------------------------------------- | 15 | function warn(...) |
| 58 | -- Tests the command connection | 16 | local s = call(format, arg) |
| 59 | ----------------------------------------------------------------------------- | 17 | write("WARNING: ", s, "\n") |
| 60 | function test_command(cmd, par) | ||
| 61 | local cmd_back, par_back | ||
| 62 | reconnect() | ||
| 63 | send_command(COMMAND) | ||
| 64 | write("testing command ") | ||
| 65 | print_command(cmd, par) | ||
| 66 | send_command(cmd, par) | ||
| 67 | cmd_back, par_back = get_command() | ||
| 68 | if cmd_back ~= cmd or par_back ~= par then | ||
| 69 | fail(cmd) | ||
| 70 | else | ||
| 71 | pass() | ||
| 72 | end | ||
| 73 | end | 18 | end |
| 74 | 19 | ||
| 75 | ----------------------------------------------------------------------------- | 20 | function remote(...) |
| 76 | -- Tests ASCII line transmission | 21 | local s = call(format, arg) |
| 77 | -- Input | 22 | s = gsub(s, "\n", ";") |
| 78 | -- len: length of line to be tested | 23 | s = gsub(s, "%s+", " ") |
| 79 | ----------------------------------------------------------------------------- | 24 | s = gsub(s, "^%s*", "") |
| 80 | function test_asciiline(len) | 25 | control:send(s, "\n") |
| 81 | local str, str10, back, err | 26 | control:receive() |
| 82 | reconnect() | ||
| 83 | send_command(ECHO_LINE) | ||
| 84 | str = strrep("x", mod(len, 10)) | ||
| 85 | str10 = strrep("aZb.c#dAe?", floor(len/10)) | ||
| 86 | str = str .. str10 | ||
| 87 | write("testing ", len, " byte(s) line\n") | ||
| 88 | err = data:send(str, "\n") | ||
| 89 | if err then fail(err) end | ||
| 90 | back, err = data:receive() | ||
| 91 | if err then fail(err) end | ||
| 92 | if back == str then pass("lines match") | ||
| 93 | else fail("lines don't match") end | ||
| 94 | end | 27 | end |
| 95 | 28 | ||
| 96 | ----------------------------------------------------------------------------- | 29 | function test(test) |
| 97 | -- Tests multiple pattern transmission | 30 | write("----------------------------------------------\n", |
| 98 | -- Input | 31 | "testing: ", test, "\n", |
| 99 | -- len: length of line to be tested | 32 | "----------------------------------------------\n") |
| 100 | ----------------------------------------------------------------------------- | ||
| 101 | function test_multiple() | ||
| 102 | local p1 = "unix line\n" | ||
| 103 | local p2 = "dos line\r\n" | ||
| 104 | local p3 = "raw bytes" | ||
| 105 | local bp1, bp2, bp3 | ||
| 106 | reconnect() | ||
| 107 | send_command(ECHO_BLOCK, strlen(p1)+strlen(p2)+strlen(p3)) | ||
| 108 | err = data:send(p1, p2, p3) | ||
| 109 | if err then fail(err) end | ||
| 110 | bp1, bp2, bp3, err = data:receive("*lu", "*l", strlen(p3)) | ||
| 111 | if err then fail(err) end | ||
| 112 | if bp1.."\n" == p1 and bp2.."\r\n" == p2 and bp3 == p3 then | ||
| 113 | pass("patterns match") | ||
| 114 | else fail("patterns don't match") end | ||
| 115 | end | 33 | end |
| 116 | 34 | ||
| 117 | ----------------------------------------------------------------------------- | 35 | function check_timeout(tm, sl, elapsed, err, opp, mode, alldone) |
| 118 | -- Tests closed connection detection | 36 | if tm < sl then |
| 119 | ----------------------------------------------------------------------------- | 37 | if opp == "send" then |
| 120 | function test_closed() | 38 | if not err then warn("must be buffered") |
| 121 | local str = "This is our little test line" | 39 | elseif err == "timeout" then pass("proper timeout") |
| 122 | local len = strlen(str) | 40 | else fail("unexpected error '%s'", err) end |
| 123 | local back, err, total | 41 | else |
| 124 | reconnect() | 42 | if err ~= "timeout" then fail("should have timed out") |
| 125 | print("testing close while reading line") | 43 | else pass("proper timeout") end |
| 126 | send_command(ECHO_BLOCK, len) | 44 | end |
| 127 | data:send(str) | 45 | else |
| 128 | send_command(CLOSE) | 46 | if mode == "return" then |
| 129 | -- try to get a line | 47 | if elapsed > tm then |
| 130 | back, err = data:receive() | 48 | if err ~= "timeout" then fail("should have timed out") |
| 131 | if not err then fail("shold have gotten 'closed'.") | 49 | else pass("proper timeout") end |
| 132 | elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.") | 50 | elseif elapsed < tm then |
| 133 | elseif str ~= back then fail("didn't receive what i should 'closed'.") | 51 | if err then fail(err) |
| 134 | else pass("rightfull 'closed' received") end | 52 | else pass("ok") end |
| 135 | reconnect() | 53 | else |
| 136 | print("testing close while reading block") | 54 | if alldone then |
| 137 | send_command(ECHO_BLOCK, len) | 55 | if err then fail("unexpected error '%s'", err) |
| 138 | data:send(str) | 56 | else pass("ok") end |
| 139 | send_command(CLOSE) | 57 | else |
| 140 | -- try to get a line | 58 | if err ~= "timeout" then fail(err) |
| 141 | back, err = data:receive(2*len) | 59 | else pass("proper timeoutk") end |
| 142 | if not err then fail("shold have gotten 'closed'.") | 60 | end |
| 143 | elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.") | 61 | end |
| 144 | elseif str ~= back then fail("didn't receive what I should.") | 62 | else |
| 145 | else pass("rightfull 'closed' received") end | 63 | if err then fail(err) |
| 64 | else pass("ok") end | ||
| 65 | end | ||
| 66 | end | ||
| 146 | end | 67 | end |
| 147 | 68 | ||
| 148 | ----------------------------------------------------------------------------- | 69 | write("----------------------------------------------\n", |
| 149 | -- Tests binary line transmission | 70 | "LuaSocket Test Procedures\n", |
| 150 | -- Input | 71 | "----------------------------------------------\n") |
| 151 | -- len: length of line to be tested | ||
| 152 | ----------------------------------------------------------------------------- | ||
| 153 | function test_rawline(len) | ||
| 154 | local str, str10, back, err | ||
| 155 | reconnect() | ||
| 156 | send_command(ECHO_LINE) | ||
| 157 | str = strrep(strchar(47), mod(len, 10)) | ||
| 158 | str10 = strrep(strchar(120,21,77,4,5,0,7,36,44,100), floor(len/10)) | ||
| 159 | str = str .. str10 | ||
| 160 | write("testing ", len, " byte(s) line\n") | ||
| 161 | err = data:send(str, "\n") | ||
| 162 | if err then fail(err) end | ||
| 163 | back, err = data:receive() | ||
| 164 | if err then fail(err) end | ||
| 165 | if back == str then pass("lines match") | ||
| 166 | else fail("lines don't match") end | ||
| 167 | end | ||
| 168 | 72 | ||
| 169 | ----------------------------------------------------------------------------- | 73 | if not _time or not _sleep then fail("not compiled with _DEBUG") end |
| 170 | -- Tests block transmission | ||
| 171 | -- Input | ||
| 172 | -- len: length of block to be tested | ||
| 173 | ----------------------------------------------------------------------------- | ||
| 174 | function test_block(len) | ||
| 175 | local half = floor(len/2) | ||
| 176 | local s1, s2, back, err | ||
| 177 | reconnect() | ||
| 178 | send_command(ECHO_BLOCK, len) | ||
| 179 | write("testing ", len, " byte(s) block\n") | ||
| 180 | s1 = strrep("x", half) | ||
| 181 | err = data:send(s1) | ||
| 182 | if err then fail(err) end | ||
| 183 | s2 = strrep("y", len-half) | ||
| 184 | err = data:send(s2) | ||
| 185 | if err then fail(err) end | ||
| 186 | back, err = data:receive(len) | ||
| 187 | if err then fail(err) end | ||
| 188 | if back == s1..s2 then pass("blocks match") | ||
| 189 | else fail("blocks don't match") end | ||
| 190 | end | ||
| 191 | 74 | ||
| 192 | ----------------------------------------------------------------------------- | 75 | start = _time() |
| 193 | -- Tests if return-timeout was respected | ||
| 194 | -- delta: time elapsed during transfer | ||
| 195 | -- t: timeout value | ||
| 196 | -- s: time server slept | ||
| 197 | -- err: error code returned by I/O operation | ||
| 198 | -- o: operation being executed | ||
| 199 | ----------------------------------------------------------------------------- | ||
| 200 | function blockedtimed_out(t, s, err, o) | ||
| 201 | if err == "timeout" then | ||
| 202 | if s >= t then | ||
| 203 | pass("got rightfull forced timeout") | ||
| 204 | return 1 | ||
| 205 | else | ||
| 206 | pass("got natural cause timeout") | ||
| 207 | return 1 | ||
| 208 | end | ||
| 209 | elseif s > t then | ||
| 210 | if o == "send" then | ||
| 211 | pass("must have been buffered (may be wrong)") | ||
| 212 | else | ||
| 213 | fail("should have gotten timeout") | ||
| 214 | end | ||
| 215 | end | ||
| 216 | end | ||
| 217 | 76 | ||
| 218 | ----------------------------------------------------------------------------- | 77 | function tcpreconnect() |
| 219 | -- Tests blocked-timeout conformance | 78 | write("attempting data connection... ") |
| 220 | -- Input | 79 | if data then data:close() end |
| 221 | -- len: length of block to be tested | 80 | remote [[ |
| 222 | -- t: timeout value | 81 | if data then data:close() data = nil end |
| 223 | -- s: server sleep between transfers | 82 | data = server:accept() |
| 224 | ----------------------------------------------------------------------------- | 83 | ]] |
| 225 | function test_blockedtimeout(len, t, s) | 84 | data, error = connect(HOST, PORT) |
| 226 | local str, err, back, total | 85 | if not data then fail(error) |
| 227 | reconnect() | 86 | else pass("connected!") end |
| 228 | send_command(RECEIVE_BLOCK, len) | ||
| 229 | send_command(SLEEP, s) | ||
| 230 | send_command(RECEIVE_BLOCK, len) | ||
| 231 | write("testing ", len, " bytes, ", t, | ||
| 232 | "s block timeout, ", s, "s sleep\n") | ||
| 233 | data:timeout(t) | ||
| 234 | str = strrep("a", 2*len) | ||
| 235 | err, total = data:send(str) | ||
| 236 | if blockedtimed_out(t, s, err, "send") then return end | ||
| 237 | if err then fail(err) end | ||
| 238 | send_command(SEND_BLOCK) | ||
| 239 | send_command(SLEEP, s) | ||
| 240 | send_command(SEND_BLOCK) | ||
| 241 | back, err = data:receive(2*len) | ||
| 242 | if blockedtimed_out(t, s, err, "receive") then return end | ||
| 243 | if err then fail(err) end | ||
| 244 | if back == str then pass("blocks match") | ||
| 245 | else fail("blocks don't match") end | ||
| 246 | end | 87 | end |
| 88 | reconnect = tcpreconnect | ||
| 247 | 89 | ||
| 248 | ----------------------------------------------------------------------------- | 90 | pass("attempting control connection...") |
| 249 | -- Tests if return-timeout was respected | 91 | control, error = connect(HOST, PORT) |
| 250 | -- delta: time elapsed during transfer | 92 | if error then fail(error) |
| 251 | -- t: timeout value | 93 | else pass("connected!") end |
| 252 | -- err: error code returned by I/O operation | ||
| 253 | ----------------------------------------------------------------------------- | ||
| 254 | function returntimed_out(delta, t, err) | ||
| 255 | if err == "timeout" then | ||
| 256 | if delta >= t then | ||
| 257 | pass("got rightfull timeout") | ||
| 258 | return 1 | ||
| 259 | else | ||
| 260 | fail("shouldn't have gotten timeout") | ||
| 261 | end | ||
| 262 | elseif delta > t then | ||
| 263 | pass(format("but took %fs longer than should have", delta - t)) | ||
| 264 | end | ||
| 265 | end | ||
| 266 | 94 | ||
| 267 | ----------------------------------------------------------------------------- | 95 | ------------------------------------------------------------------------ |
| 268 | -- Tests return-timeout conformance | 96 | test("bugs") |
| 269 | -- Input | ||
| 270 | -- len: length of block to be tested | ||
| 271 | -- t: timeout value | ||
| 272 | -- s: server sleep between transfers | ||
| 273 | ----------------------------------------------------------------------------- | ||
| 274 | function test_returntimeout(len, t, s) | ||
| 275 | local str, err, back, delta, total | ||
| 276 | reconnect() | ||
| 277 | send_command(RECEIVE_BLOCK, len) | ||
| 278 | send_command(SLEEP, s) | ||
| 279 | send_command(RECEIVE_BLOCK, len) | ||
| 280 | write("testing ", len, " bytes, ", t, | ||
| 281 | "s return timeout, ", s, "s sleep\n") | ||
| 282 | data:timeout(t, "return") | ||
| 283 | str = strrep("a", 2*len) | ||
| 284 | err, total, delta = data:send(str) | ||
| 285 | print("sent in " .. delta .. "s") | ||
| 286 | if returntimed_out(delta, t, err) then return end | ||
| 287 | if err then fail("unexpected error: " .. err) end | ||
| 288 | send_command(SEND_BLOCK) | ||
| 289 | send_command(SLEEP, s) | ||
| 290 | send_command(SEND_BLOCK) | ||
| 291 | back, err, delta = data:receive(2*len) | ||
| 292 | print("received in " .. delta .. "s") | ||
| 293 | if returntimed_out(delta, t, err) then return end | ||
| 294 | if err then fail("unexpected error: " .. err) end | ||
| 295 | if back == str then pass("blocks match") | ||
| 296 | else fail("blocks don't match") end | ||
| 297 | end | ||
| 298 | 97 | ||
| 299 | ----------------------------------------------------------------------------- | 98 | write("empty host connect: ") |
| 300 | -- Tests read patterns | 99 | function empty_connect() |
| 301 | ----------------------------------------------------------------------------- | 100 | if data then data:close() data = nil end |
| 302 | function test_word() | 101 | remote [[ |
| 303 | local b1 = " \t one two three \n this_is_a_very" | 102 | if data then data:close() data = nil end |
| 304 | local b2 = "_big_word " | 103 | data = server:accept() |
| 305 | send_command(ECHO_BLOCK, strlen(b1)+strlen(b2)) | 104 | ]] |
| 306 | err = data:send(b1, b2) | 105 | data, err = connect("", PORT) |
| 307 | local a1, a2, a3, a4 | 106 | if not data then |
| 308 | a1, a2, a3, a4, err = data:receive("*w", "*w", "*w", "*w") | 107 | pass("ok") |
| 309 | if err then fail(err) end | 108 | data = connect(HOST, PORT) |
| 310 | _, err = data:receive(1) -- get last space | 109 | else fail("should not have connected!") end |
| 311 | if err then fail(err) end | ||
| 312 | if a1 ~= "one" or a2 ~= "two" or a3 ~= "three" or | ||
| 313 | a4 ~= "this_is_a_very_big_word" then fail("'*w' failed") end | ||
| 314 | pass("'*w' is ok") | ||
| 315 | end | 110 | end |
| 316 | 111 | ||
| 317 | function test_patterns() | 112 | empty_connect() |
| 318 | local dos_line1 = "this the first dos line" | 113 | |
| 319 | local dos_line2 = "this is another dos line" | 114 | ------------------------------------------------------------------------ |
| 320 | local unix_line1 = "this the first unix line" | 115 | test("method registration") |
| 321 | local unix_line2 = "this is another unix line" | 116 | |
| 322 | local block = dos_line1 .. "\r\n" .. dos_line2 .. "\r\n" | 117 | function test_methods(sock, methods) |
| 323 | reconnect() | 118 | for _, v in methods do |
| 324 | block = block .. unix_line1 .. "\n" .. unix_line2 .. "\n" | 119 | if type(sock[v]) ~= "function" then |
| 325 | block = block .. block | 120 | fail(type(sock) .. " method " .. v .. "not registered") |
| 326 | send_command(ECHO_BLOCK, strlen(block)) | 121 | end |
| 327 | err = data:send(block) | 122 | end |
| 328 | if err then fail(err) end | 123 | pass(type(sock) .. " methods are ok") |
| 329 | local back = data:receive("*l") | ||
| 330 | if back ~= dos_line1 then fail("'*l' failed") end | ||
| 331 | back = data:receive("*l") | ||
| 332 | if back ~= dos_line2 then fail("'*l' failed") end | ||
| 333 | back = data:receive("*lu") | ||
| 334 | if back ~= unix_line1 then fail("'*lu' failed") end | ||
| 335 | back = data:receive("*lu") | ||
| 336 | if back ~= unix_line2 then fail("'*lu' failed") end | ||
| 337 | back = data:receive() | ||
| 338 | if back ~= dos_line1 then fail("default failed") end | ||
| 339 | back = data:receive() | ||
| 340 | if back ~= dos_line2 then fail("default failed") end | ||
| 341 | back = data:receive("*lu") | ||
| 342 | if back ~= unix_line1 then fail("'*lu' failed") end | ||
| 343 | back = data:receive("*lu") | ||
| 344 | if back ~= unix_line2 then fail("'*lu' failed") end | ||
| 345 | pass("line patterns are ok") | ||
| 346 | send_command(ECHO_BLOCK, strlen(block)) | ||
| 347 | err = data:send(block) | ||
| 348 | if err then fail(err) end | ||
| 349 | back = data:receive(strlen(block)) | ||
| 350 | if back ~= block then fail("number failed") end | ||
| 351 | pass("number is ok") | ||
| 352 | test_word() | ||
| 353 | send_command(ECHO_BLOCK, strlen(block)) | ||
| 354 | send_command(SLEEP, 1) | ||
| 355 | send_command(CLOSE) | ||
| 356 | err = data:send(block) | ||
| 357 | if err then fail(err) end | ||
| 358 | back = data:receive("*a") | ||
| 359 | if back ~= block then fail("'*a' failed") end | ||
| 360 | pass("'*a' is ok") | ||
| 361 | end | 124 | end |
| 362 | 125 | ||
| 363 | ----------------------------------------------------------------------------- | 126 | test_methods(control, { |
| 364 | -- Test for select bugs | 127 | "close", |
| 365 | ----------------------------------------------------------------------------- | 128 | "timeout", |
| 366 | function test_select() | 129 | "send", |
| 367 | local r, s, e = select(nil, nil, 0.1) | 130 | "receive", |
| 368 | assert(type(r) == "table" and type(s) == "table" and e == "timeout") | 131 | "getpeername", |
| 369 | pass("both nil") | 132 | "getsockname" |
| 370 | data:close() | 133 | }) |
| 371 | r, s, e = select({ data }, { data }, 0.1) | 134 | |
| 372 | assert(type(r) == "table" and type(s) == "table" and e == "timeout") | 135 | if udpsocket then |
| 373 | pass("closed sockets") | 136 | test_methods(udpsocket(), { |
| 374 | e = call(select, {"wrong", 1, 0.1}, "x", nil) | 137 | "close", |
| 375 | assert(e == nil) | 138 | "timeout", |
| 376 | pass("invalid input") | 139 | "send", |
| 140 | "sendto", | ||
| 141 | "receive", | ||
| 142 | "receivefrom", | ||
| 143 | "getpeername", | ||
| 144 | "getsockname", | ||
| 145 | "setsockname", | ||
| 146 | "setpeername" | ||
| 147 | }) | ||
| 377 | end | 148 | end |
| 378 | 149 | ||
| 379 | ----------------------------------------------------------------------------- | 150 | test_methods(bind("*", 0), { |
| 380 | -- Execute all tests | 151 | "close", |
| 381 | ----------------------------------------------------------------------------- | 152 | "timeout", |
| 382 | start = _time() | 153 | "accept" |
| 154 | }) | ||
| 383 | 155 | ||
| 384 | new_test("control connection test") | 156 | if pipe then |
| 385 | test_command(EXIT) | 157 | local p1, p2 = pipe() |
| 386 | test_command(CONNECT) | 158 | test_methods(p1, { |
| 387 | test_command(CLOSE) | 159 | "close", |
| 388 | test_command(ECHO_BLOCK, 12234) | 160 | "timeout", |
| 389 | test_command(SLEEP, 1111) | 161 | "send", |
| 390 | test_command(ECHO_LINE) | 162 | "receive" |
| 163 | }) | ||
| 164 | test_methods(p2, { | ||
| 165 | "close", | ||
| 166 | "timeout", | ||
| 167 | "send", | ||
| 168 | "receive" | ||
| 169 | }) | ||
| 170 | end | ||
| 391 | 171 | ||
| 392 | new_test("testing for select bugs") | 172 | if filesocket then |
| 393 | test_select() | 173 | test_methods(filesocket(0), { |
| 174 | "close", | ||
| 175 | "timeout", | ||
| 176 | "send", | ||
| 177 | "receive" | ||
| 178 | }) | ||
| 179 | end | ||
| 394 | 180 | ||
| 395 | new_test("connection close test") | 181 | ------------------------------------------------------------------------ |
| 396 | test_closed() | 182 | test("select function") |
| 183 | function test_selectbugs() | ||
| 184 | local r, s, e = select(nil, nil, 0.1) | ||
| 185 | assert(type(r) == "table" and type(s) == "table" and e == "timeout") | ||
| 186 | pass("both nil: ok") | ||
| 187 | local udp = udpsocket() | ||
| 188 | udp:close() | ||
| 189 | r, s, e = select({ data }, { data }, 0.1) | ||
| 190 | assert(type(r) == "table" and type(s) == "table" and e == "timeout") | ||
| 191 | pass("closed sockets: ok") | ||
| 192 | e = call(select, {"wrong", 1, 0.1}, "x", nil) | ||
| 193 | assert(e == nil) | ||
| 194 | pass("invalid input: ok") | ||
| 195 | end | ||
| 397 | 196 | ||
| 398 | new_test("read pattern test") | 197 | test_selectbugs() |
| 399 | test_patterns() | ||
| 400 | 198 | ||
| 401 | new_test("multiple pattern test") | 199 | ------------------------------------------------------------------------ |
| 402 | test_multiple() | 200 | test("character line") |
| 201 | reconnect() | ||
| 202 | |||
| 203 | function test_asciiline(len) | ||
| 204 | local str, str10, back, err | ||
| 205 | str = strrep("x", mod(len, 10)) | ||
| 206 | str10 = strrep("aZb.c#dAe?", floor(len/10)) | ||
| 207 | str = str .. str10 | ||
| 208 | pass(len .. " byte(s) line") | ||
| 209 | remote "str = data:receive()" | ||
| 210 | err = data:send(str, "\n") | ||
| 211 | if err then fail(err) end | ||
| 212 | remote "data:send(str, '\\n')" | ||
| 213 | back, err = data:receive() | ||
| 214 | if err then fail(err) end | ||
| 215 | if back == str then pass("lines match") | ||
| 216 | else fail("lines don't match") end | ||
| 217 | end | ||
| 403 | 218 | ||
| 404 | new_test("character string test") | ||
| 405 | test_asciiline(1) | 219 | test_asciiline(1) |
| 406 | test_asciiline(17) | 220 | test_asciiline(17) |
| 407 | test_asciiline(200) | 221 | test_asciiline(200) |
| 408 | test_asciiline(3000) | 222 | test_asciiline(4091) |
| 409 | test_asciiline(80000) | 223 | test_asciiline(80199) |
| 410 | test_asciiline(800000) | 224 | test_asciiline(800000) |
| 411 | 225 | ||
| 412 | new_test("binary string test") | 226 | ------------------------------------------------------------------------ |
| 227 | test("binary line") | ||
| 228 | reconnect() | ||
| 229 | |||
| 230 | function test_rawline(len) | ||
| 231 | local str, str10, back, err | ||
| 232 | str = strrep(strchar(47), mod(len, 10)) | ||
| 233 | str10 = strrep(strchar(120,21,77,4,5,0,7,36,44,100), floor(len/10)) | ||
| 234 | str = str .. str10 | ||
| 235 | pass(len .. " byte(s) line") | ||
| 236 | remote "str = data:receive()" | ||
| 237 | err = data:send(str, "\n") | ||
| 238 | if err then fail(err) end | ||
| 239 | remote "data:send(str, '\\n')" | ||
| 240 | back, err = data:receive() | ||
| 241 | if err then fail(err) end | ||
| 242 | if back == str then pass("lines match") | ||
| 243 | else fail("lines don't match") end | ||
| 244 | end | ||
| 245 | |||
| 413 | test_rawline(1) | 246 | test_rawline(1) |
| 414 | test_rawline(17) | 247 | test_rawline(17) |
| 415 | test_rawline(200) | 248 | test_rawline(200) |
| 416 | test_rawline(3000) | 249 | test_rawline(4091) |
| 417 | test_rawline(8000) | 250 | test_rawline(80199) |
| 418 | test_rawline(80000) | ||
| 419 | test_rawline(800000) | 251 | test_rawline(800000) |
| 252 | test_rawline(80199) | ||
| 253 | test_rawline(4091) | ||
| 254 | test_rawline(200) | ||
| 255 | test_rawline(17) | ||
| 256 | test_rawline(1) | ||
| 420 | 257 | ||
| 421 | new_test("blocking transfer test") | 258 | ------------------------------------------------------------------------ |
| 422 | test_block(1) | 259 | test("raw transfer") |
| 423 | test_block(17) | 260 | reconnect() |
| 424 | test_block(200) | 261 | |
| 425 | test_block(3000) | 262 | function test_raw(len) |
| 426 | test_block(80000) | 263 | local half = floor(len/2) |
| 427 | test_block(800000) | 264 | local s1, s2, back, err |
| 265 | s1 = strrep("x", half) | ||
| 266 | s2 = strrep("y", len-half) | ||
| 267 | pass(len .. " byte(s) block") | ||
| 268 | remote (format("str = data:receive(%d)", len)) | ||
| 269 | err = data:send(s1) | ||
| 270 | if err then fail(err) end | ||
| 271 | err = data:send(s2) | ||
| 272 | if err then fail(err) end | ||
| 273 | remote "data:send(str)" | ||
| 274 | back, err = data:receive(len) | ||
| 275 | if err then fail(err) end | ||
| 276 | if back == s1..s2 then pass("blocks match") | ||
| 277 | else fail("blocks don't match") end | ||
| 278 | end | ||
| 279 | |||
| 280 | test_raw(1) | ||
| 281 | test_raw(17) | ||
| 282 | test_raw(200) | ||
| 283 | test_raw(4091) | ||
| 284 | test_raw(80199) | ||
| 285 | test_raw(800000) | ||
| 286 | test_raw(80199) | ||
| 287 | test_raw(4091) | ||
| 288 | test_raw(200) | ||
| 289 | test_raw(17) | ||
| 290 | test_raw(1) | ||
| 291 | ------------------------------------------------------------------------ | ||
| 292 | test("non-blocking transfer") | ||
| 293 | reconnect() | ||
| 428 | 294 | ||
| 429 | new_test("non-blocking transfer test") | ||
| 430 | -- the value is not important, we only want | 295 | -- the value is not important, we only want |
| 431 | -- to test non-blockin I/O anyways | 296 | -- to test non-blockin I/O anyways |
| 432 | data:timeout(200) | 297 | data:timeout(200) |
| 433 | test_block(1) | 298 | test_raw(1) |
| 434 | test_block(17) | 299 | test_raw(17) |
| 435 | test_block(200) | 300 | test_raw(200) |
| 436 | test_block(3000) | 301 | test_raw(4091) |
| 437 | test_block(80000) | 302 | test_raw(80199) |
| 438 | test_block(800000) | 303 | test_raw(800000) |
| 439 | 304 | test_raw(80199) | |
| 440 | new_test("blocked timeout test") | 305 | test_raw(4091) |
| 441 | test_blockedtimeout(80, 1, 2) | 306 | test_raw(200) |
| 442 | test_blockedtimeout(80, 2, 2) | 307 | test_raw(17) |
| 443 | test_blockedtimeout(80, 3, 2) | 308 | test_raw(1) |
| 444 | test_blockedtimeout(800, 1, 0) | 309 | |
| 445 | test_blockedtimeout(8000, 2, 3) | 310 | ------------------------------------------------------------------------ |
| 446 | test_blockedtimeout(80000, 2, 1) | 311 | test("mixed patterns") |
| 447 | test_blockedtimeout(800000, 0.01, 0) | 312 | reconnect() |
| 448 | 313 | ||
| 449 | new_test("return timeout test") | 314 | function test_mixed(len) |
| 450 | test_returntimeout(80, 2, 1) | 315 | local inter = floor(len/3) |
| 451 | test_returntimeout(80, 1, 2) | 316 | local p1 = "unix " .. strrep("x", inter) .. "line\n" |
| 452 | test_returntimeout(8000, 1, 2) | 317 | local p2 = "dos " .. strrep("y", inter) .. "line\r\n" |
| 453 | test_returntimeout(80000, 2, 1) | 318 | local p3 = "raw " .. strrep("z", inter) .. "bytes" |
| 454 | test_returntimeout(800000, 0.1, 0) | 319 | local bp1, bp2, bp3 |
| 455 | test_returntimeout(800000, 2, 1) | 320 | pass(len .. " byte(s) patterns") |
| 456 | 321 | remote (format("str = data:receive(%d)", strlen(p1)+strlen(p2)+strlen(p3))) | |
| 457 | ----------------------------------------------------------------------------- | 322 | err = data:send(p1, p2, p3) |
| 458 | -- Close connection and exit server. We are done. | 323 | if err then fail(err) end |
| 459 | ----------------------------------------------------------------------------- | 324 | remote "data:send(str)" |
| 460 | new_test("the library has passed all tests") | 325 | bp1, bp2, bp3, err = data:receive("*lu", "*l", strlen(p3)) |
| 461 | print("client: closing connection with server") | 326 | if err then fail(err) end |
| 462 | send_command(CLOSE) | 327 | if bp1.."\n" == p1 and bp2.."\r\n" == p2 and bp3 == p3 then |
| 463 | send_command(EXIT) | 328 | pass("patterns match") |
| 464 | control:close() | 329 | else fail("patterns don't match") end |
| 465 | print(format("time elapsed: %6.2fs", _time() - start)) | 330 | end |
| 466 | print("client: exiting...") | 331 | |
| 467 | exit() | 332 | test_mixed(1) |
| 333 | test_mixed(17) | ||
| 334 | test_mixed(200) | ||
| 335 | test_mixed(4091) | ||
| 336 | test_mixed(80199) | ||
| 337 | test_mixed(800000) | ||
| 338 | test_mixed(80199) | ||
| 339 | test_mixed(4091) | ||
| 340 | test_mixed(200) | ||
| 341 | test_mixed(17) | ||
| 342 | test_mixed(1) | ||
| 343 | |||
| 344 | ------------------------------------------------------------------------ | ||
| 345 | test("closed connection detection") | ||
| 346 | |||
| 347 | function test_closed() | ||
| 348 | local back, err | ||
| 349 | local str = 'little string' | ||
| 350 | reconnect() | ||
| 351 | pass("trying read detection") | ||
| 352 | remote (format ([[ | ||
| 353 | data:send('%s') | ||
| 354 | data:close() | ||
| 355 | data = nil | ||
| 356 | ]], str)) | ||
| 357 | -- try to get a line | ||
| 358 | back, err = data:receive() | ||
| 359 | if not err then fail("shold have gotten 'closed'.") | ||
| 360 | elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.") | ||
| 361 | elseif str ~= back then fail("didn't receive partial result.") | ||
| 362 | else pass("graceful 'closed' received") end | ||
| 363 | reconnect() | ||
| 364 | pass("trying write detection") | ||
| 365 | remote [[ | ||
| 366 | data:close() | ||
| 367 | data = nil | ||
| 368 | ]] | ||
| 369 | err, total = data:send(strrep("ugauga", 100000)) | ||
| 370 | if not err then | ||
| 371 | pass("failed: output buffer is at least %d bytes long!", total) | ||
| 372 | elseif err ~= "closed" then | ||
| 373 | fail("got '"..err.."' instead of 'closed'.") | ||
| 374 | else | ||
| 375 | pass("graceful 'closed' received after %d bytes were sent", total) | ||
| 376 | end | ||
| 377 | end | ||
| 378 | |||
| 379 | test_closed() | ||
| 380 | |||
| 381 | ------------------------------------------------------------------------ | ||
| 382 | test("return timeout on receive") | ||
| 383 | function test_blockingtimeoutreceive(len, tm, sl) | ||
| 384 | local str, err, total | ||
| 385 | reconnect() | ||
| 386 | pass("%d bytes, %ds return timeout, %ds pause", len, tm, sl) | ||
| 387 | remote (format ([[ | ||
| 388 | data:timeout(%d) | ||
| 389 | str = strrep('a', %d) | ||
| 390 | data:send(str) | ||
| 391 | print('server: sleeping for %ds') | ||
| 392 | _sleep(%d) | ||
| 393 | print('server: woke up') | ||
| 394 | data:send(str) | ||
| 395 | ]], 2*tm, len, sl, sl)) | ||
| 396 | data:timeout(tm, "return") | ||
| 397 | str, err, elapsed = data:receive(2*len) | ||
| 398 | check_timeout(tm, sl, elapsed, err, "receive", "return", | ||
| 399 | strlen(str) == 2*len) | ||
| 400 | end | ||
| 401 | test_blockingtimeoutreceive(800091, 1, 3) | ||
| 402 | test_blockingtimeoutreceive(800091, 2, 3) | ||
| 403 | test_blockingtimeoutreceive(800091, 3, 2) | ||
| 404 | test_blockingtimeoutreceive(800091, 3, 1) | ||
| 405 | |||
| 406 | ------------------------------------------------------------------------ | ||
| 407 | test("return timeout on send") | ||
| 408 | function test_returntimeoutsend(len, tm, sl) | ||
| 409 | local str, err, total | ||
| 410 | reconnect() | ||
| 411 | pass("%d bytes, %ds return timeout, %ds pause", len, tm, sl) | ||
| 412 | remote (format ([[ | ||
| 413 | data:timeout(%d) | ||
| 414 | str = data:receive(%d) | ||
| 415 | print('server: sleeping for %ds') | ||
| 416 | _sleep(%d) | ||
| 417 | print('server: woke up') | ||
| 418 | str = data:receive(%d) | ||
| 419 | ]], 2*tm, len, sl, sl, len)) | ||
| 420 | data:timeout(tm, "return") | ||
| 421 | str = strrep("a", 2*len) | ||
| 422 | err, total, elapsed = data:send(str) | ||
| 423 | check_timeout(tm, sl, elapsed, err, "send", "return", | ||
| 424 | total == 2*len) | ||
| 425 | end | ||
| 426 | test_returntimeoutsend(800091, 1, 3) | ||
| 427 | test_returntimeoutsend(800091, 2, 3) | ||
| 428 | test_returntimeoutsend(800091, 3, 2) | ||
| 429 | test_returntimeoutsend(800091, 3, 1) | ||
| 430 | |||
| 431 | |||
| 432 | ------------------------------------------------------------------------ | ||
| 433 | test("blocking timeout on receive") | ||
| 434 | function test_blockingtimeoutreceive(len, tm, sl) | ||
| 435 | local str, err, total | ||
| 436 | reconnect() | ||
| 437 | pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl) | ||
| 438 | remote (format ([[ | ||
| 439 | data:timeout(%d) | ||
| 440 | str = strrep('a', %d) | ||
| 441 | data:send(str) | ||
| 442 | print('server: sleeping for %ds') | ||
| 443 | _sleep(%d) | ||
| 444 | print('server: woke up') | ||
| 445 | data:send(str) | ||
| 446 | ]], 2*tm, len, sl, sl)) | ||
| 447 | data:timeout(tm) | ||
| 448 | str, err, elapsed = data:receive(2*len) | ||
| 449 | check_timeout(tm, sl, elapsed, err, "receive", "blocking", | ||
| 450 | strlen(str) == 2*len) | ||
| 451 | end | ||
| 452 | test_blockingtimeoutreceive(800091, 1, 3) | ||
| 453 | test_blockingtimeoutreceive(800091, 2, 3) | ||
| 454 | test_blockingtimeoutreceive(800091, 3, 2) | ||
| 455 | test_blockingtimeoutreceive(800091, 3, 1) | ||
| 456 | |||
| 457 | |||
| 458 | ------------------------------------------------------------------------ | ||
| 459 | test("blocking timeout on send") | ||
| 460 | function test_blockingtimeoutsend(len, tm, sl) | ||
| 461 | local str, err, total | ||
| 462 | reconnect() | ||
| 463 | pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl) | ||
| 464 | remote (format ([[ | ||
| 465 | data:timeout(%d) | ||
| 466 | str = data:receive(%d) | ||
| 467 | print('server: sleeping for %ds') | ||
| 468 | _sleep(%d) | ||
| 469 | print('server: woke up') | ||
| 470 | str = data:receive(%d) | ||
| 471 | ]], 2*tm, len, sl, sl, len)) | ||
| 472 | data:timeout(tm) | ||
| 473 | str = strrep("a", 2*len) | ||
| 474 | err, total, elapsed = data:send(str) | ||
| 475 | check_timeout(tm, sl, elapsed, err, "send", "blocking", | ||
| 476 | total == 2*len) | ||
| 477 | end | ||
| 478 | test_blockingtimeoutsend(800091, 1, 3) | ||
| 479 | test_blockingtimeoutsend(800091, 2, 3) | ||
| 480 | test_blockingtimeoutsend(800091, 3, 2) | ||
| 481 | test_blockingtimeoutsend(800091, 3, 1) | ||
| 482 | |||
| 483 | ------------------------------------------------------------------------ | ||
| 484 | 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 @@ | |||
| 1 | ----------------------------------------------------------------------------- | 1 | HOST = HOST or "localhost" |
| 2 | -- LuaSocket automated test module | 2 | PORT = PORT or "8080" |
| 3 | -- testsrvr.lua | ||
| 4 | -- This is the server module. It's completely controled by the client module | ||
| 5 | -- by the use of a control connection. | ||
| 6 | ----------------------------------------------------------------------------- | ||
| 7 | 3 | ||
| 8 | ----------------------------------------------------------------------------- | 4 | server, error = bind(HOST, PORT) |
| 9 | -- Read command definitions | 5 | if not server then print("server: " .. tostring(error)) exit() end |
| 10 | ----------------------------------------------------------------------------- | ||
| 11 | HOST = HOST or "*" | ||
| 12 | assert(dofile("testcmd.lua")) | ||
| 13 | test_debug_mode() | ||
| 14 | |||
| 15 | ----------------------------------------------------------------------------- | ||
| 16 | -- Start control connection | ||
| 17 | ----------------------------------------------------------------------------- | ||
| 18 | server, err = bind(HOST, PORT) | ||
| 19 | if not server then | ||
| 20 | fail(err) | ||
| 21 | exit(1) | ||
| 22 | end | ||
| 23 | print("server: waiting for control connection...") | ||
| 24 | control = server:accept() | ||
| 25 | print("server: control connection stablished!") | ||
| 26 | |||
| 27 | ----------------------------------------------------------------------------- | ||
| 28 | -- Executes a command, detecting any possible failures | ||
| 29 | -- Input | ||
| 30 | -- cmd: command to be executed | ||
| 31 | -- par: command parameters, if needed | ||
| 32 | ----------------------------------------------------------------------------- | ||
| 33 | function execute_command(cmd, par) | ||
| 34 | if cmd == CONNECT then | ||
| 35 | print("server: waiting for data connection...") | ||
| 36 | data = server:accept() | ||
| 37 | data:timeout(10) | ||
| 38 | if not data then | ||
| 39 | fail("server: unable to start data connection!") | ||
| 40 | else | ||
| 41 | print("server: data connection stablished!") | ||
| 42 | end | ||
| 43 | elseif cmd == CLOSE then | ||
| 44 | print("server: closing connection with client...") | ||
| 45 | if data then | ||
| 46 | data:close() | ||
| 47 | data = nil | ||
| 48 | end | ||
| 49 | elseif cmd == ECHO_LINE then | ||
| 50 | str, err = data:receive() | ||
| 51 | if err then fail("server: " .. err) end | ||
| 52 | err = data:send(str, "\n") | ||
| 53 | if err then fail("server: " .. err) end | ||
| 54 | elseif cmd == ECHO_BLOCK then | ||
| 55 | str, err = data:receive(par) | ||
| 56 | print(format("server: received %d bytes", strlen(str))) | ||
| 57 | if err then fail("server: " .. err) end | ||
| 58 | print(format("server: sending %d bytes", strlen(str))) | ||
| 59 | err = data:send(str) | ||
| 60 | if err then fail("server: " .. err) end | ||
| 61 | elseif cmd == RECEIVE_BLOCK then | ||
| 62 | str, err = data:receive(par) | ||
| 63 | print(format("server: received %d bytes", strlen(str))) | ||
| 64 | elseif cmd == SEND_BLOCK then | ||
| 65 | print(format("server: sending %d bytes", strlen(str))) | ||
| 66 | err = data:send(str) | ||
| 67 | elseif cmd == ECHO_TIMEOUT then | ||
| 68 | str, err = data:receive(par) | ||
| 69 | if err then fail("server: " .. err) end | ||
| 70 | err = data:send(str) | ||
| 71 | if err then fail("server: " .. err) end | ||
| 72 | elseif cmd == COMMAND then | ||
| 73 | cmd, par = get_command() | ||
| 74 | send_command(cmd, par) | ||
| 75 | elseif cmd == EXIT then | ||
| 76 | print("server: exiting...") | ||
| 77 | exit(0) | ||
| 78 | elseif cmd == SYNC then | ||
| 79 | print("server: synchronizing...") | ||
| 80 | send_command(SYNC) | ||
| 81 | elseif cmd == SLEEP then | ||
| 82 | print("server: sleeping for " .. par .. " seconds...") | ||
| 83 | _sleep(par) | ||
| 84 | print("server: woke up!") | ||
| 85 | end | ||
| 86 | end | ||
| 87 | |||
| 88 | ----------------------------------------------------------------------------- | ||
| 89 | -- Loop forever, accepting and executing commands | ||
| 90 | ----------------------------------------------------------------------------- | ||
| 91 | while 1 do | 6 | while 1 do |
| 92 | cmd, par = get_command() | 7 | print("server: waiting for client connection..."); |
| 93 | if not cmd then fail("server: " .. par) end | 8 | control = server:accept() |
| 94 | print_command(cmd, par) | 9 | while 1 do |
| 95 | execute_command(cmd, par) | 10 | command, error = control:receive() |
| 11 | if error then | ||
| 12 | control:close() | ||
| 13 | print("server: closing connection...") | ||
| 14 | break | ||
| 15 | end | ||
| 16 | error = control:send("\n") | ||
| 17 | if error then | ||
| 18 | control:close() | ||
| 19 | print("server: closing connection...") | ||
| 20 | break | ||
| 21 | end | ||
| 22 | dostring(command) | ||
| 23 | end | ||
| 96 | end | 24 | end |
