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 ] |
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 { |
50 | fn new() -> Self { |
51 | Self { |
52 | leaked_buffers: LeakedBuffers::new(), |
53 | } |
54 | } |
55 | } |
56 | |
57 | impl AsyncRead for BadAsyncRead { |
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 ] |
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 | |