1 | #![warn (rust_2018_idioms)] |
2 | #![cfg (feature = "full" )] |
3 | |
4 | use std::pin::Pin; |
5 | use std::task::{Context, Poll}; |
6 | use tokio::io::{AsyncRead, AsyncReadExt, ReadBuf}; |
7 | use tokio_test::assert_ok; |
8 | use tokio_test::io::Builder; |
9 | |
10 | #[tokio::test ] |
11 | async fn read_to_end() { |
12 | let mut buf = vec![]; |
13 | let mut rd: &[u8] = b"hello world" ; |
14 | |
15 | let n = assert_ok!(rd.read_to_end(&mut buf).await); |
16 | assert_eq!(n, 11); |
17 | assert_eq!(buf[..], b"hello world" [..]); |
18 | } |
19 | |
20 | #[derive(Copy, Clone, Debug)] |
21 | enum State { |
22 | Initializing, |
23 | JustFilling, |
24 | Done, |
25 | } |
26 | |
27 | struct UninitTest { |
28 | num_init: usize, |
29 | state: State, |
30 | } |
31 | |
32 | impl AsyncRead for UninitTest { |
33 | fn poll_read( |
34 | self: Pin<&mut Self>, |
35 | _cx: &mut Context<'_>, |
36 | buf: &mut ReadBuf<'_>, |
37 | ) -> Poll<std::io::Result<()>> { |
38 | let me = Pin::into_inner(self); |
39 | let real_num_init = buf.initialized().len() - buf.filled().len(); |
40 | assert_eq!(real_num_init, me.num_init, "{:?}" , me.state); |
41 | |
42 | match me.state { |
43 | State::Initializing => { |
44 | buf.initialize_unfilled_to(me.num_init + 2); |
45 | buf.advance(1); |
46 | me.num_init += 1; |
47 | |
48 | if me.num_init == 24 { |
49 | me.state = State::JustFilling; |
50 | } |
51 | } |
52 | State::JustFilling => { |
53 | buf.advance(1); |
54 | me.num_init -= 1; |
55 | |
56 | if me.num_init == 15 { |
57 | // The buffer is resized on next call. |
58 | me.num_init = 0; |
59 | me.state = State::Done; |
60 | } |
61 | } |
62 | State::Done => { /* .. do nothing .. */ } |
63 | } |
64 | |
65 | Poll::Ready(Ok(())) |
66 | } |
67 | } |
68 | |
69 | #[tokio::test ] |
70 | async fn read_to_end_uninit() { |
71 | let mut buf = Vec::with_capacity(64); |
72 | let mut test = UninitTest { |
73 | num_init: 0, |
74 | state: State::Initializing, |
75 | }; |
76 | |
77 | test.read_to_end(&mut buf).await.unwrap(); |
78 | assert_eq!(buf.len(), 33); |
79 | } |
80 | |
81 | #[tokio::test ] |
82 | async fn read_to_end_doesnt_grow_with_capacity() { |
83 | let arr: Vec<u8> = (0..100).collect(); |
84 | |
85 | // We only test from 32 since we allocate at least 32 bytes each time |
86 | for len in 32..100 { |
87 | let bytes = &arr[..len]; |
88 | for split in 0..len { |
89 | for cap in 0..101 { |
90 | let mut mock = if split == 0 { |
91 | Builder::new().read(bytes).build() |
92 | } else { |
93 | Builder::new() |
94 | .read(&bytes[..split]) |
95 | .read(&bytes[split..]) |
96 | .build() |
97 | }; |
98 | let mut buf = Vec::with_capacity(cap); |
99 | AsyncReadExt::read_to_end(&mut mock, &mut buf) |
100 | .await |
101 | .unwrap(); |
102 | // It has the right data. |
103 | assert_eq!(buf.as_slice(), bytes); |
104 | // Unless cap was smaller than length, then we did not reallocate. |
105 | if cap >= len { |
106 | assert_eq!(buf.capacity(), cap); |
107 | } |
108 | } |
109 | } |
110 | } |
111 | } |
112 | |
113 | #[tokio::test ] |
114 | async fn read_to_end_grows_capacity_if_unfit() { |
115 | let bytes = b"the_vector_startingcap_will_be_smaller" ; |
116 | let mut mock = Builder::new().read(bytes).build(); |
117 | let initial_capacity = bytes.len() - 4; |
118 | let mut buf = Vec::with_capacity(initial_capacity); |
119 | AsyncReadExt::read_to_end(&mut mock, &mut buf) |
120 | .await |
121 | .unwrap(); |
122 | // *4 since it doubles when it doesn't fit and again when reaching EOF |
123 | assert_eq!(buf.capacity(), initial_capacity * 4); |
124 | } |
125 | |