]> git.lizzy.rs Git - rust.git/blob - library/std/src/io/tests.rs
add benchmarks
[rust.git] / library / std / src / io / tests.rs
1 use super::{repeat, Cursor, SeekFrom};
2 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;
8 use crate::io::{self, IoSlice, IoSliceMut};
9 use crate::io::{BufRead, Read, Seek, Write};
10 use crate::ops::Deref;
11 #[cfg(unix)]
12 use crate::os::unix::io::AsRawFd;
13
14 #[test]
15 #[cfg_attr(target_os = "emscripten", ignore)]
16 fn read_until() {
17     let mut buf = Cursor::new(&b"12"[..]);
18     let mut v = Vec::new();
19     assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 2);
20     assert_eq!(v, b"12");
21
22     let mut buf = Cursor::new(&b"1233"[..]);
23     let mut v = Vec::new();
24     assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 3);
25     assert_eq!(v, b"123");
26     v.truncate(0);
27     assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 1);
28     assert_eq!(v, b"3");
29     v.truncate(0);
30     assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 0);
31     assert_eq!(v, []);
32 }
33
34 #[test]
35 fn split() {
36     let buf = Cursor::new(&b"12"[..]);
37     let mut s = buf.split(b'3');
38     assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']);
39     assert!(s.next().is_none());
40
41     let buf = Cursor::new(&b"1233"[..]);
42     let mut s = buf.split(b'3');
43     assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']);
44     assert_eq!(s.next().unwrap().unwrap(), vec![]);
45     assert!(s.next().is_none());
46 }
47
48 #[test]
49 fn read_line() {
50     let mut buf = Cursor::new(&b"12"[..]);
51     let mut v = String::new();
52     assert_eq!(buf.read_line(&mut v).unwrap(), 2);
53     assert_eq!(v, "12");
54
55     let mut buf = Cursor::new(&b"12\n\n"[..]);
56     let mut v = String::new();
57     assert_eq!(buf.read_line(&mut v).unwrap(), 3);
58     assert_eq!(v, "12\n");
59     v.truncate(0);
60     assert_eq!(buf.read_line(&mut v).unwrap(), 1);
61     assert_eq!(v, "\n");
62     v.truncate(0);
63     assert_eq!(buf.read_line(&mut v).unwrap(), 0);
64     assert_eq!(v, "");
65 }
66
67 #[test]
68 fn lines() {
69     let buf = Cursor::new(&b"12\r"[..]);
70     let mut s = buf.lines();
71     assert_eq!(s.next().unwrap().unwrap(), "12\r".to_string());
72     assert!(s.next().is_none());
73
74     let buf = Cursor::new(&b"12\r\n\n"[..]);
75     let mut s = buf.lines();
76     assert_eq!(s.next().unwrap().unwrap(), "12".to_string());
77     assert_eq!(s.next().unwrap().unwrap(), "".to_string());
78     assert!(s.next().is_none());
79 }
80
81 #[test]
82 fn read_to_end() {
83     let mut c = Cursor::new(&b""[..]);
84     let mut v = Vec::new();
85     assert_eq!(c.read_to_end(&mut v).unwrap(), 0);
86     assert_eq!(v, []);
87
88     let mut c = Cursor::new(&b"1"[..]);
89     let mut v = Vec::new();
90     assert_eq!(c.read_to_end(&mut v).unwrap(), 1);
91     assert_eq!(v, b"1");
92
93     let cap = 1024 * 1024;
94     let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>();
95     let mut v = Vec::new();
96     let (a, b) = data.split_at(data.len() / 2);
97     assert_eq!(Cursor::new(a).read_to_end(&mut v).unwrap(), a.len());
98     assert_eq!(Cursor::new(b).read_to_end(&mut v).unwrap(), b.len());
99     assert_eq!(v, data);
100 }
101
102 #[test]
103 fn read_to_string() {
104     let mut c = Cursor::new(&b""[..]);
105     let mut v = String::new();
106     assert_eq!(c.read_to_string(&mut v).unwrap(), 0);
107     assert_eq!(v, "");
108
109     let mut c = Cursor::new(&b"1"[..]);
110     let mut v = String::new();
111     assert_eq!(c.read_to_string(&mut v).unwrap(), 1);
112     assert_eq!(v, "1");
113
114     let mut c = Cursor::new(&b"\xff"[..]);
115     let mut v = String::new();
116     assert!(c.read_to_string(&mut v).is_err());
117 }
118
119 #[test]
120 fn read_exact() {
121     let mut buf = [0; 4];
122
123     let mut c = Cursor::new(&b""[..]);
124     assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
125
126     let mut c = Cursor::new(&b"123"[..]).chain(Cursor::new(&b"456789"[..]));
127     c.read_exact(&mut buf).unwrap();
128     assert_eq!(&buf, b"1234");
129     c.read_exact(&mut buf).unwrap();
130     assert_eq!(&buf, b"5678");
131     assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
132 }
133
134 #[test]
135 fn read_exact_slice() {
136     let mut buf = [0; 4];
137
138     let mut c = &b""[..];
139     assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
140
141     let mut c = &b"123"[..];
142     assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
143     // make sure the optimized (early returning) method is being used
144     assert_eq!(&buf, &[0; 4]);
145
146     let mut c = &b"1234"[..];
147     c.read_exact(&mut buf).unwrap();
148     assert_eq!(&buf, b"1234");
149
150     let mut c = &b"56789"[..];
151     c.read_exact(&mut buf).unwrap();
152     assert_eq!(&buf, b"5678");
153     assert_eq!(c, b"9");
154 }
155
156 #[test]
157 fn take_eof() {
158     struct R;
159
160     impl Read for R {
161         fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
162             Err(io::Error::new(io::ErrorKind::Other, ""))
163         }
164     }
165     impl BufRead for R {
166         fn fill_buf(&mut self) -> io::Result<&[u8]> {
167             Err(io::Error::new(io::ErrorKind::Other, ""))
168         }
169         fn consume(&mut self, _amt: usize) {}
170     }
171
172     let mut buf = [0; 1];
173     assert_eq!(0, R.take(0).read(&mut buf).unwrap());
174     assert_eq!(b"", R.take(0).fill_buf().unwrap());
175 }
176
177 fn cmp_bufread<Br1: BufRead, Br2: BufRead>(mut br1: Br1, mut br2: Br2, exp: &[u8]) {
178     let mut cat = Vec::new();
179     loop {
180         let consume = {
181             let buf1 = br1.fill_buf().unwrap();
182             let buf2 = br2.fill_buf().unwrap();
183             let minlen = if buf1.len() < buf2.len() { buf1.len() } else { buf2.len() };
184             assert_eq!(buf1[..minlen], buf2[..minlen]);
185             cat.extend_from_slice(&buf1[..minlen]);
186             minlen
187         };
188         if consume == 0 {
189             break;
190         }
191         br1.consume(consume);
192         br2.consume(consume);
193     }
194     assert_eq!(br1.fill_buf().unwrap().len(), 0);
195     assert_eq!(br2.fill_buf().unwrap().len(), 0);
196     assert_eq!(&cat[..], &exp[..])
197 }
198
199 #[test]
200 fn chain_bufread() {
201     let testdata = b"ABCDEFGHIJKL";
202     let chain1 =
203         (&testdata[..3]).chain(&testdata[3..6]).chain(&testdata[6..9]).chain(&testdata[9..]);
204     let chain2 = (&testdata[..4]).chain(&testdata[4..8]).chain(&testdata[8..]);
205     cmp_bufread(chain1, chain2, &testdata[..]);
206 }
207
208 #[test]
209 fn chain_zero_length_read_is_not_eof() {
210     let a = b"A";
211     let b = b"B";
212     let mut s = String::new();
213     let mut chain = (&a[..]).chain(&b[..]);
214     chain.read(&mut []).unwrap();
215     chain.read_to_string(&mut s).unwrap();
216     assert_eq!("AB", s);
217 }
218
219 #[bench]
220 #[cfg_attr(target_os = "emscripten", ignore)]
221 fn bench_read_to_end(b: &mut test::Bencher) {
222     b.iter(|| {
223         let mut lr = repeat(1).take(10000000);
224         let mut vec = Vec::with_capacity(1024);
225         super::read_to_end(&mut lr, &mut vec)
226     });
227 }
228
229 #[test]
230 fn seek_len() -> io::Result<()> {
231     let mut c = Cursor::new(vec![0; 15]);
232     assert_eq!(c.stream_len()?, 15);
233
234     c.seek(SeekFrom::End(0))?;
235     let old_pos = c.stream_position()?;
236     assert_eq!(c.stream_len()?, 15);
237     assert_eq!(c.stream_position()?, old_pos);
238
239     c.seek(SeekFrom::Start(7))?;
240     c.seek(SeekFrom::Current(2))?;
241     let old_pos = c.stream_position()?;
242     assert_eq!(c.stream_len()?, 15);
243     assert_eq!(c.stream_position()?, old_pos);
244
245     Ok(())
246 }
247
248 #[test]
249 fn seek_position() -> io::Result<()> {
250     // All `asserts` are duplicated here to make sure the method does not
251     // change anything about the seek state.
252     let mut c = Cursor::new(vec![0; 15]);
253     assert_eq!(c.stream_position()?, 0);
254     assert_eq!(c.stream_position()?, 0);
255
256     c.seek(SeekFrom::End(0))?;
257     assert_eq!(c.stream_position()?, 15);
258     assert_eq!(c.stream_position()?, 15);
259
260     c.seek(SeekFrom::Start(7))?;
261     c.seek(SeekFrom::Current(2))?;
262     assert_eq!(c.stream_position()?, 9);
263     assert_eq!(c.stream_position()?, 9);
264
265     c.seek(SeekFrom::End(-3))?;
266     c.seek(SeekFrom::Current(1))?;
267     c.seek(SeekFrom::Current(-5))?;
268     assert_eq!(c.stream_position()?, 8);
269     assert_eq!(c.stream_position()?, 8);
270
271     Ok(())
272 }
273
274 // A simple example reader which uses the default implementation of
275 // read_to_end.
276 struct ExampleSliceReader<'a> {
277     slice: &'a [u8],
278 }
279
280 impl<'a> Read for ExampleSliceReader<'a> {
281     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
282         let len = cmp::min(self.slice.len(), buf.len());
283         buf[..len].copy_from_slice(&self.slice[..len]);
284         self.slice = &self.slice[len..];
285         Ok(len)
286     }
287 }
288
289 #[test]
290 fn test_read_to_end_capacity() -> io::Result<()> {
291     let input = &b"foo"[..];
292
293     // read_to_end() generally needs to over-allocate, both for efficiency
294     // and so that it can distinguish EOF. Assert that this is the case
295     // with this simple ExampleSliceReader struct, which uses the default
296     // implementation of read_to_end. Even though vec1 is allocated with
297     // exactly enough capacity for the read, read_to_end will allocate more
298     // space here.
299     let mut vec1 = Vec::with_capacity(input.len());
300     ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?;
301     assert_eq!(vec1.len(), input.len());
302     assert!(vec1.capacity() > input.len(), "allocated more");
303
304     // However, std::io::Take includes an implementation of read_to_end
305     // that will not allocate when the limit has already been reached. In
306     // this case, vec2 never grows.
307     let mut vec2 = Vec::with_capacity(input.len());
308     ExampleSliceReader { slice: input }.take(input.len() as u64).read_to_end(&mut vec2)?;
309     assert_eq!(vec2.len(), input.len());
310     assert_eq!(vec2.capacity(), input.len(), "did not allocate more");
311
312     Ok(())
313 }
314
315 #[test]
316 fn io_slice_mut_advance() {
317     let mut buf1 = [1; 8];
318     let mut buf2 = [2; 16];
319     let mut buf3 = [3; 8];
320     let mut bufs = &mut [
321         IoSliceMut::new(&mut buf1),
322         IoSliceMut::new(&mut buf2),
323         IoSliceMut::new(&mut buf3),
324     ][..];
325
326     // Only in a single buffer..
327     bufs = IoSliceMut::advance(bufs, 1);
328     assert_eq!(bufs[0].deref(), [1; 7].as_ref());
329     assert_eq!(bufs[1].deref(), [2; 16].as_ref());
330     assert_eq!(bufs[2].deref(), [3; 8].as_ref());
331
332     // Removing a buffer, leaving others as is.
333     bufs = IoSliceMut::advance(bufs, 7);
334     assert_eq!(bufs[0].deref(), [2; 16].as_ref());
335     assert_eq!(bufs[1].deref(), [3; 8].as_ref());
336
337     // Removing a buffer and removing from the next buffer.
338     bufs = IoSliceMut::advance(bufs, 18);
339     assert_eq!(bufs[0].deref(), [3; 6].as_ref());
340 }
341
342 #[test]
343 fn io_slice_mut_advance_empty_slice() {
344     let empty_bufs = &mut [][..];
345     // Shouldn't panic.
346     IoSliceMut::advance(empty_bufs, 1);
347 }
348
349 #[test]
350 fn io_slice_mut_advance_beyond_total_length() {
351     let mut buf1 = [1; 8];
352     let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..];
353
354     // Going beyond the total length should be ok.
355     bufs = IoSliceMut::advance(bufs, 9);
356     assert!(bufs.is_empty());
357 }
358
359 #[test]
360 fn io_slice_advance() {
361     let buf1 = [1; 8];
362     let buf2 = [2; 16];
363     let buf3 = [3; 8];
364     let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..];
365
366     // Only in a single buffer..
367     bufs = IoSlice::advance(bufs, 1);
368     assert_eq!(bufs[0].deref(), [1; 7].as_ref());
369     assert_eq!(bufs[1].deref(), [2; 16].as_ref());
370     assert_eq!(bufs[2].deref(), [3; 8].as_ref());
371
372     // Removing a buffer, leaving others as is.
373     bufs = IoSlice::advance(bufs, 7);
374     assert_eq!(bufs[0].deref(), [2; 16].as_ref());
375     assert_eq!(bufs[1].deref(), [3; 8].as_ref());
376
377     // Removing a buffer and removing from the next buffer.
378     bufs = IoSlice::advance(bufs, 18);
379     assert_eq!(bufs[0].deref(), [3; 6].as_ref());
380 }
381
382 #[test]
383 fn io_slice_advance_empty_slice() {
384     let empty_bufs = &mut [][..];
385     // Shouldn't panic.
386     IoSlice::advance(empty_bufs, 1);
387 }
388
389 #[test]
390 fn io_slice_advance_beyond_total_length() {
391     let buf1 = [1; 8];
392     let mut bufs = &mut [IoSlice::new(&buf1)][..];
393
394     // Going beyond the total length should be ok.
395     bufs = IoSlice::advance(bufs, 9);
396     assert!(bufs.is_empty());
397 }
398
399 /// Create a new writer that reads from at most `n_bufs` and reads
400 /// `per_call` bytes (in total) per call to write.
401 fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter {
402     TestWriter { n_bufs, per_call, written: Vec::new() }
403 }
404
405 struct TestWriter {
406     n_bufs: usize,
407     per_call: usize,
408     written: Vec<u8>,
409 }
410
411 impl Write for TestWriter {
412     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
413         self.write_vectored(&[IoSlice::new(buf)])
414     }
415
416     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
417         let mut left = self.per_call;
418         let mut written = 0;
419         for buf in bufs.iter().take(self.n_bufs) {
420             let n = min(left, buf.len());
421             self.written.extend_from_slice(&buf[0..n]);
422             left -= n;
423             written += n;
424         }
425         Ok(written)
426     }
427
428     fn flush(&mut self) -> io::Result<()> {
429         Ok(())
430     }
431 }
432
433 #[test]
434 fn test_writer_read_from_one_buf() {
435     let mut writer = test_writer(1, 2);
436
437     assert_eq!(writer.write(&[]).unwrap(), 0);
438     assert_eq!(writer.write_vectored(&[]).unwrap(), 0);
439
440     // Read at most 2 bytes.
441     assert_eq!(writer.write(&[1, 1, 1]).unwrap(), 2);
442     let bufs = &[IoSlice::new(&[2, 2, 2])];
443     assert_eq!(writer.write_vectored(bufs).unwrap(), 2);
444
445     // Only read from first buf.
446     let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4, 4])];
447     assert_eq!(writer.write_vectored(bufs).unwrap(), 1);
448
449     assert_eq!(writer.written, &[1, 1, 2, 2, 3]);
450 }
451
452 #[test]
453 fn test_writer_read_from_multiple_bufs() {
454     let mut writer = test_writer(3, 3);
455
456     // Read at most 3 bytes from two buffers.
457     let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])];
458     assert_eq!(writer.write_vectored(bufs).unwrap(), 3);
459
460     // Read at most 3 bytes from three buffers.
461     let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])];
462     assert_eq!(writer.write_vectored(bufs).unwrap(), 3);
463
464     assert_eq!(writer.written, &[1, 2, 2, 3, 4, 5]);
465 }
466
467 #[test]
468 fn test_write_all_vectored() {
469     #[rustfmt::skip] // Becomes unreadable otherwise.
470     let tests: Vec<(_, &'static [u8])> = vec![
471         (vec![], &[]),
472         (vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]),
473         (vec![IoSlice::new(&[1])], &[1]),
474         (vec![IoSlice::new(&[1, 2])], &[1, 2]),
475         (vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]),
476         (vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]),
477         (vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]),
478         (vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]),
479         (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2])], &[1, 2, 2]),
480         (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]),
481         (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]),
482         (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]),
483         (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]),
484         (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 2, 2, 2, 2]),
485         (vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]),
486         (vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]),
487         (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]),
488         (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 2, 2, 3, 3, 3]),
489         (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]),
490     ];
491
492     let writer_configs = &[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)];
493
494     for (n_bufs, per_call) in writer_configs.iter().copied() {
495         for (mut input, wanted) in tests.clone().into_iter() {
496             let mut writer = test_writer(n_bufs, per_call);
497             assert!(writer.write_all_vectored(&mut *input).is_ok());
498             assert_eq!(&*writer.written, &*wanted);
499         }
500     }
501 }
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 }