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