1 use test_programs::p3::wasi::sockets::types::{
2     ErrorCode, IpAddress, IpAddressFamily, IpSocketAddress, UdpSocket,
3 };
4 use test_programs::sockets::supports_ipv6;
5 
6 struct Component;
7 
8 test_programs::p3::export!(Component);
9 
test_udp_unbound_state_invariants(family: IpAddressFamily)10 async fn test_udp_unbound_state_invariants(family: IpAddressFamily) {
11     let sock = UdpSocket::create(family).unwrap();
12 
13     // Skipping: udp::bind
14 
15     assert!(matches!(
16         sock.send(b"test".into(), None).await,
17         Err(ErrorCode::InvalidArgument)
18     ));
19     assert!(matches!(sock.disconnect(), Err(ErrorCode::InvalidState)));
20     assert!(matches!(
21         sock.get_local_address(),
22         Err(ErrorCode::InvalidState)
23     ));
24     assert!(matches!(
25         sock.get_remote_address(),
26         Err(ErrorCode::InvalidState)
27     ));
28     assert_eq!(sock.get_address_family(), family);
29 
30     assert!(matches!(sock.get_unicast_hop_limit(), Ok(_)));
31     assert!(matches!(sock.set_unicast_hop_limit(255), Ok(_)));
32     assert!(matches!(sock.get_receive_buffer_size(), Ok(_)));
33     assert!(matches!(sock.set_receive_buffer_size(16000), Ok(_)));
34     assert!(matches!(sock.get_send_buffer_size(), Ok(_)));
35     assert!(matches!(sock.set_send_buffer_size(16000), Ok(_)));
36 }
37 
test_udp_bound_state_invariants(family: IpAddressFamily)38 fn test_udp_bound_state_invariants(family: IpAddressFamily) {
39     let bind_address = IpSocketAddress::new(IpAddress::new_loopback(family), 0);
40     let sock = UdpSocket::create(family).unwrap();
41     sock.bind(bind_address).unwrap();
42 
43     assert!(matches!(
44         sock.bind(bind_address),
45         Err(ErrorCode::InvalidState)
46     ));
47     // Skipping: udp::connect
48 
49     assert!(matches!(sock.get_local_address(), Ok(_)));
50     assert!(matches!(
51         sock.get_remote_address(),
52         Err(ErrorCode::InvalidState)
53     ));
54     assert_eq!(sock.get_address_family(), family);
55 
56     assert!(matches!(sock.get_unicast_hop_limit(), Ok(_)));
57     assert!(matches!(sock.set_unicast_hop_limit(255), Ok(_)));
58     assert!(matches!(sock.get_receive_buffer_size(), Ok(_)));
59     assert!(matches!(sock.set_receive_buffer_size(16000), Ok(_)));
60     assert!(matches!(sock.get_send_buffer_size(), Ok(_)));
61     assert!(matches!(sock.set_send_buffer_size(16000), Ok(_)));
62 }
63 
test_udp_connected_state_invariants(family: IpAddressFamily)64 fn test_udp_connected_state_invariants(family: IpAddressFamily) {
65     let bind_address = IpSocketAddress::new(IpAddress::new_loopback(family), 0);
66     let connect_address = IpSocketAddress::new(IpAddress::new_loopback(family), 54321);
67     let sock = UdpSocket::create(family).unwrap();
68     sock.connect(connect_address).unwrap();
69 
70     assert!(matches!(
71         sock.bind(bind_address),
72         Err(ErrorCode::InvalidState)
73     ));
74     // Skipping: udp::connect
75 
76     assert!(matches!(sock.get_local_address(), Ok(_)));
77     assert!(matches!(sock.get_remote_address(), Ok(_)));
78     assert_eq!(sock.get_address_family(), family);
79 
80     assert!(matches!(sock.get_unicast_hop_limit(), Ok(_)));
81     assert!(matches!(sock.set_unicast_hop_limit(255), Ok(_)));
82     assert!(matches!(sock.get_receive_buffer_size(), Ok(_)));
83     assert!(matches!(sock.set_receive_buffer_size(16000), Ok(_)));
84     assert!(matches!(sock.get_send_buffer_size(), Ok(_)));
85     assert!(matches!(sock.set_send_buffer_size(16000), Ok(_)));
86 }
87 
88 impl test_programs::p3::exports::wasi::cli::run::Guest for Component {
run() -> Result<(), ()>89     async fn run() -> Result<(), ()> {
90         test_udp_unbound_state_invariants(IpAddressFamily::Ipv4).await;
91         test_udp_bound_state_invariants(IpAddressFamily::Ipv4);
92         test_udp_connected_state_invariants(IpAddressFamily::Ipv4);
93 
94         if supports_ipv6() {
95             test_udp_unbound_state_invariants(IpAddressFamily::Ipv6).await;
96             test_udp_bound_state_invariants(IpAddressFamily::Ipv6);
97             test_udp_connected_state_invariants(IpAddressFamily::Ipv6);
98         }
99         Ok(())
100     }
101 }
102 
main()103 fn main() {}
104