v / vlib / net / udp_test.v
141 lines · 118 sloc · 3.66 KB · 619a45308d8b662b619cdbcac66aab5545096a56
Raw
1import net
2import time
3
4fn echo_server(mut c net.UdpConn) {
5 mut count := 0
6 for {
7 eprintln('> echo_server loop count: ${count}')
8 mut buf := []u8{len: 100}
9 read, addr := c.read(mut buf) or { continue }
10 eprintln('Server got addr ${addr}, read: ${read} | buf: ${buf}')
11 c.write_to(addr, buf[..read]) or {
12 println('Server: connection dropped')
13 return
14 }
15 count++
16 // Normally, after responding, the test will end, but there are sometimes cases,
17 // when the echo_server continued looping, printing messages constantly.
18 // The sleep here, is a small precaution against spamming the CI with log messages,
19 // when there are network problems, and it allows easier root cause diagnostic, when
20 // they do happen:
21 time.sleep(1000 * time.millisecond)
22 }
23}
24
25const server_addr = '127.0.0.1:40003'
26
27fn echo() ! {
28 mut c := net.dial_udp(server_addr) or { panic('could not net.dial_udp: ${err}') }
29 defer {
30 c.close() or {}
31 }
32 data := 'Hello from vlib/net!'
33
34 c.write_string(data) or { panic('could not write_string: ${err}') }
35
36 mut buf := []u8{len: 100, init: 0}
37 read, addr := c.read(mut buf) or { panic('could not read: ${err}') }
38
39 assert read == data.len
40 println('Got address ${addr}')
41 // Can't test this here because loopback addresses
42 // are mapped to other addresses
43 // assert addr.str() == '127.0.0.1:30001'
44
45 for i := 0; i < read; i++ {
46 assert buf[i] == data[i]
47 }
48
49 println('Got "${buf.bytestr()}"')
50
51 c.close()!
52}
53
54fn test_udp() {
55 mut l := net.listen_udp(server_addr) or { panic('could not listen_udp: ${err}') }
56
57 spawn echo_server(mut l)
58 echo() or { panic('could not echo: ${err}') }
59
60 l.close() or {}
61}
62
63fn udp_write_after_delay(addr string, delay time.Duration, payload string, done chan bool) {
64 time.sleep(delay)
65 mut conn := net.dial_udp(addr) or { panic(err) }
66 defer {
67 conn.close() or {}
68 }
69 conn.write_string(payload) or { panic(err) }
70 done <- true
71}
72
73fn test_udp_read_timeout_is_honored_for_blocking_reads() ! {
74 mut listener := net.listen_udp('127.0.0.1:0')!
75 defer {
76 listener.close() or {}
77 }
78 addr := listener.sock.address()!.str()
79 delay := 200 * time.millisecond
80 timeout := 20 * time.millisecond
81 payload := 'late udp packet'
82 done := chan bool{cap: 1}
83
84 spawn udp_write_after_delay(addr, delay, payload, done)
85 listener.set_read_timeout(timeout)
86
87 mut buf := []u8{len: payload.len}
88 if _, _ := listener.read(mut buf) {
89 assert false, 'expected udp read timeout before delayed packet arrived'
90 } else {
91 assert err.code() == net.err_timed_out_code
92 }
93
94 _ = <-done
95 listener.set_read_timeout(time.second)
96 read, _ := listener.read(mut buf)!
97 assert read == payload.len
98 assert buf[..read].bytestr() == payload
99}
100
101fn test_udp_multicast_ipv4_socket_options() ! {
102 mut listener := net.listen_udp('0.0.0.0:0')!
103 defer {
104 listener.close() or {}
105 }
106
107 listener.join_multicast_group('224.0.0.1', '0.0.0.0')!
108 listener.leave_multicast_group('224.0.0.1', '0.0.0.0')!
109 listener.set_multicast_ttl(2)!
110 listener.set_multicast_loop(true)!
111 listener.set_multicast_loop(false)!
112 listener.set_multicast_interface('0.0.0.0')!
113}
114
115fn test_udp_multicast_validates_inputs() ! {
116 mut listener := net.listen_udp('0.0.0.0:0')!
117 defer {
118 listener.close() or {}
119 }
120
121 mut ttl_failed := false
122 listener.set_multicast_ttl(-1) or {
123 ttl_failed = true
124 assert err.msg().contains('multicast ttl')
125 }
126 assert ttl_failed
127
128 mut non_multicast_failed := false
129 listener.join_multicast_group('127.0.0.1', '') or {
130 non_multicast_failed = true
131 assert err.msg().contains('not an ipv4 multicast address')
132 }
133 assert non_multicast_failed
134
135 mut iface_failed := false
136 listener.set_multicast_interface('not-an-ip') or {
137 iface_failed = true
138 assert err.msg().contains('ipv4 multicast interface')
139 }
140 assert iface_failed
141}
142