1 #![warn(rust_2018_idioms)]
2 #![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support panic recovery
3 
4 use tokio::io::{AsyncRead, AsyncReadExt, ReadBuf};
5 use tokio_test::assert_ok;
6 
7 use std::io;
8 use std::pin::Pin;
9 use std::task::{Context, Poll};
10 
11 mod support {
12     pub(crate) mod leaked_buffers;
13 }
14 use support::leaked_buffers::LeakedBuffers;
15 
16 #[tokio::test]
read()17 async fn read() {
18     #[derive(Default)]
19     struct Rd {
20         poll_cnt: usize,
21     }
22 
23     impl AsyncRead for Rd {
24         fn poll_read(
25             mut self: Pin<&mut Self>,
26             _cx: &mut Context<'_>,
27             buf: &mut ReadBuf<'_>,
28         ) -> Poll<io::Result<()>> {
29             assert_eq!(0, self.poll_cnt);
30             self.poll_cnt += 1;
31 
32             buf.put_slice(b"hello world");
33             Poll::Ready(Ok(()))
34         }
35     }
36 
37     let mut buf = Box::new([0; 11]);
38     let mut rd = Rd::default();
39 
40     let n = assert_ok!(rd.read(&mut buf[..]).await);
41     assert_eq!(n, 11);
42     assert_eq!(buf[..], b"hello world"[..]);
43 }
44 
45 struct BadAsyncRead {
46     leaked_buffers: LeakedBuffers,
47 }
48 
49 impl BadAsyncRead {
new() -> Self50     fn new() -> Self {
51         Self {
52             leaked_buffers: LeakedBuffers::new(),
53         }
54     }
55 }
56 
57 impl AsyncRead for BadAsyncRead {
poll_read( mut self: Pin<&mut Self>, _cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<io::Result<()>>58     fn poll_read(
59         mut self: Pin<&mut Self>,
60         _cx: &mut Context<'_>,
61         buf: &mut ReadBuf<'_>,
62     ) -> Poll<io::Result<()>> {
63         *buf = ReadBuf::new(unsafe { self.leaked_buffers.create(buf.capacity()) });
64         buf.advance(buf.capacity());
65 
66         Poll::Ready(Ok(()))
67     }
68 }
69 
70 #[tokio::test]
71 #[should_panic]
read_buf_bad_async_read()72 async fn read_buf_bad_async_read() {
73     let mut buf = Vec::with_capacity(10);
74     BadAsyncRead::new().read_buf(&mut buf).await.unwrap();
75 }
76