comparison test/testclnt.lua @ 0:4b915342e2a8

LuaSocket 2.0.2 + CMake build description.
author Eric Wing <ewing . public |-at-| gmail . com>
date Tue, 26 Aug 2008 18:40:01 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4b915342e2a8
1 local socket = require"socket"
2
3 host = host or "localhost"
4 port = port or "8383"
5
6 function pass(...)
7 local s = string.format(unpack(arg))
8 io.stderr:write(s, "\n")
9 end
10
11 function fail(...)
12 local s = string.format(unpack(arg))
13 io.stderr:write("ERROR: ", s, "!\n")
14 socket.sleep(3)
15 os.exit()
16 end
17
18 function warn(...)
19 local s = string.format(unpack(arg))
20 io.stderr:write("WARNING: ", s, "\n")
21 end
22
23 function remote(...)
24 local s = string.format(unpack(arg))
25 s = string.gsub(s, "\n", ";")
26 s = string.gsub(s, "%s+", " ")
27 s = string.gsub(s, "^%s*", "")
28 control:send(s .. "\n")
29 control:receive()
30 end
31
32 function test(test)
33 io.stderr:write("----------------------------------------------\n",
34 "testing: ", test, "\n",
35 "----------------------------------------------\n")
36 end
37
38 function check_timeout(tm, sl, elapsed, err, opp, mode, alldone)
39 if tm < sl then
40 if opp == "send" then
41 if not err then warn("must be buffered")
42 elseif err == "timeout" then pass("proper timeout")
43 else fail("unexpected error '%s'", err) end
44 else
45 if err ~= "timeout" then fail("should have timed out")
46 else pass("proper timeout") end
47 end
48 else
49 if mode == "total" then
50 if elapsed > tm then
51 if err ~= "timeout" then fail("should have timed out")
52 else pass("proper timeout") end
53 elseif elapsed < tm then
54 if err then fail(err)
55 else pass("ok") end
56 else
57 if alldone then
58 if err then fail("unexpected error '%s'", err)
59 else pass("ok") end
60 else
61 if err ~= "timeout" then fail(err)
62 else pass("proper timeoutk") end
63 end
64 end
65 else
66 if err then fail(err)
67 else pass("ok") end
68 end
69 end
70 end
71
72 if not socket._DEBUG then
73 fail("Please define LUASOCKET_DEBUG and recompile LuaSocket")
74 end
75
76 io.stderr:write("----------------------------------------------\n",
77 "LuaSocket Test Procedures\n",
78 "----------------------------------------------\n")
79
80 start = socket.gettime()
81
82 function reconnect()
83 io.stderr:write("attempting data connection... ")
84 if data then data:close() end
85 remote [[
86 if data then data:close() data = nil end
87 data = server:accept()
88 data:setoption("tcp-nodelay", true)
89 ]]
90 data, err = socket.connect(host, port)
91 if not data then fail(err)
92 else pass("connected!") end
93 data:setoption("tcp-nodelay", true)
94 end
95
96 pass("attempting control connection...")
97 control, err = socket.connect(host, port)
98 if err then fail(err)
99 else pass("connected!") end
100 control:setoption("tcp-nodelay", true)
101
102 ------------------------------------------------------------------------
103 function test_methods(sock, methods)
104 for _, v in pairs(methods) do
105 if type(sock[v]) ~= "function" then
106 fail(sock.class .. " method '" .. v .. "' not registered")
107 end
108 end
109 pass(sock.class .. " methods are ok")
110 end
111
112 ------------------------------------------------------------------------
113 function test_mixed(len)
114 reconnect()
115 local inter = math.ceil(len/4)
116 local p1 = "unix " .. string.rep("x", inter) .. "line\n"
117 local p2 = "dos " .. string.rep("y", inter) .. "line\r\n"
118 local p3 = "raw " .. string.rep("z", inter) .. "bytes"
119 local p4 = "end" .. string.rep("w", inter) .. "bytes"
120 local bp1, bp2, bp3, bp4
121 remote (string.format("str = data:receive(%d)",
122 string.len(p1)+string.len(p2)+string.len(p3)+string.len(p4)))
123 sent, err = data:send(p1..p2..p3..p4)
124 if err then fail(err) end
125 remote "data:send(str); data:close()"
126 bp1, err = data:receive()
127 if err then fail(err) end
128 bp2, err = data:receive()
129 if err then fail(err) end
130 bp3, err = data:receive(string.len(p3))
131 if err then fail(err) end
132 bp4, err = data:receive("*a")
133 if err then fail(err) end
134 if bp1.."\n" == p1 and bp2.."\r\n" == p2 and bp3 == p3 and bp4 == p4 then
135 pass("patterns match")
136 else fail("patterns don't match") end
137 end
138
139 ------------------------------------------------------------------------
140 function test_asciiline(len)
141 reconnect()
142 local str, str10, back, err
143 str = string.rep("x", math.mod(len, 10))
144 str10 = string.rep("aZb.c#dAe?", math.floor(len/10))
145 str = str .. str10
146 remote "str = data:receive()"
147 sent, err = data:send(str.."\n")
148 if err then fail(err) end
149 remote "data:send(str ..'\\n')"
150 back, err = data:receive()
151 if err then fail(err) end
152 if back == str then pass("lines match")
153 else fail("lines don't match") end
154 end
155
156 ------------------------------------------------------------------------
157 function test_rawline(len)
158 reconnect()
159 local str, str10, back, err
160 str = string.rep(string.char(47), math.mod(len, 10))
161 str10 = string.rep(string.char(120,21,77,4,5,0,7,36,44,100),
162 math.floor(len/10))
163 str = str .. str10
164 remote "str = data:receive()"
165 sent, err = data:send(str.."\n")
166 if err then fail(err) end
167 remote "data:send(str..'\\n')"
168 back, err = data:receive()
169 if err then fail(err) end
170 if back == str then pass("lines match")
171 else fail("lines don't match") end
172 end
173
174 ------------------------------------------------------------------------
175 function test_raw(len)
176 reconnect()
177 local half = math.floor(len/2)
178 local s1, s2, back, err
179 s1 = string.rep("x", half)
180 s2 = string.rep("y", len-half)
181 remote (string.format("str = data:receive(%d)", len))
182 sent, err = data:send(s1)
183 if err then fail(err) end
184 sent, err = data:send(s2)
185 if err then fail(err) end
186 remote "data:send(str)"
187 back, err = data:receive(len)
188 if err then fail(err) end
189 if back == s1..s2 then pass("blocks match")
190 else fail("blocks don't match") end
191 end
192
193 ------------------------------------------------------------------------
194 function test_totaltimeoutreceive(len, tm, sl)
195 reconnect()
196 local str, err, partial
197 pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl)
198 remote (string.format ([[
199 data:settimeout(%d)
200 str = string.rep('a', %d)
201 data:send(str)
202 print('server: sleeping for %ds')
203 socket.sleep(%d)
204 print('server: woke up')
205 data:send(str)
206 ]], 2*tm, len, sl, sl))
207 data:settimeout(tm, "total")
208 local t = socket.gettime()
209 str, err, partial, elapsed = data:receive(2*len)
210 check_timeout(tm, sl, elapsed, err, "receive", "total",
211 string.len(str or partial) == 2*len)
212 end
213
214 ------------------------------------------------------------------------
215 function test_totaltimeoutsend(len, tm, sl)
216 reconnect()
217 local str, err, total
218 pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl)
219 remote (string.format ([[
220 data:settimeout(%d)
221 str = data:receive(%d)
222 print('server: sleeping for %ds')
223 socket.sleep(%d)
224 print('server: woke up')
225 str = data:receive(%d)
226 ]], 2*tm, len, sl, sl, len))
227 data:settimeout(tm, "total")
228 str = string.rep("a", 2*len)
229 total, err, partial, elapsed = data:send(str)
230 check_timeout(tm, sl, elapsed, err, "send", "total",
231 total == 2*len)
232 end
233
234 ------------------------------------------------------------------------
235 function test_blockingtimeoutreceive(len, tm, sl)
236 reconnect()
237 local str, err, partial
238 pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl)
239 remote (string.format ([[
240 data:settimeout(%d)
241 str = string.rep('a', %d)
242 data:send(str)
243 print('server: sleeping for %ds')
244 socket.sleep(%d)
245 print('server: woke up')
246 data:send(str)
247 ]], 2*tm, len, sl, sl))
248 data:settimeout(tm)
249 str, err, partial, elapsed = data:receive(2*len)
250 check_timeout(tm, sl, elapsed, err, "receive", "blocking",
251 string.len(str or partial) == 2*len)
252 end
253
254 ------------------------------------------------------------------------
255 function test_blockingtimeoutsend(len, tm, sl)
256 reconnect()
257 local str, err, total
258 pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl)
259 remote (string.format ([[
260 data:settimeout(%d)
261 str = data:receive(%d)
262 print('server: sleeping for %ds')
263 socket.sleep(%d)
264 print('server: woke up')
265 str = data:receive(%d)
266 ]], 2*tm, len, sl, sl, len))
267 data:settimeout(tm)
268 str = string.rep("a", 2*len)
269 total, err, partial, elapsed = data:send(str)
270 check_timeout(tm, sl, elapsed, err, "send", "blocking",
271 total == 2*len)
272 end
273
274 ------------------------------------------------------------------------
275 function empty_connect()
276 reconnect()
277 if data then data:close() data = nil end
278 remote [[
279 if data then data:close() data = nil end
280 data = server:accept()
281 ]]
282 data, err = socket.connect("", port)
283 if not data then
284 pass("ok")
285 data = socket.connect(host, port)
286 else
287 pass("gethostbyname returns localhost on empty string...")
288 end
289 end
290
291 ------------------------------------------------------------------------
292 function isclosed(c)
293 return c:getfd() == -1 or c:getfd() == (2^32-1)
294 end
295
296 function active_close()
297 reconnect()
298 if isclosed(data) then fail("should not be closed") end
299 data:close()
300 if not isclosed(data) then fail("should be closed") end
301 data = nil
302 local udp = socket.udp()
303 if isclosed(udp) then fail("should not be closed") end
304 udp:close()
305 if not isclosed(udp) then fail("should be closed") end
306 pass("ok")
307 end
308
309 ------------------------------------------------------------------------
310 function test_closed()
311 local back, partial, err
312 local str = 'little string'
313 reconnect()
314 pass("trying read detection")
315 remote (string.format ([[
316 data:send('%s')
317 data:close()
318 data = nil
319 ]], str))
320 -- try to get a line
321 back, err, partial = data:receive()
322 if not err then fail("should have gotten 'closed'.")
323 elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.")
324 elseif str ~= partial then fail("didn't receive partial result.")
325 else pass("graceful 'closed' received") end
326 reconnect()
327 pass("trying write detection")
328 remote [[
329 data:close()
330 data = nil
331 ]]
332 total, err, partial = data:send(string.rep("ugauga", 100000))
333 if not err then
334 pass("failed: output buffer is at least %d bytes long!", total)
335 elseif err ~= "closed" then
336 fail("got '"..err.."' instead of 'closed'.")
337 else
338 pass("graceful 'closed' received after %d bytes were sent", partial)
339 end
340 end
341
342 ------------------------------------------------------------------------
343 function test_selectbugs()
344 local r, s, e = socket.select(nil, nil, 0.1)
345 assert(type(r) == "table" and type(s) == "table" and
346 (e == "timeout" or e == "error"))
347 pass("both nil: ok")
348 local udp = socket.udp()
349 udp:close()
350 r, s, e = socket.select({ udp }, { udp }, 0.1)
351 assert(type(r) == "table" and type(s) == "table" and
352 (e == "timeout" or e == "error"))
353 pass("closed sockets: ok")
354 e = pcall(socket.select, "wrong", 1, 0.1)
355 assert(e == false)
356 e = pcall(socket.select, {}, 1, 0.1)
357 assert(e == false)
358 pass("invalid input: ok")
359 end
360
361 ------------------------------------------------------------------------
362 function accept_timeout()
363 io.stderr:write("accept with timeout (if it hangs, it failed): ")
364 local s, e = socket.bind("*", 0, 0)
365 assert(s, e)
366 local t = socket.gettime()
367 s:settimeout(1)
368 local c, e = s:accept()
369 assert(not c, "should not accept")
370 assert(e == "timeout", string.format("wrong error message (%s)", e))
371 t = socket.gettime() - t
372 assert(t < 2, string.format("took to long to give up (%gs)", t))
373 s:close()
374 pass("good")
375 end
376
377 ------------------------------------------------------------------------
378 function connect_timeout()
379 io.stderr:write("connect with timeout (if it hangs, it failed!): ")
380 local t = socket.gettime()
381 local c, e = socket.tcp()
382 assert(c, e)
383 c:settimeout(0.1)
384 local t = socket.gettime()
385 local r, e = c:connect("10.0.0.1", 81)
386 print(r, e)
387 assert(not r, "should not connect")
388 assert(socket.gettime() - t < 2, "took too long to give up.")
389 c:close()
390 print("ok")
391 end
392
393 ------------------------------------------------------------------------
394 function accept_errors()
395 io.stderr:write("not listening: ")
396 local d, e = socket.bind("*", 0)
397 assert(d, e);
398 local c, e = socket.tcp();
399 assert(c, e);
400 d:setfd(c:getfd())
401 d:settimeout(2)
402 local r, e = d:accept()
403 assert(not r and e)
404 print("ok: ", e)
405 io.stderr:write("not supported: ")
406 local c, e = socket.udp()
407 assert(c, e);
408 d:setfd(c:getfd())
409 local r, e = d:accept()
410 assert(not r and e)
411 print("ok: ", e)
412 end
413
414 ------------------------------------------------------------------------
415 function connect_errors()
416 io.stderr:write("connection refused: ")
417 local c, e = socket.connect("localhost", 1);
418 assert(not c and e)
419 print("ok: ", e)
420 io.stderr:write("host not found: ")
421 local c, e = socket.connect("host.is.invalid", 1);
422 assert(not c and e, e)
423 print("ok: ", e)
424 end
425
426 ------------------------------------------------------------------------
427 function rebind_test()
428 local c = socket.bind("localhost", 0)
429 local i, p = c:getsockname()
430 local s, e = socket.tcp()
431 assert(s, e)
432 s:setoption("reuseaddr", false)
433 r, e = s:bind("localhost", p)
434 assert(not r, "managed to rebind!")
435 assert(e)
436 print("ok: ", e)
437 end
438
439 ------------------------------------------------------------------------
440 function getstats_test()
441 reconnect()
442 local t = 0
443 for i = 1, 25 do
444 local c = math.random(1, 100)
445 remote (string.format ([[
446 str = data:receive(%d)
447 data:send(str)
448 ]], c))
449 data:send(string.rep("a", c))
450 data:receive(c)
451 t = t + c
452 local r, s, a = data:getstats()
453 assert(r == t, "received count failed" .. tostring(r)
454 .. "/" .. tostring(t))
455 assert(s == t, "sent count failed" .. tostring(s)
456 .. "/" .. tostring(t))
457 end
458 print("ok")
459 end
460
461
462 ------------------------------------------------------------------------
463 function test_nonblocking(size)
464 reconnect()
465 print("Testing " .. 2*size .. " bytes")
466 remote(string.format([[
467 data:send(string.rep("a", %d))
468 socket.sleep(0.5)
469 data:send(string.rep("b", %d) .. "\n")
470 ]], size, size))
471 local err = "timeout"
472 local part = ""
473 local str
474 data:settimeout(0)
475 while 1 do
476 str, err, part = data:receive("*l", part)
477 if err ~= "timeout" then break end
478 end
479 assert(str == (string.rep("a", size) .. string.rep("b", size)))
480 reconnect()
481 remote(string.format([[
482 str = data:receive(%d)
483 socket.sleep(0.5)
484 str = data:receive(2*%d, str)
485 data:send(str)
486 ]], size, size))
487 data:settimeout(0)
488 local start = 0
489 while 1 do
490 ret, err, start = data:send(str, start+1)
491 if err ~= "timeout" then break end
492 end
493 data:send("\n")
494 data:settimeout(-1)
495 local back = data:receive(2*size)
496 assert(back == str, "'" .. back .. "' vs '" .. str .. "'")
497 print("ok")
498 end
499
500 ------------------------------------------------------------------------
501 function test_readafterclose()
502 local back, partial, err
503 local str = 'little string'
504 reconnect()
505 pass("trying repeated '*a' pattern")
506 remote (string.format ([[
507 data:send('%s')
508 data:close()
509 data = nil
510 ]], str))
511 back, err, partial = data:receive("*a")
512 assert(back == str, "unexpected data read")
513 back, err, partial = data:receive("*a")
514 assert(back == nil and err == "closed", "should have returned 'closed'")
515 print("ok")
516 reconnect()
517 pass("trying active close before '*a'")
518 remote (string.format ([[
519 data:close()
520 data = nil
521 ]]))
522 data:close()
523 back, err, partial = data:receive("*a")
524 assert(back == nil and err == "closed", "should have returned 'closed'")
525 print("ok")
526 reconnect()
527 pass("trying active close before '*l'")
528 remote (string.format ([[
529 data:close()
530 data = nil
531 ]]))
532 data:close()
533 back, err, partial = data:receive()
534 assert(back == nil and err == "closed", "should have returned 'closed'")
535 print("ok")
536 reconnect()
537 pass("trying active close before raw 1")
538 remote (string.format ([[
539 data:close()
540 data = nil
541 ]]))
542 data:close()
543 back, err, partial = data:receive(1)
544 assert(back == nil and err == "closed", "should have returned 'closed'")
545 print("ok")
546 reconnect()
547 pass("trying active close before raw 0")
548 remote (string.format ([[
549 data:close()
550 data = nil
551 ]]))
552 data:close()
553 back, err, partial = data:receive(0)
554 assert(back == nil and err == "closed", "should have returned 'closed'")
555 print("ok")
556 end
557
558 test("method registration")
559 test_methods(socket.tcp(), {
560 "accept",
561 "bind",
562 "close",
563 "connect",
564 "dirty",
565 "getfd",
566 "getpeername",
567 "getsockname",
568 "getstats",
569 "setstats",
570 "listen",
571 "receive",
572 "send",
573 "setfd",
574 "setoption",
575 "setpeername",
576 "setsockname",
577 "settimeout",
578 "shutdown",
579 })
580
581 test_methods(socket.udp(), {
582 "close",
583 "getpeername",
584 "dirty",
585 "getfd",
586 "getpeername",
587 "getsockname",
588 "receive",
589 "receivefrom",
590 "send",
591 "sendto",
592 "setfd",
593 "setoption",
594 "setpeername",
595 "setsockname",
596 "settimeout"
597 })
598
599 test("testing read after close")
600 test_readafterclose()
601
602 test("select function")
603 test_selectbugs()
604
605 test("connect function")
606 connect_timeout()
607 empty_connect()
608 connect_errors()
609
610 test("rebinding: ")
611 rebind_test()
612
613 test("active close: ")
614 active_close()
615
616 test("closed connection detection: ")
617 test_closed()
618
619 test("accept function: ")
620 accept_timeout()
621 accept_errors()
622
623 test("getstats test")
624 getstats_test()
625
626 test("character line")
627 test_asciiline(1)
628 test_asciiline(17)
629 test_asciiline(200)
630 test_asciiline(4091)
631 test_asciiline(80199)
632 test_asciiline(8000000)
633 test_asciiline(80199)
634 test_asciiline(4091)
635 test_asciiline(200)
636 test_asciiline(17)
637 test_asciiline(1)
638
639 test("mixed patterns")
640 test_mixed(1)
641 test_mixed(17)
642 test_mixed(200)
643 test_mixed(4091)
644 test_mixed(801990)
645 test_mixed(4091)
646 test_mixed(200)
647 test_mixed(17)
648 test_mixed(1)
649
650 test("binary line")
651 test_rawline(1)
652 test_rawline(17)
653 test_rawline(200)
654 test_rawline(4091)
655 test_rawline(80199)
656 test_rawline(8000000)
657 test_rawline(80199)
658 test_rawline(4091)
659 test_rawline(200)
660 test_rawline(17)
661 test_rawline(1)
662
663 test("raw transfer")
664 test_raw(1)
665 test_raw(17)
666 test_raw(200)
667 test_raw(4091)
668 test_raw(80199)
669 test_raw(8000000)
670 test_raw(80199)
671 test_raw(4091)
672 test_raw(200)
673 test_raw(17)
674 test_raw(1)
675
676 test("non-blocking transfer")
677 test_nonblocking(1)
678 test_nonblocking(17)
679 test_nonblocking(200)
680 test_nonblocking(4091)
681 test_nonblocking(80199)
682 test_nonblocking(800000)
683 test_nonblocking(80199)
684 test_nonblocking(4091)
685 test_nonblocking(200)
686 test_nonblocking(17)
687 test_nonblocking(1)
688
689 test("total timeout on send")
690 test_totaltimeoutsend(800091, 1, 3)
691 test_totaltimeoutsend(800091, 2, 3)
692 test_totaltimeoutsend(800091, 5, 2)
693 test_totaltimeoutsend(800091, 3, 1)
694
695 test("total timeout on receive")
696 test_totaltimeoutreceive(800091, 1, 3)
697 test_totaltimeoutreceive(800091, 2, 3)
698 test_totaltimeoutreceive(800091, 3, 2)
699 test_totaltimeoutreceive(800091, 3, 1)
700
701 test("blocking timeout on send")
702 test_blockingtimeoutsend(800091, 1, 3)
703 test_blockingtimeoutsend(800091, 2, 3)
704 test_blockingtimeoutsend(800091, 3, 2)
705 test_blockingtimeoutsend(800091, 3, 1)
706
707 test("blocking timeout on receive")
708 test_blockingtimeoutreceive(800091, 1, 3)
709 test_blockingtimeoutreceive(800091, 2, 3)
710 test_blockingtimeoutreceive(800091, 3, 2)
711 test_blockingtimeoutreceive(800091, 3, 1)
712
713 test(string.format("done in %.2fs", socket.gettime() - start))