1*301dc716SAlex Crichton use wasip2::filesystem::types::*;
2*301dc716SAlex Crichton use wasip2::sockets::network::*;
3*301dc716SAlex Crichton 
main()4*301dc716SAlex Crichton fn main() {
5*301dc716SAlex Crichton     match std::env::args().nth(1).as_deref() {
6*301dc716SAlex Crichton         Some("poll") => poll(),
7*301dc716SAlex Crichton         Some("read") => read(),
8*301dc716SAlex Crichton         Some("write") => write(),
9*301dc716SAlex Crichton         Some("write-stream") => write_stream(),
10*301dc716SAlex Crichton         Some("write-stream-blocking") => write_stream_blocking(),
11*301dc716SAlex Crichton         Some("mkdir") => mkdir(),
12*301dc716SAlex Crichton         Some("resolve") => resolve(),
13*301dc716SAlex Crichton         Some("udp-send-many") => udp_send_many(),
14*301dc716SAlex Crichton         Some("udp-send-big") => udp_send_big(),
15*301dc716SAlex Crichton         Some("write-zeroes") => write_zeroes(),
16*301dc716SAlex Crichton         Some("write-stream-buffer-too-large") => write_stream_buffer_too_large(),
17*301dc716SAlex Crichton         Some("write-zeroes-buffer-too-large") => write_zeroes_buffer_too_large(),
18*301dc716SAlex Crichton         Some("read-file-big") => read_file_big(),
19*301dc716SAlex Crichton         Some("read-tcp-big") => read_tcp_big(),
20*301dc716SAlex Crichton         other => panic!("unknown arg {other:?}"),
21*301dc716SAlex Crichton     }
22*301dc716SAlex Crichton }
23*301dc716SAlex Crichton 
poll()24*301dc716SAlex Crichton fn poll() {
25*301dc716SAlex Crichton     let mut events = Vec::new();
26*301dc716SAlex Crichton     let sub = wasip2::clocks::monotonic_clock::subscribe_duration(0);
27*301dc716SAlex Crichton     for _ in 0..5000 {
28*301dc716SAlex Crichton         events.push(&sub);
29*301dc716SAlex Crichton     }
30*301dc716SAlex Crichton 
31*301dc716SAlex Crichton     wasip2::io::poll::poll(&events);
32*301dc716SAlex Crichton     unreachable!()
33*301dc716SAlex Crichton }
34*301dc716SAlex Crichton 
preopen() -> Descriptor35*301dc716SAlex Crichton fn preopen() -> Descriptor {
36*301dc716SAlex Crichton     let mut dirs = wasip2::filesystem::preopens::get_directories();
37*301dc716SAlex Crichton     assert_eq!(dirs.len(), 1);
38*301dc716SAlex Crichton     dirs.pop().unwrap().0
39*301dc716SAlex Crichton }
40*301dc716SAlex Crichton 
read()41*301dc716SAlex Crichton fn read() {
42*301dc716SAlex Crichton     let f = preopen()
43*301dc716SAlex Crichton         .open_at(
44*301dc716SAlex Crichton             PathFlags::empty(),
45*301dc716SAlex Crichton             "1mb",
46*301dc716SAlex Crichton             OpenFlags::empty(),
47*301dc716SAlex Crichton             DescriptorFlags::empty(),
48*301dc716SAlex Crichton         )
49*301dc716SAlex Crichton         .unwrap();
50*301dc716SAlex Crichton 
51*301dc716SAlex Crichton     // 0-length is ok
52*301dc716SAlex Crichton     f.read(0, 0).unwrap();
53*301dc716SAlex Crichton 
54*301dc716SAlex Crichton     // This isn't transferring data from the guest to the host, so this is ok.
55*301dc716SAlex Crichton     f.read(1 << 20, 0).unwrap();
56*301dc716SAlex Crichton 
57*301dc716SAlex Crichton     // Host shouldn't allocate based on what the guest asks for...
58*301dc716SAlex Crichton     f.read(u64::MAX, 0).unwrap();
59*301dc716SAlex Crichton 
60*301dc716SAlex Crichton     f.read_via_stream(0)
61*301dc716SAlex Crichton         .unwrap()
62*301dc716SAlex Crichton         .blocking_read(1 << 20)
63*301dc716SAlex Crichton         .unwrap();
64*301dc716SAlex Crichton }
65*301dc716SAlex Crichton 
write()66*301dc716SAlex Crichton fn write() {
67*301dc716SAlex Crichton     let f = preopen()
68*301dc716SAlex Crichton         .open_at(
69*301dc716SAlex Crichton             PathFlags::empty(),
70*301dc716SAlex Crichton             "hi",
71*301dc716SAlex Crichton             OpenFlags::CREATE,
72*301dc716SAlex Crichton             DescriptorFlags::empty(),
73*301dc716SAlex Crichton         )
74*301dc716SAlex Crichton         .unwrap();
75*301dc716SAlex Crichton     f.write(&[0; 5001], 0).unwrap();
76*301dc716SAlex Crichton     unreachable!()
77*301dc716SAlex Crichton }
78*301dc716SAlex Crichton 
write_stream()79*301dc716SAlex Crichton fn write_stream() {
80*301dc716SAlex Crichton     preopen()
81*301dc716SAlex Crichton         .open_at(
82*301dc716SAlex Crichton             PathFlags::empty(),
83*301dc716SAlex Crichton             "hi",
84*301dc716SAlex Crichton             OpenFlags::CREATE,
85*301dc716SAlex Crichton             DescriptorFlags::empty(),
86*301dc716SAlex Crichton         )
87*301dc716SAlex Crichton         .unwrap()
88*301dc716SAlex Crichton         .write_via_stream(0)
89*301dc716SAlex Crichton         .unwrap()
90*301dc716SAlex Crichton         .write(&[0; 5001])
91*301dc716SAlex Crichton         .unwrap();
92*301dc716SAlex Crichton     unreachable!()
93*301dc716SAlex Crichton }
94*301dc716SAlex Crichton 
write_stream_blocking()95*301dc716SAlex Crichton fn write_stream_blocking() {
96*301dc716SAlex Crichton     preopen()
97*301dc716SAlex Crichton         .open_at(
98*301dc716SAlex Crichton             PathFlags::empty(),
99*301dc716SAlex Crichton             "hi",
100*301dc716SAlex Crichton             OpenFlags::CREATE,
101*301dc716SAlex Crichton             DescriptorFlags::empty(),
102*301dc716SAlex Crichton         )
103*301dc716SAlex Crichton         .unwrap()
104*301dc716SAlex Crichton         .write_via_stream(0)
105*301dc716SAlex Crichton         .unwrap()
106*301dc716SAlex Crichton         .blocking_write_and_flush(&[0; 5001])
107*301dc716SAlex Crichton         .unwrap();
108*301dc716SAlex Crichton     unreachable!()
109*301dc716SAlex Crichton }
110*301dc716SAlex Crichton 
mkdir()111*301dc716SAlex Crichton fn mkdir() {
112*301dc716SAlex Crichton     let mut name = String::new();
113*301dc716SAlex Crichton     for _ in 0..5001 {
114*301dc716SAlex Crichton         name.push_str("a");
115*301dc716SAlex Crichton     }
116*301dc716SAlex Crichton     preopen().create_directory_at(&name).unwrap();
117*301dc716SAlex Crichton     unreachable!()
118*301dc716SAlex Crichton }
119*301dc716SAlex Crichton 
resolve()120*301dc716SAlex Crichton fn resolve() {
121*301dc716SAlex Crichton     let network = wasip2::sockets::instance_network::instance_network();
122*301dc716SAlex Crichton     let mut name = String::new();
123*301dc716SAlex Crichton     for _ in 0..5001 {
124*301dc716SAlex Crichton         name.push_str("a");
125*301dc716SAlex Crichton     }
126*301dc716SAlex Crichton     wasip2::sockets::ip_name_lookup::resolve_addresses(&network, &name).unwrap();
127*301dc716SAlex Crichton     unreachable!();
128*301dc716SAlex Crichton }
129*301dc716SAlex Crichton 
udp_socket() -> wasip2::sockets::udp::UdpSocket130*301dc716SAlex Crichton fn udp_socket() -> wasip2::sockets::udp::UdpSocket {
131*301dc716SAlex Crichton     let socket =
132*301dc716SAlex Crichton         wasip2::sockets::udp_create_socket::create_udp_socket(IpAddressFamily::Ipv4).unwrap();
133*301dc716SAlex Crichton     let network = wasip2::sockets::instance_network::instance_network();
134*301dc716SAlex Crichton 
135*301dc716SAlex Crichton     socket
136*301dc716SAlex Crichton         .start_bind(
137*301dc716SAlex Crichton             &network,
138*301dc716SAlex Crichton             IpSocketAddress::Ipv4(Ipv4SocketAddress {
139*301dc716SAlex Crichton                 address: (127, 0, 0, 1),
140*301dc716SAlex Crichton                 port: 0,
141*301dc716SAlex Crichton             }),
142*301dc716SAlex Crichton         )
143*301dc716SAlex Crichton         .unwrap();
144*301dc716SAlex Crichton     socket.finish_bind().unwrap();
145*301dc716SAlex Crichton     socket
146*301dc716SAlex Crichton }
147*301dc716SAlex Crichton 
udp_send_many()148*301dc716SAlex Crichton fn udp_send_many() {
149*301dc716SAlex Crichton     let socket = udp_socket();
150*301dc716SAlex Crichton     let (_incoming, outgoing) = socket.stream(None).unwrap();
151*301dc716SAlex Crichton     let mut dgrams = Vec::new();
152*301dc716SAlex Crichton 
153*301dc716SAlex Crichton     for _ in 0..5000 {
154*301dc716SAlex Crichton         dgrams.push(wasip2::sockets::udp::OutgoingDatagram {
155*301dc716SAlex Crichton             data: Vec::new(),
156*301dc716SAlex Crichton             remote_address: None,
157*301dc716SAlex Crichton         });
158*301dc716SAlex Crichton     }
159*301dc716SAlex Crichton 
160*301dc716SAlex Crichton     outgoing.send(&dgrams).unwrap();
161*301dc716SAlex Crichton     unreachable!()
162*301dc716SAlex Crichton }
163*301dc716SAlex Crichton 
udp_send_big()164*301dc716SAlex Crichton fn udp_send_big() {
165*301dc716SAlex Crichton     let socket = udp_socket();
166*301dc716SAlex Crichton     let (_incoming, outgoing) = socket.stream(None).unwrap();
167*301dc716SAlex Crichton     let mut dgrams = Vec::new();
168*301dc716SAlex Crichton 
169*301dc716SAlex Crichton     for _ in 0..2 {
170*301dc716SAlex Crichton         dgrams.push(wasip2::sockets::udp::OutgoingDatagram {
171*301dc716SAlex Crichton             data: vec![0; 2500],
172*301dc716SAlex Crichton             remote_address: None,
173*301dc716SAlex Crichton         });
174*301dc716SAlex Crichton     }
175*301dc716SAlex Crichton 
176*301dc716SAlex Crichton     outgoing.send(&dgrams).unwrap();
177*301dc716SAlex Crichton     unreachable!()
178*301dc716SAlex Crichton }
179*301dc716SAlex Crichton 
write_zeroes()180*301dc716SAlex Crichton fn write_zeroes() {
181*301dc716SAlex Crichton     preopen()
182*301dc716SAlex Crichton         .open_at(
183*301dc716SAlex Crichton             PathFlags::empty(),
184*301dc716SAlex Crichton             "hi",
185*301dc716SAlex Crichton             OpenFlags::CREATE,
186*301dc716SAlex Crichton             DescriptorFlags::empty(),
187*301dc716SAlex Crichton         )
188*301dc716SAlex Crichton         .unwrap()
189*301dc716SAlex Crichton         .write_via_stream(0)
190*301dc716SAlex Crichton         .unwrap()
191*301dc716SAlex Crichton         .write_zeroes(u64::MAX)
192*301dc716SAlex Crichton         .unwrap();
193*301dc716SAlex Crichton     unreachable!()
194*301dc716SAlex Crichton }
195*301dc716SAlex Crichton 
write_stream_buffer_too_large()196*301dc716SAlex Crichton fn write_stream_buffer_too_large() {
197*301dc716SAlex Crichton     preopen()
198*301dc716SAlex Crichton         .open_at(
199*301dc716SAlex Crichton             PathFlags::empty(),
200*301dc716SAlex Crichton             "hi",
201*301dc716SAlex Crichton             OpenFlags::CREATE,
202*301dc716SAlex Crichton             DescriptorFlags::empty(),
203*301dc716SAlex Crichton         )
204*301dc716SAlex Crichton         .unwrap()
205*301dc716SAlex Crichton         .write_via_stream(0)
206*301dc716SAlex Crichton         .unwrap()
207*301dc716SAlex Crichton         .blocking_write_and_flush(&[0; 5000])
208*301dc716SAlex Crichton         .unwrap();
209*301dc716SAlex Crichton     unreachable!()
210*301dc716SAlex Crichton }
211*301dc716SAlex Crichton 
write_zeroes_buffer_too_large()212*301dc716SAlex Crichton fn write_zeroes_buffer_too_large() {
213*301dc716SAlex Crichton     preopen()
214*301dc716SAlex Crichton         .open_at(
215*301dc716SAlex Crichton             PathFlags::empty(),
216*301dc716SAlex Crichton             "hi",
217*301dc716SAlex Crichton             OpenFlags::CREATE,
218*301dc716SAlex Crichton             DescriptorFlags::empty(),
219*301dc716SAlex Crichton         )
220*301dc716SAlex Crichton         .unwrap()
221*301dc716SAlex Crichton         .write_via_stream(0)
222*301dc716SAlex Crichton         .unwrap()
223*301dc716SAlex Crichton         .blocking_write_zeroes_and_flush(5000)
224*301dc716SAlex Crichton         .unwrap();
225*301dc716SAlex Crichton     unreachable!()
226*301dc716SAlex Crichton }
227*301dc716SAlex Crichton 
read_file_big()228*301dc716SAlex Crichton fn read_file_big() {
229*301dc716SAlex Crichton     preopen()
230*301dc716SAlex Crichton         .open_at(
231*301dc716SAlex Crichton             PathFlags::empty(),
232*301dc716SAlex Crichton             "1mb",
233*301dc716SAlex Crichton             OpenFlags::empty(),
234*301dc716SAlex Crichton             DescriptorFlags::empty(),
235*301dc716SAlex Crichton         )
236*301dc716SAlex Crichton         .unwrap()
237*301dc716SAlex Crichton         .read_via_stream(0)
238*301dc716SAlex Crichton         .unwrap()
239*301dc716SAlex Crichton         .blocking_read(u64::MAX)
240*301dc716SAlex Crichton         .unwrap();
241*301dc716SAlex Crichton }
242*301dc716SAlex Crichton 
read_tcp_big()243*301dc716SAlex Crichton fn read_tcp_big() {
244*301dc716SAlex Crichton     let server =
245*301dc716SAlex Crichton         wasip2::sockets::tcp_create_socket::create_tcp_socket(IpAddressFamily::Ipv4).unwrap();
246*301dc716SAlex Crichton     let client =
247*301dc716SAlex Crichton         wasip2::sockets::tcp_create_socket::create_tcp_socket(IpAddressFamily::Ipv4).unwrap();
248*301dc716SAlex Crichton 
249*301dc716SAlex Crichton     server
250*301dc716SAlex Crichton         .start_bind(
251*301dc716SAlex Crichton             &wasip2::sockets::instance_network::instance_network(),
252*301dc716SAlex Crichton             IpSocketAddress::Ipv4(Ipv4SocketAddress {
253*301dc716SAlex Crichton                 address: (127, 0, 0, 1),
254*301dc716SAlex Crichton                 port: 0,
255*301dc716SAlex Crichton             }),
256*301dc716SAlex Crichton         )
257*301dc716SAlex Crichton         .unwrap();
258*301dc716SAlex Crichton     server.finish_bind().unwrap();
259*301dc716SAlex Crichton     server.start_listen().unwrap();
260*301dc716SAlex Crichton     server.finish_listen().unwrap();
261*301dc716SAlex Crichton 
262*301dc716SAlex Crichton     client
263*301dc716SAlex Crichton         .start_connect(
264*301dc716SAlex Crichton             &wasip2::sockets::instance_network::instance_network(),
265*301dc716SAlex Crichton             server.local_address().unwrap(),
266*301dc716SAlex Crichton         )
267*301dc716SAlex Crichton         .unwrap();
268*301dc716SAlex Crichton     client.subscribe().block();
269*301dc716SAlex Crichton     let (input, _output) = client.finish_connect().unwrap();
270*301dc716SAlex Crichton 
271*301dc716SAlex Crichton     {
272*301dc716SAlex Crichton         server.subscribe().block();
273*301dc716SAlex Crichton         let (socket, input, output) = server.accept().unwrap();
274*301dc716SAlex Crichton         drop((input, output));
275*301dc716SAlex Crichton         drop(socket);
276*301dc716SAlex Crichton     }
277*301dc716SAlex Crichton 
278*301dc716SAlex Crichton     match input.blocking_read(u64::MAX) {
279*301dc716SAlex Crichton         Err(wasip2::io::streams::StreamError::Closed) => {}
280*301dc716SAlex Crichton         other => panic!("unexpected result: {other:?}"),
281*301dc716SAlex Crichton     }
282*301dc716SAlex Crichton }
283