1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

Addresses issues raised in PR#2474

- runs rustfmt on test_dd.rs
- eliminates compiler warnings
- adds many words to spellchecker ignore list
- adds sanity test for vexing conv=nocreat issue. Still WIP.
This commit is contained in:
Tyler 2021-07-06 11:52:48 -07:00
parent 418ecbe61a
commit 1ad89c5e89
9 changed files with 455 additions and 360 deletions

View file

@ -1,53 +1,41 @@
use crate::common::util::*;
use std::fs::{File, OpenOptions};
use std::io::{BufReader, Read, Write};
use std::path::{PathBuf};
use std::fs::{OpenOptions, File};
use std::path::PathBuf;
use tempfile::tempfile;
macro_rules! inf
{
($fname:expr) =>
{{
macro_rules! inf {
($fname:expr) => {{
&format!("if={}", $fname)
}};
}
macro_rules! of
{
($fname:expr) =>
{{
macro_rules! of {
($fname:expr) => {{
&format!("of={}", $fname)
}};
}
macro_rules! fixture_path
{
($fname:expr) =>
{{
macro_rules! fixture_path {
($fname:expr) => {{
PathBuf::from(format!("./tests/fixtures/dd/{}", $fname))
}};
}
macro_rules! assert_fixture_exists
{
($fname:expr) =>
{{
macro_rules! assert_fixture_exists {
($fname:expr) => {{
let fpath = fixture_path!($fname);
if !fpath.exists()
{
if !fpath.exists() {
panic!("Fixture missing: {:?}", fpath);
}
}};
}
macro_rules! assert_fixture_not_exists
{
($fname:expr) =>
{{
macro_rules! assert_fixture_not_exists {
($fname:expr) => {{
let fpath = PathBuf::from(format!("./fixtures/dd/{}", $fname));
if fpath.exists()
{
if fpath.exists() {
panic!("Fixture present: {:?}", fpath);
}
}};
@ -84,34 +72,23 @@ macro_rules! cmp_file (
};
);
fn build_ascii_block(n: usize) -> Vec<u8>
{
(0..=127)
.cycle()
.take(n)
.collect()
fn build_ascii_block(n: usize) -> Vec<u8> {
(0..=127).cycle().take(n).collect()
}
// Sanity Tests
#[test]
fn version()
{
new_ucmd!()
.args(&["--version"])
.succeeds();
fn version() {
new_ucmd!().args(&["--version"]).succeeds();
}
#[test]
fn help()
{
new_ucmd!()
.args(&["--help"])
.succeeds();
fn help() {
new_ucmd!().args(&["--help"]).succeeds();
}
#[test]
fn test_stdin_stdout()
{
fn test_stdin_stdout() {
let input = build_ascii_block(521);
let output = String::from_utf8(input.clone()).unwrap();
new_ucmd!()
@ -125,17 +102,12 @@ fn test_stdin_stdout()
// Top-Level Items
// count=N, skip=N, status=LEVEL, conv=FLAG, *flag=FLAG
#[test]
fn test_stdin_stdout_count()
{
fn test_stdin_stdout_count() {
let input = build_ascii_block(521);
let mut output = String::from_utf8(input.clone()).unwrap();
output.truncate(256);
new_ucmd!()
.args(&[
"status=none",
"count=2",
"ibs=128",
])
.args(&["status=none", "count=2", "ibs=128"])
.pipe_in(input)
.run()
.no_stderr()
@ -143,17 +115,12 @@ fn test_stdin_stdout_count()
}
#[test]
fn test_stdin_stdout_count_bytes()
{
fn test_stdin_stdout_count_bytes() {
let input = build_ascii_block(521);
let mut output = String::from_utf8(input.clone()).unwrap();
output.truncate(256);
new_ucmd!()
.args(&[
"status=none",
"count=256",
"iflag=count_bytes",
])
.args(&["status=none", "count=256", "iflag=count_bytes"])
.pipe_in(input)
.run()
.no_stderr()
@ -161,17 +128,12 @@ fn test_stdin_stdout_count_bytes()
}
#[test]
fn test_stdin_stdout_skip()
{
fn test_stdin_stdout_skip() {
let input = build_ascii_block(521);
let mut output = String::from_utf8(input.clone()).unwrap();
let _ = output.drain(..256);
new_ucmd!()
.args(&[
"status=none",
"skip=2",
"ibs=128",
])
.args(&["status=none", "skip=2", "ibs=128"])
.pipe_in(input)
.run()
.no_stderr()
@ -179,18 +141,12 @@ fn test_stdin_stdout_skip()
}
#[test]
fn test_stdin_stdout_skip_bytes()
{
fn test_stdin_stdout_skip_bytes() {
let input = build_ascii_block(521);
let mut output = String::from_utf8(input.clone()).unwrap();
let _ = output.drain(..256);
new_ucmd!()
.args(&[
"status=none",
"skip=256",
"ibs=128",
"iflag=skip_bytes",
])
.args(&["status=none", "skip=256", "ibs=128", "iflag=skip_bytes"])
.pipe_in(input)
.run()
.no_stderr()
@ -198,16 +154,11 @@ fn test_stdin_stdout_skip_bytes()
}
#[test]
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();
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();
new_ucmd!()
.args(&[
"status=none",
"skip=5K",
"iflag=skip_bytes"
])
.args(&["status=none", "skip=5K", "iflag=skip_bytes"])
.pipe_in(input)
.run()
.no_stderr()
@ -216,16 +167,11 @@ fn test_stdin_stdout_skip_w_multiplier()
}
#[test]
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();
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();
new_ucmd!()
.args(&[
"status=none",
"count=2KiB",
"iflag=count_bytes",
])
.args(&["status=none", "count=2KiB", "iflag=count_bytes"])
.pipe_in(input)
.run()
.no_stderr()
@ -234,133 +180,93 @@ fn test_stdin_stdout_count_w_multiplier()
}
#[test]
fn test_final_stats_noxfer()
{
fn test_final_stats_noxfer() {
new_ucmd!()
.args(&[
"status=noxfer",
])
.args(&["status=noxfer"])
.succeeds()
.stderr_only("");
}
#[test]
fn test_final_stats_unspec()
{
fn test_final_stats_unspec() {
let output = vec![
"0+0 records in",
"0+0 records out",
"0 bytes (0 B, 0 B) copied, 0.0 s, 0 B/s",
];
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();
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();
}
#[test]
fn test_excl_causes_failure_when_present()
{
fn test_excl_causes_failure_when_present() {
let fname = "this-file-exists-excl.txt";
assert_fixture_exists!(&fname);
let (_fix, mut ucmd) = at_and_ucmd!();
ucmd.args(&[
"of=this-file-exists-excl.txt",
"conv=excl",
])
ucmd.args(&["of=this-file-exists-excl.txt", "conv=excl"])
.fails();
}
#[test]
fn test_atime_updated()
{
fn test_atime_updated() {
let fname = "this-file-exists-no-noatime.txt";
assert_fixture_exists!(&fname);
let (fix, mut ucmd) = at_and_ucmd!();
ucmd.args(&[
"status=none",
inf!(fname),
]);
ucmd.args(&["status=none", inf!(fname)]);
let pre_atime = fix.metadata(&fname).accessed().unwrap();
ucmd.pipe_in("")
.run()
.no_stderr()
.success();
ucmd.pipe_in("").run().no_stderr().success();
let post_atime = fix.metadata(&fname).accessed().unwrap();
assert!(pre_atime != post_atime);
}
#[test]
fn test_noatime_does_not_update_infile_atime()
{
fn test_noatime_does_not_update_infile_atime() {
let fname = "this-ifile-exists-noatime.txt";
assert_fixture_exists!(&fname);
let (fix, mut ucmd) = at_and_ucmd!();
ucmd.args(&[
"status=none",
"iflag=noatime",
inf!(fname),
]);
ucmd.args(&["status=none", "iflag=noatime", inf!(fname)]);
let pre_atime = fix.metadata(&fname).accessed().unwrap();
ucmd.run()
.no_stderr()
.success();
ucmd.run().no_stderr().success();
let post_atime = fix.metadata(&fname).accessed().unwrap();
assert_eq!(pre_atime, post_atime);
}
#[test]
fn test_noatime_does_not_update_ofile_atime()
{
fn test_noatime_does_not_update_ofile_atime() {
let fname = "this-ofile-exists-noatime.txt";
assert_fixture_exists!(&fname);
let (fix, mut ucmd) = at_and_ucmd!();
ucmd.args(&[
"status=none",
"oflag=noatime",
of!(fname),
]);
ucmd.args(&["status=none", "oflag=noatime", of!(fname)]);
let pre_atime = fix.metadata(&fname).accessed().unwrap();
ucmd.pipe_in("")
.run()
.no_stderr()
.success();
ucmd.pipe_in("").run().no_stderr().success();
let post_atime = fix.metadata(&fname).accessed().unwrap();
assert_eq!(pre_atime, post_atime);
}
#[test]
fn test_nocreat_causes_failure_when_outfile_not_present()
{
fn test_nocreat_causes_failure_when_outfile_not_present() {
let fname = "this-file-does-not-exist.txt";
assert_fixture_not_exists!(&fname);
let (fix, mut ucmd) = at_and_ucmd!();
ucmd.args(&[
"conv=nocreat",
of!(&fname),
])
.pipe_in("")
.run();
ucmd.args(&["conv=nocreat", of!(&fname)]).pipe_in("").run();
assert!(!fix.file_exists(&fname));
@ -368,25 +274,17 @@ fn test_nocreat_causes_failure_when_outfile_not_present()
}
#[test]
fn test_notrunc_does_not_truncate()
{
fn test_notrunc_does_not_truncate() {
// Set up test if needed (eg. after failure)
let fname = "this-file-exists-notrunc.txt";
let fpath = fixture_path!(fname);
match fpath.metadata()
{
Ok(m) if m.len() == 256 => {},
_ =>
build_test_file!(&fpath, &build_ascii_block(256)),
match fpath.metadata() {
Ok(m) if m.len() == 256 => {}
_ => build_test_file!(&fpath, &build_ascii_block(256)),
}
let (fix, mut ucmd) = at_and_ucmd!();
ucmd.args(&[
"status=none",
"conv=notrunc",
of!(&fname),
"if=null.txt",
])
ucmd.args(&["status=none", "conv=notrunc", of!(&fname), "if=null.txt"])
.run()
.no_stdout()
.no_stderr()
@ -396,24 +294,17 @@ fn test_notrunc_does_not_truncate()
}
#[test]
fn test_existing_file_truncated()
{
fn test_existing_file_truncated() {
// Set up test if needed (eg. after failure)
let fname = "this-file-exists-truncated.txt";
let fpath = fixture_path!(fname);
match fpath.metadata()
{
Ok(m) if m.len() == 256 => {},
_ =>
build_test_file!(&fpath, &vec![0; 256]),
match fpath.metadata() {
Ok(m) if m.len() == 256 => {}
_ => build_test_file!(&fpath, &vec![0; 256]),
}
let (fix, mut ucmd) = at_and_ucmd!();
ucmd.args(&[
"status=none",
"if=null.txt",
of!(fname),
])
ucmd.args(&["status=none", "if=null.txt", of!(fname)])
.run()
.no_stdout()
.no_stderr()
@ -423,37 +314,28 @@ fn test_existing_file_truncated()
}
#[test]
fn test_null_stats()
{
fn test_null_stats() {
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",
];
let stats = stats.into_iter()
.fold(String::new(), | mut acc, s | {
acc.push_str(s);
acc
});
let stats = stats.into_iter().fold(String::new(), |mut acc, s| {
acc.push_str(s);
acc
});
new_ucmd!()
.args(&[
"if=null.txt",
])
.args(&["if=null.txt"])
.run()
.stderr_only(stats)
.success();
}
#[test]
fn test_null_fullblock()
{
fn test_null_fullblock() {
new_ucmd!()
.args(&[
"if=null.txt",
"status=none",
"iflag=fullblock",
])
.args(&["if=null.txt", "status=none", "iflag=fullblock"])
.run()
.no_stdout()
.no_stderr()
@ -463,8 +345,7 @@ fn test_null_fullblock()
#[cfg(unix)]
// #[ignore] // See note below before running this test!
#[test]
fn test_fullblock()
{
fn test_fullblock() {
let tname = "fullblock-from-urand";
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
let exp_stats = vec![
@ -472,11 +353,10 @@ fn test_fullblock()
"1+0 records out\n",
"134217728 bytes (134 MB, 128 MiB) copied,",
];
let exp_stats = exp_stats.into_iter()
.fold(Vec::new(), | mut acc, s | {
acc.extend(s.bytes());
acc
});
let exp_stats = exp_stats.into_iter().fold(Vec::new(), |mut acc, s| {
acc.extend(s.bytes());
acc
});
let ucmd = new_ucmd!()
.args(&[
@ -491,7 +371,8 @@ fn test_fullblock()
// a reasonable value for testing most systems.
"count=1",
"iflag=fullblock",
]).run();
])
.run();
ucmd.success();
let run_stats = &ucmd.stderr()[..exp_stats.len()];
@ -500,20 +381,12 @@ fn test_fullblock()
// Fileio
#[test]
fn test_ys_to_stdout()
{
let output: Vec<_> = String::from("y\n")
.bytes()
.cycle()
.take(1024)
.collect();
fn test_ys_to_stdout() {
let output: Vec<_> = String::from("y\n").bytes().cycle().take(1024).collect();
let output = String::from_utf8(output).unwrap();
new_ucmd!()
.args(&[
"status=none",
"if=y-nl-1k.txt",
])
.args(&["status=none", "if=y-nl-1k.txt"])
.run()
.no_stderr()
.stdout_is(output)
@ -521,15 +394,11 @@ fn test_ys_to_stdout()
}
#[test]
fn test_zeros_to_stdout()
{
let output = vec![0; 256*1024];
fn test_zeros_to_stdout() {
let output = vec![0; 256 * 1024];
let output = String::from_utf8(output).unwrap();
new_ucmd!()
.args(&[
"status=none",
"if=zero-256k.txt",
])
.args(&["status=none", "if=zero-256k.txt"])
.run()
.no_stderr()
.stdout_is(output)
@ -537,22 +406,12 @@ fn test_zeros_to_stdout()
}
#[test]
fn test_to_stdout_with_ibs_obs()
{
let output: Vec<_> = String::from("y\n")
.bytes()
.cycle()
.take(1024)
.collect();
fn test_to_stdout_with_ibs_obs() {
let output: Vec<_> = String::from("y\n").bytes().cycle().take(1024).collect();
let output = String::from_utf8(output).unwrap();
new_ucmd!()
.args(&[
"status=none",
"if=y-nl-1k.txt",
"ibs=521",
"obs=1031",
])
.args(&["status=none", "if=y-nl-1k.txt", "ibs=521", "obs=1031"])
.run()
.no_stderr()
.stdout_is(output)
@ -560,17 +419,13 @@ fn test_to_stdout_with_ibs_obs()
}
#[test]
fn test_ascii_10k_to_stdout()
{
let output = build_ascii_block(1024*1024);
fn test_ascii_10k_to_stdout() {
let output = build_ascii_block(1024 * 1024);
// build_test_file!("ascii-10k.txt", &output);
let output = String::from_utf8(output).unwrap();
new_ucmd!()
.args(&[
"status=none",
"if=ascii-10k.txt",
])
.args(&["status=none", "if=ascii-10k.txt"])
.run()
.no_stderr()
.stdout_is(output)
@ -578,30 +433,26 @@ fn test_ascii_10k_to_stdout()
}
#[test]
fn test_zeros_to_file()
{
fn test_zeros_to_file() {
let tname = "zero-256k";
let test_fn = format!("{}.txt", tname);
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
let (fix, mut ucmd) = at_and_ucmd!();
ucmd.args(&[
"status=none",
inf!(test_fn),
of!(tmp_fn),
])
.run()
.no_stderr()
.no_stdout()
.success();
ucmd.args(&["status=none", inf!(test_fn), of!(tmp_fn)])
.run()
.no_stderr()
.no_stdout()
.success();
cmp_file!(File::open(fixture_path!(&test_fn)).unwrap(),
fix.open(&tmp_fn));
cmp_file!(
File::open(fixture_path!(&test_fn)).unwrap(),
fix.open(&tmp_fn)
);
}
#[test]
fn test_to_file_with_ibs_obs()
{
fn test_to_file_with_ibs_obs() {
let tname = "zero-256k";
let test_fn = format!("{}.txt", tname);
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
@ -614,46 +465,47 @@ fn test_to_file_with_ibs_obs()
"ibs=222",
"obs=111",
])
.run()
.no_stderr()
.no_stdout()
.success();
.run()
.no_stderr()
.no_stdout()
.success();
cmp_file!(File::open(fixture_path!(&test_fn)).unwrap(),
fix.open(&tmp_fn));
cmp_file!(
File::open(fixture_path!(&test_fn)).unwrap(),
fix.open(&tmp_fn)
);
}
#[test]
fn test_ascii_521k_to_file()
{
fn test_ascii_521k_to_file() {
let tname = "ascii-521k";
let input = build_ascii_block(512*1024);
let input = build_ascii_block(512 * 1024);
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
let (fix, mut ucmd) = at_and_ucmd!();
ucmd.args(&[
"status=none",
of!(tmp_fn),
])
ucmd.args(&["status=none", of!(tmp_fn)])
.pipe_in(input.clone())
.run()
.no_stderr()
.no_stdout()
.success();
assert_eq!(512*1024, fix.metadata(&tmp_fn).len());
assert_eq!(512 * 1024, fix.metadata(&tmp_fn).len());
cmp_file!({ let mut input_f = tempfile().unwrap();
input_f.write(&input).unwrap();
input_f },
fix.open(&tmp_fn));
cmp_file!(
{
let mut input_f = tempfile().unwrap();
input_f.write(&input).unwrap();
input_f
},
fix.open(&tmp_fn)
);
}
#[ignore]
#[cfg(unix)]
#[test]
fn test_ascii_5_gibi_to_file()
{
fn test_ascii_5_gibi_to_file() {
let tname = "ascii-5G";
let tmp_fn = format!("TESTFILE-{}.tmp", &tname);
@ -665,37 +517,28 @@ fn test_ascii_5_gibi_to_file()
"if=/dev/zero",
of!(tmp_fn),
])
.run()
.no_stderr()
.no_stdout()
.success();
.run()
.no_stderr()
.no_stdout()
.success();
assert_eq!(5*1024*1024*1024, fix.metadata(&tmp_fn).len());
assert_eq!(5 * 1024 * 1024 * 1024, fix.metadata(&tmp_fn).len());
}
#[test]
fn test_self_transfer()
{
fn test_self_transfer() {
let fname = "self-transfer-256k.txt";
let (fix, mut ucmd) = at_and_ucmd!();
ucmd.args(&[
"status=none",
"conv=notrunc",
inf!(fname),
of!(fname),
]);
ucmd.args(&["status=none", "conv=notrunc", inf!(fname), of!(fname)]);
assert!(fix.file_exists(fname));
assert_eq!(256*1024, fix.metadata(fname).len());
assert_eq!(256 * 1024, fix.metadata(fname).len());
ucmd.run()
.no_stdout()
.no_stderr()
.success();
ucmd.run().no_stdout().no_stderr().success();
assert!(fix.file_exists(fname));
assert_eq!(256*1024, fix.metadata(fname).len());
assert_eq!(256 * 1024, fix.metadata(fname).len());
}
// conv=[ascii,ebcdic,ibm], conv=[ucase,lcase], conv=[block,unblock], conv=sync