diff options
Diffstat (limited to 'vendor/gix-features/tests/pipe.rs')
-rw-r--r-- | vendor/gix-features/tests/pipe.rs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/vendor/gix-features/tests/pipe.rs b/vendor/gix-features/tests/pipe.rs new file mode 100644 index 000000000..4815000bf --- /dev/null +++ b/vendor/gix-features/tests/pipe.rs @@ -0,0 +1,117 @@ +mod io { + use std::io::{BufRead, ErrorKind, Read, Write}; + + use gix_features::io; + + #[test] + fn threaded_read_to_end() { + let (mut writer, mut reader) = gix_features::io::pipe::unidirectional(0); + + let message = "Hello, world!"; + std::thread::spawn(move || { + writer + .write_all(message.as_bytes()) + .expect("writes to work if reader is present") + }); + + let mut received = String::new(); + reader.read_to_string(&mut received).unwrap(); + + assert_eq!(&received, message); + } + + #[test] + fn lack_of_reader_fails_with_broken_pipe() { + let (mut writer, _) = io::pipe::unidirectional(None); + assert_eq!( + writer.write_all(b"must fail").unwrap_err().kind(), + ErrorKind::BrokenPipe + ); + } + #[test] + fn line_reading_one_by_one() { + let (mut writer, mut reader) = io::pipe::unidirectional(2); + writer.write_all(b"a\n").expect("success"); + writer.write_all(b"b\nc").expect("success"); + drop(writer); + let mut buf = String::new(); + for expected in &["a\n", "b\n", "c"] { + buf.clear(); + assert_eq!(reader.read_line(&mut buf).expect("success"), expected.len()); + assert_eq!(buf, *expected); + } + } + + #[test] + fn line_reading() { + let (mut writer, reader) = io::pipe::unidirectional(2); + writer.write_all(b"a\n").expect("success"); + writer.write_all(b"b\nc\n").expect("success"); + drop(writer); + assert_eq!( + reader.lines().flat_map(Result::ok).collect::<Vec<_>>(), + vec!["a", "b", "c"] + ) + } + + #[test] + fn writer_can_inject_errors() { + let (writer, mut reader) = io::pipe::unidirectional(1); + writer + .channel + .send(Err(std::io::Error::new(std::io::ErrorKind::Other, "the error"))) + .expect("send success"); + let mut buf = [0]; + assert_eq!( + reader.read(&mut buf).unwrap_err().to_string(), + "the error", + "using Read trait, errors are propagated" + ); + + writer + .channel + .send(Err(std::io::Error::new(std::io::ErrorKind::Other, "the error"))) + .expect("send success"); + assert_eq!( + reader.fill_buf().unwrap_err().to_string(), + "the error", + "using BufRead trait, errors are propagated" + ); + } + + #[test] + fn continue_on_empty_writes() { + let (mut writer, mut reader) = io::pipe::unidirectional(2); + writer.write_all(&[]).expect("write successful and non-blocking"); + let input = b"hello"; + writer + .write_all(input) + .expect("second write works as well as there is capacity"); + let mut buf = vec![0u8; input.len()]; + assert_eq!(reader.read(&mut buf).expect("read succeeds"), input.len()); + assert_eq!(buf, &input[..]); + } + + #[test] + fn small_reads() { + const BLOCK_SIZE: usize = 20; + let block_count = 20; + let (mut writer, mut reader) = io::pipe::unidirectional(Some(4)); + std::thread::spawn(move || { + for _ in 0..block_count { + let data = &[0; BLOCK_SIZE]; + writer.write_all(data).unwrap(); + } + }); + + let mut small_read_buf = [0; BLOCK_SIZE / 2]; + let mut bytes_read = 0; + while let Ok(size) = reader.read(&mut small_read_buf) { + if size == 0 { + break; + } + bytes_read += size; + } + assert_eq!(block_count * BLOCK_SIZE, bytes_read); + } +} |