1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

Merge pull request #3141 from jfinkels/dd-modules

dd: move unit tests into dd.rs and test_dd.rs
This commit is contained in:
Sylvestre Ledru 2022-02-17 10:15:07 +01:00 committed by GitHub
commit 8e79b7fcb8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
61 changed files with 835 additions and 1100 deletions

View file

@ -7,9 +7,6 @@
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, 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 seekable
#[cfg(test)]
mod dd_unit_tests;
mod datastructures;
use datastructures::*;
@ -1193,3 +1190,454 @@ General-Flags
")
)
}
#[cfg(test)]
mod tests {
use crate::datastructures::{IConvFlags, IFlags, OConvFlags};
use crate::ReadStat;
use crate::{block, calc_bsize, unblock, uu_app, Input, Output, OutputTrait};
use std::cmp;
use std::fs;
use std::fs::File;
use std::io;
use std::io::{BufReader, Read};
struct LazyReader<R: Read> {
src: R,
}
impl<R: Read> Read for LazyReader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let reduced = cmp::max(buf.len() / 2, 1);
self.src.read(&mut buf[..reduced])
}
}
const NEWLINE: u8 = b'\n';
const SPACE: u8 = b' ';
#[test]
fn block_test_no_nl() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, 3u8];
let res = block(&buf, 4, &mut rs);
assert_eq!(res, vec![vec![0u8, 1u8, 2u8, 3u8],]);
}
#[test]
fn block_test_no_nl_short_record() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, 3u8];
let res = block(&buf, 8, &mut rs);
assert_eq!(
res,
vec![vec![0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE],]
);
}
#[test]
fn block_test_no_nl_trunc() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, 3u8, 4u8];
let res = block(&buf, 4, &mut rs);
// Commented section(s) should be truncated and appear for reference only.
assert_eq!(res, vec![vec![0u8, 1u8, 2u8, 3u8 /*, 4u8*/],]);
assert_eq!(rs.records_truncated, 1);
}
#[test]
fn block_test_nl_gt_cbs_trunc() {
let mut rs = ReadStat::default();
let buf = [
0u8, 1u8, 2u8, 3u8, 4u8, NEWLINE, 0u8, 1u8, 2u8, 3u8, 4u8, NEWLINE, 5u8, 6u8, 7u8, 8u8,
];
let res = block(&buf, 4, &mut rs);
assert_eq!(
res,
vec![
// Commented section(s) should be truncated and appear for reference only.
vec![0u8, 1u8, 2u8, 3u8],
// vec![4u8, SPACE, SPACE, SPACE],
vec![0u8, 1u8, 2u8, 3u8],
// vec![4u8, SPACE, SPACE, SPACE],
vec![5u8, 6u8, 7u8, 8u8],
]
);
assert_eq!(rs.records_truncated, 2);
}
#[test]
fn block_test_surrounded_nl() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, 3u8, NEWLINE, 4u8, 5u8, 6u8, 7u8, 8u8];
let res = block(&buf, 8, &mut rs);
assert_eq!(
res,
vec![
vec![0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE],
vec![4u8, 5u8, 6u8, 7u8, 8u8, SPACE, SPACE, SPACE],
]
);
}
#[test]
fn block_test_multiple_nl_same_cbs_block() {
let mut rs = ReadStat::default();
let buf = [
0u8, 1u8, 2u8, 3u8, NEWLINE, 4u8, NEWLINE, 5u8, 6u8, 7u8, 8u8, 9u8,
];
let res = block(&buf, 8, &mut rs);
assert_eq!(
res,
vec![
vec![0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE],
vec![4u8, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE],
vec![5u8, 6u8, 7u8, 8u8, 9u8, SPACE, SPACE, SPACE],
]
);
}
#[test]
fn block_test_multiple_nl_diff_cbs_block() {
let mut rs = ReadStat::default();
let buf = [
0u8, 1u8, 2u8, 3u8, NEWLINE, 4u8, 5u8, 6u8, 7u8, NEWLINE, 8u8, 9u8,
];
let res = block(&buf, 8, &mut rs);
assert_eq!(
res,
vec![
vec![0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE],
vec![4u8, 5u8, 6u8, 7u8, SPACE, SPACE, SPACE, SPACE],
vec![8u8, 9u8, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE],
]
);
}
#[test]
fn block_test_end_nl_diff_cbs_block() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, 3u8, NEWLINE];
let res = block(&buf, 4, &mut rs);
assert_eq!(res, vec![vec![0u8, 1u8, 2u8, 3u8],]);
}
#[test]
fn block_test_end_nl_same_cbs_block() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, NEWLINE];
let res = block(&buf, 4, &mut rs);
assert_eq!(res, vec![vec![0u8, 1u8, 2u8, SPACE]]);
}
#[test]
fn block_test_double_end_nl() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, NEWLINE, NEWLINE];
let res = block(&buf, 4, &mut rs);
assert_eq!(
res,
vec![vec![0u8, 1u8, 2u8, SPACE], vec![SPACE, SPACE, SPACE, SPACE],]
);
}
#[test]
fn block_test_start_nl() {
let mut rs = ReadStat::default();
let buf = [NEWLINE, 0u8, 1u8, 2u8, 3u8];
let res = block(&buf, 4, &mut rs);
assert_eq!(
res,
vec![vec![SPACE, SPACE, SPACE, SPACE], vec![0u8, 1u8, 2u8, 3u8],]
);
}
#[test]
fn block_test_double_surrounded_nl_no_trunc() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, 3u8, NEWLINE, NEWLINE, 4u8, 5u8, 6u8, 7u8];
let res = block(&buf, 8, &mut rs);
assert_eq!(
res,
vec![
vec![0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE],
vec![SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE],
vec![4u8, 5u8, 6u8, 7u8, SPACE, SPACE, SPACE, SPACE],
]
);
}
#[test]
fn block_test_double_surrounded_nl_double_trunc() {
let mut rs = ReadStat::default();
let buf = [
0u8, 1u8, 2u8, 3u8, NEWLINE, NEWLINE, 4u8, 5u8, 6u8, 7u8, 8u8,
];
let res = block(&buf, 4, &mut rs);
assert_eq!(
res,
vec![
// Commented section(s) should be truncated and appear for reference only.
vec![0u8, 1u8, 2u8, 3u8],
vec![SPACE, SPACE, SPACE, SPACE],
vec![4u8, 5u8, 6u8, 7u8 /*, 8u8*/],
]
);
assert_eq!(rs.records_truncated, 1);
}
#[test]
fn unblock_test_full_cbs() {
let buf = [0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8];
let res = unblock(&buf, 8);
assert_eq!(res, vec![0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, NEWLINE],);
}
#[test]
fn unblock_test_all_space() {
let buf = [SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE];
let res = unblock(&buf, 8);
assert_eq!(res, vec![NEWLINE],);
}
#[test]
fn unblock_test_decoy_spaces() {
let buf = [0u8, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, 7u8];
let res = unblock(&buf, 8);
assert_eq!(
res,
vec![0u8, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, 7u8, NEWLINE],
);
}
#[test]
fn unblock_test_strip_single_cbs() {
let buf = [0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE];
let res = unblock(&buf, 8);
assert_eq!(res, vec![0u8, 1u8, 2u8, 3u8, NEWLINE],);
}
#[test]
fn unblock_test_strip_multi_cbs() {
let buf = vec![
vec![0u8, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE],
vec![0u8, 1u8, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE],
vec![0u8, 1u8, 2u8, SPACE, SPACE, SPACE, SPACE, SPACE],
vec![0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE],
]
.into_iter()
.flatten()
.collect::<Vec<_>>();
let res = unblock(&buf, 8);
let exp = vec![
vec![0u8, NEWLINE],
vec![0u8, 1u8, NEWLINE],
vec![0u8, 1u8, 2u8, NEWLINE],
vec![0u8, 1u8, 2u8, 3u8, NEWLINE],
]
.into_iter()
.flatten()
.collect::<Vec<_>>();
assert_eq!(res, exp);
}
#[test]
fn bsize_test_primes() {
let (n, m) = (7901, 7919);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, n * m);
}
#[test]
fn bsize_test_rel_prime_obs_greater() {
let (n, m) = (7 * 5119, 13 * 5119);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, 7 * 13 * 5119);
}
#[test]
fn bsize_test_rel_prime_ibs_greater() {
let (n, m) = (13 * 5119, 7 * 5119);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, 7 * 13 * 5119);
}
#[test]
fn bsize_test_3fac_rel_prime() {
let (n, m) = (11 * 13 * 5119, 7 * 11 * 5119);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, 7 * 11 * 13 * 5119);
}
#[test]
fn bsize_test_ibs_greater() {
let (n, m) = (512 * 1024, 256 * 1024);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, n);
}
#[test]
fn bsize_test_obs_greater() {
let (n, m) = (256 * 1024, 512 * 1024);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, m);
}
#[test]
fn bsize_test_bs_eq() {
let (n, m) = (1024, 1024);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, m);
}
#[test]
#[should_panic]
fn test_nocreat_causes_failure_when_ofile_doesnt_exist() {
let args = vec![
String::from("dd"),
String::from("--conv=nocreat"),
String::from("--of=not-a-real.file"),
];
let matches = uu_app().try_get_matches_from(args).unwrap();
let _ = Output::<File>::new(&matches).unwrap();
}
#[test]
fn test_deadbeef_16_delayed() {
let input = Input {
src: LazyReader {
src: File::open("./test-resources/deadbeef-16.test").unwrap(),
},
non_ascii: false,
ibs: 16,
print_level: None,
count: None,
cflags: IConvFlags {
sync: Some(0),
..IConvFlags::default()
},
iflags: IFlags::default(),
};
let output = Output {
dst: File::create("./test-resources/FAILED-deadbeef-16-delayed.test").unwrap(),
obs: 32,
cflags: OConvFlags::default(),
};
output.dd_out(input).unwrap();
let tmp_fname = "./test-resources/FAILED-deadbeef-16-delayed.test";
let spec = File::open("./test-resources/deadbeef-16.spec").unwrap();
let res = File::open(tmp_fname).unwrap();
// Check test file isn't empty (unless spec file is too)
assert_eq!(
res.metadata().unwrap().len(),
spec.metadata().unwrap().len()
);
let spec = BufReader::new(spec);
let res = BufReader::new(res);
// Check all bytes match
for (b_res, b_spec) in res.bytes().zip(spec.bytes()) {
assert_eq!(b_res.unwrap(), b_spec.unwrap());
}
fs::remove_file(tmp_fname).unwrap();
}
#[test]
fn test_random_73k_test_lazy_fullblock() {
let input = Input {
src: LazyReader {
src: File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test")
.unwrap(),
},
non_ascii: false,
ibs: 521,
print_level: None,
count: None,
cflags: IConvFlags::default(),
iflags: IFlags {
fullblock: true,
..IFlags::default()
},
};
let output = Output {
dst: File::create("./test-resources/FAILED-random_73k_test_lazy_fullblock.test")
.unwrap(),
obs: 1031,
cflags: OConvFlags::default(),
};
output.dd_out(input).unwrap();
let tmp_fname = "./test-resources/FAILED-random_73k_test_lazy_fullblock.test";
let spec =
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap();
let res = File::open(tmp_fname).unwrap();
// Check test file isn't empty (unless spec file is too)
assert_eq!(
res.metadata().unwrap().len(),
spec.metadata().unwrap().len()
);
let spec = BufReader::new(spec);
let res = BufReader::new(res);
// Check all bytes match
for (b_res, b_spec) in res.bytes().zip(spec.bytes()) {
assert_eq!(b_res.unwrap(), b_spec.unwrap());
}
fs::remove_file(tmp_fname).unwrap();
}
}

View file

@ -1,351 +0,0 @@
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, 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
use super::*;
#[cfg(unix)]
macro_rules! make_block_test (
( $test_id:ident, $test_name:expr, $src:expr, $block:expr, $spec:expr ) =>
{
make_spec_test!($test_id,
$test_name,
Input {
src: $src,
non_ascii: false,
ibs: 512,
print_level: None,
count: None,
cflags: IConvFlags {
block: $block,
..IConvFlags::default()
},
iflags: IFlags::default(),
},
Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: 512,
cflags: OConvFlags::default(),
},
$spec,
format!("./test-resources/FAILED-{}.test", $test_name)
);
};
);
#[cfg(unix)]
macro_rules! make_unblock_test (
( $test_id:ident, $test_name:expr, $src:expr, $unblock:expr, $spec:expr ) =>
{
make_spec_test!($test_id,
$test_name,
Input {
src: $src,
non_ascii: false,
ibs: 512,
print_level: None,
count: None,
cflags: IConvFlags {
unblock: $unblock,
..IConvFlags::default()
},
iflags: IFlags::default(),
},
Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: 512,
cflags: OConvFlags::default(),
},
$spec,
format!("./test-resources/FAILED-{}.test", $test_name)
);
};
);
#[test]
fn block_test_no_nl() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, 3u8];
let res = block(&buf, 4, &mut rs);
assert_eq!(res, vec![vec![0u8, 1u8, 2u8, 3u8],]);
}
#[test]
fn block_test_no_nl_short_record() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, 3u8];
let res = block(&buf, 8, &mut rs);
assert_eq!(
res,
vec![vec![0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE],]
);
}
#[test]
fn block_test_no_nl_trunc() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, 3u8, 4u8];
let res = block(&buf, 4, &mut rs);
// Commented section(s) should be truncated and appear for reference only.
assert_eq!(res, vec![vec![0u8, 1u8, 2u8, 3u8 /*, 4u8*/],]);
assert_eq!(rs.records_truncated, 1);
}
#[test]
fn block_test_nl_gt_cbs_trunc() {
let mut rs = ReadStat::default();
let buf = [
0u8, 1u8, 2u8, 3u8, 4u8, NEWLINE, 0u8, 1u8, 2u8, 3u8, 4u8, NEWLINE, 5u8, 6u8, 7u8, 8u8,
];
let res = block(&buf, 4, &mut rs);
assert_eq!(
res,
vec![
// Commented section(s) should be truncated and appear for reference only.
vec![0u8, 1u8, 2u8, 3u8],
// vec![4u8, SPACE, SPACE, SPACE],
vec![0u8, 1u8, 2u8, 3u8],
// vec![4u8, SPACE, SPACE, SPACE],
vec![5u8, 6u8, 7u8, 8u8],
]
);
assert_eq!(rs.records_truncated, 2);
}
#[test]
fn block_test_surrounded_nl() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, 3u8, NEWLINE, 4u8, 5u8, 6u8, 7u8, 8u8];
let res = block(&buf, 8, &mut rs);
assert_eq!(
res,
vec![
vec![0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE],
vec![4u8, 5u8, 6u8, 7u8, 8u8, SPACE, SPACE, SPACE],
]
);
}
#[test]
fn block_test_multiple_nl_same_cbs_block() {
let mut rs = ReadStat::default();
let buf = [
0u8, 1u8, 2u8, 3u8, NEWLINE, 4u8, NEWLINE, 5u8, 6u8, 7u8, 8u8, 9u8,
];
let res = block(&buf, 8, &mut rs);
assert_eq!(
res,
vec![
vec![0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE],
vec![4u8, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE],
vec![5u8, 6u8, 7u8, 8u8, 9u8, SPACE, SPACE, SPACE],
]
);
}
#[test]
fn block_test_multiple_nl_diff_cbs_block() {
let mut rs = ReadStat::default();
let buf = [
0u8, 1u8, 2u8, 3u8, NEWLINE, 4u8, 5u8, 6u8, 7u8, NEWLINE, 8u8, 9u8,
];
let res = block(&buf, 8, &mut rs);
assert_eq!(
res,
vec![
vec![0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE],
vec![4u8, 5u8, 6u8, 7u8, SPACE, SPACE, SPACE, SPACE],
vec![8u8, 9u8, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE],
]
);
}
#[test]
fn block_test_end_nl_diff_cbs_block() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, 3u8, NEWLINE];
let res = block(&buf, 4, &mut rs);
assert_eq!(res, vec![vec![0u8, 1u8, 2u8, 3u8],]);
}
#[test]
fn block_test_end_nl_same_cbs_block() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, NEWLINE];
let res = block(&buf, 4, &mut rs);
assert_eq!(res, vec![vec![0u8, 1u8, 2u8, SPACE]]);
}
#[test]
fn block_test_double_end_nl() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, NEWLINE, NEWLINE];
let res = block(&buf, 4, &mut rs);
assert_eq!(
res,
vec![vec![0u8, 1u8, 2u8, SPACE], vec![SPACE, SPACE, SPACE, SPACE],]
);
}
#[test]
fn block_test_start_nl() {
let mut rs = ReadStat::default();
let buf = [NEWLINE, 0u8, 1u8, 2u8, 3u8];
let res = block(&buf, 4, &mut rs);
assert_eq!(
res,
vec![vec![SPACE, SPACE, SPACE, SPACE], vec![0u8, 1u8, 2u8, 3u8],]
);
}
#[test]
fn block_test_double_surrounded_nl_no_trunc() {
let mut rs = ReadStat::default();
let buf = [0u8, 1u8, 2u8, 3u8, NEWLINE, NEWLINE, 4u8, 5u8, 6u8, 7u8];
let res = block(&buf, 8, &mut rs);
assert_eq!(
res,
vec![
vec![0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE],
vec![SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE],
vec![4u8, 5u8, 6u8, 7u8, SPACE, SPACE, SPACE, SPACE],
]
);
}
#[test]
fn block_test_double_surrounded_nl_double_trunc() {
let mut rs = ReadStat::default();
let buf = [
0u8, 1u8, 2u8, 3u8, NEWLINE, NEWLINE, 4u8, 5u8, 6u8, 7u8, 8u8,
];
let res = block(&buf, 4, &mut rs);
assert_eq!(
res,
vec![
// Commented section(s) should be truncated and appear for reference only.
vec![0u8, 1u8, 2u8, 3u8],
vec![SPACE, SPACE, SPACE, SPACE],
vec![4u8, 5u8, 6u8, 7u8 /*, 8u8*/],
]
);
assert_eq!(rs.records_truncated, 1);
}
#[cfg(unix)]
make_block_test!(
block_cbs16,
"block-cbs-16",
File::open("./test-resources/dd-block-cbs16.test").unwrap(),
Some(16),
File::open("./test-resources/dd-block-cbs16.spec").unwrap()
);
#[cfg(unix)]
make_block_test!(
block_cbs16_as_cbs8,
"block-cbs-16-as-cbs8",
File::open("./test-resources/dd-block-cbs16.test").unwrap(),
Some(8),
File::open("./test-resources/dd-block-cbs8.spec").unwrap()
);
#[cfg(unix)]
make_block_test!(
block_consecutive_nl,
"block-consecutive-nl",
File::open("./test-resources/dd-block-consecutive-nl.test").unwrap(),
Some(16),
File::open("./test-resources/dd-block-consecutive-nl-cbs16.spec").unwrap()
);
#[test]
fn unblock_test_full_cbs() {
let buf = [0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8];
let res = unblock(&buf, 8);
assert_eq!(res, vec![0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, NEWLINE],);
}
#[test]
fn unblock_test_all_space() {
let buf = [SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE];
let res = unblock(&buf, 8);
assert_eq!(res, vec![NEWLINE],);
}
#[test]
fn unblock_test_decoy_spaces() {
let buf = [0u8, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, 7u8];
let res = unblock(&buf, 8);
assert_eq!(
res,
vec![0u8, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, 7u8, NEWLINE],
);
}
#[test]
fn unblock_test_strip_single_cbs() {
let buf = [0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE];
let res = unblock(&buf, 8);
assert_eq!(res, vec![0u8, 1u8, 2u8, 3u8, NEWLINE],);
}
#[test]
fn unblock_test_strip_multi_cbs() {
let buf = vec![
vec![0u8, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE],
vec![0u8, 1u8, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE],
vec![0u8, 1u8, 2u8, SPACE, SPACE, SPACE, SPACE, SPACE],
vec![0u8, 1u8, 2u8, 3u8, SPACE, SPACE, SPACE, SPACE],
]
.into_iter()
.flatten()
.collect::<Vec<_>>();
let res = unblock(&buf, 8);
let exp = vec![
vec![0u8, NEWLINE],
vec![0u8, 1u8, NEWLINE],
vec![0u8, 1u8, 2u8, NEWLINE],
vec![0u8, 1u8, 2u8, 3u8, NEWLINE],
]
.into_iter()
.flatten()
.collect::<Vec<_>>();
assert_eq!(res, exp);
}
#[cfg(unix)]
make_unblock_test!(
unblock_multi_16,
"unblock-multi-16",
File::open("./test-resources/dd-unblock-cbs16.test").unwrap(),
Some(16),
File::open("./test-resources/dd-unblock-cbs16.spec").unwrap()
);
#[cfg(unix)]
make_unblock_test!(
unblock_multi_16_as_8,
"unblock-multi-16-as-8",
File::open("./test-resources/dd-unblock-cbs16.test").unwrap(),
Some(8),
File::open("./test-resources/dd-unblock-cbs8.spec").unwrap()
);

View file

@ -1,106 +0,0 @@
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, 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
use super::*;
macro_rules! make_sync_test (
( $test_id:ident, $test_name:expr, $src:expr, $sync:expr, $ibs:expr, $obs:expr, $spec:expr ) =>
{
make_spec_test!($test_id,
$test_name,
Input {
src: $src,
non_ascii: false,
ibs: $ibs,
print_level: None,
count: None,
cflags: IConvFlags {
sync: $sync,
..IConvFlags::default()
},
iflags: IFlags::default(),
},
Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: $obs,
cflags: OConvFlags::default(),
},
$spec,
format!("./test-resources/FAILED-{}.test", $test_name)
);
};
);
// Zeros
make_sync_test!(
zeros_4k_conv_sync_obs_gt_ibs,
"zeros_4k_conv_sync_obs_gt_ibs",
File::open("./test-resources/zeros-620f0b67a91f7f74151bc5be745b7110.test").unwrap(),
Some(0u8),
521,
1031,
File::open("./test-resources/gnudd-conv-sync-ibs-521-obs-1031-zeros.spec").unwrap()
);
make_sync_test!(
zeros_4k_conv_sync_ibs_gt_obs,
"zeros_4k_conv_sync_ibs_gt_obs",
File::open("./test-resources/zeros-620f0b67a91f7f74151bc5be745b7110.test").unwrap(),
Some(0u8),
1031,
521,
File::open("./test-resources/gnudd-conv-sync-ibs-1031-obs-521-zeros.spec").unwrap()
);
// Deadbeef
make_sync_test!(
deadbeef_32k_conv_sync_obs_gt_ibs,
"deadbeef_32k_conv_sync_obs_gt_ibs",
File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap(),
Some(0u8),
521,
1031,
File::open("./test-resources/gnudd-conv-sync-ibs-521-obs-1031-deadbeef.spec").unwrap()
);
make_sync_test!(
deadbeef_32k_conv_sync_ibs_gt_obs,
"deadbeef_32k_conv_sync_ibs_gt_obs",
File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap(),
Some(0u8),
1031,
521,
File::open("./test-resources/gnudd-conv-sync-ibs-1031-obs-521-deadbeef.spec").unwrap()
);
// Random
make_sync_test!(
random_73k_test_bs_prime_obs_gt_ibs_sync,
"random-73k-test-bs-prime-obs-gt-ibs-sync",
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap(),
Some(0u8),
521,
1031,
File::open("./test-resources/gnudd-conv-sync-ibs-521-obs-1031-random.spec").unwrap()
);
make_sync_test!(
random_73k_test_bs_prime_ibs_gt_obs_sync,
"random-73k-test-bs-prime-ibs-gt-obs-sync",
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap(),
Some(0u8),
1031,
521,
File::open("./test-resources/gnudd-conv-sync-ibs-1031-obs-521-random.spec").unwrap()
);
make_sync_test!(
deadbeef_16_delayed,
"deadbeef-16-delayed",
LazyReader {
src: File::open("./test-resources/deadbeef-16.test").unwrap()
},
Some(0u8),
16,
32,
File::open("./test-resources/deadbeef-16.spec").unwrap()
);

View file

@ -1,233 +0,0 @@
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, 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
use super::*;
macro_rules! make_conv_test (
( $test_id:ident, $test_name:expr, $src:expr, $ctable:expr, $spec:expr ) =>
{
make_spec_test!($test_id,
$test_name,
Input {
src: $src,
non_ascii: false,
ibs: 512,
print_level: None,
count: None,
cflags: icf!($ctable),
iflags: IFlags::default(),
},
Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: 512,
cflags: OConvFlags::default(),
},
$spec,
format!("./test-resources/FAILED-{}.test", $test_name)
);
};
);
macro_rules! make_icf_test (
( $test_id:ident, $test_name:expr, $src:expr, $icf:expr, $spec:expr ) =>
{
make_spec_test!($test_id,
$test_name,
Input {
src: $src,
non_ascii: false,
ibs: 512,
print_level: None,
count: None,
cflags: $icf,
iflags: IFlags::default(),
},
Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: 512,
cflags: OConvFlags::default(),
},
$spec,
format!("./test-resources/FAILED-{}.test", $test_name)
);
};
);
make_conv_test!(
atoe_conv_spec_test,
"atoe-conv-spec-test",
File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(),
Some(&ASCII_TO_EBCDIC),
File::open("./test-resources/gnudd-conv-atoe-seq-byte-values.spec").unwrap()
);
make_conv_test!(
etoa_conv_spec_test,
"etoa-conv-spec-test",
File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(),
Some(&EBCDIC_TO_ASCII),
File::open("./test-resources/gnudd-conv-etoa-seq-byte-values.spec").unwrap()
);
make_conv_test!(
atoibm_conv_spec_test,
"atoibm-conv-spec-test",
File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(),
Some(&ASCII_TO_IBM),
File::open("./test-resources/gnudd-conv-atoibm-seq-byte-values.spec").unwrap()
);
make_conv_test!(
lcase_ascii_to_ucase_ascii,
"lcase_ascii_to_ucase_ascii",
File::open("./test-resources/lcase-ascii.test").unwrap(),
Some(&ASCII_LCASE_TO_UCASE),
File::open("./test-resources/ucase-ascii.test").unwrap()
);
make_conv_test!(
ucase_ascii_to_lcase_ascii,
"ucase_ascii_to_lcase_ascii",
File::open("./test-resources/ucase-ascii.test").unwrap(),
Some(&ASCII_UCASE_TO_LCASE),
File::open("./test-resources/lcase-ascii.test").unwrap()
);
make_conv_test!(
// conv=ebcdic,ucase
atoe_and_ucase_conv_spec_test,
"atoe-and-ucase-conv-spec-test",
File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(),
Some(&ASCII_TO_EBCDIC_LCASE_TO_UCASE),
File::open("./test-resources/ucase-ebcdic.test").unwrap()
);
make_conv_test!(
// conv=ebcdic,lcase
atoe_and_lcase_conv_spec_test,
"atoe-and-lcase-conv-spec-test",
File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(),
Some(&ASCII_TO_EBCDIC_UCASE_TO_LCASE),
File::open("./test-resources/lcase-ebcdic.test").unwrap()
);
make_conv_test!(
// conv=ibm,ucase
atoibm_and_ucase_conv_spec_test,
"atoibm-and-ucase-conv-spec-test",
File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(),
Some(&ASCII_TO_IBM_UCASE_TO_LCASE),
File::open("./test-resources/lcase-ibm.test").unwrap()
);
make_conv_test!(
// conv=ibm,lcase
atoibm_and_lcase_conv_spec_test,
"atoibm-and-lcase-conv-spec-test",
File::open("./test-resources/seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test").unwrap(),
Some(&ASCII_TO_IBM_LCASE_TO_UCASE),
File::open("./test-resources/ucase-ibm.test").unwrap()
);
#[test]
fn all_valid_ascii_ebcdic_ascii_roundtrip_conv_test() {
// ASCII->EBCDIC
let test_name = "all-valid-ascii-to-ebcdic";
let tmp_fname_ae = format!("./test-resources/FAILED-{}.test", test_name);
let i = Input {
src: File::open(
"./test-resources/all-valid-ascii-chars-37eff01866ba3f538421b30b7cbefcac.test",
)
.unwrap(),
non_ascii: false,
ibs: 128,
print_level: None,
count: None,
cflags: icf!(Some(&ASCII_TO_EBCDIC)),
iflags: IFlags::default(),
};
let o = Output {
dst: File::create(&tmp_fname_ae).unwrap(),
obs: 1024,
cflags: OConvFlags::default(),
};
o.dd_out(i).unwrap();
// EBCDIC->ASCII
let test_name = "all-valid-ebcdic-to-ascii";
let tmp_fname_ea = format!("./test-resources/FAILED-{}.test", test_name);
let i = Input {
src: File::open(&tmp_fname_ae).unwrap(),
non_ascii: false,
ibs: 256,
print_level: None,
count: None,
cflags: icf!(Some(&EBCDIC_TO_ASCII)),
iflags: IFlags::default(),
};
let o = Output {
dst: File::create(&tmp_fname_ea).unwrap(),
obs: 1024,
cflags: OConvFlags::default(),
};
o.dd_out(i).unwrap();
// Final Comparison
let res = File::open(&tmp_fname_ea).unwrap();
let spec =
File::open("./test-resources/all-valid-ascii-chars-37eff01866ba3f538421b30b7cbefcac.test")
.unwrap();
assert_eq!(
res.metadata().unwrap().len(),
spec.metadata().unwrap().len()
);
let res = BufReader::new(res);
let spec = BufReader::new(spec);
let res = BufReader::new(res);
// Check all bytes match
for (b_res, b_spec) in res.bytes().zip(spec.bytes()) {
assert_eq!(b_res.unwrap(), b_spec.unwrap());
}
fs::remove_file(&tmp_fname_ae).unwrap();
fs::remove_file(&tmp_fname_ea).unwrap();
}
make_icf_test!(
swab_256_test,
"swab-256",
File::open("./test-resources/seq-byte-values.test").unwrap(),
IConvFlags {
ctable: None,
block: None,
unblock: None,
swab: true,
sync: None,
noerror: false,
},
File::open("./test-resources/seq-byte-values-swapped.test").unwrap()
);
make_icf_test!(
swab_257_test,
"swab-257",
File::open("./test-resources/seq-byte-values-odd.test").unwrap(),
IConvFlags {
ctable: None,
block: None,
unblock: None,
swab: true,
sync: None,
noerror: false,
},
File::open("./test-resources/seq-byte-values-odd.spec").unwrap()
);

View file

@ -1,89 +0,0 @@
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, 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
use super::*;
mod block_unblock_tests;
mod conv_sync_tests;
mod conversion_tests;
mod sanity_tests;
use std::fs;
use std::io::prelude::*;
use std::io::BufReader;
struct LazyReader<R: Read> {
src: R,
}
impl<R: Read> Read for LazyReader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let reduced = cmp::max(buf.len() / 2, 1);
self.src.read(&mut buf[..reduced])
}
}
#[macro_export]
macro_rules! icf (
( $ctable:expr ) =>
{
IConvFlags {
ctable: $ctable,
..IConvFlags::default()
}
};
);
#[macro_export]
macro_rules! make_spec_test (
( $test_id:ident, $test_name:expr, $src:expr ) =>
{
// When spec not given, output should match input
make_spec_test!($test_id, $test_name, $src, $src);
};
( $test_id:ident, $test_name:expr, $src:expr, $spec:expr ) =>
{
make_spec_test!($test_id,
$test_name,
Input {
src: $src,
non_ascii: false,
ibs: 512,
print_level: None,
count: None,
cflags: IConvFlags::default(),
iflags: IFlags::default(),
},
Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: 512,
cflags: OConvFlags::default(),
},
$spec,
format!("./test-resources/FAILED-{}.test", $test_name)
);
};
( $test_id:ident, $test_name:expr, $i:expr, $o:expr, $spec:expr, $tmp_fname:expr ) =>
{
#[test]
fn $test_id()
{
$o.dd_out($i).unwrap();
let res = File::open($tmp_fname).unwrap();
// Check test file isn't empty (unless spec file is too)
assert_eq!(res.metadata().unwrap().len(), $spec.metadata().unwrap().len());
let spec = BufReader::new($spec);
let res = BufReader::new(res);
// Check all bytes match
for (b_res, b_spec) in res.bytes().zip(spec.bytes())
{
assert_eq!(b_res.unwrap(),
b_spec.unwrap());
}
fs::remove_file($tmp_fname).unwrap();
}
};
);

View file

@ -1,316 +0,0 @@
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, 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
use super::*;
const DST_PLACEHOLDER: Vec<u8> = Vec::new();
macro_rules! make_io_test (
( $test_id:ident, $test_name:expr, $i:expr, $o:expr, $spec:expr ) =>
{
make_spec_test!($test_id,
$test_name,
$i,
Output {
dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(),
obs: $o.obs,
cflags: $o.cflags,
},
$spec,
format!("./test-resources/FAILED-{}.test", $test_name)
);
};
);
make_spec_test!(
zeros_4k_test,
"zeros-4k",
File::open("./test-resources/zeros-620f0b67a91f7f74151bc5be745b7110.test").unwrap()
);
make_spec_test!(
ones_4k_test,
"ones-4k",
File::open("./test-resources/ones-6ae59e64850377ee5470c854761551ea.test").unwrap()
);
make_spec_test!(
deadbeef_32k_test,
"deadbeef-32k",
File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap()
);
make_spec_test!(
random_73k_test,
"random-73k",
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap()
);
make_io_test!(
random_73k_test_not_a_multiple_obs_gt_ibs,
"random-73k-not-a-multiple-obs-gt-ibs",
Input {
src: File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap(),
non_ascii: false,
ibs: 521,
print_level: None,
count: None,
cflags: IConvFlags::default(),
iflags: IFlags::default(),
},
Output {
dst: DST_PLACEHOLDER,
obs: 1031,
cflags: OConvFlags::default(),
},
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap()
);
make_io_test!(
random_73k_test_obs_lt_not_a_multiple_ibs,
"random-73k-obs-lt-not-a-multiple-ibs",
Input {
src: File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap(),
non_ascii: false,
ibs: 1031,
print_level: None,
count: None,
cflags: IConvFlags::default(),
iflags: IFlags::default(),
},
Output {
dst: DST_PLACEHOLDER,
obs: 521,
cflags: OConvFlags::default(),
},
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap()
);
make_io_test!(
deadbeef_all_32k_test_count_reads,
"deadbeef_all_32k_test_count_reads",
Input {
src: File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap(),
non_ascii: false,
ibs: 1024,
print_level: None,
count: Some(CountType::Reads(32)),
cflags: IConvFlags::default(),
iflags: IFlags::default(),
},
Output {
dst: DST_PLACEHOLDER,
obs: 1024,
cflags: OConvFlags::default(),
},
File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap()
);
make_io_test!(
deadbeef_all_32k_test_count_bytes,
"deadbeef_all_32k_test_count_bytes",
Input {
src: File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap(),
non_ascii: false,
ibs: 531,
print_level: None,
count: Some(CountType::Bytes(32 * 1024)),
cflags: IConvFlags::default(),
iflags: IFlags::default(),
},
Output {
dst: DST_PLACEHOLDER,
obs: 1031,
cflags: OConvFlags::default(),
},
File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap()
);
make_io_test!(
deadbeef_32k_to_16k_test_count_reads,
"deadbeef_32k_test_count_reads",
Input {
src: File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap(),
non_ascii: false,
ibs: 1024,
print_level: None,
count: Some(CountType::Reads(16)),
cflags: IConvFlags::default(),
iflags: IFlags::default(),
},
Output {
dst: DST_PLACEHOLDER,
obs: 1031,
cflags: OConvFlags::default(),
},
File::open("./test-resources/gnudd-deadbeef-first-16k.spec").unwrap()
);
make_io_test!(
deadbeef_32k_to_12345_test_count_bytes,
"deadbeef_32k_to_12345_test_count_bytes",
Input {
src: File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap(),
non_ascii: false,
ibs: 531,
print_level: None,
count: Some(CountType::Bytes(12345)),
cflags: IConvFlags::default(),
iflags: IFlags::default(),
},
Output {
dst: DST_PLACEHOLDER,
obs: 1031,
cflags: OConvFlags::default(),
},
File::open("./test-resources/gnudd-deadbeef-first-12345.spec").unwrap()
);
make_io_test!(
random_73k_test_count_reads,
"random-73k-test-count-reads",
Input {
src: File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap(),
non_ascii: false,
ibs: 1024,
print_level: None,
count: Some(CountType::Reads(32)),
cflags: IConvFlags::default(),
iflags: IFlags::default(),
},
Output {
dst: DST_PLACEHOLDER,
obs: 1024,
cflags: OConvFlags::default(),
},
File::open("./test-resources/gnudd-random-first-32k.spec").unwrap()
);
make_io_test!(
random_73k_test_count_bytes,
"random-73k-test-count-bytes",
Input {
src: File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap(),
non_ascii: false,
ibs: 521,
print_level: None,
count: Some(CountType::Bytes(32 * 1024)),
cflags: IConvFlags::default(),
iflags: IFlags::default(),
},
Output {
dst: DST_PLACEHOLDER,
obs: 1031,
cflags: OConvFlags::default(),
},
File::open("./test-resources/gnudd-random-first-32k.spec").unwrap()
);
make_io_test!(
random_73k_test_lazy_fullblock,
"random-73k-test-lazy-fullblock",
Input {
src: LazyReader {
src: File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test")
.unwrap()
},
non_ascii: false,
ibs: 521,
print_level: None,
count: None,
cflags: IConvFlags::default(),
iflags: IFlags {
fullblock: true,
..IFlags::default()
},
},
Output {
dst: DST_PLACEHOLDER,
obs: 1031,
cflags: OConvFlags::default(),
},
File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap()
);
// Test internal buffer size fn
#[test]
fn bsize_test_primes() {
let (n, m) = (7901, 7919);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, n * m);
}
#[test]
fn bsize_test_rel_prime_obs_greater() {
let (n, m) = (7 * 5119, 13 * 5119);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, 7 * 13 * 5119);
}
#[test]
fn bsize_test_rel_prime_ibs_greater() {
let (n, m) = (13 * 5119, 7 * 5119);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, 7 * 13 * 5119);
}
#[test]
fn bsize_test_3fac_rel_prime() {
let (n, m) = (11 * 13 * 5119, 7 * 11 * 5119);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, 7 * 11 * 13 * 5119);
}
#[test]
fn bsize_test_ibs_greater() {
let (n, m) = (512 * 1024, 256 * 1024);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, n);
}
#[test]
fn bsize_test_obs_greater() {
let (n, m) = (256 * 1024, 512 * 1024);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, m);
}
#[test]
fn bsize_test_bs_eq() {
let (n, m) = (1024, 1024);
let res = calc_bsize(n, m);
assert!(res % n == 0);
assert!(res % m == 0);
assert_eq!(res, m);
}
#[test]
#[should_panic]
fn test_nocreat_causes_failure_when_ofile_doesnt_exist() {
let args = vec![
String::from("dd"),
String::from("--conv=nocreat"),
String::from("--of=not-a-real.file"),
];
let matches = uu_app().try_get_matches_from(args).unwrap();
let _ = Output::<File>::new(&matches).unwrap();
}

View file

@ -702,5 +702,364 @@ fn test_partial_records_out() {
.stderr_is("1+1 records in\n1+1 records out\n");
}
// conv=[ascii,ebcdic,ibm], conv=[ucase,lcase], conv=[block,unblock], conv=sync
// TODO: Move conv tests from unit test module
#[test]
fn test_block_cbs16() {
new_ucmd!()
.args(&["conv=block", "cbs=16"])
.pipe_in_fixture("dd-block-cbs16.test")
.succeeds()
.stdout_is_fixture_bytes("dd-block-cbs16.spec");
}
#[test]
fn test_block_cbs16_as_cbs8() {
new_ucmd!()
.args(&["conv=block", "cbs=8"])
.pipe_in_fixture("dd-block-cbs16.test")
.succeeds()
.stdout_is_fixture_bytes("dd-block-cbs8.spec");
}
#[test]
fn test_block_consecutive_nl() {
new_ucmd!()
.args(&["conv=block", "cbs=16"])
.pipe_in_fixture("dd-block-consecutive-nl.test")
.succeeds()
.stdout_is_fixture_bytes("dd-block-consecutive-nl-cbs16.spec");
}
#[test]
fn test_unblock_multi_16() {
new_ucmd!()
.args(&["conv=unblock", "cbs=16"])
.pipe_in_fixture("dd-unblock-cbs16.test")
.succeeds()
.stdout_is_fixture_bytes("dd-unblock-cbs16.spec");
}
#[test]
fn test_unblock_multi_16_as_8() {
new_ucmd!()
.args(&["conv=unblock", "cbs=8"])
.pipe_in_fixture("dd-unblock-cbs16.test")
.succeeds()
.stdout_is_fixture_bytes("dd-unblock-cbs8.spec");
}
#[test]
fn test_atoe_conv_spec_test() {
new_ucmd!()
.args(&["conv=ebcdic"])
.pipe_in_fixture("seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test")
.succeeds()
.stdout_is_fixture_bytes("gnudd-conv-atoe-seq-byte-values.spec");
}
#[test]
fn test_etoa_conv_spec_test() {
new_ucmd!()
.args(&["conv=ascii"])
.pipe_in_fixture("seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test")
.succeeds()
.stdout_is_fixture_bytes("gnudd-conv-etoa-seq-byte-values.spec");
}
#[test]
fn test_atoibm_conv_spec_test() {
new_ucmd!()
.args(&["conv=ibm"])
.pipe_in_fixture("seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test")
.succeeds()
.stdout_is_fixture_bytes("gnudd-conv-atoibm-seq-byte-values.spec");
}
#[test]
fn test_lcase_ascii_to_ucase_ascii() {
new_ucmd!()
.args(&["conv=ucase"])
.pipe_in_fixture("lcase-ascii.test")
.succeeds()
.stdout_is_fixture_bytes("ucase-ascii.test");
}
#[test]
fn test_ucase_ascii_to_lcase_ascii() {
new_ucmd!()
.args(&["conv=lcase"])
.pipe_in_fixture("ucase-ascii.test")
.succeeds()
.stdout_is_fixture_bytes("lcase-ascii.test");
}
#[test]
fn test_atoe_and_ucase_conv_spec_test() {
new_ucmd!()
.args(&["conv=ebcdic,ucase"])
.pipe_in_fixture("seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test")
.succeeds()
.stdout_is_fixture_bytes("ucase-ebcdic.test");
}
#[test]
fn test_atoe_and_lcase_conv_spec_test() {
new_ucmd!()
.args(&["conv=ebcdic,lcase"])
.pipe_in_fixture("seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test")
.succeeds()
.stdout_is_fixture_bytes("lcase-ebcdic.test");
}
// TODO I think uppercase and lowercase are unintentionally swapped in
// the code that parses the command-line arguments. See this line from
// `parseargs.rs`:
//
// (ConvFlag::FmtAtoI, ConvFlag::UCase) => Some(&ASCII_TO_IBM_UCASE_TO_LCASE),
// (ConvFlag::FmtAtoI, ConvFlag::LCase) => Some(&ASCII_TO_IBM_LCASE_TO_UCASE),
//
// If my reading is correct and that is a typo, then the
// UCASE_TO_LCASE and LCASE_TO_UCASE in those lines should be swapped,
// and the expected output for the following two tests should be
// updated accordingly.
#[test]
fn test_atoibm_and_ucase_conv_spec_test() {
new_ucmd!()
.args(&["conv=ibm,ucase"])
.pipe_in_fixture("seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test")
.succeeds()
.stdout_is_fixture_bytes("lcase-ibm.test");
}
#[test]
fn test_atoibm_and_lcase_conv_spec_test() {
new_ucmd!()
.args(&["conv=ibm,lcase"])
.pipe_in_fixture("seq-byte-values-b632a992d3aed5d8d1a59cc5a5a455ba.test")
.succeeds()
.stdout_is_fixture_bytes("ucase-ibm.test");
}
#[test]
fn test_swab_256_test() {
new_ucmd!()
.args(&["conv=swab"])
.pipe_in_fixture("seq-byte-values.test")
.succeeds()
.stdout_is_fixture_bytes("seq-byte-values-swapped.test");
}
#[test]
fn test_swab_257_test() {
new_ucmd!()
.args(&["conv=swab"])
.pipe_in_fixture("seq-byte-values-odd.test")
.succeeds()
.stdout_is_fixture_bytes("seq-byte-values-odd.spec");
}
#[test]
fn test_zeros_4k_conv_sync_obs_gt_ibs() {
new_ucmd!()
.args(&["conv=sync", "ibs=521", "obs=1031"])
.pipe_in_fixture("zeros-620f0b67a91f7f74151bc5be745b7110.test")
.succeeds()
.stdout_is_fixture_bytes("gnudd-conv-sync-ibs-521-obs-1031-zeros.spec");
}
#[test]
fn test_zeros_4k_conv_sync_ibs_gt_obs() {
new_ucmd!()
.args(&["conv=sync", "ibs=1031", "obs=521"])
.pipe_in_fixture("zeros-620f0b67a91f7f74151bc5be745b7110.test")
.succeeds()
.stdout_is_fixture_bytes("gnudd-conv-sync-ibs-1031-obs-521-zeros.spec");
}
#[test]
fn test_deadbeef_32k_conv_sync_obs_gt_ibs() {
new_ucmd!()
.args(&[
"conv=sync",
"ibs=521",
"obs=1031",
"if=deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test",
])
.succeeds()
.stdout_is_fixture_bytes("gnudd-conv-sync-ibs-521-obs-1031-deadbeef.spec");
}
#[test]
fn test_deadbeef_32k_conv_sync_ibs_gt_obs() {
new_ucmd!()
.args(&[
"conv=sync",
"ibs=1031",
"obs=521",
"if=deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test",
])
.succeeds()
.stdout_is_fixture_bytes("gnudd-conv-sync-ibs-1031-obs-521-deadbeef.spec");
}
#[test]
fn test_random_73k_test_bs_prime_obs_gt_ibs_sync() {
new_ucmd!()
.args(&[
"conv=sync",
"ibs=521",
"obs=1031",
"if=random-5828891cb1230748e146f34223bbd3b5.test",
])
.succeeds()
.stdout_is_fixture_bytes("gnudd-conv-sync-ibs-521-obs-1031-random.spec");
}
#[test]
fn test_random_73k_test_bs_prime_ibs_gt_obs_sync() {
new_ucmd!()
.args(&[
"conv=sync",
"ibs=1031",
"obs=521",
"if=random-5828891cb1230748e146f34223bbd3b5.test",
])
.succeeds()
.stdout_is_fixture_bytes("gnudd-conv-sync-ibs-1031-obs-521-random.spec");
}
#[test]
fn test_identity() {
new_ucmd!()
.args(&["if=zeros-620f0b67a91f7f74151bc5be745b7110.test"])
.succeeds()
.stdout_is_fixture_bytes("zeros-620f0b67a91f7f74151bc5be745b7110.test");
new_ucmd!()
.args(&["if=ones-6ae59e64850377ee5470c854761551ea.test"])
.succeeds()
.stdout_is_fixture_bytes("ones-6ae59e64850377ee5470c854761551ea.test");
new_ucmd!()
.args(&["if=deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test"])
.succeeds()
.stdout_is_fixture_bytes("deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test");
new_ucmd!()
.args(&["if=random-5828891cb1230748e146f34223bbd3b5.test"])
.succeeds()
.stdout_is_fixture_bytes("random-5828891cb1230748e146f34223bbd3b5.test");
}
#[test]
fn test_random_73k_test_not_a_multiple_obs_gt_ibs() {
new_ucmd!()
.args(&[
"ibs=521",
"obs=1031",
"if=random-5828891cb1230748e146f34223bbd3b5.test",
])
.succeeds()
.stdout_is_fixture_bytes("random-5828891cb1230748e146f34223bbd3b5.test");
}
#[test]
fn test_random_73k_test_obs_lt_not_a_multiple_ibs() {
new_ucmd!()
.args(&[
"ibs=1031",
"obs=521",
"if=random-5828891cb1230748e146f34223bbd3b5.test",
])
.succeeds()
.stdout_is_fixture_bytes("random-5828891cb1230748e146f34223bbd3b5.test");
}
#[test]
fn test_deadbeef_all_32k_test_count_reads() {
new_ucmd!()
.args(&[
"bs=1024",
"count=32",
"if=deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test",
])
.succeeds()
.stdout_is_fixture_bytes("deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test");
}
#[test]
fn test_deadbeef_all_32k_test_count_bytes() {
new_ucmd!()
.args(&[
"ibs=531",
"obs=1031",
"count=32x1024",
"oflag=count_bytes",
"if=deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test",
])
.succeeds()
.stdout_is_fixture_bytes("deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test");
}
#[test]
fn test_deadbeef_32k_to_16k_test_count_reads() {
new_ucmd!()
.args(&[
"ibs=1024",
"obs=1031",
"count=16",
"if=deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test",
])
.succeeds()
.stdout_is_fixture_bytes("gnudd-deadbeef-first-16k.spec");
}
#[test]
fn test_deadbeef_32k_to_12345_test_count_bytes() {
new_ucmd!()
.args(&[
"ibs=531",
"obs=1031",
"count=12345",
"iflag=count_bytes",
"if=deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test",
])
.succeeds()
.stdout_is_fixture_bytes("gnudd-deadbeef-first-12345.spec");
}
#[test]
fn test_random_73k_test_count_reads() {
new_ucmd!()
.args(&[
"bs=1024",
"count=32",
"if=random-5828891cb1230748e146f34223bbd3b5.test",
])
.succeeds()
.stdout_is_fixture_bytes("gnudd-random-first-32k.spec");
}
#[test]
fn test_random_73k_test_count_bytes() {
new_ucmd!()
.args(&[
"ibs=521",
"obs=1031",
"count=32x1024",
"iflag=count_bytes",
"if=random-5828891cb1230748e146f34223bbd3b5.test",
])
.succeeds()
.stdout_is_fixture_bytes("gnudd-random-first-32k.spec");
}
#[test]
fn test_all_valid_ascii_ebcdic_ascii_roundtrip_conv_test() {
let tmp = new_ucmd!()
.args(&["ibs=128", "obs=1024", "conv=ebcdic"])
.pipe_in_fixture("all-valid-ascii-chars-37eff01866ba3f538421b30b7cbefcac.test")
.succeeds()
.stdout_move_bytes();
new_ucmd!()
.args(&["ibs=256", "obs=1024", "conv=ascii"])
.pipe_in(tmp)
.succeeds()
.stdout_is_fixture_bytes("all-valid-ascii-chars-37eff01866ba3f538421b30b7cbefcac.test");
}

View file

@ -265,6 +265,28 @@ impl CmdResult {
let contents = read_scenario_fixture(&self.tmpd, file_rel_path);
self.stdout_is(String::from_utf8(contents).unwrap())
}
/// Assert that the bytes of stdout exactly match those of the given file.
///
/// Contrast this with [`CmdResult::stdout_is_fixture`], which
/// decodes the contents of the file as a UTF-8 [`String`] before
/// comparison with stdout.
///
/// # Examples
///
/// Use this method in a unit test like this:
///
/// ```rust,ignore
/// #[test]
/// fn test_something() {
/// new_ucmd!().succeeds().stdout_is_fixture_bytes("expected.bin");
/// }
/// ```
pub fn stdout_is_fixture_bytes<T: AsRef<OsStr>>(&self, file_rel_path: T) -> &Self {
let contents = read_scenario_fixture(&self.tmpd, file_rel_path);
self.stdout_is_bytes(contents)
}
/// like stdout_is_fixture(...), but replaces the data in fixture file based on values provided in template_vars
/// command output
pub fn stdout_is_templated_fixture<T: AsRef<OsStr>>(

BIN
tests/fixtures/dd/deadbeef-16.spec vendored Normal file

Binary file not shown.

1
tests/fixtures/dd/deadbeef-16.test vendored Normal file
View file

@ -0,0 +1 @@
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

Binary file not shown.