diff options
| author | The8472 <git@infinite-source.de> | 2020-10-07 23:07:04 +0200 |
|---|---|---|
| committer | The8472 <git@infinite-source.de> | 2020-11-13 22:38:27 +0100 |
| commit | 18bfe2a66beb79f912f8d1e344dda5f054cdd9c3 (patch) | |
| tree | 53d2832fd0d9751b06619ad99d683a0d9e4320fc | |
| parent | 7f5d2722afea902e89e44062765733c4800b7d21 (diff) | |
| download | rust-18bfe2a66beb79f912f8d1e344dda5f054cdd9c3.tar.gz rust-18bfe2a66beb79f912f8d1e344dda5f054cdd9c3.zip | |
move copy specialization tests to their own module
| -rw-r--r-- | library/std/src/io/copy.rs | 3 | ||||
| -rw-r--r-- | library/std/src/io/copy/tests.rs | 179 | ||||
| -rw-r--r-- | library/std/src/io/tests.rs | 181 |
3 files changed, 182 insertions, 181 deletions
diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs index b88bca2f2b4..db47ba97fe4 100644 --- a/library/std/src/io/copy.rs +++ b/library/std/src/io/copy.rs @@ -1,6 +1,9 @@ use crate::io::{self, ErrorKind, Read, Write}; use crate::mem::MaybeUninit; +#[cfg(all(test, unix))] +mod tests; + /// Copies the entire contents of a reader into a writer. /// /// This function will continuously read data from `reader` and then diff --git a/library/std/src/io/copy/tests.rs b/library/std/src/io/copy/tests.rs new file mode 100644 index 00000000000..fcff5fa934d --- /dev/null +++ b/library/std/src/io/copy/tests.rs @@ -0,0 +1,179 @@ +use crate::env::temp_dir; +use crate::fs::OpenOptions; +use crate::io; +use crate::io::Result; +use crate::io::SeekFrom; +use crate::io::{BufRead, Read, Seek, Write}; +use crate::os::unix::io::AsRawFd; + +#[test] +fn copy_specialization() -> Result<()> { + use crate::io::{BufReader, BufWriter}; + + let path = crate::env::temp_dir(); + let source_path = path.join("copy-spec.source"); + let sink_path = path.join("copy-spec.sink"); + + let result: Result<()> = try { + let mut source = crate::fs::OpenOptions::new() + .read(true) + .write(true) + .create(true) + .truncate(true) + .open(&source_path)?; + source.write_all(b"abcdefghiklmnopqr")?; + source.seek(SeekFrom::Start(8))?; + let mut source = BufReader::with_capacity(8, source.take(5)); + source.fill_buf()?; + assert_eq!(source.buffer(), b"iklmn"); + source.get_mut().set_limit(6); + source.get_mut().get_mut().seek(SeekFrom::Start(1))?; // "bcdefg" + let mut source = source.take(10); // "iklmnbcdef" + + let mut sink = crate::fs::OpenOptions::new() + .read(true) + .write(true) + .create(true) + .truncate(true) + .open(&sink_path)?; + sink.write_all(b"000000")?; + let mut sink = BufWriter::with_capacity(5, sink); + sink.write_all(b"wxyz")?; + assert_eq!(sink.buffer(), b"wxyz"); + + let copied = crate::io::copy(&mut source, &mut sink)?; + assert_eq!(copied, 10); + assert_eq!(sink.buffer().len(), 0); + + let mut sink = sink.into_inner()?; + sink.seek(SeekFrom::Start(0))?; + let mut copied = Vec::new(); + sink.read_to_end(&mut copied)?; + assert_eq!(&copied, b"000000wxyziklmnbcdef"); + }; + + let rm1 = crate::fs::remove_file(source_path); + let rm2 = crate::fs::remove_file(sink_path); + + result.and(rm1).and(rm2) +} + +#[bench] +fn bench_file_to_file_copy(b: &mut test::Bencher) { + const BYTES: usize = 128 * 1024; + let src_path = temp_dir().join("file-copy-bench-src"); + let mut src = crate::fs::OpenOptions::new() + .create(true) + .truncate(true) + .read(true) + .write(true) + .open(src_path) + .unwrap(); + src.write(&vec![0u8; BYTES]).unwrap(); + + let sink_path = temp_dir().join("file-copy-bench-sink"); + let mut sink = crate::fs::OpenOptions::new() + .create(true) + .truncate(true) + .write(true) + .open(sink_path) + .unwrap(); + + b.bytes = BYTES as u64; + b.iter(|| { + src.seek(SeekFrom::Start(0)).unwrap(); + sink.seek(SeekFrom::Start(0)).unwrap(); + assert_eq!(BYTES as u64, io::copy(&mut src, &mut sink).unwrap()); + }); +} + +#[bench] +fn bench_file_to_socket_copy(b: &mut test::Bencher) { + const BYTES: usize = 128 * 1024; + let src_path = temp_dir().join("pipe-copy-bench-src"); + let mut src = OpenOptions::new() + .create(true) + .truncate(true) + .read(true) + .write(true) + .open(src_path) + .unwrap(); + src.write(&vec![0u8; BYTES]).unwrap(); + + let sink_drainer = crate::net::TcpListener::bind("localhost:0").unwrap(); + let mut sink = crate::net::TcpStream::connect(sink_drainer.local_addr().unwrap()).unwrap(); + let mut sink_drainer = sink_drainer.accept().unwrap().0; + + crate::thread::spawn(move || { + let mut sink_buf = vec![0u8; 1024 * 1024]; + loop { + sink_drainer.read(&mut sink_buf[..]).unwrap(); + } + }); + + b.bytes = BYTES as u64; + b.iter(|| { + src.seek(SeekFrom::Start(0)).unwrap(); + assert_eq!(BYTES as u64, io::copy(&mut src, &mut sink).unwrap()); + }); +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +#[bench] +fn bench_socket_pipe_socket_copy(b: &mut test::Bencher) { + use crate::io::ErrorKind; + use crate::process::{ChildStdin, ChildStdout}; + use crate::sys_common::FromInner; + + let (read_end, write_end) = crate::sys::pipe::anon_pipe().unwrap(); + + let mut read_end = ChildStdout::from_inner(read_end); + let write_end = ChildStdin::from_inner(write_end); + + let acceptor = crate::net::TcpListener::bind("localhost:0").unwrap(); + let mut remote_end = crate::net::TcpStream::connect(acceptor.local_addr().unwrap()).unwrap(); + + let local_end = crate::sync::Arc::new(acceptor.accept().unwrap().0); + + crate::thread::spawn(move || { + let mut sink_buf = vec![0u8; 1024 * 1024]; + remote_end.set_nonblocking(true).unwrap(); + loop { + match remote_end.write(&mut sink_buf[..]) { + Err(err) if err.kind() == ErrorKind::WouldBlock => {} + Ok(_) => {} + err => { + err.expect("write failed"); + } + }; + match remote_end.read(&mut sink_buf[..]) { + Err(err) if err.kind() == ErrorKind::WouldBlock => {} + Ok(_) => {} + err => { + err.expect("read failed"); + } + }; + } + }); + + let local_source = local_end.clone(); + crate::thread::spawn(move || { + loop { + crate::sys::fs::sendfile_splice( + crate::sys::fs::SpliceMode::Splice, + local_source.as_raw_fd(), + write_end.as_raw_fd(), + u64::MAX, + ); + } + }); + + const BYTES: usize = 128 * 1024; + b.bytes = BYTES as u64; + b.iter(|| { + assert_eq!( + BYTES as u64, + io::copy(&mut (&mut read_end).take(BYTES as u64), &mut &*local_end).unwrap() + ); + }); +} diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index 9a0672e88b8..f176c2f088c 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -1,15 +1,8 @@ use super::{repeat, Cursor, SeekFrom}; use crate::cmp::{self, min}; -use crate::env::temp_dir; -#[cfg(unix)] -use crate::fs::OpenOptions; -#[cfg(unix)] -use crate::io::Result; use crate::io::{self, IoSlice, IoSliceMut}; use crate::io::{BufRead, Read, Seek, Write}; use crate::ops::Deref; -#[cfg(unix)] -use crate::os::unix::io::AsRawFd; #[test] #[cfg_attr(target_os = "emscripten", ignore)] @@ -499,177 +492,3 @@ fn test_write_all_vectored() { } } } - -#[test] -#[cfg(unix)] -fn copy_specialization() -> Result<()> { - use crate::io::{BufReader, BufWriter}; - - let path = crate::env::temp_dir(); - let source_path = path.join("copy-spec.source"); - let sink_path = path.join("copy-spec.sink"); - - let result: Result<()> = try { - let mut source = crate::fs::OpenOptions::new() - .read(true) - .write(true) - .create(true) - .truncate(true) - .open(&source_path)?; - source.write_all(b"abcdefghiklmnopqr")?; - source.seek(SeekFrom::Start(8))?; - let mut source = BufReader::with_capacity(8, source.take(5)); - source.fill_buf()?; - assert_eq!(source.buffer(), b"iklmn"); - source.get_mut().set_limit(6); - source.get_mut().get_mut().seek(SeekFrom::Start(1))?; // "bcdefg" - let mut source = source.take(10); // "iklmnbcdef" - - let mut sink = crate::fs::OpenOptions::new() - .read(true) - .write(true) - .create(true) - .truncate(true) - .open(&sink_path)?; - sink.write_all(b"000000")?; - let mut sink = BufWriter::with_capacity(5, sink); - sink.write_all(b"wxyz")?; - assert_eq!(sink.buffer(), b"wxyz"); - - let copied = crate::io::copy(&mut source, &mut sink)?; - assert_eq!(copied, 10); - assert_eq!(sink.buffer().len(), 0); - - let mut sink = sink.into_inner()?; - sink.seek(SeekFrom::Start(0))?; - let mut copied = Vec::new(); - sink.read_to_end(&mut copied)?; - assert_eq!(&copied, b"000000wxyziklmnbcdef"); - }; - - let rm1 = crate::fs::remove_file(source_path); - let rm2 = crate::fs::remove_file(sink_path); - - result.and(rm1).and(rm2) -} - -#[bench] -fn bench_file_to_file_copy(b: &mut test::Bencher) { - const BYTES: usize = 128 * 1024; - let src_path = temp_dir().join("file-copy-bench-src"); - let mut src = crate::fs::OpenOptions::new() - .create(true) - .truncate(true) - .read(true) - .write(true) - .open(src_path) - .unwrap(); - src.write(&vec![0u8; BYTES]).unwrap(); - - let sink_path = temp_dir().join("file-copy-bench-sink"); - let mut sink = crate::fs::OpenOptions::new() - .create(true) - .truncate(true) - .write(true) - .open(sink_path) - .unwrap(); - - b.bytes = BYTES as u64; - b.iter(|| { - src.seek(SeekFrom::Start(0)).unwrap(); - sink.seek(SeekFrom::Start(0)).unwrap(); - assert_eq!(BYTES as u64, io::copy(&mut src, &mut sink).unwrap()); - }); -} - -#[cfg(unix)] -#[bench] -fn bench_file_to_socket_copy(b: &mut test::Bencher) { - const BYTES: usize = 128 * 1024; - let src_path = temp_dir().join("pipe-copy-bench-src"); - let mut src = OpenOptions::new() - .create(true) - .truncate(true) - .read(true) - .write(true) - .open(src_path) - .unwrap(); - src.write(&vec![0u8; BYTES]).unwrap(); - - let sink_drainer = crate::net::TcpListener::bind("localhost:0").unwrap(); - let mut sink = crate::net::TcpStream::connect(sink_drainer.local_addr().unwrap()).unwrap(); - let mut sink_drainer = sink_drainer.accept().unwrap().0; - - crate::thread::spawn(move || { - let mut sink_buf = vec![0u8; 1024 * 1024]; - loop { - sink_drainer.read(&mut sink_buf[..]).unwrap(); - } - }); - - b.bytes = BYTES as u64; - b.iter(|| { - src.seek(SeekFrom::Start(0)).unwrap(); - assert_eq!(BYTES as u64, io::copy(&mut src, &mut sink).unwrap()); - }); -} - -#[cfg(any(target_os = "linux", target_os = "android"))] -#[bench] -fn bench_socket_pipe_socket_copy(b: &mut test::Bencher) { - use crate::io::ErrorKind; - use crate::process::{ChildStdin, ChildStdout}; - use crate::sys_common::FromInner; - - let (read_end, write_end) = crate::sys::pipe::anon_pipe().unwrap(); - - let mut read_end = ChildStdout::from_inner(read_end); - let write_end = ChildStdin::from_inner(write_end); - - let acceptor = crate::net::TcpListener::bind("localhost:0").unwrap(); - let mut remote_end = crate::net::TcpStream::connect(acceptor.local_addr().unwrap()).unwrap(); - - let local_end = crate::sync::Arc::new(acceptor.accept().unwrap().0); - - crate::thread::spawn(move || { - let mut sink_buf = vec![0u8; 1024 * 1024]; - remote_end.set_nonblocking(true).unwrap(); - loop { - match remote_end.write(&mut sink_buf[..]) { - Err(err) if err.kind() == ErrorKind::WouldBlock => {} - Ok(_) => {} - err => { - err.expect("write failed"); - } - }; - match remote_end.read(&mut sink_buf[..]) { - Err(err) if err.kind() == ErrorKind::WouldBlock => {} - Ok(_) => {} - err => { - err.expect("read failed"); - } - }; - } - }); - - let local_source = local_end.clone(); - crate::thread::spawn(move || { - loop { - crate::sys::fs::sendfile_splice( - crate::sys::fs::SpliceMode::Splice, - local_source.as_raw_fd(), - write_end.as_raw_fd(), - u64::MAX, - ); - } - }); - - const BYTES: usize = 128 * 1024; - b.bytes = BYTES as u64; - b.iter(|| { - assert_eq!( - BYTES as u64, - io::copy(&mut (&mut read_end).take(BYTES as u64), &mut &*local_end).unwrap() - ); - }); -} |
