1 use futures::join;
2 use test_programs::p3::wasi::sockets::types::{
3 IpAddressFamily, IpSocketAddress, Ipv4SocketAddress, Ipv6SocketAddress, TcpSocket,
4 };
5 use test_programs::p3::wit_stream;
6 use test_programs::sockets::supports_ipv6;
7 use wit_bindgen::StreamResult;
8
9 struct Component;
10
11 test_programs::p3::export!(Component);
12
test_tcp_sample_application(family: IpAddressFamily, bind_address: IpSocketAddress)13 async fn test_tcp_sample_application(family: IpAddressFamily, bind_address: IpSocketAddress) {
14 let first_message = b"Hello, world!";
15 let second_message = b"Greetings, planet!";
16
17 let listener = TcpSocket::create(family).unwrap();
18
19 listener.bind(bind_address).unwrap();
20 listener.set_listen_backlog_size(32).unwrap();
21 let mut accept = listener.listen().unwrap();
22
23 let addr = listener.get_local_address().unwrap();
24
25 join!(
26 async {
27 let client = TcpSocket::create(family).unwrap();
28 client.connect(addr).await.unwrap();
29 let (mut data_tx, data_rx) = wit_stream::new();
30 join!(
31 async {
32 client.send(data_rx).await.unwrap();
33 },
34 async {
35 let (result, _) = data_tx.write(vec![]).await;
36 assert_eq!(result, StreamResult::Complete(0));
37 let remaining = data_tx.write_all(first_message.into()).await;
38 assert!(remaining.is_empty());
39 drop(data_tx);
40 }
41 );
42 },
43 async {
44 let sock = accept.next().await.unwrap();
45 let (mut data_rx, fut) = sock.receive();
46 let (result, data) = data_rx.read(Vec::with_capacity(100)).await;
47 assert_eq!(result, StreamResult::Complete(first_message.len()));
48 // Check that we sent and received our message!
49 assert_eq!(data, first_message); // Not guaranteed to work but should work in practice.
50
51 let (result, data) = data_rx.read(Vec::with_capacity(1)).await;
52 assert_eq!(result, StreamResult::Dropped);
53 assert_eq!(data, []);
54
55 fut.await.unwrap();
56 },
57 );
58
59 // Another client
60 join!(
61 async {
62 let client = TcpSocket::create(family).unwrap();
63 client.connect(addr).await.unwrap();
64 let (mut data_tx, data_rx) = wit_stream::new();
65 join!(
66 async {
67 client.send(data_rx).await.unwrap();
68 },
69 async {
70 let remaining = data_tx.write_all(second_message.into()).await;
71 assert!(remaining.is_empty());
72 drop(data_tx);
73 }
74 );
75 },
76 async {
77 let sock = accept.next().await.unwrap();
78 let (mut data_rx, fut) = sock.receive();
79 let (result, data) = data_rx.read(Vec::with_capacity(100)).await;
80 assert_eq!(result, StreamResult::Complete(second_message.len()));
81 // Check that we sent and received our message!
82 assert_eq!(data, second_message); // Not guaranteed to work but should work in practice.
83
84 let (result, data) = data_rx.read(Vec::with_capacity(1)).await;
85 assert_eq!(result, StreamResult::Dropped);
86 assert_eq!(data, []);
87
88 fut.await.unwrap();
89 }
90 );
91 }
92
93 impl test_programs::p3::exports::wasi::cli::run::Guest for Component {
run() -> Result<(), ()>94 async fn run() -> Result<(), ()> {
95 test_tcp_sample_application(
96 IpAddressFamily::Ipv4,
97 IpSocketAddress::Ipv4(Ipv4SocketAddress {
98 port: 0, // use any free port
99 address: (127, 0, 0, 1), // localhost
100 }),
101 )
102 .await;
103 if supports_ipv6() {
104 test_tcp_sample_application(
105 IpAddressFamily::Ipv6,
106 IpSocketAddress::Ipv6(Ipv6SocketAddress {
107 port: 0, // use any free port
108 address: (0, 0, 0, 0, 0, 0, 0, 1), // localhost
109 flow_info: 0,
110 scope_id: 0,
111 }),
112 )
113 .await;
114 }
115 Ok(())
116 }
117 }
118
main()119 fn main() {}
120