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