1 | import io |
2 | import net |
3 | import strings |
4 | |
5 | const ( |
6 | server_port = ':22443' |
7 | ) |
8 | |
9 | fn accept(mut server net.TcpListener, c chan &net.TcpConn) { |
10 | c <- server.accept() or { panic(err) } |
11 | } |
12 | |
13 | fn setup() (&net.TcpListener, &net.TcpConn, &net.TcpConn) { |
14 | mut server := net.listen_tcp(.ip6, server_port) or { panic(err) } |
15 | |
16 | c := chan &net.TcpConn{} |
17 | spawn accept(mut server, c) |
18 | mut client := net.dial_tcp('localhost${server_port}') or { panic(err) } |
19 | |
20 | socket := <-c |
21 | |
22 | $if debug_peer_ip ? { |
23 | eprintln('${server.addr()}\n${client.peer_addr()}, ${client.addr()}\n${socket.peer_addr()}, ${socket.addr()}') |
24 | } |
25 | assert true |
26 | return server, client, socket |
27 | } |
28 | |
29 | fn cleanup(mut server net.TcpListener, mut client net.TcpConn, mut socket net.TcpConn) { |
30 | server.close() or {} |
31 | client.close() or {} |
32 | socket.close() or {} |
33 | } |
34 | |
35 | fn test_socket() { |
36 | mut server, mut client, mut socket := setup() |
37 | defer { |
38 | cleanup(mut server, mut client, mut socket) |
39 | } |
40 | message := 'Hello World' |
41 | socket.write_string(message) or { |
42 | assert false |
43 | return |
44 | } |
45 | assert true |
46 | $if debug { |
47 | println('message send: ${message}') |
48 | } |
49 | $if debug { |
50 | println('send socket: ${socket.sock.handle}') |
51 | } |
52 | mut buf := []u8{len: 1024} |
53 | nbytes := client.read(mut buf) or { |
54 | assert false |
55 | return |
56 | } |
57 | received := buf[0..nbytes].bytestr() |
58 | $if debug { |
59 | println('message received: ${received}') |
60 | } |
61 | $if debug { |
62 | println('client: ${client.sock.handle}') |
63 | } |
64 | assert message == received |
65 | } |
66 | |
67 | fn test_socket_write_and_read() { |
68 | mut server, mut client, mut socket := setup() |
69 | defer { |
70 | cleanup(mut server, mut client, mut socket) |
71 | } |
72 | message1 := 'a message 1' |
73 | socket.write_string(message1) or { assert false } |
74 | mut rbuf := []u8{len: message1.len} |
75 | client.read(mut rbuf) or { |
76 | assert false |
77 | return |
78 | } |
79 | line := rbuf.bytestr() |
80 | assert line == message1 |
81 | } |
82 | |
83 | fn test_socket_read_line() { |
84 | mut server, mut client, mut socket := setup() |
85 | mut reader := io.new_buffered_reader(reader: client) |
86 | defer { |
87 | cleanup(mut server, mut client, mut socket) |
88 | } |
89 | message1, message2 := 'message1', 'message2' |
90 | message := '${message1}\n${message2}\n' |
91 | socket.write_string(message) or { assert false } |
92 | assert true |
93 | // |
94 | line1 := reader.read_line() or { |
95 | // println(reader.buf) |
96 | assert false |
97 | return |
98 | } |
99 | line2 := reader.read_line() or { |
100 | // println(reader.buf) |
101 | assert false |
102 | return |
103 | } |
104 | assert line1 == message1 |
105 | assert line2 == message2 |
106 | } |
107 | |
108 | fn test_socket_write_fail_without_panic() { |
109 | mut server, mut client, mut socket := setup() |
110 | defer { |
111 | cleanup(mut server, mut client, mut socket) |
112 | } |
113 | message2 := 'a message 2' |
114 | // ensure that socket.write (i.e. done on the server side) |
115 | // continues to work, even when the client side has been disconnected |
116 | // this test is important for a stable long standing server |
117 | client.close() or {} |
118 | $if solaris { |
119 | return |
120 | } |
121 | $if freebsd { |
122 | return |
123 | } |
124 | // TODO: fix segfaulting on Solaris and FreeBSD |
125 | for i := 0; i < 3; i++ { |
126 | socket.write_string(message2) or { |
127 | println('write to a socket without a recipient should produce an option fail: ${err} | ${message2}') |
128 | assert true |
129 | } |
130 | } |
131 | } |
132 | |
133 | fn test_socket_read_line_long_line_without_eol() { |
134 | mut server, mut client, mut socket := setup() |
135 | mut reader := io.new_buffered_reader(reader: client) |
136 | defer { |
137 | cleanup(mut server, mut client, mut socket) |
138 | } |
139 | message := strings.repeat_string('123', 400) |
140 | socket.write_string(message) or { |
141 | assert false |
142 | return |
143 | } |
144 | socket.write_string('\n') or { |
145 | assert false |
146 | return |
147 | } |
148 | line := reader.read_line() or { |
149 | assert false |
150 | return |
151 | } |
152 | assert line == message |
153 | } |