1 use futures::join;
2 use test_programs::p3::wasi::sockets::types::{
3     ErrorCode, IpAddress, IpAddressFamily, IpSocketAddress, TcpSocket,
4 };
5 use test_programs::sockets::supports_ipv6;
6 
7 struct Component;
8 
9 test_programs::p3::export!(Component);
10 
test_tcp_unbound_state_invariants(family: IpAddressFamily)11 fn test_tcp_unbound_state_invariants(family: IpAddressFamily) {
12     let sock = TcpSocket::create(family).unwrap();
13 
14     // TODO: Test send and receive
15     //assert!(matches!(
16     //    sock.shutdown(ShutdownType::Both),
17     //    Err(ErrorCode::InvalidState)
18     //));
19     assert!(matches!(
20         sock.get_local_address(),
21         Err(ErrorCode::InvalidState)
22     ));
23     assert!(matches!(
24         sock.get_remote_address(),
25         Err(ErrorCode::InvalidState)
26     ));
27     assert!(!sock.get_is_listening());
28     assert_eq!(sock.get_address_family(), family);
29 
30     sock.set_listen_backlog_size(32).unwrap();
31 
32     assert!(sock.get_keep_alive_enabled().is_ok());
33     sock.set_keep_alive_enabled(false).unwrap();
34     assert_eq!(sock.get_keep_alive_enabled().unwrap(), false);
35 
36     assert!(sock.get_keep_alive_idle_time().is_ok());
37     sock.set_keep_alive_idle_time(1).unwrap();
38 
39     assert!(sock.get_keep_alive_interval().is_ok());
40     sock.set_keep_alive_interval(1).unwrap();
41 
42     assert!(sock.get_keep_alive_count().is_ok());
43     sock.set_keep_alive_count(1).unwrap();
44 
45     assert!(sock.get_hop_limit().is_ok());
46     sock.set_hop_limit(255).unwrap();
47     assert_eq!(sock.get_hop_limit().unwrap(), 255);
48 
49     assert!(sock.get_receive_buffer_size().is_ok());
50     sock.set_receive_buffer_size(16000).unwrap();
51 
52     assert!(sock.get_send_buffer_size().is_ok());
53     sock.set_send_buffer_size(16000).unwrap();
54 }
55 
test_tcp_bound_state_invariants(family: IpAddressFamily)56 fn test_tcp_bound_state_invariants(family: IpAddressFamily) {
57     let bind_address = IpSocketAddress::new(IpAddress::new_loopback(family), 0);
58     let sock = TcpSocket::create(family).unwrap();
59     sock.bind(bind_address).unwrap();
60 
61     assert!(matches!(
62         sock.bind(bind_address),
63         Err(ErrorCode::InvalidState)
64     ));
65     // TODO: Test send and receive
66     //assert!(matches!(
67     //    sock.shutdown(ShutdownType::Both),
68     //    Err(ErrorCode::InvalidState)
69     //));
70 
71     assert!(sock.get_local_address().is_ok());
72     assert!(matches!(
73         sock.get_remote_address(),
74         Err(ErrorCode::InvalidState)
75     ));
76     assert!(!sock.get_is_listening());
77     assert_eq!(sock.get_address_family(), family);
78 
79     sock.set_listen_backlog_size(32).unwrap();
80 
81     assert!(sock.get_keep_alive_enabled().is_ok());
82     sock.set_keep_alive_enabled(false).unwrap();
83     assert_eq!(sock.get_keep_alive_enabled().unwrap(), false);
84 
85     assert!(sock.get_keep_alive_idle_time().is_ok());
86     sock.set_keep_alive_idle_time(1).unwrap();
87 
88     assert!(sock.get_keep_alive_interval().is_ok());
89     sock.set_keep_alive_interval(1).unwrap();
90 
91     assert!(sock.get_keep_alive_count().is_ok());
92     sock.set_keep_alive_count(1).unwrap();
93 
94     assert!(sock.get_hop_limit().is_ok());
95     sock.set_hop_limit(255).unwrap();
96     assert_eq!(sock.get_hop_limit().unwrap(), 255);
97 
98     assert!(sock.get_receive_buffer_size().is_ok());
99     sock.set_receive_buffer_size(16000).unwrap();
100 
101     assert!(sock.get_send_buffer_size().is_ok());
102     sock.set_send_buffer_size(16000).unwrap();
103 }
104 
test_tcp_listening_state_invariants(family: IpAddressFamily)105 async fn test_tcp_listening_state_invariants(family: IpAddressFamily) {
106     let bind_address = IpSocketAddress::new(IpAddress::new_loopback(family), 0);
107     let sock = TcpSocket::create(family).unwrap();
108     sock.bind(bind_address).unwrap();
109     sock.listen().unwrap();
110 
111     assert!(matches!(
112         sock.bind(bind_address),
113         Err(ErrorCode::InvalidState)
114     ));
115     assert!(matches!(
116         sock.connect(IpSocketAddress::new(IpAddress::new_loopback(family), 1))
117             .await,
118         Err(ErrorCode::InvalidState)
119     ));
120     assert!(matches!(sock.listen(), Err(ErrorCode::InvalidState)));
121     // Skipping: tcp::accept
122     // TODO: Test send and receive
123     //assert!(matches!(
124     //    sock.shutdown(ShutdownType::Both),
125     //    Err(ErrorCode::InvalidState)
126     //));
127 
128     assert!(sock.get_local_address().is_ok());
129     assert!(matches!(
130         sock.get_remote_address(),
131         Err(ErrorCode::InvalidState)
132     ));
133     assert!(sock.get_is_listening());
134     assert_eq!(sock.get_address_family(), family);
135 
136     assert!(matches!(
137         sock.set_listen_backlog_size(32),
138         Ok(_) | Err(ErrorCode::NotSupported)
139     ));
140 
141     assert!(sock.get_keep_alive_enabled().is_ok());
142     sock.set_keep_alive_enabled(false).unwrap();
143     assert_eq!(sock.get_keep_alive_enabled().unwrap(), false);
144 
145     assert!(sock.get_keep_alive_idle_time().is_ok());
146     sock.set_keep_alive_idle_time(1).unwrap();
147 
148     assert!(sock.get_keep_alive_interval().is_ok());
149     sock.set_keep_alive_interval(1).unwrap();
150 
151     assert!(sock.get_keep_alive_count().is_ok());
152     sock.set_keep_alive_count(1).unwrap();
153 
154     assert!(sock.get_hop_limit().is_ok());
155     sock.set_hop_limit(255).unwrap();
156     assert_eq!(sock.get_hop_limit().unwrap(), 255);
157 
158     assert!(sock.get_receive_buffer_size().is_ok());
159     sock.set_receive_buffer_size(16000).unwrap();
160 
161     assert!(sock.get_send_buffer_size().is_ok());
162     sock.set_send_buffer_size(16000).unwrap();
163 }
164 
test_tcp_connected_state_invariants(family: IpAddressFamily)165 async fn test_tcp_connected_state_invariants(family: IpAddressFamily) {
166     let bind_address = IpSocketAddress::new(IpAddress::new_loopback(family), 0);
167     let sock_listener = TcpSocket::create(family).unwrap();
168     sock_listener.bind(bind_address).unwrap();
169     let mut accept = sock_listener.listen().unwrap();
170     let addr_listener = sock_listener.get_local_address().unwrap();
171     let sock = TcpSocket::create(family).unwrap();
172     join!(
173         async {
174             sock.connect(addr_listener).await.unwrap();
175         },
176         async {
177             accept.next().await.unwrap();
178         }
179     );
180 
181     assert!(matches!(
182         sock.bind(bind_address),
183         Err(ErrorCode::InvalidState)
184     ));
185     assert!(matches!(
186         sock.connect(addr_listener).await,
187         Err(ErrorCode::InvalidState)
188     ));
189     assert!(matches!(sock.listen(), Err(ErrorCode::InvalidState)));
190     // Skipping: tcp::shutdown
191 
192     assert!(sock.get_local_address().is_ok());
193     assert!(sock.get_remote_address().is_ok());
194     assert!(!sock.get_is_listening());
195     assert_eq!(sock.get_address_family(), family);
196 
197     assert!(sock.get_keep_alive_enabled().is_ok());
198     sock.set_keep_alive_enabled(false).unwrap();
199     assert_eq!(sock.get_keep_alive_enabled().unwrap(), false);
200 
201     assert!(sock.get_keep_alive_idle_time().is_ok());
202     sock.set_keep_alive_idle_time(1).unwrap();
203 
204     assert!(sock.get_keep_alive_interval().is_ok());
205     sock.set_keep_alive_interval(1).unwrap();
206 
207     assert!(sock.get_keep_alive_count().is_ok());
208     sock.set_keep_alive_count(1).unwrap();
209 
210     assert!(sock.get_hop_limit().is_ok());
211     sock.set_hop_limit(255).unwrap();
212     assert_eq!(sock.get_hop_limit().unwrap(), 255);
213 
214     assert!(sock.get_receive_buffer_size().is_ok());
215     sock.set_receive_buffer_size(16000).unwrap();
216 
217     assert!(sock.get_send_buffer_size().is_ok());
218     sock.set_send_buffer_size(16000).unwrap();
219 }
220 
221 impl test_programs::p3::exports::wasi::cli::run::Guest for Component {
run() -> Result<(), ()>222     async fn run() -> Result<(), ()> {
223         test_tcp_unbound_state_invariants(IpAddressFamily::Ipv4);
224         test_tcp_bound_state_invariants(IpAddressFamily::Ipv4);
225         test_tcp_listening_state_invariants(IpAddressFamily::Ipv4).await;
226         test_tcp_connected_state_invariants(IpAddressFamily::Ipv4).await;
227 
228         if supports_ipv6() {
229             test_tcp_unbound_state_invariants(IpAddressFamily::Ipv6);
230             test_tcp_bound_state_invariants(IpAddressFamily::Ipv6);
231             test_tcp_listening_state_invariants(IpAddressFamily::Ipv6).await;
232             test_tcp_connected_state_invariants(IpAddressFamily::Ipv6).await;
233         }
234 
235         Ok(())
236     }
237 }
238 
main()239 fn main() {}
240