Skip to content

Commit 18bfe2a

Browse files
committed
move copy specialization tests to their own module
1 parent 7f5d272 commit 18bfe2a

File tree

3 files changed

+182
-181
lines changed

3 files changed

+182
-181
lines changed

library/std/src/io/copy.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use crate::io::{self, ErrorKind, Read, Write};
22
use crate::mem::MaybeUninit;
33

4+
#[cfg(all(test, unix))]
5+
mod tests;
6+
47
/// Copies the entire contents of a reader into a writer.
58
///
69
/// This function will continuously read data from `reader` and then

library/std/src/io/copy/tests.rs

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
use crate::env::temp_dir;
2+
use crate::fs::OpenOptions;
3+
use crate::io;
4+
use crate::io::Result;
5+
use crate::io::SeekFrom;
6+
use crate::io::{BufRead, Read, Seek, Write};
7+
use crate::os::unix::io::AsRawFd;
8+
9+
#[test]
10+
fn copy_specialization() -> Result<()> {
11+
use crate::io::{BufReader, BufWriter};
12+
13+
let path = crate::env::temp_dir();
14+
let source_path = path.join("copy-spec.source");
15+
let sink_path = path.join("copy-spec.sink");
16+
17+
let result: Result<()> = try {
18+
let mut source = crate::fs::OpenOptions::new()
19+
.read(true)
20+
.write(true)
21+
.create(true)
22+
.truncate(true)
23+
.open(&source_path)?;
24+
source.write_all(b"abcdefghiklmnopqr")?;
25+
source.seek(SeekFrom::Start(8))?;
26+
let mut source = BufReader::with_capacity(8, source.take(5));
27+
source.fill_buf()?;
28+
assert_eq!(source.buffer(), b"iklmn");
29+
source.get_mut().set_limit(6);
30+
source.get_mut().get_mut().seek(SeekFrom::Start(1))?; // "bcdefg"
31+
let mut source = source.take(10); // "iklmnbcdef"
32+
33+
let mut sink = crate::fs::OpenOptions::new()
34+
.read(true)
35+
.write(true)
36+
.create(true)
37+
.truncate(true)
38+
.open(&sink_path)?;
39+
sink.write_all(b"000000")?;
40+
let mut sink = BufWriter::with_capacity(5, sink);
41+
sink.write_all(b"wxyz")?;
42+
assert_eq!(sink.buffer(), b"wxyz");
43+
44+
let copied = crate::io::copy(&mut source, &mut sink)?;
45+
assert_eq!(copied, 10);
46+
assert_eq!(sink.buffer().len(), 0);
47+
48+
let mut sink = sink.into_inner()?;
49+
sink.seek(SeekFrom::Start(0))?;
50+
let mut copied = Vec::new();
51+
sink.read_to_end(&mut copied)?;
52+
assert_eq!(&copied, b"000000wxyziklmnbcdef");
53+
};
54+
55+
let rm1 = crate::fs::remove_file(source_path);
56+
let rm2 = crate::fs::remove_file(sink_path);
57+
58+
result.and(rm1).and(rm2)
59+
}
60+
61+
#[bench]
62+
fn bench_file_to_file_copy(b: &mut test::Bencher) {
63+
const BYTES: usize = 128 * 1024;
64+
let src_path = temp_dir().join("file-copy-bench-src");
65+
let mut src = crate::fs::OpenOptions::new()
66+
.create(true)
67+
.truncate(true)
68+
.read(true)
69+
.write(true)
70+
.open(src_path)
71+
.unwrap();
72+
src.write(&vec![0u8; BYTES]).unwrap();
73+
74+
let sink_path = temp_dir().join("file-copy-bench-sink");
75+
let mut sink = crate::fs::OpenOptions::new()
76+
.create(true)
77+
.truncate(true)
78+
.write(true)
79+
.open(sink_path)
80+
.unwrap();
81+
82+
b.bytes = BYTES as u64;
83+
b.iter(|| {
84+
src.seek(SeekFrom::Start(0)).unwrap();
85+
sink.seek(SeekFrom::Start(0)).unwrap();
86+
assert_eq!(BYTES as u64, io::copy(&mut src, &mut sink).unwrap());
87+
});
88+
}
89+
90+
#[bench]
91+
fn bench_file_to_socket_copy(b: &mut test::Bencher) {
92+
const BYTES: usize = 128 * 1024;
93+
let src_path = temp_dir().join("pipe-copy-bench-src");
94+
let mut src = OpenOptions::new()
95+
.create(true)
96+
.truncate(true)
97+
.read(true)
98+
.write(true)
99+
.open(src_path)
100+
.unwrap();
101+
src.write(&vec![0u8; BYTES]).unwrap();
102+
103+
let sink_drainer = crate::net::TcpListener::bind("localhost:0").unwrap();
104+
let mut sink = crate::net::TcpStream::connect(sink_drainer.local_addr().unwrap()).unwrap();
105+
let mut sink_drainer = sink_drainer.accept().unwrap().0;
106+
107+
crate::thread::spawn(move || {
108+
let mut sink_buf = vec![0u8; 1024 * 1024];
109+
loop {
110+
sink_drainer.read(&mut sink_buf[..]).unwrap();
111+
}
112+
});
113+
114+
b.bytes = BYTES as u64;
115+
b.iter(|| {
116+
src.seek(SeekFrom::Start(0)).unwrap();
117+
assert_eq!(BYTES as u64, io::copy(&mut src, &mut sink).unwrap());
118+
});
119+
}
120+
121+
#[cfg(any(target_os = "linux", target_os = "android"))]
122+
#[bench]
123+
fn bench_socket_pipe_socket_copy(b: &mut test::Bencher) {
124+
use crate::io::ErrorKind;
125+
use crate::process::{ChildStdin, ChildStdout};
126+
use crate::sys_common::FromInner;
127+
128+
let (read_end, write_end) = crate::sys::pipe::anon_pipe().unwrap();
129+
130+
let mut read_end = ChildStdout::from_inner(read_end);
131+
let write_end = ChildStdin::from_inner(write_end);
132+
133+
let acceptor = crate::net::TcpListener::bind("localhost:0").unwrap();
134+
let mut remote_end = crate::net::TcpStream::connect(acceptor.local_addr().unwrap()).unwrap();
135+
136+
let local_end = crate::sync::Arc::new(acceptor.accept().unwrap().0);
137+
138+
crate::thread::spawn(move || {
139+
let mut sink_buf = vec![0u8; 1024 * 1024];
140+
remote_end.set_nonblocking(true).unwrap();
141+
loop {
142+
match remote_end.write(&mut sink_buf[..]) {
143+
Err(err) if err.kind() == ErrorKind::WouldBlock => {}
144+
Ok(_) => {}
145+
err => {
146+
err.expect("write failed");
147+
}
148+
};
149+
match remote_end.read(&mut sink_buf[..]) {
150+
Err(err) if err.kind() == ErrorKind::WouldBlock => {}
151+
Ok(_) => {}
152+
err => {
153+
err.expect("read failed");
154+
}
155+
};
156+
}
157+
});
158+
159+
let local_source = local_end.clone();
160+
crate::thread::spawn(move || {
161+
loop {
162+
crate::sys::fs::sendfile_splice(
163+
crate::sys::fs::SpliceMode::Splice,
164+
local_source.as_raw_fd(),
165+
write_end.as_raw_fd(),
166+
u64::MAX,
167+
);
168+
}
169+
});
170+
171+
const BYTES: usize = 128 * 1024;
172+
b.bytes = BYTES as u64;
173+
b.iter(|| {
174+
assert_eq!(
175+
BYTES as u64,
176+
io::copy(&mut (&mut read_end).take(BYTES as u64), &mut &*local_end).unwrap()
177+
);
178+
});
179+
}

library/std/src/io/tests.rs

Lines changed: 0 additions & 181 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
use super::{repeat, Cursor, SeekFrom};
22
use crate::cmp::{self, min};
3-
use crate::env::temp_dir;
4-
#[cfg(unix)]
5-
use crate::fs::OpenOptions;
6-
#[cfg(unix)]
7-
use crate::io::Result;
83
use crate::io::{self, IoSlice, IoSliceMut};
94
use crate::io::{BufRead, Read, Seek, Write};
105
use crate::ops::Deref;
11-
#[cfg(unix)]
12-
use crate::os::unix::io::AsRawFd;
136

147
#[test]
158
#[cfg_attr(target_os = "emscripten", ignore)]
@@ -499,177 +492,3 @@ fn test_write_all_vectored() {
499492
}
500493
}
501494
}
502-
503-
#[test]
504-
#[cfg(unix)]
505-
fn copy_specialization() -> Result<()> {
506-
use crate::io::{BufReader, BufWriter};
507-
508-
let path = crate::env::temp_dir();
509-
let source_path = path.join("copy-spec.source");
510-
let sink_path = path.join("copy-spec.sink");
511-
512-
let result: Result<()> = try {
513-
let mut source = crate::fs::OpenOptions::new()
514-
.read(true)
515-
.write(true)
516-
.create(true)
517-
.truncate(true)
518-
.open(&source_path)?;
519-
source.write_all(b"abcdefghiklmnopqr")?;
520-
source.seek(SeekFrom::Start(8))?;
521-
let mut source = BufReader::with_capacity(8, source.take(5));
522-
source.fill_buf()?;
523-
assert_eq!(source.buffer(), b"iklmn");
524-
source.get_mut().set_limit(6);
525-
source.get_mut().get_mut().seek(SeekFrom::Start(1))?; // "bcdefg"
526-
let mut source = source.take(10); // "iklmnbcdef"
527-
528-
let mut sink = crate::fs::OpenOptions::new()
529-
.read(true)
530-
.write(true)
531-
.create(true)
532-
.truncate(true)
533-
.open(&sink_path)?;
534-
sink.write_all(b"000000")?;
535-
let mut sink = BufWriter::with_capacity(5, sink);
536-
sink.write_all(b"wxyz")?;
537-
assert_eq!(sink.buffer(), b"wxyz");
538-
539-
let copied = crate::io::copy(&mut source, &mut sink)?;
540-
assert_eq!(copied, 10);
541-
assert_eq!(sink.buffer().len(), 0);
542-
543-
let mut sink = sink.into_inner()?;
544-
sink.seek(SeekFrom::Start(0))?;
545-
let mut copied = Vec::new();
546-
sink.read_to_end(&mut copied)?;
547-
assert_eq!(&copied, b"000000wxyziklmnbcdef");
548-
};
549-
550-
let rm1 = crate::fs::remove_file(source_path);
551-
let rm2 = crate::fs::remove_file(sink_path);
552-
553-
result.and(rm1).and(rm2)
554-
}
555-
556-
#[bench]
557-
fn bench_file_to_file_copy(b: &mut test::Bencher) {
558-
const BYTES: usize = 128 * 1024;
559-
let src_path = temp_dir().join("file-copy-bench-src");
560-
let mut src = crate::fs::OpenOptions::new()
561-
.create(true)
562-
.truncate(true)
563-
.read(true)
564-
.write(true)
565-
.open(src_path)
566-
.unwrap();
567-
src.write(&vec![0u8; BYTES]).unwrap();
568-
569-
let sink_path = temp_dir().join("file-copy-bench-sink");
570-
let mut sink = crate::fs::OpenOptions::new()
571-
.create(true)
572-
.truncate(true)
573-
.write(true)
574-
.open(sink_path)
575-
.unwrap();
576-
577-
b.bytes = BYTES as u64;
578-
b.iter(|| {
579-
src.seek(SeekFrom::Start(0)).unwrap();
580-
sink.seek(SeekFrom::Start(0)).unwrap();
581-
assert_eq!(BYTES as u64, io::copy(&mut src, &mut sink).unwrap());
582-
});
583-
}
584-
585-
#[cfg(unix)]
586-
#[bench]
587-
fn bench_file_to_socket_copy(b: &mut test::Bencher) {
588-
const BYTES: usize = 128 * 1024;
589-
let src_path = temp_dir().join("pipe-copy-bench-src");
590-
let mut src = OpenOptions::new()
591-
.create(true)
592-
.truncate(true)
593-
.read(true)
594-
.write(true)
595-
.open(src_path)
596-
.unwrap();
597-
src.write(&vec![0u8; BYTES]).unwrap();
598-
599-
let sink_drainer = crate::net::TcpListener::bind("localhost:0").unwrap();
600-
let mut sink = crate::net::TcpStream::connect(sink_drainer.local_addr().unwrap()).unwrap();
601-
let mut sink_drainer = sink_drainer.accept().unwrap().0;
602-
603-
crate::thread::spawn(move || {
604-
let mut sink_buf = vec![0u8; 1024 * 1024];
605-
loop {
606-
sink_drainer.read(&mut sink_buf[..]).unwrap();
607-
}
608-
});
609-
610-
b.bytes = BYTES as u64;
611-
b.iter(|| {
612-
src.seek(SeekFrom::Start(0)).unwrap();
613-
assert_eq!(BYTES as u64, io::copy(&mut src, &mut sink).unwrap());
614-
});
615-
}
616-
617-
#[cfg(any(target_os = "linux", target_os = "android"))]
618-
#[bench]
619-
fn bench_socket_pipe_socket_copy(b: &mut test::Bencher) {
620-
use crate::io::ErrorKind;
621-
use crate::process::{ChildStdin, ChildStdout};
622-
use crate::sys_common::FromInner;
623-
624-
let (read_end, write_end) = crate::sys::pipe::anon_pipe().unwrap();
625-
626-
let mut read_end = ChildStdout::from_inner(read_end);
627-
let write_end = ChildStdin::from_inner(write_end);
628-
629-
let acceptor = crate::net::TcpListener::bind("localhost:0").unwrap();
630-
let mut remote_end = crate::net::TcpStream::connect(acceptor.local_addr().unwrap()).unwrap();
631-
632-
let local_end = crate::sync::Arc::new(acceptor.accept().unwrap().0);
633-
634-
crate::thread::spawn(move || {
635-
let mut sink_buf = vec![0u8; 1024 * 1024];
636-
remote_end.set_nonblocking(true).unwrap();
637-
loop {
638-
match remote_end.write(&mut sink_buf[..]) {
639-
Err(err) if err.kind() == ErrorKind::WouldBlock => {}
640-
Ok(_) => {}
641-
err => {
642-
err.expect("write failed");
643-
}
644-
};
645-
match remote_end.read(&mut sink_buf[..]) {
646-
Err(err) if err.kind() == ErrorKind::WouldBlock => {}
647-
Ok(_) => {}
648-
err => {
649-
err.expect("read failed");
650-
}
651-
};
652-
}
653-
});
654-
655-
let local_source = local_end.clone();
656-
crate::thread::spawn(move || {
657-
loop {
658-
crate::sys::fs::sendfile_splice(
659-
crate::sys::fs::SpliceMode::Splice,
660-
local_source.as_raw_fd(),
661-
write_end.as_raw_fd(),
662-
u64::MAX,
663-
);
664-
}
665-
});
666-
667-
const BYTES: usize = 128 * 1024;
668-
b.bytes = BYTES as u64;
669-
b.iter(|| {
670-
assert_eq!(
671-
BYTES as u64,
672-
io::copy(&mut (&mut read_end).take(BYTES as u64), &mut &*local_end).unwrap()
673-
);
674-
});
675-
}

0 commit comments

Comments
 (0)