]> git.lizzy.rs Git - rust.git/blob - library/std/src/io/tests.rs
Rollup merge of #97015 - nrc:read-buf-cursor, r=Mark-Simulacrum
[rust.git] / library / std / src / io / tests.rs
1 use super::{repeat, BorrowedBuf, Cursor, SeekFrom};
2 use crate::cmp::{self, min};
3 use crate::io::{self, IoSlice, IoSliceMut};
4 use crate::io::{BufRead, BufReader, Read, Seek, Write};
5 use crate::mem::MaybeUninit;
6 use crate::ops::Deref;
7
8 #[test]
9 #[cfg_attr(target_os = "emscripten", ignore)]
10 fn read_until() {
11     let mut buf = Cursor::new(&b"12"[..]);
12     let mut v = Vec::new();
13     assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 2);
14     assert_eq!(v, b"12");
15
16     let mut buf = Cursor::new(&b"1233"[..]);
17     let mut v = Vec::new();
18     assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 3);
19     assert_eq!(v, b"123");
20     v.truncate(0);
21     assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 1);
22     assert_eq!(v, b"3");
23     v.truncate(0);
24     assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 0);
25     assert_eq!(v, []);
26 }
27
28 #[test]
29 fn split() {
30     let buf = Cursor::new(&b"12"[..]);
31     let mut s = buf.split(b'3');
32     assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']);
33     assert!(s.next().is_none());
34
35     let buf = Cursor::new(&b"1233"[..]);
36     let mut s = buf.split(b'3');
37     assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']);
38     assert_eq!(s.next().unwrap().unwrap(), vec![]);
39     assert!(s.next().is_none());
40 }
41
42 #[test]
43 fn read_line() {
44     let mut buf = Cursor::new(&b"12"[..]);
45     let mut v = String::new();
46     assert_eq!(buf.read_line(&mut v).unwrap(), 2);
47     assert_eq!(v, "12");
48
49     let mut buf = Cursor::new(&b"12\n\n"[..]);
50     let mut v = String::new();
51     assert_eq!(buf.read_line(&mut v).unwrap(), 3);
52     assert_eq!(v, "12\n");
53     v.truncate(0);
54     assert_eq!(buf.read_line(&mut v).unwrap(), 1);
55     assert_eq!(v, "\n");
56     v.truncate(0);
57     assert_eq!(buf.read_line(&mut v).unwrap(), 0);
58     assert_eq!(v, "");
59 }
60
61 #[test]
62 fn lines() {
63     let buf = Cursor::new(&b"12\r"[..]);
64     let mut s = buf.lines();
65     assert_eq!(s.next().unwrap().unwrap(), "12\r".to_string());
66     assert!(s.next().is_none());
67
68     let buf = Cursor::new(&b"12\r\n\n"[..]);
69     let mut s = buf.lines();
70     assert_eq!(s.next().unwrap().unwrap(), "12".to_string());
71     assert_eq!(s.next().unwrap().unwrap(), "".to_string());
72     assert!(s.next().is_none());
73 }
74
75 #[test]
76 fn buf_read_has_data_left() {
77     let mut buf = Cursor::new(&b"abcd"[..]);
78     assert!(buf.has_data_left().unwrap());
79     buf.read_exact(&mut [0; 2]).unwrap();
80     assert!(buf.has_data_left().unwrap());
81     buf.read_exact(&mut [0; 2]).unwrap();
82     assert!(!buf.has_data_left().unwrap());
83 }
84
85 #[test]
86 fn read_to_end() {
87     let mut c = Cursor::new(&b""[..]);
88     let mut v = Vec::new();
89     assert_eq!(c.read_to_end(&mut v).unwrap(), 0);
90     assert_eq!(v, []);
91
92     let mut c = Cursor::new(&b"1"[..]);
93     let mut v = Vec::new();
94     assert_eq!(c.read_to_end(&mut v).unwrap(), 1);
95     assert_eq!(v, b"1");
96
97     let cap = if cfg!(miri) { 1024 } else { 1024 * 1024 };
98     let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>();
99     let mut v = Vec::new();
100     let (a, b) = data.split_at(data.len() / 2);
101     assert_eq!(Cursor::new(a).read_to_end(&mut v).unwrap(), a.len());
102     assert_eq!(Cursor::new(b).read_to_end(&mut v).unwrap(), b.len());
103     assert_eq!(v, data);
104 }
105
106 #[test]
107 fn read_to_string() {
108     let mut c = Cursor::new(&b""[..]);
109     let mut v = String::new();
110     assert_eq!(c.read_to_string(&mut v).unwrap(), 0);
111     assert_eq!(v, "");
112
113     let mut c = Cursor::new(&b"1"[..]);
114     let mut v = String::new();
115     assert_eq!(c.read_to_string(&mut v).unwrap(), 1);
116     assert_eq!(v, "1");
117
118     let mut c = Cursor::new(&b"\xff"[..]);
119     let mut v = String::new();
120     assert!(c.read_to_string(&mut v).is_err());
121 }
122
123 #[test]
124 fn read_exact() {
125     let mut buf = [0; 4];
126
127     let mut c = Cursor::new(&b""[..]);
128     assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
129
130     let mut c = Cursor::new(&b"123"[..]).chain(Cursor::new(&b"456789"[..]));
131     c.read_exact(&mut buf).unwrap();
132     assert_eq!(&buf, b"1234");
133     c.read_exact(&mut buf).unwrap();
134     assert_eq!(&buf, b"5678");
135     assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
136 }
137
138 #[test]
139 fn read_exact_slice() {
140     let mut buf = [0; 4];
141
142     let mut c = &b""[..];
143     assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
144
145     let mut c = &b"123"[..];
146     assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
147     // make sure the optimized (early returning) method is being used
148     assert_eq!(&buf, &[0; 4]);
149
150     let mut c = &b"1234"[..];
151     c.read_exact(&mut buf).unwrap();
152     assert_eq!(&buf, b"1234");
153
154     let mut c = &b"56789"[..];
155     c.read_exact(&mut buf).unwrap();
156     assert_eq!(&buf, b"5678");
157     assert_eq!(c, b"9");
158 }
159
160 #[test]
161 fn read_buf_exact() {
162     let buf: &mut [_] = &mut [0; 4];
163     let mut buf: BorrowedBuf<'_> = buf.into();
164
165     let mut c = Cursor::new(&b""[..]);
166     assert_eq!(c.read_buf_exact(buf.unfilled()).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
167
168     let mut c = Cursor::new(&b"123456789"[..]);
169     c.read_buf_exact(buf.unfilled()).unwrap();
170     assert_eq!(buf.filled(), b"1234");
171
172     buf.clear();
173
174     c.read_buf_exact(buf.unfilled()).unwrap();
175     assert_eq!(buf.filled(), b"5678");
176
177     buf.clear();
178
179     assert_eq!(c.read_buf_exact(buf.unfilled()).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
180 }
181
182 #[test]
183 fn take_eof() {
184     struct R;
185
186     impl Read for R {
187         fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
188             Err(io::const_io_error!(io::ErrorKind::Other, ""))
189         }
190     }
191     impl BufRead for R {
192         fn fill_buf(&mut self) -> io::Result<&[u8]> {
193             Err(io::const_io_error!(io::ErrorKind::Other, ""))
194         }
195         fn consume(&mut self, _amt: usize) {}
196     }
197
198     let mut buf = [0; 1];
199     assert_eq!(0, R.take(0).read(&mut buf).unwrap());
200     assert_eq!(b"", R.take(0).fill_buf().unwrap());
201 }
202
203 fn cmp_bufread<Br1: BufRead, Br2: BufRead>(mut br1: Br1, mut br2: Br2, exp: &[u8]) {
204     let mut cat = Vec::new();
205     loop {
206         let consume = {
207             let buf1 = br1.fill_buf().unwrap();
208             let buf2 = br2.fill_buf().unwrap();
209             let minlen = if buf1.len() < buf2.len() { buf1.len() } else { buf2.len() };
210             assert_eq!(buf1[..minlen], buf2[..minlen]);
211             cat.extend_from_slice(&buf1[..minlen]);
212             minlen
213         };
214         if consume == 0 {
215             break;
216         }
217         br1.consume(consume);
218         br2.consume(consume);
219     }
220     assert_eq!(br1.fill_buf().unwrap().len(), 0);
221     assert_eq!(br2.fill_buf().unwrap().len(), 0);
222     assert_eq!(&cat[..], &exp[..])
223 }
224
225 #[test]
226 fn chain_bufread() {
227     let testdata = b"ABCDEFGHIJKL";
228     let chain1 =
229         (&testdata[..3]).chain(&testdata[3..6]).chain(&testdata[6..9]).chain(&testdata[9..]);
230     let chain2 = (&testdata[..4]).chain(&testdata[4..8]).chain(&testdata[8..]);
231     cmp_bufread(chain1, chain2, &testdata[..]);
232 }
233
234 #[test]
235 fn bufreader_size_hint() {
236     let testdata = b"ABCDEFGHIJKL";
237     let mut buf_reader = BufReader::new(&testdata[..]);
238     assert_eq!(buf_reader.buffer().len(), 0);
239
240     let buffer_length = testdata.len();
241     buf_reader.fill_buf().unwrap();
242
243     // Check that size hint matches buffer contents
244     let mut buffered_bytes = buf_reader.bytes();
245     let (lower_bound, _upper_bound) = buffered_bytes.size_hint();
246     assert_eq!(lower_bound, buffer_length);
247
248     // Check that size hint matches buffer contents after advancing
249     buffered_bytes.next().unwrap().unwrap();
250     let (lower_bound, _upper_bound) = buffered_bytes.size_hint();
251     assert_eq!(lower_bound, buffer_length - 1);
252 }
253
254 #[test]
255 fn empty_size_hint() {
256     let size_hint = io::empty().bytes().size_hint();
257     assert_eq!(size_hint, (0, Some(0)));
258 }
259
260 #[test]
261 fn slice_size_hint() {
262     let size_hint = (&[1, 2, 3]).bytes().size_hint();
263     assert_eq!(size_hint, (3, Some(3)));
264 }
265
266 #[test]
267 fn take_size_hint() {
268     let size_hint = (&[1, 2, 3]).take(2).bytes().size_hint();
269     assert_eq!(size_hint, (2, Some(2)));
270
271     let size_hint = (&[1, 2, 3]).take(4).bytes().size_hint();
272     assert_eq!(size_hint, (3, Some(3)));
273
274     let size_hint = io::repeat(0).take(3).bytes().size_hint();
275     assert_eq!(size_hint, (3, Some(3)));
276 }
277
278 #[test]
279 fn chain_empty_size_hint() {
280     let chain = io::empty().chain(io::empty());
281     let size_hint = chain.bytes().size_hint();
282     assert_eq!(size_hint, (0, Some(0)));
283 }
284
285 #[test]
286 fn chain_size_hint() {
287     let testdata = b"ABCDEFGHIJKL";
288     let mut buf_reader_1 = BufReader::new(&testdata[..6]);
289     let mut buf_reader_2 = BufReader::new(&testdata[6..]);
290
291     buf_reader_1.fill_buf().unwrap();
292     buf_reader_2.fill_buf().unwrap();
293
294     let chain = buf_reader_1.chain(buf_reader_2);
295     let size_hint = chain.bytes().size_hint();
296     assert_eq!(size_hint, (testdata.len(), Some(testdata.len())));
297 }
298
299 #[test]
300 fn chain_zero_length_read_is_not_eof() {
301     let a = b"A";
302     let b = b"B";
303     let mut s = String::new();
304     let mut chain = (&a[..]).chain(&b[..]);
305     chain.read(&mut []).unwrap();
306     chain.read_to_string(&mut s).unwrap();
307     assert_eq!("AB", s);
308 }
309
310 #[bench]
311 #[cfg_attr(target_os = "emscripten", ignore)]
312 #[cfg_attr(miri, ignore)] // Miri isn't fast...
313 fn bench_read_to_end(b: &mut test::Bencher) {
314     b.iter(|| {
315         let mut lr = repeat(1).take(10000000);
316         let mut vec = Vec::with_capacity(1024);
317         super::default_read_to_end(&mut lr, &mut vec)
318     });
319 }
320
321 #[test]
322 fn seek_len() -> io::Result<()> {
323     let mut c = Cursor::new(vec![0; 15]);
324     assert_eq!(c.stream_len()?, 15);
325
326     c.seek(SeekFrom::End(0))?;
327     let old_pos = c.stream_position()?;
328     assert_eq!(c.stream_len()?, 15);
329     assert_eq!(c.stream_position()?, old_pos);
330
331     c.seek(SeekFrom::Start(7))?;
332     c.seek(SeekFrom::Current(2))?;
333     let old_pos = c.stream_position()?;
334     assert_eq!(c.stream_len()?, 15);
335     assert_eq!(c.stream_position()?, old_pos);
336
337     Ok(())
338 }
339
340 #[test]
341 fn seek_position() -> io::Result<()> {
342     // All `asserts` are duplicated here to make sure the method does not
343     // change anything about the seek state.
344     let mut c = Cursor::new(vec![0; 15]);
345     assert_eq!(c.stream_position()?, 0);
346     assert_eq!(c.stream_position()?, 0);
347
348     c.seek(SeekFrom::End(0))?;
349     assert_eq!(c.stream_position()?, 15);
350     assert_eq!(c.stream_position()?, 15);
351
352     c.seek(SeekFrom::Start(7))?;
353     c.seek(SeekFrom::Current(2))?;
354     assert_eq!(c.stream_position()?, 9);
355     assert_eq!(c.stream_position()?, 9);
356
357     c.seek(SeekFrom::End(-3))?;
358     c.seek(SeekFrom::Current(1))?;
359     c.seek(SeekFrom::Current(-5))?;
360     assert_eq!(c.stream_position()?, 8);
361     assert_eq!(c.stream_position()?, 8);
362
363     c.rewind()?;
364     assert_eq!(c.stream_position()?, 0);
365     assert_eq!(c.stream_position()?, 0);
366
367     Ok(())
368 }
369
370 // A simple example reader which uses the default implementation of
371 // read_to_end.
372 struct ExampleSliceReader<'a> {
373     slice: &'a [u8],
374 }
375
376 impl<'a> Read for ExampleSliceReader<'a> {
377     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
378         let len = cmp::min(self.slice.len(), buf.len());
379         buf[..len].copy_from_slice(&self.slice[..len]);
380         self.slice = &self.slice[len..];
381         Ok(len)
382     }
383 }
384
385 #[test]
386 fn test_read_to_end_capacity() -> io::Result<()> {
387     let input = &b"foo"[..];
388
389     // read_to_end() takes care not to over-allocate when a buffer is the
390     // exact size needed.
391     let mut vec1 = Vec::with_capacity(input.len());
392     ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?;
393     assert_eq!(vec1.len(), input.len());
394     assert_eq!(vec1.capacity(), input.len(), "did not allocate more");
395
396     Ok(())
397 }
398
399 #[test]
400 fn io_slice_mut_advance_slices() {
401     let mut buf1 = [1; 8];
402     let mut buf2 = [2; 16];
403     let mut buf3 = [3; 8];
404     let mut bufs = &mut [
405         IoSliceMut::new(&mut buf1),
406         IoSliceMut::new(&mut buf2),
407         IoSliceMut::new(&mut buf3),
408     ][..];
409
410     // Only in a single buffer..
411     IoSliceMut::advance_slices(&mut bufs, 1);
412     assert_eq!(bufs[0].deref(), [1; 7].as_ref());
413     assert_eq!(bufs[1].deref(), [2; 16].as_ref());
414     assert_eq!(bufs[2].deref(), [3; 8].as_ref());
415
416     // Removing a buffer, leaving others as is.
417     IoSliceMut::advance_slices(&mut bufs, 7);
418     assert_eq!(bufs[0].deref(), [2; 16].as_ref());
419     assert_eq!(bufs[1].deref(), [3; 8].as_ref());
420
421     // Removing a buffer and removing from the next buffer.
422     IoSliceMut::advance_slices(&mut bufs, 18);
423     assert_eq!(bufs[0].deref(), [3; 6].as_ref());
424 }
425
426 #[test]
427 #[should_panic]
428 fn io_slice_mut_advance_slices_empty_slice() {
429     let mut empty_bufs = &mut [][..];
430     IoSliceMut::advance_slices(&mut empty_bufs, 1);
431 }
432
433 #[test]
434 #[should_panic]
435 fn io_slice_mut_advance_slices_beyond_total_length() {
436     let mut buf1 = [1; 8];
437     let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..];
438
439     IoSliceMut::advance_slices(&mut bufs, 9);
440     assert!(bufs.is_empty());
441 }
442
443 #[test]
444 fn io_slice_advance_slices() {
445     let buf1 = [1; 8];
446     let buf2 = [2; 16];
447     let buf3 = [3; 8];
448     let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..];
449
450     // Only in a single buffer..
451     IoSlice::advance_slices(&mut bufs, 1);
452     assert_eq!(bufs[0].deref(), [1; 7].as_ref());
453     assert_eq!(bufs[1].deref(), [2; 16].as_ref());
454     assert_eq!(bufs[2].deref(), [3; 8].as_ref());
455
456     // Removing a buffer, leaving others as is.
457     IoSlice::advance_slices(&mut bufs, 7);
458     assert_eq!(bufs[0].deref(), [2; 16].as_ref());
459     assert_eq!(bufs[1].deref(), [3; 8].as_ref());
460
461     // Removing a buffer and removing from the next buffer.
462     IoSlice::advance_slices(&mut bufs, 18);
463     assert_eq!(bufs[0].deref(), [3; 6].as_ref());
464 }
465
466 #[test]
467 #[should_panic]
468 fn io_slice_advance_slices_empty_slice() {
469     let mut empty_bufs = &mut [][..];
470     IoSlice::advance_slices(&mut empty_bufs, 1);
471 }
472
473 #[test]
474 #[should_panic]
475 fn io_slice_advance_slices_beyond_total_length() {
476     let buf1 = [1; 8];
477     let mut bufs = &mut [IoSlice::new(&buf1)][..];
478
479     IoSlice::advance_slices(&mut bufs, 9);
480     assert!(bufs.is_empty());
481 }
482
483 /// Create a new writer that reads from at most `n_bufs` and reads
484 /// `per_call` bytes (in total) per call to write.
485 fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter {
486     TestWriter { n_bufs, per_call, written: Vec::new() }
487 }
488
489 struct TestWriter {
490     n_bufs: usize,
491     per_call: usize,
492     written: Vec<u8>,
493 }
494
495 impl Write for TestWriter {
496     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
497         self.write_vectored(&[IoSlice::new(buf)])
498     }
499
500     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
501         let mut left = self.per_call;
502         let mut written = 0;
503         for buf in bufs.iter().take(self.n_bufs) {
504             let n = min(left, buf.len());
505             self.written.extend_from_slice(&buf[0..n]);
506             left -= n;
507             written += n;
508         }
509         Ok(written)
510     }
511
512     fn flush(&mut self) -> io::Result<()> {
513         Ok(())
514     }
515 }
516
517 #[test]
518 fn test_writer_read_from_one_buf() {
519     let mut writer = test_writer(1, 2);
520
521     assert_eq!(writer.write(&[]).unwrap(), 0);
522     assert_eq!(writer.write_vectored(&[]).unwrap(), 0);
523
524     // Read at most 2 bytes.
525     assert_eq!(writer.write(&[1, 1, 1]).unwrap(), 2);
526     let bufs = &[IoSlice::new(&[2, 2, 2])];
527     assert_eq!(writer.write_vectored(bufs).unwrap(), 2);
528
529     // Only read from first buf.
530     let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4, 4])];
531     assert_eq!(writer.write_vectored(bufs).unwrap(), 1);
532
533     assert_eq!(writer.written, &[1, 1, 2, 2, 3]);
534 }
535
536 #[test]
537 fn test_writer_read_from_multiple_bufs() {
538     let mut writer = test_writer(3, 3);
539
540     // Read at most 3 bytes from two buffers.
541     let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])];
542     assert_eq!(writer.write_vectored(bufs).unwrap(), 3);
543
544     // Read at most 3 bytes from three buffers.
545     let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])];
546     assert_eq!(writer.write_vectored(bufs).unwrap(), 3);
547
548     assert_eq!(writer.written, &[1, 2, 2, 3, 4, 5]);
549 }
550
551 #[test]
552 fn test_write_all_vectored() {
553     #[rustfmt::skip] // Becomes unreadable otherwise.
554     let tests: Vec<(_, &'static [u8])> = vec![
555         (vec![], &[]),
556         (vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]),
557         (vec![IoSlice::new(&[1])], &[1]),
558         (vec![IoSlice::new(&[1, 2])], &[1, 2]),
559         (vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]),
560         (vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]),
561         (vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]),
562         (vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]),
563         (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2])], &[1, 2, 2]),
564         (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]),
565         (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]),
566         (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]),
567         (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]),
568         (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 2, 2, 2, 2]),
569         (vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]),
570         (vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]),
571         (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]),
572         (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 2, 2, 3, 3, 3]),
573         (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]),
574     ];
575
576     let writer_configs = &[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)];
577
578     for (n_bufs, per_call) in writer_configs.iter().copied() {
579         for (mut input, wanted) in tests.clone().into_iter() {
580             let mut writer = test_writer(n_bufs, per_call);
581             assert!(writer.write_all_vectored(&mut *input).is_ok());
582             assert_eq!(&*writer.written, &*wanted);
583         }
584     }
585 }
586
587 // Issue 94981
588 #[test]
589 #[should_panic = "number of read bytes exceeds limit"]
590 fn test_take_wrong_length() {
591     struct LieAboutSize(bool);
592
593     impl Read for LieAboutSize {
594         fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
595             // Lie about the read size at first time of read.
596             if core::mem::take(&mut self.0) { Ok(buf.len() + 1) } else { Ok(buf.len()) }
597         }
598     }
599
600     let mut buffer = vec![0; 4];
601     let mut reader = LieAboutSize(true).take(4);
602     // Primed the `Limit` by lying about the read size.
603     let _ = reader.read(&mut buffer[..]);
604 }
605
606 #[bench]
607 fn bench_take_read(b: &mut test::Bencher) {
608     b.iter(|| {
609         let mut buf = [0; 64];
610
611         [255; 128].take(64).read(&mut buf).unwrap();
612     });
613 }
614
615 #[bench]
616 fn bench_take_read_buf(b: &mut test::Bencher) {
617     b.iter(|| {
618         let buf: &mut [_] = &mut [MaybeUninit::uninit(); 64];
619
620         let mut buf: BorrowedBuf<'_> = buf.into();
621
622         [255; 128].take(64).read_buf(buf.unfilled()).unwrap();
623     });
624 }