Add several tests; Fix blocking when creating fifo node caused by opening file for reading - move the open to the block which runs only if it is a normal file;

This commit is contained in:
Nathan Fisher 2023-12-12 09:02:36 -05:00
parent 3c49fb2324
commit e226f1982d
1 changed files with 38 additions and 15 deletions

View File

@ -24,18 +24,18 @@ enum Kind {
impl From<u32> for Kind {
fn from(value: u32) -> Self {
if value & 0o60000 != 0 {
Self::Block
if value & 0o40000 != 0 {
Self::Dir
} else if value & 0o20000 != 0 {
Self::Char
} else if value & 0o60000 != 0 {
Self::Block
} else if value & 0o10000 != 0 {
Self::Pipe
} else if value & 0o40000 != 0 {
Self::Dir
} else if value & 0o100000 != 0 {
Self::Normal
} else {
panic!();
unreachable!();
}
}
}
@ -131,13 +131,11 @@ impl Node {
links: &Mutex<HashMap<u64, String>>,
) -> Result<Self, Error> {
let name = String::from(path);
let fd = fs::File::open(path)?;
let meta = fs::symlink_metadata(path)?;
let mode = meta.mode();
let uid = meta.uid();
let gid = meta.gid();
let mtime = meta.mtime().try_into()?;
let mut reader = BufReader::new(fd);
let ft = meta.file_type();
let filetype = 'blk: {
if ft.is_dir() {
@ -171,6 +169,8 @@ impl Node {
break 'blk FileType::Fifo;
} else if kind == Kind::Normal {
let mut data = vec![];
let fd = fs::File::open(path)?;
let mut reader = BufReader::new(fd);
let len = reader.read_to_end(&mut data)?.try_into()?;
let checksum = match algorithm {
Algorithm::Md5 => {
@ -308,10 +308,37 @@ impl Node {
#[cfg(test)]
mod tests {
use super::*;
use std::{ffi::CString, fmt::Write, fs::remove_file};
use std::{fmt::Write, fs::remove_file};
static LI: &[u8] = include_bytes!("../test/li.txt");
#[test]
fn get_kind_dir() {
let meta = fs::symlink_metadata("test").unwrap();
let mode = meta.mode();
let kind = Kind::from(mode);
assert_eq!(kind, Kind::Dir);
}
#[test]
fn get_kind_fifo() {
let _ = remove_file("test/fifo");
nix::mkfifo("test/fifo", 0o644).unwrap();
let meta = fs::symlink_metadata("test/fifo").unwrap();
let mode = meta.mode();
let kind = Kind::from(mode);
assert_eq!(kind, Kind::Pipe);
}
#[test]
#[cfg(target_os = "linux")]
fn get_kind_char() {
let meta = fs::symlink_metadata("/dev/null").unwrap();
let mode = meta.mode();
let kind = Kind::from(mode);
assert_eq!(kind, Kind::Char);
}
#[test]
fn from_file_path() {
let links = Mutex::new(HashMap::new());
@ -359,21 +386,17 @@ mod tests {
}
}
// TODO: Discover why this test blocks
/*#[test]
#[test]
fn from_fifo_path() {
let _res = remove_file("test/fifo");
let fname = CString::new("test/fifo").unwrap();
unsafe {
libc::mkfifo(fname.as_ptr(), 0o644);
}
nix::mkfifo("test/fifo", 0o644).unwrap();
let links = Mutex::new(HashMap::new());
let node = Node::from_path("test/fifo", Algorithm::Skip, &links).unwrap();
let FileType::Fifo = node.filetype else {
eprintln!("Incorrect filetype: {:?}", node.filetype);
panic!();
};
}*/
}
#[test]
fn load_store_file() {