aboutsummaryrefslogtreecommitdiff
path: root/test/testclnt.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/testclnt.lua')
-rw-r--r--test/testclnt.lua195
1 files changed, 195 insertions, 0 deletions
diff --git a/test/testclnt.lua b/test/testclnt.lua
index 170e187..bbe48bb 100644
--- a/test/testclnt.lua
+++ b/test/testclnt.lua
@@ -619,6 +619,198 @@ remote([[
619end 619end
620 620
621------------------------------------------------------------------------ 621------------------------------------------------------------------------
622function test_maxsize()
623 -- Group A: argument errors, raised before any I/O
624 reconnect()
625 printf("argument errors: ")
626 -- bounds pre-implementation calls (where arg 4 is silently dropped and
627 -- these become real, otherwise-unbounded blocking reads on an idle
628 -- socket) so a meaningful failure doesn't hang the suite
629 data:settimeout(0.2)
630 local ok
631 ok = pcall(data.receive, data, "*l", nil, 0)
632 assert(not ok, "A1 failed: maxsize=0 should raise")
633 ok = pcall(data.receive, data, "*l", nil, -1)
634 assert(not ok, "A2 failed: maxsize=-1 should raise")
635 ok = pcall(data.receive, data, "*l", nil, "abc")
636 assert(not ok, "A3 failed: non-number maxsize should raise")
637 ok = pcall(data.receive, data, "*l", string.rep("x", 10), 10)
638 assert(not ok, "A4 failed: #prefix == maxsize should raise")
639 ok = pcall(data.receive, data, "*l", string.rep("x", 11), 10)
640 assert(not ok, "A5 failed: #prefix > maxsize should raise")
641 ok = pcall(data.receive, data, 100, nil, 50)
642 assert(not ok, "A6 failed: wanted > maxsize should raise")
643 ok = pcall(data.receive, data, "*l", nil, math.huge)
644 assert(not ok, "A7 failed: maxsize=math.huge should raise (size_t overflow)")
645 ok = pcall(data.receive, data, math.huge)
646 assert(not ok, "A8 failed: wanted=math.huge should raise (size_t overflow)")
647 data:settimeout(0.1)
648 ok = pcall(data.receive, data, 50, nil, 100)
649 assert(ok, "A9 failed: wanted <= maxsize should not raise")
650 data:settimeout(-1)
651 remote [[ data:send('intact\n') ]]
652 local line, err = data:receive("*l", nil, 100)
653 assert(line == "intact",
654 "A10 failed: socket touched by a failed argcheck (err=" ..
655 tostring(err) .. ")")
656 pass("ok")
657
658 -- Group B: *l boundary
659 reconnect()
660 printf("*l boundary: ")
661 remote [[ data:send('hello\n') ]]
662 local d, e, p = data:receive("*l", nil, 100)
663 assert(d == "hello" and e == nil, "B1 failed")
664
665 remote(string.format([[data:send(string.rep('a',%d) .. '\n')]], 100))
666 d, e = data:receive("*l", nil, 100)
667 assert(d == string.rep("a", 100) and e == nil,
668 "B2 failed: exact-budget line should succeed")
669
670 remote(string.format([[data:send(string.rep('a',%d) .. '\n')]], 101))
671 d, e, p = data:receive("*l", nil, 100)
672 assert(d == nil and e == "oversized" and p == string.rep("a", 100),
673 "B3 failed: one-over-budget should be oversized")
674 d, e = data:receive("*l", nil, 100)
675 assert(d == "a" and e == nil,
676 "B3 failed: leftover byte and terminator should still be there")
677
678 remote(string.format([[data:send(string.rep('\r',%d) .. string.rep('a',%d) .. '\n')]], 50, 100))
679 d, e = data:receive("*l", nil, 100)
680 assert(d == string.rep("a", 100) and e == nil, "B4 failed: CRs must not count")
681
682 remote(string.format([[data:send(string.rep('a',%d) .. '\r\n')]], 100))
683 d, e = data:receive("*l", nil, 100)
684 assert(d == string.rep("a", 100) and e == nil, "B5 failed: CRLF at boundary")
685 pass("ok")
686
687 remote(string.format([[data:send(string.rep('a',%d) .. '\n')]], 101))
688 d, e, p = data:receive("*l", nil, 100)
689 assert(d == nil and e == "oversized" and p == string.rep("a", 100),
690 "B6 failed: one-over-budget should be oversized")
691 d, e = data:receive("*l", p, 150) -- increase limit, try again with prefix
692 assert(d == string.rep("a", 101) and e == nil,
693 "B6 failed: leftover byte and terminator should still be there")
694
695 -- Group C: *l and I1 (timeout/close at the cap)
696 reconnect()
697 printf("I1 (timeout/closed at the cap): ")
698 remote(string.format([[data:send(string.rep('a',%d))]], 50))
699 data:settimeout(0.5)
700 d, e, p = data:receive("*l", nil, 100)
701 assert(d == nil and e == "timeout", "C1 failed: expected timeout below cap")
702 assert(#p < 100, "C1 failed: timeout partial must be strictly < maxsize")
703 ok = pcall(data.receive, data, "*l", p, 100)
704 assert(ok, "C1 failed: retry with prefix=partial, same maxsize must not raise")
705
706 reconnect()
707 remote(string.format([[data:send(string.rep('a',%d))]], 100))
708 data:settimeout(0.5)
709 d, e, p = data:receive("*l", nil, 100)
710 assert(e == "oversized" and #p == 100,
711 "C2 failed: exactly-at-cap timeout must be oversized, got " .. tostring(e))
712
713 reconnect()
714 remote(string.format([[data:send(string.rep('a',%d)) data:close() data = nil]], 100))
715 d, e, p = data:receive("*l", nil, 100)
716 assert(e == "oversized" and #p == 100,
717 "C3 failed: exactly-at-cap close must be oversized, got " .. tostring(e))
718 pass("ok")
719
720 -- Group D: drain idiom
721 -- 5030 (not a multiple of the 100 cap) so the boundary of the 50th
722 -- oversized chunk doesn't land exactly on the '\n': when it does, the
723 -- terminator check wins over the cap check (by design -- see B2/I1) and
724 -- the would-be 50th oversized chunk instead succeeds outright.
725 reconnect()
726 printf("drain idiom: ")
727 remote(string.format([[data:send(string.rep('x',%d) .. '\n' .. 'next\n')]], 5030))
728 local iterations = 0
729 repeat
730 d, e, p = data:receive("*l", "", 100)
731 if e == "oversized" then
732 assert(#p == 100, "D1 failed: oversized partial length " .. #p)
733 iterations = iterations + 1
734 end
735 until e ~= "oversized"
736 assert(iterations == 50,
737 "D1 failed: expected 50 oversized iterations, got " .. iterations)
738 assert(d == string.rep("x", 30) and e == nil, "D1 failed: final call should succeed")
739 local nextline = data:receive("*l")
740 assert(nextline == "next", "D1 failed: stream misaligned, got " .. tostring(nextline))
741 pass("ok")
742
743 -- Group E: *a
744 reconnect()
745 printf("*a boundary: ")
746 remote [[ data:send('abc') data:close() data = nil ]]
747 d, e = data:receive("*a", nil, 100)
748 assert(d == "abc" and e == nil, "E1 failed")
749
750 reconnect()
751 remote(string.format([[data:send(string.rep('a',%d)) data:close() data = nil]], 100))
752 d, e = data:receive("*a", nil, 100)
753 assert(d == string.rep("a", 100) and e == nil,
754 "E2 failed: completion should beat the cap")
755
756 reconnect()
757 remote(string.format([[data:send(string.rep('a',%d)) data:close() data = nil]], 250))
758 d, e, p = data:receive("*a", "", 100)
759 assert(e == "oversized" and #p == 100, "E3a failed: first chunk")
760 d, e, p = data:receive("*a", "", 100)
761 assert(e == "oversized" and #p == 100, "E3a failed: second chunk")
762 d, e = data:receive("*a", "", 100)
763 assert(d == string.rep("a", 50) and e == nil, "E3a failed: final chunk")
764
765 reconnect()
766 remote(string.format([[data:send(string.rep('a',%d)) data:close() data = nil]], 250))
767 d, e, p = data:receive("*a", "", 100)
768 assert(e == "oversized" and #p == 100, "E3b failed: first chunk")
769 d, e, p = data:receive("*a", p, 200) -- increase maxsize, try again with prefix
770 assert(e == "oversized" and #p == 200, "E3b failed: second chunk")
771 d, e = data:receive("*a", p, 300) -- increase maxsize, try again with prefix
772 assert(d == string.rep("a", 250) and e == nil, "E3b failed: final chunk")
773
774 reconnect()
775 remote(string.format([[data:send(string.rep('a',%d))]], 100))
776 data:settimeout(0.3)
777 d, e, p = data:receive("*a", nil, 100)
778 assert(e == "oversized" and #p == 100,
779 "E4 failed: expected oversized not timeout, got " .. tostring(e))
780
781 reconnect()
782 remote(string.format([[data:send(string.rep('a',%d))]], 50))
783 data:settimeout(0.3)
784 d, e, p = data:receive("*a", nil, 100)
785 assert(e == "timeout" and #p < 100, "E5 failed")
786 pass("ok")
787
788 -- Group F: numeric pattern (recvraw untouched)
789 reconnect()
790 printf("numeric pattern (recvraw unchanged): ")
791 remote(string.format([[data:send(string.rep('a',%d))]], 50))
792 d, e = data:receive(50, nil, 100)
793 assert(d == string.rep("a", 50) and e == nil, "F1 failed")
794
795 reconnect()
796 remote(string.format([[data:send(string.rep('a',%d))]], 25))
797 d, e = data:receive(50, string.rep("p", 25), 100)
798 assert(e == nil and #d == 50, "F2 failed")
799 pass("ok")
800
801 -- Group G: no-maxsize regression snapshot
802 reconnect()
803 printf("no-maxsize regression: ")
804 remote(string.format([[data:send(string.rep('a',%d) .. '\n')]], 5000))
805 d, e = data:receive("*l")
806 assert(d == string.rep("a", 5000) and e == nil, "G2 failed: plain *l")
807 remote(string.format([[data:send(string.rep('a',%d) .. '\n')]], 5000))
808 d, e = data:receive("*l", "")
809 assert(d == string.rep("a", 5000) and e == nil, "G2 failed: *l with prefix")
810 pass("ok")
811end
812
813------------------------------------------------------------------------
622test("method registration") 814test("method registration")
623 815
624local tcp_methods = { 816local tcp_methods = {
@@ -796,6 +988,9 @@ test_blockingtimeoutreceive(800091, 2, 3)
796test_blockingtimeoutreceive(800091, 3, 2) 988test_blockingtimeoutreceive(800091, 3, 2)
797test_blockingtimeoutreceive(800091, 3, 1) 989test_blockingtimeoutreceive(800091, 3, 1)
798 990
991test("receive maxsize")
992test_maxsize()
993
799test("shutting server down") 994test("shutting server down")
800reconnect() 995reconnect()
801remote("os.exit()") 996remote("os.exit()")