2021-07-24 23:38:08 +00:00
|
|
|
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, availible, behaviour, bmax, bremain, btotal, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, outfile, parseargs, rlen, rmax, rposition, rremain, rsofar, rstat, sigusr, sigval, wlen, wstat
|
2021-07-23 21:53:24 +00:00
|
|
|
|
2021-03-16 21:32:55 +00:00
|
|
|
use crate::common::util::*;
|
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
use std::fs::{File, OpenOptions};
|
2021-06-30 21:47:48 +00:00
|
|
|
use std::io::{BufReader, Read, Write};
|
2021-07-06 18:52:48 +00:00
|
|
|
use std::path::PathBuf;
|
2021-06-30 21:47:48 +00:00
|
|
|
use tempfile::tempfile;
|
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
macro_rules! inf {
|
|
|
|
($fname:expr) => {{
|
2021-06-30 21:47:48 +00:00
|
|
|
&format!("if={}", $fname)
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
macro_rules! of {
|
|
|
|
($fname:expr) => {{
|
2021-06-30 21:47:48 +00:00
|
|
|
&format!("of={}", $fname)
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
macro_rules! fixture_path {
|
|
|
|
($fname:expr) => {{
|
2021-06-30 21:47:48 +00:00
|
|
|
PathBuf::from(format!("./tests/fixtures/dd/{}", $fname))
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
macro_rules! assert_fixture_exists {
|
|
|
|
($fname:expr) => {{
|
2021-06-30 21:47:48 +00:00
|
|
|
let fpath = fixture_path!($fname);
|
2021-07-06 18:52:48 +00:00
|
|
|
if !fpath.exists() {
|
2021-06-30 21:47:48 +00:00
|
|
|
panic!("Fixture missing: {:?}", fpath);
|
|
|
|
}
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
2021-08-04 19:47:03 +00:00
|
|
|
#[cfg(target_os = "linux")]
|
2021-07-06 18:52:48 +00:00
|
|
|
macro_rules! assert_fixture_not_exists {
|
|
|
|
($fname:expr) => {{
|
2021-06-30 21:47:48 +00:00
|
|
|
let fpath = PathBuf::from(format!("./fixtures/dd/{}", $fname));
|
2021-07-06 18:52:48 +00:00
|
|
|
if fpath.exists() {
|
2021-06-30 21:47:48 +00:00
|
|
|
panic!("Fixture present: {:?}", fpath);
|
|
|
|
}
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! build_test_file {
|
|
|
|
($fp:expr, $data:expr) => {{
|
|
|
|
OpenOptions::new()
|
|
|
|
.write(true)
|
|
|
|
.create(true)
|
|
|
|
.truncate(true)
|
|
|
|
.open($fp)
|
|
|
|
.unwrap()
|
|
|
|
.write_all($data)
|
|
|
|
.unwrap()
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! cmp_file (
|
|
|
|
($spec:expr, $test:expr) =>
|
|
|
|
{
|
|
|
|
let specfile_len = $spec.metadata().unwrap().len();
|
|
|
|
let testfile_len = $test.metadata().unwrap().len();
|
|
|
|
assert_eq!(testfile_len, specfile_len);
|
|
|
|
|
|
|
|
let spec = BufReader::new($spec);
|
|
|
|
let test = BufReader::new($test);
|
|
|
|
|
|
|
|
for (b_spec, b_test) in spec.bytes().zip(test.bytes())
|
|
|
|
{
|
|
|
|
assert_eq!(b_spec.unwrap(),
|
|
|
|
b_test.unwrap());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
);
|
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
fn build_ascii_block(n: usize) -> Vec<u8> {
|
|
|
|
(0..=127).cycle().take(n).collect()
|
2021-06-30 21:47:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sanity Tests
|
2021-06-21 18:17:47 +00:00
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn version() {
|
|
|
|
new_ucmd!().args(&["--version"]).succeeds();
|
2021-06-21 18:17:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn help() {
|
|
|
|
new_ucmd!().args(&["--help"]).succeeds();
|
2021-06-21 18:17:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_stdin_stdout() {
|
2021-06-21 18:17:47 +00:00
|
|
|
let input = build_ascii_block(521);
|
|
|
|
let output = String::from_utf8(input.clone()).unwrap();
|
|
|
|
new_ucmd!()
|
|
|
|
.args(&["status=none"])
|
|
|
|
.pipe_in(input)
|
2021-06-30 21:47:48 +00:00
|
|
|
.run()
|
|
|
|
.no_stderr()
|
2021-06-21 18:17:47 +00:00
|
|
|
.stdout_only(output);
|
|
|
|
}
|
|
|
|
|
2021-06-30 21:47:48 +00:00
|
|
|
// Top-Level Items
|
|
|
|
// count=N, skip=N, status=LEVEL, conv=FLAG, *flag=FLAG
|
2021-06-21 18:17:47 +00:00
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_stdin_stdout_count() {
|
2021-06-21 18:17:47 +00:00
|
|
|
let input = build_ascii_block(521);
|
|
|
|
let mut output = String::from_utf8(input.clone()).unwrap();
|
|
|
|
output.truncate(256);
|
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["status=none", "count=2", "ibs=128"])
|
2021-06-21 18:17:47 +00:00
|
|
|
.pipe_in(input)
|
2021-06-30 21:47:48 +00:00
|
|
|
.run()
|
|
|
|
.no_stderr()
|
2021-06-21 18:17:47 +00:00
|
|
|
.stdout_only(output);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_stdin_stdout_count_bytes() {
|
2021-06-21 18:17:47 +00:00
|
|
|
let input = build_ascii_block(521);
|
|
|
|
let mut output = String::from_utf8(input.clone()).unwrap();
|
|
|
|
output.truncate(256);
|
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["status=none", "count=256", "iflag=count_bytes"])
|
2021-06-21 18:17:47 +00:00
|
|
|
.pipe_in(input)
|
2021-06-30 21:47:48 +00:00
|
|
|
.run()
|
|
|
|
.no_stderr()
|
2021-06-21 18:17:47 +00:00
|
|
|
.stdout_only(output);
|
2021-03-16 21:32:55 +00:00
|
|
|
}
|
2021-06-21 18:17:47 +00:00
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_stdin_stdout_skip() {
|
2021-06-21 18:17:47 +00:00
|
|
|
let input = build_ascii_block(521);
|
|
|
|
let mut output = String::from_utf8(input.clone()).unwrap();
|
|
|
|
let _ = output.drain(..256);
|
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["status=none", "skip=2", "ibs=128"])
|
2021-06-21 18:17:47 +00:00
|
|
|
.pipe_in(input)
|
2021-06-30 21:47:48 +00:00
|
|
|
.run()
|
|
|
|
.no_stderr()
|
2021-06-21 18:17:47 +00:00
|
|
|
.stdout_only(output);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_stdin_stdout_skip_bytes() {
|
2021-06-21 18:17:47 +00:00
|
|
|
let input = build_ascii_block(521);
|
|
|
|
let mut output = String::from_utf8(input.clone()).unwrap();
|
|
|
|
let _ = output.drain(..256);
|
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["status=none", "skip=256", "ibs=128", "iflag=skip_bytes"])
|
2021-06-21 18:17:47 +00:00
|
|
|
.pipe_in(input)
|
2021-06-30 21:47:48 +00:00
|
|
|
.run()
|
|
|
|
.no_stderr()
|
2021-06-21 18:17:47 +00:00
|
|
|
.stdout_only(output);
|
|
|
|
}
|
|
|
|
|
2021-06-30 21:47:48 +00:00
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_stdin_stdout_skip_w_multiplier() {
|
|
|
|
let input = build_ascii_block(10 * 1024);
|
|
|
|
let output = String::from_utf8(input[5 * 1024..].to_vec()).unwrap();
|
2021-06-30 21:47:48 +00:00
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["status=none", "skip=5K", "iflag=skip_bytes"])
|
2021-06-30 21:47:48 +00:00
|
|
|
.pipe_in(input)
|
|
|
|
.run()
|
|
|
|
.no_stderr()
|
|
|
|
.stdout_is(output)
|
|
|
|
.success();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_stdin_stdout_count_w_multiplier() {
|
|
|
|
let input = build_ascii_block(5 * 1024);
|
|
|
|
let output = String::from_utf8(input[..2 * 1024].to_vec()).unwrap();
|
2021-06-30 21:47:48 +00:00
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["status=none", "count=2KiB", "iflag=count_bytes"])
|
2021-06-30 21:47:48 +00:00
|
|
|
.pipe_in(input)
|
|
|
|
.run()
|
|
|
|
.no_stderr()
|
|
|
|
.stdout_is(output)
|
|
|
|
.success();
|
|
|
|
}
|
|
|
|
|
2021-06-21 18:17:47 +00:00
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_final_stats_noxfer() {
|
2021-06-30 21:47:48 +00:00
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["status=noxfer"])
|
2021-06-21 18:17:47 +00:00
|
|
|
.succeeds()
|
|
|
|
.stderr_only("");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_final_stats_unspec() {
|
2021-06-21 18:17:47 +00:00
|
|
|
let output = vec![
|
|
|
|
"0+0 records in",
|
|
|
|
"0+0 records out",
|
|
|
|
"0 bytes (0 B, 0 B) copied, 0.0 s, 0 B/s",
|
|
|
|
];
|
2021-07-06 18:52:48 +00:00
|
|
|
let output = output.into_iter().fold(String::new(), |mut acc, s| {
|
|
|
|
acc.push_str(s);
|
|
|
|
acc.push('\n');
|
|
|
|
acc
|
|
|
|
});
|
|
|
|
new_ucmd!().run().stderr_only(&output).success();
|
2021-06-21 18:17:47 +00:00
|
|
|
}
|
|
|
|
|
2021-07-22 01:24:31 +00:00
|
|
|
#[cfg(target_os = "linux")]
|
2021-06-21 18:17:47 +00:00
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_excl_causes_failure_when_present() {
|
2021-06-30 21:47:48 +00:00
|
|
|
let fname = "this-file-exists-excl.txt";
|
|
|
|
assert_fixture_exists!(&fname);
|
|
|
|
|
|
|
|
let (_fix, mut ucmd) = at_and_ucmd!();
|
2021-07-06 18:52:48 +00:00
|
|
|
ucmd.args(&["of=this-file-exists-excl.txt", "conv=excl"])
|
2021-06-30 21:47:48 +00:00
|
|
|
.fails();
|
|
|
|
}
|
|
|
|
|
2021-07-22 01:24:31 +00:00
|
|
|
#[cfg(target_os = "linux")]
|
2021-06-30 21:47:48 +00:00
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_noatime_does_not_update_infile_atime() {
|
2021-07-22 22:49:17 +00:00
|
|
|
// NOTE: Not all environments support tracking access time. If this
|
|
|
|
// test fails on some systems and passes on others, assume the functionality
|
|
|
|
// is not working and the systems that pass it simply don't update file access time.
|
2021-06-30 21:47:48 +00:00
|
|
|
let fname = "this-ifile-exists-noatime.txt";
|
|
|
|
assert_fixture_exists!(&fname);
|
|
|
|
|
|
|
|
let (fix, mut ucmd) = at_and_ucmd!();
|
2021-07-06 18:52:48 +00:00
|
|
|
ucmd.args(&["status=none", "iflag=noatime", inf!(fname)]);
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-12 19:54:39 +00:00
|
|
|
let pre_atime = fix.metadata(fname).accessed().unwrap();
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
ucmd.run().no_stderr().success();
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-12 19:54:39 +00:00
|
|
|
let post_atime = fix.metadata(fname).accessed().unwrap();
|
2021-06-30 21:47:48 +00:00
|
|
|
assert_eq!(pre_atime, post_atime);
|
|
|
|
}
|
|
|
|
|
2021-07-22 01:24:31 +00:00
|
|
|
#[cfg(target_os = "linux")]
|
2021-06-30 21:47:48 +00:00
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_noatime_does_not_update_ofile_atime() {
|
2021-07-22 22:49:17 +00:00
|
|
|
// NOTE: Not all environments support tracking access time. If this
|
|
|
|
// test fails on some systems and passes on others, assume the functionality
|
|
|
|
// is not working and the systems that pass it simply don't update file access time.
|
2021-06-30 21:47:48 +00:00
|
|
|
let fname = "this-ofile-exists-noatime.txt";
|
|
|
|
assert_fixture_exists!(&fname);
|
|
|
|
|
|
|
|
let (fix, mut ucmd) = at_and_ucmd!();
|
2021-07-06 18:52:48 +00:00
|
|
|
ucmd.args(&["status=none", "oflag=noatime", of!(fname)]);
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-12 19:54:39 +00:00
|
|
|
let pre_atime = fix.metadata(fname).accessed().unwrap();
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
ucmd.pipe_in("").run().no_stderr().success();
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-12 19:54:39 +00:00
|
|
|
let post_atime = fix.metadata(fname).accessed().unwrap();
|
2021-06-30 21:47:48 +00:00
|
|
|
assert_eq!(pre_atime, post_atime);
|
|
|
|
}
|
|
|
|
|
2021-07-22 01:24:31 +00:00
|
|
|
#[cfg(target_os = "linux")]
|
2021-06-30 21:47:48 +00:00
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_nocreat_causes_failure_when_outfile_not_present() {
|
2021-06-30 21:47:48 +00:00
|
|
|
let fname = "this-file-does-not-exist.txt";
|
|
|
|
assert_fixture_not_exists!(&fname);
|
|
|
|
|
|
|
|
let (fix, mut ucmd) = at_and_ucmd!();
|
2021-07-08 00:27:47 +00:00
|
|
|
ucmd.args(&["conv=nocreat", of!(&fname)])
|
|
|
|
.pipe_in("")
|
|
|
|
.fails()
|
|
|
|
.stderr_is("dd Error: No such file or directory (os error 2)");
|
2021-07-12 19:54:39 +00:00
|
|
|
assert!(!fix.file_exists(fname));
|
2021-06-30 21:47:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_notrunc_does_not_truncate() {
|
2021-06-30 21:47:48 +00:00
|
|
|
// Set up test if needed (eg. after failure)
|
|
|
|
let fname = "this-file-exists-notrunc.txt";
|
|
|
|
let fpath = fixture_path!(fname);
|
2021-07-06 18:52:48 +00:00
|
|
|
match fpath.metadata() {
|
|
|
|
Ok(m) if m.len() == 256 => {}
|
|
|
|
_ => build_test_file!(&fpath, &build_ascii_block(256)),
|
2021-06-30 21:47:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let (fix, mut ucmd) = at_and_ucmd!();
|
2021-07-06 18:52:48 +00:00
|
|
|
ucmd.args(&["status=none", "conv=notrunc", of!(&fname), "if=null.txt"])
|
2021-06-30 21:47:48 +00:00
|
|
|
.run()
|
|
|
|
.no_stdout()
|
|
|
|
.no_stderr()
|
|
|
|
.success();
|
|
|
|
|
2021-07-12 19:54:39 +00:00
|
|
|
assert_eq!(256, fix.metadata(fname).len());
|
2021-06-30 21:47:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_existing_file_truncated() {
|
2021-06-30 21:47:48 +00:00
|
|
|
// Set up test if needed (eg. after failure)
|
|
|
|
let fname = "this-file-exists-truncated.txt";
|
|
|
|
let fpath = fixture_path!(fname);
|
2021-07-06 18:52:48 +00:00
|
|
|
match fpath.metadata() {
|
|
|
|
Ok(m) if m.len() == 256 => {}
|
|
|
|
_ => build_test_file!(&fpath, &vec![0; 256]),
|
2021-06-30 21:47:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let (fix, mut ucmd) = at_and_ucmd!();
|
2021-07-06 18:52:48 +00:00
|
|
|
ucmd.args(&["status=none", "if=null.txt", of!(fname)])
|
2021-06-30 21:47:48 +00:00
|
|
|
.run()
|
|
|
|
.no_stdout()
|
|
|
|
.no_stderr()
|
|
|
|
.success();
|
|
|
|
|
2021-07-12 19:54:39 +00:00
|
|
|
assert_eq!(0, fix.metadata(fname).len());
|
2021-06-30 21:47:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_null_stats() {
|
2021-06-30 21:47:48 +00:00
|
|
|
let stats = vec![
|
|
|
|
"0+0 records in\n",
|
|
|
|
"0+0 records out\n",
|
|
|
|
"0 bytes (0 B, 0 B) copied, 0.0 s, 0 B/s\n",
|
|
|
|
];
|
2021-07-06 18:52:48 +00:00
|
|
|
let stats = stats.into_iter().fold(String::new(), |mut acc, s| {
|
|
|
|
acc.push_str(s);
|
|
|
|
acc
|
|
|
|
});
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-06-21 18:17:47 +00:00
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["if=null.txt"])
|
2021-06-30 21:47:48 +00:00
|
|
|
.run()
|
|
|
|
.stderr_only(stats)
|
|
|
|
.success();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_null_fullblock() {
|
2021-06-30 21:47:48 +00:00
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["if=null.txt", "status=none", "iflag=fullblock"])
|
2021-06-30 21:47:48 +00:00
|
|
|
.run()
|
|
|
|
.no_stdout()
|
|
|
|
.no_stderr()
|
|
|
|
.success();
|
2021-06-21 18:17:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
2021-07-22 01:24:31 +00:00
|
|
|
#[ignore] // See note below before using this test.
|
2021-06-21 18:17:47 +00:00
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_fullblock() {
|
2021-06-30 21:47:48 +00:00
|
|
|
let tname = "fullblock-from-urand";
|
|
|
|
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
|
2021-07-01 21:33:30 +00:00
|
|
|
let exp_stats = vec![
|
2021-06-30 21:47:48 +00:00
|
|
|
"1+0 records in\n",
|
|
|
|
"1+0 records out\n",
|
|
|
|
"134217728 bytes (134 MB, 128 MiB) copied,",
|
2021-06-21 18:17:47 +00:00
|
|
|
];
|
2021-07-06 18:52:48 +00:00
|
|
|
let exp_stats = exp_stats.into_iter().fold(Vec::new(), |mut acc, s| {
|
|
|
|
acc.extend(s.bytes());
|
|
|
|
acc
|
|
|
|
});
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-01 21:33:30 +00:00
|
|
|
let ucmd = new_ucmd!()
|
2021-06-21 18:17:47 +00:00
|
|
|
.args(&[
|
2021-06-30 21:47:48 +00:00
|
|
|
"if=/dev/urandom",
|
|
|
|
of!(&tmp_fn),
|
|
|
|
"bs=128M",
|
|
|
|
// Note: In order for this test to actually test iflag=fullblock, the bs=VALUE
|
|
|
|
// must be big enough to 'overwhelm' urandom's store of bytes.
|
|
|
|
// Try executing 'dd if=/dev/urandom bs=128M count=1' (i.e without iflag=fullblock).
|
|
|
|
// The stats should contain the line: '0+1 records in' indicating a partial read.
|
|
|
|
// Since my system only copies 32 MiB without fullblock, I expect 128 MiB to be
|
|
|
|
// a reasonable value for testing most systems.
|
|
|
|
"count=1",
|
|
|
|
"iflag=fullblock",
|
2021-07-06 18:52:48 +00:00
|
|
|
])
|
|
|
|
.run();
|
2021-07-01 21:33:30 +00:00
|
|
|
ucmd.success();
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-01 21:33:30 +00:00
|
|
|
let run_stats = &ucmd.stderr()[..exp_stats.len()];
|
|
|
|
assert_eq!(exp_stats, run_stats);
|
2021-06-21 18:17:47 +00:00
|
|
|
}
|
|
|
|
|
2021-06-30 21:47:48 +00:00
|
|
|
// Fileio
|
2021-06-21 18:17:47 +00:00
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_ys_to_stdout() {
|
|
|
|
let output: Vec<_> = String::from("y\n").bytes().cycle().take(1024).collect();
|
2021-06-21 18:17:47 +00:00
|
|
|
let output = String::from_utf8(output).unwrap();
|
|
|
|
|
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["status=none", "if=y-nl-1k.txt"])
|
2021-06-21 18:17:47 +00:00
|
|
|
.run()
|
2021-06-30 21:47:48 +00:00
|
|
|
.no_stderr()
|
|
|
|
.stdout_is(output)
|
|
|
|
.success();
|
2021-06-21 18:17:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_zeros_to_stdout() {
|
|
|
|
let output = vec![0; 256 * 1024];
|
2021-06-21 18:17:47 +00:00
|
|
|
let output = String::from_utf8(output).unwrap();
|
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["status=none", "if=zero-256k.txt"])
|
2021-06-21 18:17:47 +00:00
|
|
|
.run()
|
2021-06-30 21:47:48 +00:00
|
|
|
.no_stderr()
|
|
|
|
.stdout_is(output)
|
|
|
|
.success();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_to_stdout_with_ibs_obs() {
|
|
|
|
let output: Vec<_> = String::from("y\n").bytes().cycle().take(1024).collect();
|
2021-06-30 21:47:48 +00:00
|
|
|
let output = String::from_utf8(output).unwrap();
|
|
|
|
|
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["status=none", "if=y-nl-1k.txt", "ibs=521", "obs=1031"])
|
2021-06-30 21:47:48 +00:00
|
|
|
.run()
|
|
|
|
.no_stderr()
|
|
|
|
.stdout_is(output)
|
|
|
|
.success();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_ascii_10k_to_stdout() {
|
|
|
|
let output = build_ascii_block(1024 * 1024);
|
2021-06-30 21:47:48 +00:00
|
|
|
// build_test_file!("ascii-10k.txt", &output);
|
|
|
|
let output = String::from_utf8(output).unwrap();
|
|
|
|
|
|
|
|
new_ucmd!()
|
2021-07-06 18:52:48 +00:00
|
|
|
.args(&["status=none", "if=ascii-10k.txt"])
|
2021-06-30 21:47:48 +00:00
|
|
|
.run()
|
|
|
|
.no_stderr()
|
|
|
|
.stdout_is(output)
|
|
|
|
.success();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_zeros_to_file() {
|
2021-06-30 21:47:48 +00:00
|
|
|
let tname = "zero-256k";
|
|
|
|
let test_fn = format!("{}.txt", tname);
|
|
|
|
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
|
2021-07-07 01:17:30 +00:00
|
|
|
assert_fixture_exists!(test_fn);
|
2021-06-30 21:47:48 +00:00
|
|
|
|
|
|
|
let (fix, mut ucmd) = at_and_ucmd!();
|
2021-07-06 18:52:48 +00:00
|
|
|
ucmd.args(&["status=none", inf!(test_fn), of!(tmp_fn)])
|
|
|
|
.run()
|
|
|
|
.no_stderr()
|
|
|
|
.no_stdout()
|
|
|
|
.success();
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
cmp_file!(
|
|
|
|
File::open(fixture_path!(&test_fn)).unwrap(),
|
|
|
|
fix.open(&tmp_fn)
|
|
|
|
);
|
2021-06-30 21:47:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_to_file_with_ibs_obs() {
|
2021-06-30 21:47:48 +00:00
|
|
|
let tname = "zero-256k";
|
|
|
|
let test_fn = format!("{}.txt", tname);
|
|
|
|
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
|
2021-07-07 01:17:30 +00:00
|
|
|
assert_fixture_exists!(test_fn);
|
2021-06-30 21:47:48 +00:00
|
|
|
|
|
|
|
let (fix, mut ucmd) = at_and_ucmd!();
|
|
|
|
ucmd.args(&[
|
|
|
|
"status=none",
|
|
|
|
inf!(test_fn),
|
|
|
|
of!(tmp_fn),
|
|
|
|
"ibs=222",
|
|
|
|
"obs=111",
|
|
|
|
])
|
2021-07-06 18:52:48 +00:00
|
|
|
.run()
|
|
|
|
.no_stderr()
|
|
|
|
.no_stdout()
|
|
|
|
.success();
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
cmp_file!(
|
|
|
|
File::open(fixture_path!(&test_fn)).unwrap(),
|
|
|
|
fix.open(&tmp_fn)
|
|
|
|
);
|
2021-06-30 21:47:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_ascii_521k_to_file() {
|
2021-06-30 21:47:48 +00:00
|
|
|
let tname = "ascii-521k";
|
2021-07-06 18:52:48 +00:00
|
|
|
let input = build_ascii_block(512 * 1024);
|
2021-06-30 21:47:48 +00:00
|
|
|
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
|
|
|
|
|
|
|
|
let (fix, mut ucmd) = at_and_ucmd!();
|
2021-07-06 18:52:48 +00:00
|
|
|
ucmd.args(&["status=none", of!(tmp_fn)])
|
2021-06-30 21:47:48 +00:00
|
|
|
.pipe_in(input.clone())
|
|
|
|
.run()
|
|
|
|
.no_stderr()
|
|
|
|
.no_stdout()
|
|
|
|
.success();
|
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
assert_eq!(512 * 1024, fix.metadata(&tmp_fn).len());
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
cmp_file!(
|
|
|
|
{
|
|
|
|
let mut input_f = tempfile().unwrap();
|
2021-07-12 19:54:39 +00:00
|
|
|
input_f.write_all(&input).unwrap();
|
2021-07-06 18:52:48 +00:00
|
|
|
input_f
|
|
|
|
},
|
|
|
|
fix.open(&tmp_fn)
|
|
|
|
);
|
2021-06-30 21:47:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[ignore]
|
|
|
|
#[cfg(unix)]
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_ascii_5_gibi_to_file() {
|
2021-06-30 21:47:48 +00:00
|
|
|
let tname = "ascii-5G";
|
|
|
|
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
|
|
|
|
|
|
|
|
let (fix, mut ucmd) = at_and_ucmd!();
|
2021-07-12 17:13:47 +00:00
|
|
|
ucmd.args(&[
|
|
|
|
"status=none",
|
|
|
|
"count=5G",
|
|
|
|
"iflag=count_bytes",
|
|
|
|
"if=/dev/zero",
|
2021-07-12 19:54:39 +00:00
|
|
|
of!(tmp_fn),
|
2021-07-12 17:13:47 +00:00
|
|
|
])
|
2021-07-06 18:52:48 +00:00
|
|
|
.run()
|
|
|
|
.no_stderr()
|
|
|
|
.no_stdout()
|
|
|
|
.success();
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
assert_eq!(5 * 1024 * 1024 * 1024, fix.metadata(&tmp_fn).len());
|
2021-06-30 21:47:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-07-06 18:52:48 +00:00
|
|
|
fn test_self_transfer() {
|
2021-06-30 21:47:48 +00:00
|
|
|
let fname = "self-transfer-256k.txt";
|
2021-07-07 01:17:30 +00:00
|
|
|
assert_fixture_exists!(fname);
|
2021-06-30 21:47:48 +00:00
|
|
|
|
|
|
|
let (fix, mut ucmd) = at_and_ucmd!();
|
2021-07-06 18:52:48 +00:00
|
|
|
ucmd.args(&["status=none", "conv=notrunc", inf!(fname), of!(fname)]);
|
2021-06-30 21:47:48 +00:00
|
|
|
|
|
|
|
assert!(fix.file_exists(fname));
|
2021-07-06 18:52:48 +00:00
|
|
|
assert_eq!(256 * 1024, fix.metadata(fname).len());
|
2021-06-30 21:47:48 +00:00
|
|
|
|
2021-07-06 18:52:48 +00:00
|
|
|
ucmd.run().no_stdout().no_stderr().success();
|
2021-06-30 21:47:48 +00:00
|
|
|
|
|
|
|
assert!(fix.file_exists(fname));
|
2021-07-06 18:52:48 +00:00
|
|
|
assert_eq!(256 * 1024, fix.metadata(fname).len());
|
2021-06-21 18:17:47 +00:00
|
|
|
}
|
|
|
|
|
2021-07-07 01:17:30 +00:00
|
|
|
#[test]
|
|
|
|
fn test_unicode_filenames() {
|
|
|
|
let tname = "😎💚🦊";
|
|
|
|
let test_fn = format!("{}.txt", tname);
|
|
|
|
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
|
|
|
|
assert_fixture_exists!(test_fn);
|
|
|
|
|
|
|
|
let (fix, mut ucmd) = at_and_ucmd!();
|
2021-07-08 16:14:06 +00:00
|
|
|
ucmd.args(&["status=none", inf!(test_fn), of!(tmp_fn)])
|
|
|
|
.run()
|
|
|
|
.no_stderr()
|
|
|
|
.no_stdout()
|
|
|
|
.success();
|
2021-07-07 01:17:30 +00:00
|
|
|
|
|
|
|
cmp_file!(
|
|
|
|
File::open(fixture_path!(&test_fn)).unwrap(),
|
|
|
|
fix.open(&tmp_fn)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-06-30 21:47:48 +00:00
|
|
|
// conv=[ascii,ebcdic,ibm], conv=[ucase,lcase], conv=[block,unblock], conv=sync
|
|
|
|
// TODO: Move conv tests from unit test module
|