1 /* testsock.i
2 * Tests of socket API.
3 */
4 /* Copyright (c) 2015, David H. Munro.
5 * All rights reserved.
6 * This file is part of yorick (http://yorick.sourceforge.net).
7 * Read the accompanying LICENSE file for details.
8 */
9
testsock(port)10 func testsock(port)
11 {
12 listener = socket((port?port:0), accept_cb);
13 write, format="%s\n", "listening - now start client yorick, then type:";
14 write, format="%s\n", "#include \"testsock.i\"";
15 write, format="testclient, %ld;\n", listener.port;
16 }
17
testclient(port,host)18 func testclient(port, host)
19 {
20 sock = socket((host?host:noop(-)), port);
21 n = test_data(*);
22 for (i=1,fail=0 ; i<=n ; ++i) {
23 s = test_data(noop(i));
24 if (i & 1) {
25 write, format="socket client send %ld...", i;
26 if (socksend(sock, s) != sizeof(s)) {
27 close, sock;
28 error, "socket test client died on test "+totxt(i);
29 }
30 write, format="%s\n", "";
31 } else {
32 r = s;
33 r(..) *= 0;
34 write, format="socket client recv %ld...", i;
35 if (sockrecv(sock, r) != sizeof(r)) {
36 close, sock;
37 error, "socket test client died on test "+totxt(i);
38 }
39 write, format="%s\n", "";
40 if (anyof(r != s)) {
41 write, format="WARNING - socket client recv failed on test %ld\n", i;
42 fail += 1;
43 }
44 }
45 }
46 write, format="socket client recv %s...", "final";
47 r = array(0, 10);
48 if (sockrecv(sock, r)!=sizeof(r)/2 || anyof(r(1:5)!=indgen(5))) {
49 write, format="%s\n", "WARNING - socket client recv failed on final test";
50 fail += 1;
51 }
52 write, format="%s\n", "";
53 close, sock;
54 if (fail) error, "socket test client recv failure count: "+totxt(fail);
55 write, format="%s\n", "SUCCESS - socket test client side passed all tests";
56 }
57
58 test_state = save(reset, recv, step, sock, req, irep, imax, fail);
recv(sock)59 func recv(sock) /* recv callback, do as little as possible */
60 {
61 if (catch(-1)) {
62 write, "FATAL - socket server recv callback closing sock";
63 close, sock;
64 return;
65 }
66 sockrecv, sock, use(req);
67 after, 0., test_state, "step"; /* defer most work */
68 }
reset(s)69 func reset(s)
70 {
71 use, sock, req, irep, imax, fail;
72 sock = s
73 req = test_data(1);
74 req(..) = 0;
75 irep = 2;
76 imax = test_data(*);
77 fail = 0;
78 write, format="\n%s\n", "connection established, listener shut down";
79 }
80 func step
81 {
82 use, sock, req, irep, imax, fail;
83 write, format="socket server recv %ld\n", irep-1;
84 if (anyof(test_data(irep-1) != req)) {
85 write, format="WARNING - socket server recv failed on test %ld\n", irep-1;
86 fail += 1;
87 }
88 if (irep <= imax) {
89 write, format="socket server send %ld...", irep;
90 socksend, sock, test_data(noop(irep));
91 write, format="%s\n", "";
92 }
93 if (irep < imax) { /* at least one more recv to wait for */
94 req = test_data(irep+1);
95 irep += 2;
96 return;
97 }
98 /* send final partial message to client */
99 write, format="socket server send %s...", "final";
100 socksend, sock, indgen(5);
101 write, format="%s\n", "";
102 close, sock;
103 req = [];
104 if (fail) error, "socket test server recv failure count: "+totxt(fail);
105 write, format="%s\n", "SUCCESS - socket test server side passed all tests";
106 maybe_prompt; /* why doesn't this work? */
107 write, format="%s", "> ";
108 }
109 sock = req = irep = imax = fail = [];
110 test_state = restore(test_state);
111
112 recv_cb = closure(test_state, "recv");
accept_cb(sock)113 func accept_cb(sock) {
114 test_state, reset, sock(recv_cb);
115 close, sock;
116 }
117
118 x = indgen(0:1738);
119 test_data = save(,x, ,char(x), ,short(x(::-1)+x(-,)), ,int(x-x(-,)),
120 ,float(x-31), ,double(x*x(-,)), ,(x-51)-1i*(x-432));
121