1 use test_programs::sockets::supports_ipv6;
2 use test_programs::wasi::sockets::network::{
3 ErrorCode, IpAddress, IpAddressFamily, IpSocketAddress, Network,
4 };
5 use test_programs::wasi::sockets::tcp::{ShutdownType, TcpSocket};
6
test_tcp_unbound_state_invariants(family: IpAddressFamily)7 fn test_tcp_unbound_state_invariants(family: IpAddressFamily) {
8 let sock = TcpSocket::new(family).unwrap();
9
10 // Skipping: tcp::start_bind
11 assert!(matches!(sock.finish_bind(), Err(ErrorCode::NotInProgress)));
12 // Skipping: tcp::start_connect
13 assert!(matches!(
14 sock.finish_connect(),
15 Err(ErrorCode::NotInProgress)
16 ));
17 assert!(matches!(
18 sock.start_listen(),
19 Err(ErrorCode::InvalidState) // Unlike POSIX, trying to listen without an explicit bind should fail in WASI.
20 ));
21 assert!(matches!(
22 sock.finish_listen(),
23 Err(ErrorCode::NotInProgress)
24 ));
25 assert!(matches!(sock.accept(), Err(ErrorCode::InvalidState)));
26 assert!(matches!(
27 sock.shutdown(ShutdownType::Both),
28 Err(ErrorCode::InvalidState)
29 ));
30
31 assert!(matches!(sock.local_address(), Err(ErrorCode::InvalidState)));
32 assert!(matches!(
33 sock.remote_address(),
34 Err(ErrorCode::InvalidState)
35 ));
36 assert_eq!(sock.is_listening(), false);
37 assert_eq!(sock.address_family(), family);
38
39 assert!(matches!(sock.set_listen_backlog_size(32), Ok(_)));
40 assert!(matches!(sock.keep_alive_enabled(), Ok(_)));
41 assert!(matches!(sock.set_keep_alive_enabled(false), Ok(_)));
42 assert!(matches!(sock.keep_alive_idle_time(), Ok(_)));
43 assert!(matches!(sock.set_keep_alive_idle_time(1), Ok(_)));
44 assert!(matches!(sock.keep_alive_interval(), Ok(_)));
45 assert!(matches!(sock.set_keep_alive_interval(1), Ok(_)));
46 assert!(matches!(sock.keep_alive_count(), Ok(_)));
47 assert!(matches!(sock.set_keep_alive_count(1), Ok(_)));
48 assert!(matches!(sock.hop_limit(), Ok(_)));
49 assert!(matches!(sock.set_hop_limit(255), Ok(_)));
50 assert!(matches!(sock.receive_buffer_size(), Ok(_)));
51 assert!(matches!(sock.set_receive_buffer_size(16000), Ok(_)));
52 assert!(matches!(sock.send_buffer_size(), Ok(_)));
53 assert!(matches!(sock.set_send_buffer_size(16000), Ok(_)));
54 }
55
test_tcp_bound_state_invariants(net: &Network, family: IpAddressFamily)56 fn test_tcp_bound_state_invariants(net: &Network, family: IpAddressFamily) {
57 let bind_address = IpSocketAddress::new(IpAddress::new_loopback(family), 0);
58 let sock = TcpSocket::new(family).unwrap();
59 sock.blocking_bind(net, bind_address).unwrap();
60
61 assert!(matches!(
62 sock.start_bind(net, bind_address),
63 Err(ErrorCode::InvalidState)
64 ));
65 assert!(matches!(sock.finish_bind(), Err(ErrorCode::NotInProgress)));
66 // Skipping: tcp::start_connect
67 assert!(matches!(
68 sock.finish_connect(),
69 Err(ErrorCode::NotInProgress)
70 ));
71 // Skipping: tcp::start_listen
72 assert!(matches!(
73 sock.finish_listen(),
74 Err(ErrorCode::NotInProgress)
75 ));
76 assert!(matches!(sock.accept(), Err(ErrorCode::InvalidState)));
77 assert!(matches!(
78 sock.shutdown(ShutdownType::Both),
79 Err(ErrorCode::InvalidState)
80 ));
81
82 assert!(matches!(sock.local_address(), Ok(_)));
83 assert!(matches!(
84 sock.remote_address(),
85 Err(ErrorCode::InvalidState)
86 ));
87 assert_eq!(sock.is_listening(), false);
88 assert_eq!(sock.address_family(), family);
89
90 assert!(matches!(sock.set_listen_backlog_size(32), Ok(_)));
91 assert!(matches!(sock.keep_alive_enabled(), Ok(_)));
92 assert!(matches!(sock.set_keep_alive_enabled(false), Ok(_)));
93 assert!(matches!(sock.keep_alive_idle_time(), Ok(_)));
94 assert!(matches!(sock.set_keep_alive_idle_time(1), Ok(_)));
95 assert!(matches!(sock.keep_alive_interval(), Ok(_)));
96 assert!(matches!(sock.set_keep_alive_interval(1), Ok(_)));
97 assert!(matches!(sock.keep_alive_count(), Ok(_)));
98 assert!(matches!(sock.set_keep_alive_count(1), Ok(_)));
99 assert!(matches!(sock.hop_limit(), Ok(_)));
100 assert!(matches!(sock.set_hop_limit(255), Ok(_)));
101 assert!(matches!(sock.receive_buffer_size(), Ok(_)));
102 assert!(matches!(sock.set_receive_buffer_size(16000), Ok(_)));
103 assert!(matches!(sock.send_buffer_size(), Ok(_)));
104 assert!(matches!(sock.set_send_buffer_size(16000), Ok(_)));
105 }
106
test_tcp_listening_state_invariants(net: &Network, family: IpAddressFamily)107 fn test_tcp_listening_state_invariants(net: &Network, family: IpAddressFamily) {
108 let bind_address = IpSocketAddress::new(IpAddress::new_loopback(family), 0);
109 let sock = TcpSocket::new(family).unwrap();
110 sock.blocking_bind(net, bind_address).unwrap();
111 sock.blocking_listen().unwrap();
112
113 assert!(matches!(
114 sock.start_bind(net, bind_address),
115 Err(ErrorCode::InvalidState)
116 ));
117 assert!(matches!(sock.finish_bind(), Err(ErrorCode::NotInProgress)));
118 assert!(matches!(
119 sock.start_connect(net, bind_address), // Actual address shouldn't matter
120 Err(ErrorCode::InvalidState)
121 ));
122 assert!(matches!(
123 sock.finish_connect(),
124 Err(ErrorCode::NotInProgress)
125 ));
126 assert!(matches!(sock.start_listen(), Err(ErrorCode::InvalidState)));
127 assert!(matches!(
128 sock.finish_listen(),
129 Err(ErrorCode::NotInProgress)
130 ));
131 // Skipping: tcp::accept
132 assert!(matches!(
133 sock.shutdown(ShutdownType::Both),
134 Err(ErrorCode::InvalidState)
135 ));
136
137 assert!(matches!(sock.local_address(), Ok(_)));
138 assert!(matches!(
139 sock.remote_address(),
140 Err(ErrorCode::InvalidState)
141 ));
142 assert_eq!(sock.is_listening(), true);
143 assert_eq!(sock.address_family(), family);
144
145 assert!(matches!(
146 sock.set_listen_backlog_size(32),
147 Ok(_) | Err(ErrorCode::NotSupported)
148 ));
149 assert!(matches!(sock.keep_alive_enabled(), Ok(_)));
150 assert!(matches!(sock.set_keep_alive_enabled(false), Ok(_)));
151 assert!(matches!(sock.keep_alive_idle_time(), Ok(_)));
152 assert!(matches!(sock.set_keep_alive_idle_time(1), Ok(_)));
153 assert!(matches!(sock.keep_alive_interval(), Ok(_)));
154 assert!(matches!(sock.set_keep_alive_interval(1), Ok(_)));
155 assert!(matches!(sock.keep_alive_count(), Ok(_)));
156 assert!(matches!(sock.set_keep_alive_count(1), Ok(_)));
157 assert!(matches!(sock.hop_limit(), Ok(_)));
158 assert!(matches!(sock.set_hop_limit(255), Ok(_)));
159 assert!(matches!(sock.receive_buffer_size(), Ok(_)));
160 assert!(matches!(sock.set_receive_buffer_size(16000), Ok(_)));
161 assert!(matches!(sock.send_buffer_size(), Ok(_)));
162 assert!(matches!(sock.set_send_buffer_size(16000), Ok(_)));
163 }
164
test_tcp_connected_state_invariants(net: &Network, family: IpAddressFamily)165 fn test_tcp_connected_state_invariants(net: &Network, family: IpAddressFamily) {
166 let bind_address = IpSocketAddress::new(IpAddress::new_loopback(family), 0);
167 let sock_listener = TcpSocket::new(family).unwrap();
168 sock_listener.blocking_bind(net, bind_address).unwrap();
169 sock_listener.blocking_listen().unwrap();
170 let addr_listener = sock_listener.local_address().unwrap();
171 let sock = TcpSocket::new(family).unwrap();
172 let (_input, _output) = sock.blocking_connect(net, addr_listener).unwrap();
173
174 assert!(matches!(
175 sock.start_bind(net, bind_address),
176 Err(ErrorCode::InvalidState)
177 ));
178 assert!(matches!(sock.finish_bind(), Err(ErrorCode::NotInProgress)));
179 assert!(matches!(
180 sock.start_connect(net, addr_listener),
181 Err(ErrorCode::InvalidState)
182 ));
183 assert!(matches!(
184 sock.finish_connect(),
185 Err(ErrorCode::NotInProgress)
186 ));
187 assert!(matches!(sock.start_listen(), Err(ErrorCode::InvalidState)));
188 assert!(matches!(
189 sock.finish_listen(),
190 Err(ErrorCode::NotInProgress)
191 ));
192 assert!(matches!(sock.accept(), Err(ErrorCode::InvalidState)));
193 // Skipping: tcp::shutdown
194
195 assert!(matches!(sock.local_address(), Ok(_)));
196 assert!(matches!(sock.remote_address(), Ok(_)));
197 assert_eq!(sock.is_listening(), false);
198 assert_eq!(sock.address_family(), family);
199
200 assert!(matches!(sock.keep_alive_enabled(), Ok(_)));
201 assert!(matches!(sock.set_keep_alive_enabled(false), Ok(_)));
202 assert!(matches!(sock.keep_alive_idle_time(), Ok(_)));
203 assert!(matches!(sock.set_keep_alive_idle_time(1), Ok(_)));
204 assert!(matches!(sock.keep_alive_interval(), Ok(_)));
205 assert!(matches!(sock.set_keep_alive_interval(1), Ok(_)));
206 assert!(matches!(sock.keep_alive_count(), Ok(_)));
207 assert!(matches!(sock.set_keep_alive_count(1), Ok(_)));
208 assert!(matches!(sock.hop_limit(), Ok(_)));
209 assert!(matches!(sock.set_hop_limit(255), Ok(_)));
210 assert!(matches!(sock.receive_buffer_size(), Ok(_)));
211 assert!(matches!(sock.set_receive_buffer_size(16000), Ok(_)));
212 assert!(matches!(sock.send_buffer_size(), Ok(_)));
213 assert!(matches!(sock.set_send_buffer_size(16000), Ok(_)));
214 }
215
main()216 fn main() {
217 let net = Network::default();
218
219 test_tcp_unbound_state_invariants(IpAddressFamily::Ipv4);
220 test_tcp_bound_state_invariants(&net, IpAddressFamily::Ipv4);
221 test_tcp_listening_state_invariants(&net, IpAddressFamily::Ipv4);
222 test_tcp_connected_state_invariants(&net, IpAddressFamily::Ipv4);
223
224 if supports_ipv6() {
225 test_tcp_unbound_state_invariants(IpAddressFamily::Ipv6);
226 test_tcp_bound_state_invariants(&net, IpAddressFamily::Ipv6);
227 test_tcp_listening_state_invariants(&net, IpAddressFamily::Ipv6);
228 test_tcp_connected_state_invariants(&net, IpAddressFamily::Ipv6);
229 }
230 }
231