use vnfs::VecFs;
use vnfs::vecfs::*;
pub fn run_suite(fs: &mut impl VecFs, base: &str) {
let dir = format!("{}/suite", base);
fs.ensure_dir(&dir, 0o755).expect("ensure_dir");
let f = format!("{}/f.txt", dir);
let payload = b"the quick brown fox jumps over the lazy dog".to_vec();
let mut w = VfIoVec::from_path(&f, 0, payload.len(), payload.clone());
w.is_creation = true;
fs.writev(std::slice::from_mut(&mut w)).expect("writev");
assert_eq!(w.length, payload.len());
let mut r = VfIoVec::from_path(&f, 0, payload.len(), Vec::new());
fs.readv(std::slice::from_mut(&mut r)).expect("readv");
assert_eq!(r.data, payload);
assert!(!r.is_failure);
let st = fs.stat(&f).expect("stat");
assert_eq!(st.size, payload.len() as u64);
assert!(st.fileid != 0);
assert!(fs.exists(&f));
assert_eq!(fs.file_type(&f).unwrap(), NF4REG);
fs.setattrsv(&[VfAttrs {
file: VfFile::from_path(&f),
masks: AttrMask {
has_size: true,
..AttrMask::default()
},
size: 5,
..VfAttrs::default()
}])
.expect("setattrsv size");
assert_eq!(fs.stat(&f).unwrap().size, 5);
let sub = format!("{}/sub", dir);
fs.mkdir(&sub, 0o750).expect("mkdir");
assert_eq!(fs.stat(&sub).unwrap().ftype, NF4DIR);
assert_eq!(fs.stat(&sub).unwrap().mode & 0o777, 0o750);
let tf = fs.open(&f, libc::O_RDWR, 0).expect("open");
let mut w = VfIoVec::from_fd(tf.fd, 0, 5, b"hello".to_vec());
fs.writev(std::slice::from_mut(&mut w)).expect("writev fd");
assert_eq!(fs.fseek(&mut tf.clone(), 0, libc::SEEK_SET).unwrap(), 0);
let mut r = VfIoVec::from_fd(tf.fd, VF_OFFSET_CUR, 5, Vec::new());
fs.readv(std::slice::from_mut(&mut r)).expect("readv fd");
assert_eq!(r.data, b"hello");
fs.close(&tf).expect("close");
let link = format!("{}/ln", dir);
fs.symlink(&f, &link).expect("symlink");
assert_eq!(fs.readlink(&link).unwrap(), f.as_bytes());
let hard = format!("{}/hard", dir);
fs.hardlinkv(&[f.as_str()], &[hard.as_str()])
.expect("hardlinkv");
assert_eq!(fs.stat(&f).unwrap().fileid, fs.stat(&hard).unwrap().fileid);
let renamed = format!("{}/renamed.txt", dir);
fs.renamev(&[(VfFile::from_path(&f), VfFile::from_path(&renamed))])
.expect("renamev");
assert!(fs.exists(&renamed));
assert!(!fs.exists(&f));
let more = format!("{}/more", dir);
fs.ensure_dir(&more, 0o755).unwrap();
let paths = [
format!("{}/a", more),
format!("{}/b", more),
format!("{}/c", more),
];
let refs: Vec<&str> = paths.iter().map(|s| s.as_str()).collect();
let files = fs
.openv(&refs, &[libc::O_CREAT | libc::O_RDWR; 3], &[0o644; 3])
.expect("openv");
fs.closev(&files).expect("closev");
let entries = fs
.listdir(&dir, AttrMask::default(), 0, false)
.expect("listdir");
assert!(
entries
.iter()
.any(|e| e.file.path.as_ref().unwrap().ends_with("renamed.txt"))
);
assert!(
entries
.iter()
.any(|e| e.file.path.as_ref().unwrap().ends_with("sub"))
);
let mut seen = 0usize;
let mut cb = |_: &VfAttrs, _: &str| {
seen += 1;
true
};
fs.listdirv(&[dir.as_str()], AttrMask::default(), 0, false, &mut cb)
.expect("listdirv");
assert!(seen >= 2);
let copy = format!("{}/copy.txt", dir);
fs.dupv(&[ExtentPair::new(&renamed, 0, ©, 0, u64::MAX)])
.expect("dupv");
assert_eq!(
fs.stat(©).unwrap().size,
fs.stat(&renamed).unwrap().size
);
let adbf = format!("{}/adb.bin", dir);
let mut a = Adb::blocknum_only(&adbf, 0, 1024, 2, 0, 100);
fs.write_adb(std::slice::from_mut(&mut a))
.expect("write_adb");
assert_eq!(a.adb_block_count, 2);
let cpsrc = format!("{}/cpsrc", dir);
let cpdst = format!("{}/cpdst", dir);
fs.ensure_dir(&format!("{}/inner", cpsrc), 0o755).unwrap();
let srcfile = format!("{}/inner/data.txt", cpsrc);
let mut w = VfIoVec::from_path(&srcfile, 0, 3, b"xyz".to_vec());
w.is_creation = true;
fs.writev(std::slice::from_mut(&mut w)).unwrap();
fs.cp_recursive(&cpsrc, &cpdst, true, false)
.expect("cp_recursive");
assert!(fs.exists(&format!("{}/inner/data.txt", cpdst)));
fs.chdir(&sub).expect("chdir");
assert!(fs.getcwd().ends_with("/sub"));
fs.rm(&[dir.as_str()], true).expect("rm recursive");
assert!(!fs.exists(&dir));
}