1 #![warn(rust_2018_idioms)]
2 #![cfg(feature = "full")]
3
4 use tokio::io::{duplex, AsyncReadExt, AsyncWriteExt};
5
6 #[tokio::test]
ping_pong()7 async fn ping_pong() {
8 let (mut a, mut b) = duplex(32);
9
10 let mut buf = [0u8; 4];
11
12 a.write_all(b"ping").await.unwrap();
13 b.read_exact(&mut buf).await.unwrap();
14 assert_eq!(&buf, b"ping");
15
16 b.write_all(b"pong").await.unwrap();
17 a.read_exact(&mut buf).await.unwrap();
18 assert_eq!(&buf, b"pong");
19 }
20
21 #[tokio::test]
across_tasks()22 async fn across_tasks() {
23 let (mut a, mut b) = duplex(32);
24
25 let t1 = tokio::spawn(async move {
26 a.write_all(b"ping").await.unwrap();
27 let mut buf = [0u8; 4];
28 a.read_exact(&mut buf).await.unwrap();
29 assert_eq!(&buf, b"pong");
30 });
31
32 let t2 = tokio::spawn(async move {
33 let mut buf = [0u8; 4];
34 b.read_exact(&mut buf).await.unwrap();
35 assert_eq!(&buf, b"ping");
36 b.write_all(b"pong").await.unwrap();
37 });
38
39 t1.await.unwrap();
40 t2.await.unwrap();
41 }
42
43 #[tokio::test]
disconnect()44 async fn disconnect() {
45 let (mut a, mut b) = duplex(32);
46
47 let t1 = tokio::spawn(async move {
48 a.write_all(b"ping").await.unwrap();
49 // and dropped
50 });
51
52 let t2 = tokio::spawn(async move {
53 let mut buf = [0u8; 32];
54 let n = b.read(&mut buf).await.unwrap();
55 assert_eq!(&buf[..n], b"ping");
56
57 let n = b.read(&mut buf).await.unwrap();
58 assert_eq!(n, 0);
59 });
60
61 t1.await.unwrap();
62 t2.await.unwrap();
63 }
64
65 #[tokio::test]
disconnect_reader()66 async fn disconnect_reader() {
67 let (a, mut b) = duplex(2);
68
69 let t1 = tokio::spawn(async move {
70 // this will block, as not all data fits into duplex
71 b.write_all(b"ping").await.unwrap_err();
72 });
73
74 let t2 = tokio::spawn(async move {
75 // here we drop the reader side, and we expect the writer in the other
76 // task to exit with an error
77 drop(a);
78 });
79
80 t2.await.unwrap();
81 t1.await.unwrap();
82 }
83
84 #[tokio::test]
max_write_size()85 async fn max_write_size() {
86 let (mut a, mut b) = duplex(32);
87
88 let t1 = tokio::spawn(async move {
89 let n = a.write(&[0u8; 64]).await.unwrap();
90 assert_eq!(n, 32);
91 let n = a.write(&[0u8; 64]).await.unwrap();
92 assert_eq!(n, 4);
93 });
94
95 let mut buf = [0u8; 4];
96 b.read_exact(&mut buf).await.unwrap();
97
98 t1.await.unwrap();
99
100 // drop b only after task t1 finishes writing
101 drop(b);
102 }
103