]> git.lizzy.rs Git - rust.git/blob - library/std/src/io/buffered/tests.rs
Rollup merge of #106835 - compiler-errors:new-solver-gat-rebase-oops, r=lcnr
[rust.git] / library / std / src / io / buffered / tests.rs
1 use crate::io::prelude::*;
2 use crate::io::{
3     self, BorrowedBuf, BufReader, BufWriter, ErrorKind, IoSlice, LineWriter, SeekFrom,
4 };
5 use crate::mem::MaybeUninit;
6 use crate::panic;
7 use crate::sync::atomic::{AtomicUsize, Ordering};
8 use crate::thread;
9
10 /// A dummy reader intended at testing short-reads propagation.
11 pub struct ShortReader {
12     lengths: Vec<usize>,
13 }
14
15 // FIXME: rustfmt and tidy disagree about the correct formatting of this
16 // function. This leads to issues for users with editors configured to
17 // rustfmt-on-save.
18 impl Read for ShortReader {
19     fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
20         if self.lengths.is_empty() { Ok(0) } else { Ok(self.lengths.remove(0)) }
21     }
22 }
23
24 #[test]
25 fn test_buffered_reader() {
26     let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
27     let mut reader = BufReader::with_capacity(2, inner);
28
29     let mut buf = [0, 0, 0];
30     let nread = reader.read(&mut buf);
31     assert_eq!(nread.unwrap(), 3);
32     assert_eq!(buf, [5, 6, 7]);
33     assert_eq!(reader.buffer(), []);
34
35     let mut buf = [0, 0];
36     let nread = reader.read(&mut buf);
37     assert_eq!(nread.unwrap(), 2);
38     assert_eq!(buf, [0, 1]);
39     assert_eq!(reader.buffer(), []);
40
41     let mut buf = [0];
42     let nread = reader.read(&mut buf);
43     assert_eq!(nread.unwrap(), 1);
44     assert_eq!(buf, [2]);
45     assert_eq!(reader.buffer(), [3]);
46
47     let mut buf = [0, 0, 0];
48     let nread = reader.read(&mut buf);
49     assert_eq!(nread.unwrap(), 1);
50     assert_eq!(buf, [3, 0, 0]);
51     assert_eq!(reader.buffer(), []);
52
53     let nread = reader.read(&mut buf);
54     assert_eq!(nread.unwrap(), 1);
55     assert_eq!(buf, [4, 0, 0]);
56     assert_eq!(reader.buffer(), []);
57
58     assert_eq!(reader.read(&mut buf).unwrap(), 0);
59 }
60
61 #[test]
62 fn test_buffered_reader_read_buf() {
63     let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
64     let mut reader = BufReader::with_capacity(2, inner);
65
66     let buf: &mut [_] = &mut [MaybeUninit::uninit(); 3];
67     let mut buf: BorrowedBuf<'_> = buf.into();
68
69     reader.read_buf(buf.unfilled()).unwrap();
70
71     assert_eq!(buf.filled(), [5, 6, 7]);
72     assert_eq!(reader.buffer(), []);
73
74     let buf: &mut [_] = &mut [MaybeUninit::uninit(); 2];
75     let mut buf: BorrowedBuf<'_> = buf.into();
76
77     reader.read_buf(buf.unfilled()).unwrap();
78
79     assert_eq!(buf.filled(), [0, 1]);
80     assert_eq!(reader.buffer(), []);
81
82     let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1];
83     let mut buf: BorrowedBuf<'_> = buf.into();
84
85     reader.read_buf(buf.unfilled()).unwrap();
86
87     assert_eq!(buf.filled(), [2]);
88     assert_eq!(reader.buffer(), [3]);
89
90     let buf: &mut [_] = &mut [MaybeUninit::uninit(); 3];
91     let mut buf: BorrowedBuf<'_> = buf.into();
92
93     reader.read_buf(buf.unfilled()).unwrap();
94
95     assert_eq!(buf.filled(), [3]);
96     assert_eq!(reader.buffer(), []);
97
98     reader.read_buf(buf.unfilled()).unwrap();
99
100     assert_eq!(buf.filled(), [3, 4]);
101     assert_eq!(reader.buffer(), []);
102
103     buf.clear();
104
105     reader.read_buf(buf.unfilled()).unwrap();
106
107     assert!(buf.filled().is_empty());
108 }
109
110 #[test]
111 fn test_buffered_reader_seek() {
112     let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
113     let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
114
115     assert_eq!(reader.seek(SeekFrom::Start(3)).ok(), Some(3));
116     assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
117     assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(3));
118     assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
119     assert_eq!(reader.seek(SeekFrom::Current(1)).ok(), Some(4));
120     assert_eq!(reader.fill_buf().ok(), Some(&[1, 2][..]));
121     reader.consume(1);
122     assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3));
123 }
124
125 #[test]
126 fn test_buffered_reader_seek_relative() {
127     let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
128     let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
129
130     assert!(reader.seek_relative(3).is_ok());
131     assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
132     assert!(reader.seek_relative(0).is_ok());
133     assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
134     assert!(reader.seek_relative(1).is_ok());
135     assert_eq!(reader.fill_buf().ok(), Some(&[1][..]));
136     assert!(reader.seek_relative(-1).is_ok());
137     assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
138     assert!(reader.seek_relative(2).is_ok());
139     assert_eq!(reader.fill_buf().ok(), Some(&[2, 3][..]));
140 }
141
142 #[test]
143 fn test_buffered_reader_stream_position() {
144     let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
145     let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner));
146
147     assert_eq!(reader.stream_position().ok(), Some(0));
148     assert_eq!(reader.seek(SeekFrom::Start(3)).ok(), Some(3));
149     assert_eq!(reader.stream_position().ok(), Some(3));
150     // relative seeking within the buffer and reading position should keep the buffer
151     assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..]));
152     assert!(reader.seek_relative(0).is_ok());
153     assert_eq!(reader.stream_position().ok(), Some(3));
154     assert_eq!(reader.buffer(), &[0, 1][..]);
155     assert!(reader.seek_relative(1).is_ok());
156     assert_eq!(reader.stream_position().ok(), Some(4));
157     assert_eq!(reader.buffer(), &[1][..]);
158     assert!(reader.seek_relative(-1).is_ok());
159     assert_eq!(reader.stream_position().ok(), Some(3));
160     assert_eq!(reader.buffer(), &[0, 1][..]);
161     // relative seeking outside the buffer will discard it
162     assert!(reader.seek_relative(2).is_ok());
163     assert_eq!(reader.stream_position().ok(), Some(5));
164     assert_eq!(reader.buffer(), &[][..]);
165 }
166
167 #[test]
168 fn test_buffered_reader_stream_position_panic() {
169     let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
170     let mut reader = BufReader::with_capacity(4, io::Cursor::new(inner));
171
172     // cause internal buffer to be filled but read only partially
173     let mut buffer = [0, 0];
174     assert!(reader.read_exact(&mut buffer).is_ok());
175     // rewinding the internal reader will cause buffer to loose sync
176     let inner = reader.get_mut();
177     assert!(inner.seek(SeekFrom::Start(0)).is_ok());
178     // overflow when subtracting the remaining buffer size from current position
179     let result = panic::catch_unwind(panic::AssertUnwindSafe(|| reader.stream_position().ok()));
180     assert!(result.is_err());
181 }
182
183 #[test]
184 fn test_buffered_reader_invalidated_after_read() {
185     let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
186     let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner));
187
188     assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
189     reader.consume(3);
190
191     let mut buffer = [0, 0, 0, 0, 0];
192     assert_eq!(reader.read(&mut buffer).ok(), Some(5));
193     assert_eq!(buffer, [0, 1, 2, 3, 4]);
194
195     assert!(reader.seek_relative(-2).is_ok());
196     let mut buffer = [0, 0];
197     assert_eq!(reader.read(&mut buffer).ok(), Some(2));
198     assert_eq!(buffer, [3, 4]);
199 }
200
201 #[test]
202 fn test_buffered_reader_invalidated_after_seek() {
203     let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
204     let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner));
205
206     assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
207     reader.consume(3);
208
209     assert!(reader.seek(SeekFrom::Current(5)).is_ok());
210
211     assert!(reader.seek_relative(-2).is_ok());
212     let mut buffer = [0, 0];
213     assert_eq!(reader.read(&mut buffer).ok(), Some(2));
214     assert_eq!(buffer, [3, 4]);
215 }
216
217 #[test]
218 fn test_buffered_reader_seek_underflow() {
219     // gimmick reader that yields its position modulo 256 for each byte
220     struct PositionReader {
221         pos: u64,
222     }
223     impl Read for PositionReader {
224         fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
225             let len = buf.len();
226             for x in buf {
227                 *x = self.pos as u8;
228                 self.pos = self.pos.wrapping_add(1);
229             }
230             Ok(len)
231         }
232     }
233     impl Seek for PositionReader {
234         fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
235             match pos {
236                 SeekFrom::Start(n) => {
237                     self.pos = n;
238                 }
239                 SeekFrom::Current(n) => {
240                     self.pos = self.pos.wrapping_add(n as u64);
241                 }
242                 SeekFrom::End(n) => {
243                     self.pos = u64::MAX.wrapping_add(n as u64);
244                 }
245             }
246             Ok(self.pos)
247         }
248     }
249
250     let mut reader = BufReader::with_capacity(5, PositionReader { pos: 0 });
251     assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2, 3, 4][..]));
252     assert_eq!(reader.seek(SeekFrom::End(-5)).ok(), Some(u64::MAX - 5));
253     assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
254     // the following seek will require two underlying seeks
255     let expected = 9223372036854775802;
256     assert_eq!(reader.seek(SeekFrom::Current(i64::MIN)).ok(), Some(expected));
257     assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5));
258     // seeking to 0 should empty the buffer.
259     assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(expected));
260     assert_eq!(reader.get_ref().pos, expected);
261 }
262
263 #[test]
264 fn test_buffered_reader_seek_underflow_discard_buffer_between_seeks() {
265     // gimmick reader that returns Err after first seek
266     struct ErrAfterFirstSeekReader {
267         first_seek: bool,
268     }
269     impl Read for ErrAfterFirstSeekReader {
270         fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
271             for x in &mut *buf {
272                 *x = 0;
273             }
274             Ok(buf.len())
275         }
276     }
277     impl Seek for ErrAfterFirstSeekReader {
278         fn seek(&mut self, _: SeekFrom) -> io::Result<u64> {
279             if self.first_seek {
280                 self.first_seek = false;
281                 Ok(0)
282             } else {
283                 Err(io::Error::new(io::ErrorKind::Other, "oh no!"))
284             }
285         }
286     }
287
288     let mut reader = BufReader::with_capacity(5, ErrAfterFirstSeekReader { first_seek: true });
289     assert_eq!(reader.fill_buf().ok(), Some(&[0, 0, 0, 0, 0][..]));
290
291     // The following seek will require two underlying seeks. The first will
292     // succeed but the second will fail. This should still invalidate the
293     // buffer.
294     assert!(reader.seek(SeekFrom::Current(i64::MIN)).is_err());
295     assert_eq!(reader.buffer().len(), 0);
296 }
297
298 #[test]
299 fn test_buffered_reader_read_to_end_consumes_buffer() {
300     let data: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7];
301     let mut reader = BufReader::with_capacity(3, data);
302     let mut buf = Vec::new();
303     assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2][..]));
304     assert_eq!(reader.read_to_end(&mut buf).ok(), Some(8));
305     assert_eq!(&buf, &[0, 1, 2, 3, 4, 5, 6, 7]);
306     assert!(reader.buffer().is_empty());
307 }
308
309 #[test]
310 fn test_buffered_reader_read_to_string_consumes_buffer() {
311     let data: &[u8] = "deadbeef".as_bytes();
312     let mut reader = BufReader::with_capacity(3, data);
313     let mut buf = String::new();
314     assert_eq!(reader.fill_buf().ok(), Some("dea".as_bytes()));
315     assert_eq!(reader.read_to_string(&mut buf).ok(), Some(8));
316     assert_eq!(&buf, "deadbeef");
317     assert!(reader.buffer().is_empty());
318 }
319
320 #[test]
321 fn test_buffered_writer() {
322     let inner = Vec::new();
323     let mut writer = BufWriter::with_capacity(2, inner);
324
325     writer.write(&[0, 1]).unwrap();
326     assert_eq!(writer.buffer(), []);
327     assert_eq!(*writer.get_ref(), [0, 1]);
328
329     writer.write(&[2]).unwrap();
330     assert_eq!(writer.buffer(), [2]);
331     assert_eq!(*writer.get_ref(), [0, 1]);
332
333     writer.write(&[3]).unwrap();
334     assert_eq!(writer.buffer(), [2, 3]);
335     assert_eq!(*writer.get_ref(), [0, 1]);
336
337     writer.flush().unwrap();
338     assert_eq!(writer.buffer(), []);
339     assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
340
341     writer.write(&[4]).unwrap();
342     writer.write(&[5]).unwrap();
343     assert_eq!(writer.buffer(), [4, 5]);
344     assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
345
346     writer.write(&[6]).unwrap();
347     assert_eq!(writer.buffer(), [6]);
348     assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]);
349
350     writer.write(&[7, 8]).unwrap();
351     assert_eq!(writer.buffer(), []);
352     assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]);
353
354     writer.write(&[9, 10, 11]).unwrap();
355     assert_eq!(writer.buffer(), []);
356     assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
357
358     writer.flush().unwrap();
359     assert_eq!(writer.buffer(), []);
360     assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
361 }
362
363 #[test]
364 fn test_buffered_writer_inner_flushes() {
365     let mut w = BufWriter::with_capacity(3, Vec::new());
366     w.write(&[0, 1]).unwrap();
367     assert_eq!(*w.get_ref(), []);
368     let w = w.into_inner().unwrap();
369     assert_eq!(w, [0, 1]);
370 }
371
372 #[test]
373 fn test_buffered_writer_seek() {
374     let mut w = BufWriter::with_capacity(3, io::Cursor::new(Vec::new()));
375     w.write_all(&[0, 1, 2, 3, 4, 5]).unwrap();
376     w.write_all(&[6, 7]).unwrap();
377     assert_eq!(w.seek(SeekFrom::Current(0)).ok(), Some(8));
378     assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]);
379     assert_eq!(w.seek(SeekFrom::Start(2)).ok(), Some(2));
380     w.write_all(&[8, 9]).unwrap();
381     assert_eq!(&w.into_inner().unwrap().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]);
382 }
383
384 #[test]
385 fn test_read_until() {
386     let inner: &[u8] = &[0, 1, 2, 1, 0];
387     let mut reader = BufReader::with_capacity(2, inner);
388     let mut v = Vec::new();
389     reader.read_until(0, &mut v).unwrap();
390     assert_eq!(v, [0]);
391     v.truncate(0);
392     reader.read_until(2, &mut v).unwrap();
393     assert_eq!(v, [1, 2]);
394     v.truncate(0);
395     reader.read_until(1, &mut v).unwrap();
396     assert_eq!(v, [1]);
397     v.truncate(0);
398     reader.read_until(8, &mut v).unwrap();
399     assert_eq!(v, [0]);
400     v.truncate(0);
401     reader.read_until(9, &mut v).unwrap();
402     assert_eq!(v, []);
403 }
404
405 #[test]
406 fn test_line_buffer() {
407     let mut writer = LineWriter::new(Vec::new());
408     writer.write(&[0]).unwrap();
409     assert_eq!(*writer.get_ref(), []);
410     writer.write(&[1]).unwrap();
411     assert_eq!(*writer.get_ref(), []);
412     writer.flush().unwrap();
413     assert_eq!(*writer.get_ref(), [0, 1]);
414     writer.write(&[0, b'\n', 1, b'\n', 2]).unwrap();
415     assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n']);
416     writer.flush().unwrap();
417     assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2]);
418     writer.write(&[3, b'\n']).unwrap();
419     assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n']);
420 }
421
422 #[test]
423 fn test_read_line() {
424     let in_buf: &[u8] = b"a\nb\nc";
425     let mut reader = BufReader::with_capacity(2, in_buf);
426     let mut s = String::new();
427     reader.read_line(&mut s).unwrap();
428     assert_eq!(s, "a\n");
429     s.truncate(0);
430     reader.read_line(&mut s).unwrap();
431     assert_eq!(s, "b\n");
432     s.truncate(0);
433     reader.read_line(&mut s).unwrap();
434     assert_eq!(s, "c");
435     s.truncate(0);
436     reader.read_line(&mut s).unwrap();
437     assert_eq!(s, "");
438 }
439
440 #[test]
441 fn test_lines() {
442     let in_buf: &[u8] = b"a\nb\nc";
443     let reader = BufReader::with_capacity(2, in_buf);
444     let mut it = reader.lines();
445     assert_eq!(it.next().unwrap().unwrap(), "a".to_string());
446     assert_eq!(it.next().unwrap().unwrap(), "b".to_string());
447     assert_eq!(it.next().unwrap().unwrap(), "c".to_string());
448     assert!(it.next().is_none());
449 }
450
451 #[test]
452 fn test_short_reads() {
453     let inner = ShortReader { lengths: vec![0, 1, 2, 0, 1, 0] };
454     let mut reader = BufReader::new(inner);
455     let mut buf = [0, 0];
456     assert_eq!(reader.read(&mut buf).unwrap(), 0);
457     assert_eq!(reader.read(&mut buf).unwrap(), 1);
458     assert_eq!(reader.read(&mut buf).unwrap(), 2);
459     assert_eq!(reader.read(&mut buf).unwrap(), 0);
460     assert_eq!(reader.read(&mut buf).unwrap(), 1);
461     assert_eq!(reader.read(&mut buf).unwrap(), 0);
462     assert_eq!(reader.read(&mut buf).unwrap(), 0);
463 }
464
465 #[test]
466 #[should_panic]
467 fn dont_panic_in_drop_on_panicked_flush() {
468     struct FailFlushWriter;
469
470     impl Write for FailFlushWriter {
471         fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
472             Ok(buf.len())
473         }
474         fn flush(&mut self) -> io::Result<()> {
475             Err(io::Error::last_os_error())
476         }
477     }
478
479     let writer = FailFlushWriter;
480     let _writer = BufWriter::new(writer);
481
482     // If writer panics *again* due to the flush error then the process will
483     // abort.
484     panic!();
485 }
486
487 #[test]
488 #[cfg_attr(target_os = "emscripten", ignore)]
489 fn panic_in_write_doesnt_flush_in_drop() {
490     static WRITES: AtomicUsize = AtomicUsize::new(0);
491
492     struct PanicWriter;
493
494     impl Write for PanicWriter {
495         fn write(&mut self, _: &[u8]) -> io::Result<usize> {
496             WRITES.fetch_add(1, Ordering::SeqCst);
497             panic!();
498         }
499         fn flush(&mut self) -> io::Result<()> {
500             Ok(())
501         }
502     }
503
504     thread::spawn(|| {
505         let mut writer = BufWriter::new(PanicWriter);
506         let _ = writer.write(b"hello world");
507         let _ = writer.flush();
508     })
509     .join()
510     .unwrap_err();
511
512     assert_eq!(WRITES.load(Ordering::SeqCst), 1);
513 }
514
515 #[bench]
516 fn bench_buffered_reader(b: &mut test::Bencher) {
517     b.iter(|| BufReader::new(io::empty()));
518 }
519
520 #[bench]
521 fn bench_buffered_reader_small_reads(b: &mut test::Bencher) {
522     let data = (0..u8::MAX).cycle().take(1024 * 4).collect::<Vec<_>>();
523     b.iter(|| {
524         let mut reader = BufReader::new(&data[..]);
525         let mut buf = [0u8; 4];
526         for _ in 0..1024 {
527             reader.read_exact(&mut buf).unwrap();
528             core::hint::black_box(&buf);
529         }
530     });
531 }
532
533 #[bench]
534 fn bench_buffered_writer(b: &mut test::Bencher) {
535     b.iter(|| BufWriter::new(io::sink()));
536 }
537
538 /// A simple `Write` target, designed to be wrapped by `LineWriter` /
539 /// `BufWriter` / etc, that can have its `write` & `flush` behavior
540 /// configured
541 #[derive(Default, Clone)]
542 struct ProgrammableSink {
543     // Writes append to this slice
544     pub buffer: Vec<u8>,
545
546     // If true, writes will always be an error
547     pub always_write_error: bool,
548
549     // If true, flushes will always be an error
550     pub always_flush_error: bool,
551
552     // If set, only up to this number of bytes will be written in a single
553     // call to `write`
554     pub accept_prefix: Option<usize>,
555
556     // If set, counts down with each write, and writes return an error
557     // when it hits 0
558     pub max_writes: Option<usize>,
559
560     // If set, attempting to write when max_writes == Some(0) will be an
561     // error; otherwise, it will return Ok(0).
562     pub error_after_max_writes: bool,
563 }
564
565 impl Write for ProgrammableSink {
566     fn write(&mut self, data: &[u8]) -> io::Result<usize> {
567         if self.always_write_error {
568             return Err(io::Error::new(io::ErrorKind::Other, "test - always_write_error"));
569         }
570
571         match self.max_writes {
572             Some(0) if self.error_after_max_writes => {
573                 return Err(io::Error::new(io::ErrorKind::Other, "test - max_writes"));
574             }
575             Some(0) => return Ok(0),
576             Some(ref mut count) => *count -= 1,
577             None => {}
578         }
579
580         let len = match self.accept_prefix {
581             None => data.len(),
582             Some(prefix) => data.len().min(prefix),
583         };
584
585         let data = &data[..len];
586         self.buffer.extend_from_slice(data);
587
588         Ok(len)
589     }
590
591     fn flush(&mut self) -> io::Result<()> {
592         if self.always_flush_error {
593             Err(io::Error::new(io::ErrorKind::Other, "test - always_flush_error"))
594         } else {
595             Ok(())
596         }
597     }
598 }
599
600 /// Previously the `LineWriter` could successfully write some bytes but
601 /// then fail to report that it has done so. Additionally, an erroneous
602 /// flush after a successful write was permanently ignored.
603 ///
604 /// Test that a line writer correctly reports the number of written bytes,
605 /// and that it attempts to flush buffered lines from previous writes
606 /// before processing new data
607 ///
608 /// Regression test for #37807
609 #[test]
610 fn erroneous_flush_retried() {
611     let writer = ProgrammableSink {
612         // Only write up to 4 bytes at a time
613         accept_prefix: Some(4),
614
615         // Accept the first two writes, then error the others
616         max_writes: Some(2),
617         error_after_max_writes: true,
618
619         ..Default::default()
620     };
621
622     // This should write the first 4 bytes. The rest will be buffered, out
623     // to the last newline.
624     let mut writer = LineWriter::new(writer);
625     assert_eq!(writer.write(b"a\nb\nc\nd\ne").unwrap(), 8);
626
627     // This write should attempt to flush "c\nd\n", then buffer "e". No
628     // errors should happen here because no further writes should be
629     // attempted against `writer`.
630     assert_eq!(writer.write(b"e").unwrap(), 1);
631     assert_eq!(&writer.get_ref().buffer, b"a\nb\nc\nd\n");
632 }
633
634 #[test]
635 fn line_vectored() {
636     let mut a = LineWriter::new(Vec::new());
637     assert_eq!(
638         a.write_vectored(&[
639             IoSlice::new(&[]),
640             IoSlice::new(b"\n"),
641             IoSlice::new(&[]),
642             IoSlice::new(b"a"),
643         ])
644         .unwrap(),
645         2,
646     );
647     assert_eq!(a.get_ref(), b"\n");
648
649     assert_eq!(
650         a.write_vectored(&[
651             IoSlice::new(&[]),
652             IoSlice::new(b"b"),
653             IoSlice::new(&[]),
654             IoSlice::new(b"a"),
655             IoSlice::new(&[]),
656             IoSlice::new(b"c"),
657         ])
658         .unwrap(),
659         3,
660     );
661     assert_eq!(a.get_ref(), b"\n");
662     a.flush().unwrap();
663     assert_eq!(a.get_ref(), b"\nabac");
664     assert_eq!(a.write_vectored(&[]).unwrap(), 0);
665     assert_eq!(
666         a.write_vectored(&[
667             IoSlice::new(&[]),
668             IoSlice::new(&[]),
669             IoSlice::new(&[]),
670             IoSlice::new(&[]),
671         ])
672         .unwrap(),
673         0,
674     );
675     assert_eq!(a.write_vectored(&[IoSlice::new(b"a\nb"),]).unwrap(), 3);
676     assert_eq!(a.get_ref(), b"\nabaca\nb");
677 }
678
679 #[test]
680 fn line_vectored_partial_and_errors() {
681     use crate::collections::VecDeque;
682
683     enum Call {
684         Write { inputs: Vec<&'static [u8]>, output: io::Result<usize> },
685         Flush { output: io::Result<()> },
686     }
687
688     #[derive(Default)]
689     struct Writer {
690         calls: VecDeque<Call>,
691     }
692
693     impl Write for Writer {
694         fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
695             self.write_vectored(&[IoSlice::new(buf)])
696         }
697
698         fn write_vectored(&mut self, buf: &[IoSlice<'_>]) -> io::Result<usize> {
699             match self.calls.pop_front().expect("unexpected call to write") {
700                 Call::Write { inputs, output } => {
701                     assert_eq!(inputs, buf.iter().map(|b| &**b).collect::<Vec<_>>());
702                     output
703                 }
704                 Call::Flush { .. } => panic!("unexpected call to write; expected a flush"),
705             }
706         }
707
708         fn is_write_vectored(&self) -> bool {
709             true
710         }
711
712         fn flush(&mut self) -> io::Result<()> {
713             match self.calls.pop_front().expect("Unexpected call to flush") {
714                 Call::Flush { output } => output,
715                 Call::Write { .. } => panic!("unexpected call to flush; expected a write"),
716             }
717         }
718     }
719
720     impl Drop for Writer {
721         fn drop(&mut self) {
722             if !thread::panicking() {
723                 assert_eq!(self.calls.len(), 0);
724             }
725         }
726     }
727
728     // partial writes keep going
729     let mut a = LineWriter::new(Writer::default());
730     a.write_vectored(&[IoSlice::new(&[]), IoSlice::new(b"abc")]).unwrap();
731
732     a.get_mut().calls.push_back(Call::Write { inputs: vec![b"abc"], output: Ok(1) });
733     a.get_mut().calls.push_back(Call::Write { inputs: vec![b"bc"], output: Ok(2) });
734     a.get_mut().calls.push_back(Call::Write { inputs: vec![b"x", b"\n"], output: Ok(2) });
735
736     a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\n")]).unwrap();
737
738     a.get_mut().calls.push_back(Call::Flush { output: Ok(()) });
739     a.flush().unwrap();
740
741     // erroneous writes stop and don't write more
742     a.get_mut().calls.push_back(Call::Write { inputs: vec![b"x", b"\na"], output: Err(err()) });
743     a.get_mut().calls.push_back(Call::Flush { output: Ok(()) });
744     assert!(a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\na")]).is_err());
745     a.flush().unwrap();
746
747     fn err() -> io::Error {
748         io::Error::new(io::ErrorKind::Other, "x")
749     }
750 }
751
752 /// Test that, in cases where vectored writing is not enabled, the
753 /// LineWriter uses the normal `write` call, which more-correctly handles
754 /// partial lines
755 #[test]
756 fn line_vectored_ignored() {
757     let writer = ProgrammableSink::default();
758     let mut writer = LineWriter::new(writer);
759
760     let content = [
761         IoSlice::new(&[]),
762         IoSlice::new(b"Line 1\nLine"),
763         IoSlice::new(b" 2\nLine 3\nL"),
764         IoSlice::new(&[]),
765         IoSlice::new(&[]),
766         IoSlice::new(b"ine 4"),
767         IoSlice::new(b"\nLine 5\n"),
768     ];
769
770     let count = writer.write_vectored(&content).unwrap();
771     assert_eq!(count, 11);
772     assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
773
774     let count = writer.write_vectored(&content[2..]).unwrap();
775     assert_eq!(count, 11);
776     assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n");
777
778     let count = writer.write_vectored(&content[5..]).unwrap();
779     assert_eq!(count, 5);
780     assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n");
781
782     let count = writer.write_vectored(&content[6..]).unwrap();
783     assert_eq!(count, 8);
784     assert_eq!(
785         writer.get_ref().buffer.as_slice(),
786         b"Line 1\nLine 2\nLine 3\nLine 4\nLine 5\n".as_ref()
787     );
788 }
789
790 /// Test that, given this input:
791 ///
792 /// Line 1\n
793 /// Line 2\n
794 /// Line 3\n
795 /// Line 4
796 ///
797 /// And given a result that only writes to midway through Line 2
798 ///
799 /// That only up to the end of Line 3 is buffered
800 ///
801 /// This behavior is desirable because it prevents flushing partial lines
802 #[test]
803 fn partial_write_buffers_line() {
804     let writer = ProgrammableSink { accept_prefix: Some(13), ..Default::default() };
805     let mut writer = LineWriter::new(writer);
806
807     assert_eq!(writer.write(b"Line 1\nLine 2\nLine 3\nLine4").unwrap(), 21);
808     assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2");
809
810     assert_eq!(writer.write(b"Line 4").unwrap(), 6);
811     assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n");
812 }
813
814 /// Test that, given this input:
815 ///
816 /// Line 1\n
817 /// Line 2\n
818 /// Line 3
819 ///
820 /// And given that the full write of lines 1 and 2 was successful
821 /// That data up to Line 3 is buffered
822 #[test]
823 fn partial_line_buffered_after_line_write() {
824     let writer = ProgrammableSink::default();
825     let mut writer = LineWriter::new(writer);
826
827     assert_eq!(writer.write(b"Line 1\nLine 2\nLine 3").unwrap(), 20);
828     assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\n");
829
830     assert!(writer.flush().is_ok());
831     assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3");
832 }
833
834 /// Test that, given a partial line that exceeds the length of
835 /// LineBuffer's buffer (that is, without a trailing newline), that that
836 /// line is written to the inner writer
837 #[test]
838 fn long_line_flushed() {
839     let writer = ProgrammableSink::default();
840     let mut writer = LineWriter::with_capacity(5, writer);
841
842     assert_eq!(writer.write(b"0123456789").unwrap(), 10);
843     assert_eq!(&writer.get_ref().buffer, b"0123456789");
844 }
845
846 /// Test that, given a very long partial line *after* successfully
847 /// flushing a complete line, that that line is buffered unconditionally,
848 /// and no additional writes take place. This assures the property that
849 /// `write` should make at-most-one attempt to write new data.
850 #[test]
851 fn line_long_tail_not_flushed() {
852     let writer = ProgrammableSink::default();
853     let mut writer = LineWriter::with_capacity(5, writer);
854
855     // Assert that Line 1\n is flushed, and 01234 is buffered
856     assert_eq!(writer.write(b"Line 1\n0123456789").unwrap(), 12);
857     assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
858
859     // Because the buffer is full, this subsequent write will flush it
860     assert_eq!(writer.write(b"5").unwrap(), 1);
861     assert_eq!(&writer.get_ref().buffer, b"Line 1\n01234");
862 }
863
864 /// Test that, if an attempt to pre-flush buffered data returns Ok(0),
865 /// this is propagated as an error.
866 #[test]
867 fn line_buffer_write0_error() {
868     let writer = ProgrammableSink {
869         // Accept one write, then return Ok(0) on subsequent ones
870         max_writes: Some(1),
871
872         ..Default::default()
873     };
874     let mut writer = LineWriter::new(writer);
875
876     // This should write "Line 1\n" and buffer "Partial"
877     assert_eq!(writer.write(b"Line 1\nPartial").unwrap(), 14);
878     assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
879
880     // This will attempt to flush "partial", which will return Ok(0), which
881     // needs to be an error, because we've already informed the client
882     // that we accepted the write.
883     let err = writer.write(b" Line End\n").unwrap_err();
884     assert_eq!(err.kind(), ErrorKind::WriteZero);
885     assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
886 }
887
888 /// Test that, if a write returns Ok(0) after a successful pre-flush, this
889 /// is propagated as Ok(0)
890 #[test]
891 fn line_buffer_write0_normal() {
892     let writer = ProgrammableSink {
893         // Accept two writes, then return Ok(0) on subsequent ones
894         max_writes: Some(2),
895
896         ..Default::default()
897     };
898     let mut writer = LineWriter::new(writer);
899
900     // This should write "Line 1\n" and buffer "Partial"
901     assert_eq!(writer.write(b"Line 1\nPartial").unwrap(), 14);
902     assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
903
904     // This will flush partial, which will succeed, but then return Ok(0)
905     // when flushing " Line End\n"
906     assert_eq!(writer.write(b" Line End\n").unwrap(), 0);
907     assert_eq!(&writer.get_ref().buffer, b"Line 1\nPartial");
908 }
909
910 /// LineWriter has a custom `write_all`; make sure it works correctly
911 #[test]
912 fn line_write_all() {
913     let writer = ProgrammableSink {
914         // Only write 5 bytes at a time
915         accept_prefix: Some(5),
916         ..Default::default()
917     };
918     let mut writer = LineWriter::new(writer);
919
920     writer.write_all(b"Line 1\nLine 2\nLine 3\nLine 4\nPartial").unwrap();
921     assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\nLine 4\n");
922     writer.write_all(b" Line 5\n").unwrap();
923     assert_eq!(
924         writer.get_ref().buffer.as_slice(),
925         b"Line 1\nLine 2\nLine 3\nLine 4\nPartial Line 5\n".as_ref(),
926     );
927 }
928
929 #[test]
930 fn line_write_all_error() {
931     let writer = ProgrammableSink {
932         // Only accept up to 3 writes of up to 5 bytes each
933         accept_prefix: Some(5),
934         max_writes: Some(3),
935         ..Default::default()
936     };
937
938     let mut writer = LineWriter::new(writer);
939     let res = writer.write_all(b"Line 1\nLine 2\nLine 3\nLine 4\nPartial");
940     assert!(res.is_err());
941     // An error from write_all leaves everything in an indeterminate state,
942     // so there's nothing else to test here
943 }
944
945 /// Under certain circumstances, the old implementation of LineWriter
946 /// would try to buffer "to the last newline" but be forced to buffer
947 /// less than that, leading to inappropriate partial line writes.
948 /// Regression test for that issue.
949 #[test]
950 fn partial_multiline_buffering() {
951     let writer = ProgrammableSink {
952         // Write only up to 5 bytes at a time
953         accept_prefix: Some(5),
954         ..Default::default()
955     };
956
957     let mut writer = LineWriter::with_capacity(10, writer);
958
959     let content = b"AAAAABBBBB\nCCCCDDDDDD\nEEE";
960
961     // When content is written, LineWriter will try to write blocks A, B,
962     // C, and D. Only block A will succeed. Under the old behavior, LineWriter
963     // would then try to buffer B, C and D, but because its capacity is 10,
964     // it will only be able to buffer B and C. We don't want to buffer
965     // partial lines concurrent with whole lines, so the correct behavior
966     // is to buffer only block B (out to the newline)
967     assert_eq!(writer.write(content).unwrap(), 11);
968     assert_eq!(writer.get_ref().buffer, *b"AAAAA");
969
970     writer.flush().unwrap();
971     assert_eq!(writer.get_ref().buffer, *b"AAAAABBBBB\n");
972 }
973
974 /// Same as test_partial_multiline_buffering, but in the event NO full lines
975 /// fit in the buffer, just buffer as much as possible
976 #[test]
977 fn partial_multiline_buffering_without_full_line() {
978     let writer = ProgrammableSink {
979         // Write only up to 5 bytes at a time
980         accept_prefix: Some(5),
981         ..Default::default()
982     };
983
984     let mut writer = LineWriter::with_capacity(5, writer);
985
986     let content = b"AAAAABBBBBBBBBB\nCCCCC\nDDDDD";
987
988     // When content is written, LineWriter will try to write blocks A, B,
989     // and C. Only block A will succeed. Under the old behavior, LineWriter
990     // would then try to buffer B and C, but because its capacity is 5,
991     // it will only be able to buffer part of B. Because it's not possible
992     // for it to buffer any complete lines, it should buffer as much of B as
993     // possible
994     assert_eq!(writer.write(content).unwrap(), 10);
995     assert_eq!(writer.get_ref().buffer, *b"AAAAA");
996
997     writer.flush().unwrap();
998     assert_eq!(writer.get_ref().buffer, *b"AAAAABBBBB");
999 }
1000
1001 #[derive(Debug, Clone, PartialEq, Eq)]
1002 enum RecordedEvent {
1003     Write(String),
1004     Flush,
1005 }
1006
1007 #[derive(Debug, Clone, Default)]
1008 struct WriteRecorder {
1009     pub events: Vec<RecordedEvent>,
1010 }
1011
1012 impl Write for WriteRecorder {
1013     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1014         use crate::str::from_utf8;
1015
1016         self.events.push(RecordedEvent::Write(from_utf8(buf).unwrap().to_string()));
1017         Ok(buf.len())
1018     }
1019
1020     fn flush(&mut self) -> io::Result<()> {
1021         self.events.push(RecordedEvent::Flush);
1022         Ok(())
1023     }
1024 }
1025
1026 /// Test that a normal, formatted writeln only results in a single write
1027 /// call to the underlying writer. A naive implementation of
1028 /// LineWriter::write_all results in two writes: one of the buffered data,
1029 /// and another of the final substring in the formatted set
1030 #[test]
1031 fn single_formatted_write() {
1032     let writer = WriteRecorder::default();
1033     let mut writer = LineWriter::new(writer);
1034
1035     // Under a naive implementation of LineWriter, this will result in two
1036     // writes: "hello, world" and "!\n", because write() has to flush the
1037     // buffer before attempting to write the last "!\n". write_all shouldn't
1038     // have this limitation.
1039     writeln!(&mut writer, "{}, {}!", "hello", "world").unwrap();
1040     assert_eq!(writer.get_ref().events, [RecordedEvent::Write("hello, world!\n".to_string())]);
1041 }
1042
1043 #[test]
1044 fn bufreader_full_initialize() {
1045     struct OneByteReader;
1046     impl Read for OneByteReader {
1047         fn read(&mut self, buf: &mut [u8]) -> crate::io::Result<usize> {
1048             if buf.len() > 0 {
1049                 buf[0] = 0;
1050                 Ok(1)
1051             } else {
1052                 Ok(0)
1053             }
1054         }
1055     }
1056     let mut reader = BufReader::new(OneByteReader);
1057     // Nothing is initialized yet.
1058     assert_eq!(reader.initialized(), 0);
1059
1060     let buf = reader.fill_buf().unwrap();
1061     // We read one byte...
1062     assert_eq!(buf.len(), 1);
1063     // But we initialized the whole buffer!
1064     assert_eq!(reader.initialized(), reader.capacity());
1065 }