1 #![allow(clippy::transmute_ptr_to_ptr)]
2 #![warn(rust_2018_idioms)]
3 #![cfg(feature = "full")]
4 
5 use tokio::io::AsyncRead;
6 use tokio_test::task;
7 use tokio_test::{assert_ready_err, assert_ready_ok};
8 
9 use bytes::{BufMut, BytesMut};
10 use std::io;
11 use std::mem::MaybeUninit;
12 use std::pin::Pin;
13 use std::task::{Context, Poll};
14 
15 #[test]
assert_obj_safe()16 fn assert_obj_safe() {
17     fn _assert<T>() {}
18     _assert::<Box<dyn AsyncRead>>();
19 }
20 
21 #[test]
read_buf_success()22 fn read_buf_success() {
23     struct Rd;
24 
25     impl AsyncRead for Rd {
26         fn poll_read(
27             self: Pin<&mut Self>,
28             _cx: &mut Context<'_>,
29             buf: &mut [u8],
30         ) -> Poll<io::Result<usize>> {
31             buf[0..11].copy_from_slice(b"hello world");
32             Poll::Ready(Ok(11))
33         }
34     }
35 
36     let mut buf = BytesMut::with_capacity(65);
37 
38     task::spawn(Rd).enter(|cx, rd| {
39         let n = assert_ready_ok!(rd.poll_read_buf(cx, &mut buf));
40 
41         assert_eq!(11, n);
42         assert_eq!(buf[..], b"hello world"[..]);
43     });
44 }
45 
46 #[test]
read_buf_error()47 fn read_buf_error() {
48     struct Rd;
49 
50     impl AsyncRead for Rd {
51         fn poll_read(
52             self: Pin<&mut Self>,
53             _cx: &mut Context<'_>,
54             _buf: &mut [u8],
55         ) -> Poll<io::Result<usize>> {
56             let err = io::ErrorKind::Other.into();
57             Poll::Ready(Err(err))
58         }
59     }
60 
61     let mut buf = BytesMut::with_capacity(65);
62 
63     task::spawn(Rd).enter(|cx, rd| {
64         let err = assert_ready_err!(rd.poll_read_buf(cx, &mut buf));
65         assert_eq!(err.kind(), io::ErrorKind::Other);
66     });
67 }
68 
69 #[test]
read_buf_no_capacity()70 fn read_buf_no_capacity() {
71     struct Rd;
72 
73     impl AsyncRead for Rd {
74         fn poll_read(
75             self: Pin<&mut Self>,
76             _cx: &mut Context<'_>,
77             _buf: &mut [u8],
78         ) -> Poll<io::Result<usize>> {
79             unimplemented!();
80         }
81     }
82 
83     let mut buf = [0u8; 0];
84 
85     task::spawn(Rd).enter(|cx, rd| {
86         let n = assert_ready_ok!(rd.poll_read_buf(cx, &mut &mut buf[..]));
87         assert_eq!(0, n);
88     });
89 }
90 
91 #[test]
read_buf_no_uninitialized()92 fn read_buf_no_uninitialized() {
93     struct Rd;
94 
95     impl AsyncRead for Rd {
96         fn poll_read(
97             self: Pin<&mut Self>,
98             _cx: &mut Context<'_>,
99             buf: &mut [u8],
100         ) -> Poll<io::Result<usize>> {
101             for b in buf {
102                 assert_eq!(0, *b);
103             }
104 
105             Poll::Ready(Ok(0))
106         }
107     }
108 
109     let mut buf = BytesMut::with_capacity(64);
110 
111     task::spawn(Rd).enter(|cx, rd| {
112         let n = assert_ready_ok!(rd.poll_read_buf(cx, &mut buf));
113         assert_eq!(0, n);
114     });
115 }
116 
117 #[test]
read_buf_uninitialized_ok()118 fn read_buf_uninitialized_ok() {
119     struct Rd;
120 
121     impl AsyncRead for Rd {
122         unsafe fn prepare_uninitialized_buffer(&self, _: &mut [MaybeUninit<u8>]) -> bool {
123             false
124         }
125 
126         fn poll_read(
127             self: Pin<&mut Self>,
128             _cx: &mut Context<'_>,
129             buf: &mut [u8],
130         ) -> Poll<io::Result<usize>> {
131             assert_eq!(buf[0..11], b"hello world"[..]);
132             Poll::Ready(Ok(0))
133         }
134     }
135 
136     // Can't create BytesMut w/ zero capacity, so fill it up
137     let mut buf = BytesMut::with_capacity(64);
138 
139     unsafe {
140         let b: &mut [u8] = std::mem::transmute(buf.bytes_mut());
141         b[0..11].copy_from_slice(b"hello world");
142     }
143 
144     task::spawn(Rd).enter(|cx, rd| {
145         let n = assert_ready_ok!(rd.poll_read_buf(cx, &mut buf));
146         assert_eq!(0, n);
147     });
148 }
149