beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / luasocket / test / testclnt.lua
blob8acb3d04bacdd7a8bb33490189496e2be9fa6925
1 local socket = require"socket"
3 host = host or "localhost"
4 port = port or "8383"
6 function printf(...)
7 io.stderr:write(string.format(...))
8 end
10 function pass(...)
11 printf(...)
12 io.stderr:write("\n")
13 end
15 function fail(...)
16 io.stderr:write("ERROR: ")
17 printf(...)
18 io.stderr:write("!\n")
19 os.exit()
20 end
22 function warn(...)
23 local s = string.format(...)
24 io.stderr:write("WARNING: ", s, "\n")
25 end
27 function remote(...)
28 local s = string.format(...)
29 s = string.gsub(s, "\n", ";")
30 s = string.gsub(s, "%s+", " ")
31 s = string.gsub(s, "^%s*", "")
32 control:send(s .. "\n")
33 control:receive()
34 end
36 function test(test)
37 io.stderr:write("----------------------------------------------\n",
38 "testing: ", test, "\n",
39 "----------------------------------------------\n")
40 end
42 function check_timeout(tm, sl, elapsed, err, opp, mode, alldone)
43 if tm < sl then
44 if opp == "send" then
45 if not err then warn("must be buffered")
46 elseif err == "timeout" then pass("proper timeout")
47 else fail("unexpected error '%s'", err) end
48 else
49 if err ~= "timeout" then fail("should have timed out")
50 else pass("proper timeout") end
51 end
52 else
53 if mode == "total" then
54 if elapsed > tm then
55 if err ~= "timeout" then fail("should have timed out")
56 else pass("proper timeout") end
57 elseif elapsed < tm then
58 if err then fail(err)
59 else pass("ok") end
60 else
61 if alldone then
62 if err then fail("unexpected error '%s'", err)
63 else pass("ok") end
64 else
65 if err ~= "timeout" then fail(err)
66 else pass("proper timeoutk") end
67 end
68 end
69 else
70 if err then fail(err)
71 else pass("ok") end
72 end
73 end
74 end
76 if not socket._DEBUG then
77 fail("Please define LUASOCKET_DEBUG and recompile LuaSocket")
78 end
80 io.stderr:write("----------------------------------------------\n",
81 "LuaSocket Test Procedures\n",
82 "----------------------------------------------\n")
84 start = socket.gettime()
86 function reconnect()
87 if data then data:close() end
88 remote [[
89 if data then data:close() data = nil end
90 data = server:accept()
91 data:setoption("tcp-nodelay", true)
93 data, err = socket.connect(host, port)
94 if not data then fail(err) end
95 data:setoption("tcp-nodelay", true)
96 end
98 printf("attempting control connection...")
99 control, err = socket.connect(host, port)
100 if err then fail(err)
101 else pass("connected!") end
102 control:setoption("tcp-nodelay", true)
104 ------------------------------------------------------------------------
105 function test_methods(sock, methods)
106 for _, v in pairs(methods) do
107 if type(sock[v]) ~= "function" then
108 fail(sock.class .. " method '" .. v .. "' not registered")
111 pass(sock.class .. " methods are ok")
114 ------------------------------------------------------------------------
115 function test_mixed(len)
116 reconnect()
117 io.stderr:write("length " .. len .. ": ")
118 local inter = math.ceil(len/4)
119 local p1 = "unix " .. string.rep("x", inter) .. "line\n"
120 local p2 = "dos " .. string.rep("y", inter) .. "line\r\n"
121 local p3 = "raw " .. string.rep("z", inter) .. "bytes"
122 local p4 = "end" .. string.rep("w", inter) .. "bytes"
123 local bp1, bp2, bp3, bp4
124 remote (string.format("str = data:receive(%d)",
125 string.len(p1)+string.len(p2)+string.len(p3)+string.len(p4)))
126 sent, err = data:send(p1..p2..p3..p4)
127 if err then fail(err) end
128 remote "data:send(str); data:close()"
129 bp1, err = data:receive()
130 if err then fail(err) end
131 bp2, err = data:receive()
132 if err then fail(err) end
133 bp3, err = data:receive(string.len(p3))
134 if err then fail(err) end
135 bp4, err = data:receive("*a")
136 if err then fail(err) end
137 if bp1.."\n" == p1 and bp2.."\r\n" == p2 and bp3 == p3 and bp4 == p4 then
138 pass("patterns match")
139 else fail("patterns don't match") end
142 ------------------------------------------------------------------------
143 if not math.mod then
144 math.mod = math.fmod
146 function test_asciiline(len)
147 reconnect()
148 io.stderr:write("length " .. len .. ": ")
149 local str, str10, back, err
150 str = string.rep("x", math.mod(len, 10))
151 str10 = string.rep("aZb.c#dAe?", math.floor(len/10))
152 str = str .. str10
153 remote "str = data:receive()"
154 sent, err = data:send(str.."\n")
155 if err then fail(err) end
156 remote "data:send(str ..'\\n')"
157 back, err = data:receive()
158 if err then fail(err) end
159 if back == str then pass("lines match")
160 else fail("lines don't match") end
163 ------------------------------------------------------------------------
164 function test_rawline(len)
165 reconnect()
166 io.stderr:write("length " .. len .. ": ")
167 local str, str10, back, err
168 str = string.rep(string.char(47), math.mod(len, 10))
169 str10 = string.rep(string.char(120,21,77,4,5,0,7,36,44,100),
170 math.floor(len/10))
171 str = str .. str10
172 remote "str = data:receive()"
173 sent, err = data:send(str.."\n")
174 if err then fail(err) end
175 remote "data:send(str..'\\n')"
176 back, err = data:receive()
177 if err then fail(err) end
178 if back == str then pass("lines match")
179 else fail("lines don't match") end
182 ------------------------------------------------------------------------
183 function test_raw(len)
184 reconnect()
185 io.stderr:write("length " .. len .. ": ")
186 local half = math.floor(len/2)
187 local s1, s2, back, err
188 s1 = string.rep("x", half)
189 s2 = string.rep("y", len-half)
190 remote (string.format("str = data:receive(%d)", len))
191 sent, err = data:send(s1)
192 if err then fail(err) end
193 sent, err = data:send(s2)
194 if err then fail(err) end
195 remote "data:send(str)"
196 back, err = data:receive(len)
197 if err then fail(err) end
198 if back == s1..s2 then pass("blocks match")
199 else fail("blocks don't match") end
202 ------------------------------------------------------------------------
203 function test_totaltimeoutreceive(len, tm, sl)
204 reconnect()
205 local str, err, partial
206 printf("%d bytes, %ds total timeout, %ds pause: ", len, tm, sl)
207 remote (string.format ([[
208 data:settimeout(%d)
209 str = string.rep('a', %d)
210 data:send(str)
211 print('server: sleeping for %ds')
212 socket.sleep(%d)
213 print('server: woke up')
214 data:send(str)
215 ]], 2*tm, len, sl, sl))
216 data:settimeout(tm, "total")
217 local t = socket.gettime()
218 str, err, partial, elapsed = data:receive(2*len)
219 check_timeout(tm, sl, elapsed, err, "receive", "total",
220 string.len(str or partial) == 2*len)
223 ------------------------------------------------------------------------
224 function test_totaltimeoutsend(len, tm, sl)
225 reconnect()
226 local str, err, total
227 printf("%d bytes, %ds total timeout, %ds pause: ", len, tm, sl)
228 remote (string.format ([[
229 data:settimeout(%d)
230 str = data:receive(%d)
231 print('server: sleeping for %ds')
232 socket.sleep(%d)
233 print('server: woke up')
234 str = data:receive(%d)
235 ]], 2*tm, len, sl, sl, len))
236 data:settimeout(tm, "total")
237 str = string.rep("a", 2*len)
238 total, err, partial, elapsed = data:send(str)
239 check_timeout(tm, sl, elapsed, err, "send", "total",
240 total == 2*len)
243 ------------------------------------------------------------------------
244 function test_blockingtimeoutreceive(len, tm, sl)
245 reconnect()
246 local str, err, partial
247 printf("%d bytes, %ds blocking timeout, %ds pause: ", len, tm, sl)
248 remote (string.format ([[
249 data:settimeout(%d)
250 str = string.rep('a', %d)
251 data:send(str)
252 print('server: sleeping for %ds')
253 socket.sleep(%d)
254 print('server: woke up')
255 data:send(str)
256 ]], 2*tm, len, sl, sl))
257 data:settimeout(tm)
258 str, err, partial, elapsed = data:receive(2*len)
259 check_timeout(tm, sl, elapsed, err, "receive", "blocking",
260 string.len(str or partial) == 2*len)
263 ------------------------------------------------------------------------
264 function test_blockingtimeoutsend(len, tm, sl)
265 reconnect()
266 local str, err, total
267 printf("%d bytes, %ds blocking timeout, %ds pause: ", len, tm, sl)
268 remote (string.format ([[
269 data:settimeout(%d)
270 str = data:receive(%d)
271 print('server: sleeping for %ds')
272 socket.sleep(%d)
273 print('server: woke up')
274 str = data:receive(%d)
275 ]], 2*tm, len, sl, sl, len))
276 data:settimeout(tm)
277 str = string.rep("a", 2*len)
278 total, err, partial, elapsed = data:send(str)
279 check_timeout(tm, sl, elapsed, err, "send", "blocking",
280 total == 2*len)
283 ------------------------------------------------------------------------
284 function empty_connect()
285 printf("empty connect: ")
286 reconnect()
287 if data then data:close() data = nil end
288 remote [[
289 if data then data:close() data = nil end
290 data = server:accept()
292 data, err = socket.connect("", port)
293 if not data then
294 pass("ok")
295 data = socket.connect(host, port)
296 else
297 pass("gethostbyname returns localhost on empty string...")
301 ------------------------------------------------------------------------
302 function isclosed(c)
303 return c:getfd() == -1 or c:getfd() == (2^32-1)
306 function active_close()
307 reconnect()
308 if isclosed(data) then fail("should not be closed") end
309 data:close()
310 if not isclosed(data) then fail("should be closed") end
311 data = nil
312 local udp = socket.udp()
313 if isclosed(udp) then fail("should not be closed") end
314 udp:close()
315 if not isclosed(udp) then fail("should be closed") end
316 pass("ok")
319 ------------------------------------------------------------------------
320 function test_closed()
321 local back, partial, err
322 local str = 'little string'
323 reconnect()
324 printf("trying read detection: ")
325 remote (string.format ([[
326 data:send('%s')
327 data:close()
328 data = nil
329 ]], str))
330 -- try to get a line
331 back, err, partial = data:receive()
332 if not err then fail("should have gotten 'closed'.")
333 elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.")
334 elseif str ~= partial then fail("didn't receive partial result.")
335 else pass("graceful 'closed' received") end
336 reconnect()
337 printf("trying write detection: ")
338 remote [[
339 data:close()
340 data = nil
342 total, err, partial = data:send(string.rep("ugauga", 100000))
343 if not err then
344 pass("failed: output buffer is at least %d bytes long!", total)
345 elseif err ~= "closed" then
346 fail("got '"..err.."' instead of 'closed'.")
347 else
348 pass("graceful 'closed' received after %d bytes were sent", partial)
352 ------------------------------------------------------------------------
353 function test_selectbugs()
354 local r, s, e = socket.select(nil, nil, 0.1)
355 assert(type(r) == "table" and type(s) == "table" and
356 (e == "timeout" or e == "error"))
357 pass("both nil: ok")
358 local udp = socket.udp()
359 udp:close()
360 r, s, e = socket.select({ udp }, { udp }, 0.1)
361 assert(type(r) == "table" and type(s) == "table" and
362 (e == "timeout" or e == "error"))
363 pass("closed sockets: ok")
364 e = pcall(socket.select, "wrong", 1, 0.1)
365 assert(e == false, tostring(e))
366 e = pcall(socket.select, {}, 1, 0.1)
367 assert(e == false, tostring(e))
368 pass("invalid input: ok")
369 local toomany = {}
370 for i = 1, socket._SETSIZE+1 do
371 toomany[#toomany+1] = socket.udp()
373 if #toomany > socket._SETSIZE then
374 local e = pcall(socket.select, toomany, nil, 0.1)
375 assert(e == false, tostring(e))
376 pass("too many sockets (" .. #toomany .. "): ok")
377 else
378 pass("unable to create enough sockets (max was "..#toomany..")")
379 pass("try using ulimit")
381 for _, c in ipairs(toomany) do c:close() end
384 ------------------------------------------------------------------------
385 function accept_timeout()
386 printf("accept with timeout (if it hangs, it failed): ")
387 local s, e = socket.bind("*", 0, 0)
388 assert(s, e)
389 local t = socket.gettime()
390 s:settimeout(1)
391 local c, e = s:accept()
392 assert(not c, "should not accept")
393 assert(e == "timeout", string.format("wrong error message (%s)", e))
394 t = socket.gettime() - t
395 assert(t < 2, string.format("took to long to give up (%gs)", t))
396 s:close()
397 pass("good")
400 ------------------------------------------------------------------------
401 function connect_timeout()
402 printf("connect with timeout (if it hangs, it failed!): ")
403 local t = socket.gettime()
404 local c, e = socket.tcp()
405 assert(c, e)
406 c:settimeout(0.1)
407 local t = socket.gettime()
408 local r, e = c:connect("10.0.0.1", 81)
409 assert(not r, "should not connect")
410 assert(socket.gettime() - t < 2, "took too long to give up.")
411 c:close()
412 pass("ok")
415 ------------------------------------------------------------------------
416 function accept_errors()
417 printf("not listening: ")
418 local d, e = socket.bind("*", 0)
419 assert(d, e);
420 local c, e = socket.tcp();
421 assert(c, e);
422 d:setfd(c:getfd())
423 d:settimeout(2)
424 local r, e = d:accept()
425 assert(not r and e)
426 pass("ok")
427 printf("not supported: ")
428 local c, e = socket.udp()
429 assert(c, e);
430 d:setfd(c:getfd())
431 local r, e = d:accept()
432 assert(not r and e)
433 pass("ok")
436 ------------------------------------------------------------------------
437 function connect_errors()
438 printf("connection refused: ")
439 local c, e = socket.connect("localhost", 1);
440 assert(not c and e)
441 pass("ok")
442 printf("host not found: ")
443 local c, e = socket.connect("host.is.invalid", 1);
444 assert(not c and e, e)
445 pass("ok")
448 ------------------------------------------------------------------------
449 function rebind_test()
450 --local c ,c1 = socket.bind("localhost", 0)
451 local c ,c1 = socket.bind("127.0.0.1", 0)
452 if not c then pass ("failed to bind! " .. tostring(c) .. ' ' .. tostring(c1)) return end
453 assert(c,c1)
455 local i, p = c:getsockname()
456 local s, e = socket.tcp()
457 assert(s, e)
458 s:setoption("reuseaddr", false)
459 r, e = s:bind("localhost", p)
460 assert(not r, "managed to rebind!")
461 assert(e)
462 pass("ok")
465 ------------------------------------------------------------------------
466 function getstats_test()
467 reconnect()
468 local t = 0
469 for i = 1, 25 do
470 local c = math.random(1, 100)
471 remote (string.format ([[
472 str = data:receive(%d)
473 data:send(str)
474 ]], c))
475 data:send(string.rep("a", c))
476 data:receive(c)
477 t = t + c
478 local r, s, a = data:getstats()
479 assert(r == t, "received count failed" .. tostring(r)
480 .. "/" .. tostring(t))
481 assert(s == t, "sent count failed" .. tostring(s)
482 .. "/" .. tostring(t))
484 pass("ok")
488 ------------------------------------------------------------------------
489 function test_nonblocking(size)
490 reconnect()
491 printf("testing " .. 2*size .. " bytes: ")
492 remote(string.format([[
493 data:send(string.rep("a", %d))
494 socket.sleep(0.5)
495 data:send(string.rep("b", %d) .. "\n")
496 ]], size, size))
497 local err = "timeout"
498 local part = ""
499 local str
500 data:settimeout(0)
501 while 1 do
502 str, err, part = data:receive("*l", part)
503 if err ~= "timeout" then break end
505 assert(str == (string.rep("a", size) .. string.rep("b", size)))
506 reconnect()
507 remote(string.format([[
508 str = data:receive(%d)
509 socket.sleep(0.5)
510 str = data:receive(2*%d, str)
511 data:send(str)
512 ]], size, size))
513 data:settimeout(0)
514 local start = 0
515 while 1 do
516 ret, err, start = data:send(str, start+1)
517 if err ~= "timeout" then break end
519 data:send("\n")
520 data:settimeout(-1)
521 local back = data:receive(2*size)
522 assert(back == str, "'" .. back .. "' vs '" .. str .. "'")
523 pass("ok")
526 ------------------------------------------------------------------------
527 function test_readafterclose()
528 local back, partial, err
529 local str = 'little string'
530 reconnect()
531 printf("trying repeated '*a' pattern")
532 remote (string.format ([[
533 data:send('%s')
534 data:close()
535 data = nil
536 ]], str))
537 back, err, partial = data:receive("*a")
538 assert(back == str, "unexpected data read")
539 back, err, partial = data:receive("*a")
540 assert(back == nil and err == "closed", "should have returned 'closed'")
541 pass("ok")
542 reconnect()
543 printf("trying active close before '*a'")
544 remote (string.format ([[
545 data:close()
546 data = nil
547 ]]))
548 data:close()
549 back, err, partial = data:receive("*a")
550 assert(back == nil and err == "closed", "should have returned 'closed'")
551 pass("ok")
552 reconnect()
553 printf("trying active close before '*l'")
554 remote (string.format ([[
555 data:close()
556 data = nil
557 ]]))
558 data:close()
559 back, err, partial = data:receive()
560 assert(back == nil and err == "closed", "should have returned 'closed'")
561 pass("ok")
562 reconnect()
563 printf("trying active close before raw 1")
564 remote (string.format ([[
565 data:close()
566 data = nil
567 ]]))
568 data:close()
569 back, err, partial = data:receive(1)
570 assert(back == nil and err == "closed", "should have returned 'closed'")
571 pass("ok")
572 reconnect()
573 printf("trying active close before raw 0")
574 remote (string.format ([[
575 data:close()
576 data = nil
577 ]]))
578 data:close()
579 back, err, partial = data:receive(0)
580 assert(back == nil and err == "closed", "should have returned 'closed'")
581 pass("ok")
584 ------------------------------------------------------------------------
585 function test_writeafterclose()
586 local str = 'little string'
587 reconnect()
588 remote (string.format ([[
589 data:close()
590 data = nil
591 ]]))
592 local sent, err, errsent
593 while not err do
594 sent, err, errsent, time = data:send(str)
596 assert(err == "closed", "should have returned 'closed'")
597 pass("ok")
600 ------------------------------------------------------------------------
602 function test_partialrecv()
603 local str = 'little string'
604 reconnect()
605 remote([[
606 data:send("7890")
608 data:settimeout(1)
609 back, err = data:receive(10, "123456")
610 assert(back == "1234567890", "failed on exact mixed length")
611 back, err = data:receive(8, "87654321")
612 assert(back == "87654321", "failed on exact length")
613 back, err = data:receive(4, "87654321")
614 assert(back == "87654321", "failed on smaller length")
615 pass("ok")
618 ------------------------------------------------------------------------
619 test("method registration")
621 local tcp_methods = {
622 "accept",
623 "bind",
624 "close",
625 "connect",
626 "dirty",
627 "getfamily",
628 "getfd",
629 "getoption",
630 "getpeername",
631 "getsockname",
632 "getstats",
633 "setstats",
634 "listen",
635 "receive",
636 "send",
637 "setfd",
638 "setoption",
639 "setpeername",
640 "setsockname",
641 "settimeout",
642 "shutdown",
644 test_methods(socket.tcp(), tcp_methods)
645 test_methods(socket.tcp6(), tcp_methods)
647 local udp_methods = {
648 "close",
649 "dirty",
650 "getfamily",
651 "getfd",
652 "getoption",
653 "getpeername",
654 "getsockname",
655 "receive",
656 "receivefrom",
657 "send",
658 "sendto",
659 "setfd",
660 "setoption",
661 "setpeername",
662 "setsockname",
663 "settimeout"
667 ------------------------------------------------------------------------
668 test_methods(socket.udp(), udp_methods)
669 test_methods(socket.udp6(), udp_methods)
671 test("partial receive")
672 test_partialrecv()
674 test("select function")
675 test_selectbugs()
677 test("read after close")
678 test_readafterclose()
680 test("write after close")
681 test_writeafterclose()
683 test("connect function")
684 connect_timeout()
685 empty_connect()
686 connect_errors()
688 test("rebinding: ")
689 rebind_test()
691 test("active close: ")
692 active_close()
694 test("closed connection detection: ")
695 test_closed()
697 test("accept function: ")
698 accept_timeout()
699 accept_errors()
701 test("getstats test")
702 getstats_test()
704 test("character line")
705 test_asciiline(1)
706 test_asciiline(17)
707 test_asciiline(200)
708 test_asciiline(4091)
709 test_asciiline(80199)
710 test_asciiline(8000000)
711 test_asciiline(80199)
712 test_asciiline(4091)
713 test_asciiline(200)
714 test_asciiline(17)
715 test_asciiline(1)
717 test("mixed patterns")
718 test_mixed(1)
719 test_mixed(17)
720 test_mixed(200)
721 test_mixed(4091)
722 test_mixed(801990)
723 test_mixed(4091)
724 test_mixed(200)
725 test_mixed(17)
726 test_mixed(1)
728 test("binary line")
729 test_rawline(1)
730 test_rawline(17)
731 test_rawline(200)
732 test_rawline(4091)
733 test_rawline(80199)
734 test_rawline(8000000)
735 test_rawline(80199)
736 test_rawline(4091)
737 test_rawline(200)
738 test_rawline(17)
739 test_rawline(1)
741 test("raw transfer")
742 test_raw(1)
743 test_raw(17)
744 test_raw(200)
745 test_raw(4091)
746 test_raw(80199)
747 test_raw(8000000)
748 test_raw(80199)
749 test_raw(4091)
750 test_raw(200)
751 test_raw(17)
752 test_raw(1)
754 test("non-blocking transfer")
755 test_nonblocking(1)
756 test_nonblocking(17)
757 test_nonblocking(200)
758 test_nonblocking(4091)
759 test_nonblocking(80199)
760 test_nonblocking(800000)
761 test_nonblocking(80199)
762 test_nonblocking(4091)
763 test_nonblocking(200)
764 test_nonblocking(17)
765 test_nonblocking(1)
767 test("total timeout on send")
768 test_totaltimeoutsend(800091, 1, 3)
769 test_totaltimeoutsend(800091, 2, 3)
770 test_totaltimeoutsend(800091, 5, 2)
771 test_totaltimeoutsend(800091, 3, 1)
773 test("total timeout on receive")
774 test_totaltimeoutreceive(800091, 1, 3)
775 test_totaltimeoutreceive(800091, 2, 3)
776 test_totaltimeoutreceive(800091, 3, 2)
777 test_totaltimeoutreceive(800091, 3, 1)
779 test("blocking timeout on send")
780 test_blockingtimeoutsend(800091, 1, 3)
781 test_blockingtimeoutsend(800091, 2, 3)
782 test_blockingtimeoutsend(800091, 3, 2)
783 test_blockingtimeoutsend(800091, 3, 1)
785 test("blocking timeout on receive")
786 test_blockingtimeoutreceive(800091, 1, 3)
787 test_blockingtimeoutreceive(800091, 2, 3)
788 test_blockingtimeoutreceive(800091, 3, 2)
789 test_blockingtimeoutreceive(800091, 3, 1)
791 test("shutting server down")
792 reconnect()
793 remote("os.exit()")
795 test(string.format("done in %.2fs", socket.gettime() - start))