1 use crate::io::prelude::*;
3 self, BorrowedBuf, BufReader, BufWriter, ErrorKind, IoSlice, LineWriter, SeekFrom,
5 use crate::mem::MaybeUninit;
7 use crate::sync::atomic::{AtomicUsize, Ordering};
10 /// A dummy reader intended at testing short-reads propagation.
11 pub struct ShortReader {
15 // FIXME: rustfmt and tidy disagree about the correct formatting of this
16 // function. This leads to issues for users with editors configured to
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)) }
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);
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(), []);
36 let nread = reader.read(&mut buf);
37 assert_eq!(nread.unwrap(), 2);
38 assert_eq!(buf, [0, 1]);
39 assert_eq!(reader.buffer(), []);
42 let nread = reader.read(&mut buf);
43 assert_eq!(nread.unwrap(), 1);
45 assert_eq!(reader.buffer(), [3]);
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(), []);
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(), []);
58 assert_eq!(reader.read(&mut buf).unwrap(), 0);
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);
66 let buf: &mut [_] = &mut [MaybeUninit::uninit(); 3];
67 let mut buf: BorrowedBuf<'_> = buf.into();
69 reader.read_buf(buf.unfilled()).unwrap();
71 assert_eq!(buf.filled(), [5, 6, 7]);
72 assert_eq!(reader.buffer(), []);
74 let buf: &mut [_] = &mut [MaybeUninit::uninit(); 2];
75 let mut buf: BorrowedBuf<'_> = buf.into();
77 reader.read_buf(buf.unfilled()).unwrap();
79 assert_eq!(buf.filled(), [0, 1]);
80 assert_eq!(reader.buffer(), []);
82 let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1];
83 let mut buf: BorrowedBuf<'_> = buf.into();
85 reader.read_buf(buf.unfilled()).unwrap();
87 assert_eq!(buf.filled(), [2]);
88 assert_eq!(reader.buffer(), [3]);
90 let buf: &mut [_] = &mut [MaybeUninit::uninit(); 3];
91 let mut buf: BorrowedBuf<'_> = buf.into();
93 reader.read_buf(buf.unfilled()).unwrap();
95 assert_eq!(buf.filled(), [3]);
96 assert_eq!(reader.buffer(), []);
98 reader.read_buf(buf.unfilled()).unwrap();
100 assert_eq!(buf.filled(), [3, 4]);
101 assert_eq!(reader.buffer(), []);
105 reader.read_buf(buf.unfilled()).unwrap();
107 assert!(buf.filled().is_empty());
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));
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][..]));
122 assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3));
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));
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][..]));
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));
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(), &[][..]);
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));
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());
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));
188 assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
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]);
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]);
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));
206 assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
209 assert!(reader.seek(SeekFrom::Current(5)).is_ok());
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]);
218 fn test_buffered_reader_seek_underflow() {
219 // gimmick reader that yields its position modulo 256 for each byte
220 struct PositionReader {
223 impl Read for PositionReader {
224 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
228 self.pos = self.pos.wrapping_add(1);
233 impl Seek for PositionReader {
234 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
236 SeekFrom::Start(n) => {
239 SeekFrom::Current(n) => {
240 self.pos = self.pos.wrapping_add(n as u64);
242 SeekFrom::End(n) => {
243 self.pos = u64::MAX.wrapping_add(n as u64);
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);
264 fn test_buffered_reader_seek_underflow_discard_buffer_between_seeks() {
265 // gimmick reader that returns Err after first seek
266 struct ErrAfterFirstSeekReader {
269 impl Read for ErrAfterFirstSeekReader {
270 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
277 impl Seek for ErrAfterFirstSeekReader {
278 fn seek(&mut self, _: SeekFrom) -> io::Result<u64> {
280 self.first_seek = false;
283 Err(io::Error::new(io::ErrorKind::Other, "oh no!"))
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][..]));
291 // The following seek will require two underlying seeks. The first will
292 // succeed but the second will fail. This should still invalidate the
294 assert!(reader.seek(SeekFrom::Current(i64::MIN)).is_err());
295 assert_eq!(reader.buffer().len(), 0);
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());
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());
321 fn test_buffered_writer() {
322 let inner = Vec::new();
323 let mut writer = BufWriter::with_capacity(2, inner);
325 writer.write(&[0, 1]).unwrap();
326 assert_eq!(writer.buffer(), []);
327 assert_eq!(*writer.get_ref(), [0, 1]);
329 writer.write(&[2]).unwrap();
330 assert_eq!(writer.buffer(), [2]);
331 assert_eq!(*writer.get_ref(), [0, 1]);
333 writer.write(&[3]).unwrap();
334 assert_eq!(writer.buffer(), [2, 3]);
335 assert_eq!(*writer.get_ref(), [0, 1]);
337 writer.flush().unwrap();
338 assert_eq!(writer.buffer(), []);
339 assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
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]);
346 writer.write(&[6]).unwrap();
347 assert_eq!(writer.buffer(), [6]);
348 assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]);
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]);
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]);
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]);
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]);
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]);
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();
392 reader.read_until(2, &mut v).unwrap();
393 assert_eq!(v, [1, 2]);
395 reader.read_until(1, &mut v).unwrap();
398 reader.read_until(8, &mut v).unwrap();
401 reader.read_until(9, &mut v).unwrap();
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']);
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");
430 reader.read_line(&mut s).unwrap();
431 assert_eq!(s, "b\n");
433 reader.read_line(&mut s).unwrap();
436 reader.read_line(&mut s).unwrap();
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());
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);
467 fn dont_panic_in_drop_on_panicked_flush() {
468 struct FailFlushWriter;
470 impl Write for FailFlushWriter {
471 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
474 fn flush(&mut self) -> io::Result<()> {
475 Err(io::Error::last_os_error())
479 let writer = FailFlushWriter;
480 let _writer = BufWriter::new(writer);
482 // If writer panics *again* due to the flush error then the process will
488 #[cfg_attr(target_os = "emscripten", ignore)]
489 fn panic_in_write_doesnt_flush_in_drop() {
490 static WRITES: AtomicUsize = AtomicUsize::new(0);
494 impl Write for PanicWriter {
495 fn write(&mut self, _: &[u8]) -> io::Result<usize> {
496 WRITES.fetch_add(1, Ordering::SeqCst);
499 fn flush(&mut self) -> io::Result<()> {
505 let mut writer = BufWriter::new(PanicWriter);
506 let _ = writer.write(b"hello world");
507 let _ = writer.flush();
512 assert_eq!(WRITES.load(Ordering::SeqCst), 1);
516 fn bench_buffered_reader(b: &mut test::Bencher) {
517 b.iter(|| BufReader::new(io::empty()));
521 fn bench_buffered_reader_small_reads(b: &mut test::Bencher) {
522 let data = (0..u8::MAX).cycle().take(1024 * 4).collect::<Vec<_>>();
524 let mut reader = BufReader::new(&data[..]);
525 let mut buf = [0u8; 4];
527 reader.read_exact(&mut buf).unwrap();
528 core::hint::black_box(&buf);
534 fn bench_buffered_writer(b: &mut test::Bencher) {
535 b.iter(|| BufWriter::new(io::sink()));
538 /// A simple `Write` target, designed to be wrapped by `LineWriter` /
539 /// `BufWriter` / etc, that can have its `write` & `flush` behavior
541 #[derive(Default, Clone)]
542 struct ProgrammableSink {
543 // Writes append to this slice
546 // If true, writes will always be an error
547 pub always_write_error: bool,
549 // If true, flushes will always be an error
550 pub always_flush_error: bool,
552 // If set, only up to this number of bytes will be written in a single
554 pub accept_prefix: Option<usize>,
556 // If set, counts down with each write, and writes return an error
558 pub max_writes: Option<usize>,
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,
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"));
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"));
575 Some(0) => return Ok(0),
576 Some(ref mut count) => *count -= 1,
580 let len = match self.accept_prefix {
582 Some(prefix) => data.len().min(prefix),
585 let data = &data[..len];
586 self.buffer.extend_from_slice(data);
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"))
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.
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
608 /// Regression test for #37807
610 fn erroneous_flush_retried() {
611 let writer = ProgrammableSink {
612 // Only write up to 4 bytes at a time
613 accept_prefix: Some(4),
615 // Accept the first two writes, then error the others
617 error_after_max_writes: true,
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);
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");
636 let mut a = LineWriter::new(Vec::new());
647 assert_eq!(a.get_ref(), b"\n");
661 assert_eq!(a.get_ref(), b"\n");
663 assert_eq!(a.get_ref(), b"\nabac");
664 assert_eq!(a.write_vectored(&[]).unwrap(), 0);
675 assert_eq!(a.write_vectored(&[IoSlice::new(b"a\nb"),]).unwrap(), 3);
676 assert_eq!(a.get_ref(), b"\nabaca\nb");
680 fn line_vectored_partial_and_errors() {
681 use crate::collections::VecDeque;
684 Write { inputs: Vec<&'static [u8]>, output: io::Result<usize> },
685 Flush { output: io::Result<()> },
690 calls: VecDeque<Call>,
693 impl Write for Writer {
694 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
695 self.write_vectored(&[IoSlice::new(buf)])
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<_>>());
704 Call::Flush { .. } => panic!("unexpected call to write; expected a flush"),
708 fn is_write_vectored(&self) -> bool {
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"),
720 impl Drop for Writer {
722 if !thread::panicking() {
723 assert_eq!(self.calls.len(), 0);
728 // partial writes keep going
729 let mut a = LineWriter::new(Writer::default());
730 a.write_vectored(&[IoSlice::new(&[]), IoSlice::new(b"abc")]).unwrap();
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) });
736 a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\n")]).unwrap();
738 a.get_mut().calls.push_back(Call::Flush { output: Ok(()) });
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());
747 fn err() -> io::Error {
748 io::Error::new(io::ErrorKind::Other, "x")
752 /// Test that, in cases where vectored writing is not enabled, the
753 /// LineWriter uses the normal `write` call, which more-correctly handles
756 fn line_vectored_ignored() {
757 let writer = ProgrammableSink::default();
758 let mut writer = LineWriter::new(writer);
762 IoSlice::new(b"Line 1\nLine"),
763 IoSlice::new(b" 2\nLine 3\nL"),
766 IoSlice::new(b"ine 4"),
767 IoSlice::new(b"\nLine 5\n"),
770 let count = writer.write_vectored(&content).unwrap();
771 assert_eq!(count, 11);
772 assert_eq!(&writer.get_ref().buffer, b"Line 1\n");
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");
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");
782 let count = writer.write_vectored(&content[6..]).unwrap();
783 assert_eq!(count, 8);
785 writer.get_ref().buffer.as_slice(),
786 b"Line 1\nLine 2\nLine 3\nLine 4\nLine 5\n".as_ref()
790 /// Test that, given this input:
797 /// And given a result that only writes to midway through Line 2
799 /// That only up to the end of Line 3 is buffered
801 /// This behavior is desirable because it prevents flushing partial lines
803 fn partial_write_buffers_line() {
804 let writer = ProgrammableSink { accept_prefix: Some(13), ..Default::default() };
805 let mut writer = LineWriter::new(writer);
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");
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");
814 /// Test that, given this input:
820 /// And given that the full write of lines 1 and 2 was successful
821 /// That data up to Line 3 is buffered
823 fn partial_line_buffered_after_line_write() {
824 let writer = ProgrammableSink::default();
825 let mut writer = LineWriter::new(writer);
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");
830 assert!(writer.flush().is_ok());
831 assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3");
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
838 fn long_line_flushed() {
839 let writer = ProgrammableSink::default();
840 let mut writer = LineWriter::with_capacity(5, writer);
842 assert_eq!(writer.write(b"0123456789").unwrap(), 10);
843 assert_eq!(&writer.get_ref().buffer, b"0123456789");
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.
851 fn line_long_tail_not_flushed() {
852 let writer = ProgrammableSink::default();
853 let mut writer = LineWriter::with_capacity(5, writer);
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");
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");
864 /// Test that, if an attempt to pre-flush buffered data returns Ok(0),
865 /// this is propagated as an error.
867 fn line_buffer_write0_error() {
868 let writer = ProgrammableSink {
869 // Accept one write, then return Ok(0) on subsequent ones
874 let mut writer = LineWriter::new(writer);
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");
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");
888 /// Test that, if a write returns Ok(0) after a successful pre-flush, this
889 /// is propagated as Ok(0)
891 fn line_buffer_write0_normal() {
892 let writer = ProgrammableSink {
893 // Accept two writes, then return Ok(0) on subsequent ones
898 let mut writer = LineWriter::new(writer);
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");
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");
910 /// LineWriter has a custom `write_all`; make sure it works correctly
912 fn line_write_all() {
913 let writer = ProgrammableSink {
914 // Only write 5 bytes at a time
915 accept_prefix: Some(5),
918 let mut writer = LineWriter::new(writer);
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();
924 writer.get_ref().buffer.as_slice(),
925 b"Line 1\nLine 2\nLine 3\nLine 4\nPartial Line 5\n".as_ref(),
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),
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
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.
950 fn partial_multiline_buffering() {
951 let writer = ProgrammableSink {
952 // Write only up to 5 bytes at a time
953 accept_prefix: Some(5),
957 let mut writer = LineWriter::with_capacity(10, writer);
959 let content = b"AAAAABBBBB\nCCCCDDDDDD\nEEE";
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");
970 writer.flush().unwrap();
971 assert_eq!(writer.get_ref().buffer, *b"AAAAABBBBB\n");
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
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),
984 let mut writer = LineWriter::with_capacity(5, writer);
986 let content = b"AAAAABBBBBBBBBB\nCCCCC\nDDDDD";
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
994 assert_eq!(writer.write(content).unwrap(), 10);
995 assert_eq!(writer.get_ref().buffer, *b"AAAAA");
997 writer.flush().unwrap();
998 assert_eq!(writer.get_ref().buffer, *b"AAAAABBBBB");
1001 #[derive(Debug, Clone, PartialEq, Eq)]
1002 enum RecordedEvent {
1007 #[derive(Debug, Clone, Default)]
1008 struct WriteRecorder {
1009 pub events: Vec<RecordedEvent>,
1012 impl Write for WriteRecorder {
1013 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1014 use crate::str::from_utf8;
1016 self.events.push(RecordedEvent::Write(from_utf8(buf).unwrap().to_string()));
1020 fn flush(&mut self) -> io::Result<()> {
1021 self.events.push(RecordedEvent::Flush);
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
1031 fn single_formatted_write() {
1032 let writer = WriteRecorder::default();
1033 let mut writer = LineWriter::new(writer);
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())]);
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> {
1056 let mut reader = BufReader::new(OneByteReader);
1057 // Nothing is initialized yet.
1058 assert_eq!(reader.initialized(), 0);
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());