Add test for extracting hardlinks; Fix multiple bugs revealed in tests; TODO: fix possible io errors caused by tests running in parallel;

This commit is contained in:
Nathan Fisher 2023-12-17 19:07:25 -05:00
parent 0ef17ca2ec
commit 71e0ba30d1

View File

@ -247,19 +247,38 @@ impl Node {
match self.filetype {
FileType::Eof => {}
FileType::Fifo => {
nix::mkfifo(&path, self.mode.into())?;
if n_path.exists() {
fs::remove_file(&n_path)?;
}
nix::mkfifo(&n_path.to_str().ok_or(Error::BadPath)?, self.mode.into())?;
if euid == 0 {
nix::chown(&path, self.uid, self.gid)?;
nix::chown(&n_path.to_str().ok_or(Error::BadPath)?, self.uid, self.gid)?;
}
}
FileType::Block(ref b) => {
if euid == 0 {
nix::mknod(&path, self.mode.into(), b.major, b.minor)?;
if n_path.exists() {
fs::remove_file(&n_path)?;
}
nix::mknod(
&n_path.to_str().ok_or(Error::BadPath)?,
self.mode.into(),
b.major,
b.minor,
)?;
}
}
FileType::Character(ref c) => {
if euid == 0 {
nix::mknod(&path, self.mode.into(), c.major, c.minor)?;
if n_path.exists() {
fs::remove_file(&n_path)?;
}
nix::mknod(
&n_path.to_str().ok_or(Error::BadPath)?,
self.mode.into(),
c.major,
c.minor,
)?;
}
}
FileType::Normal(ref n) => {
@ -273,9 +292,9 @@ impl Node {
writer.write_all(&n.data)?;
}
if euid == 0 {
nix::chown(&path, self.uid, self.gid)?;
nix::chown(&n_path.to_str().ok_or(Error::BadPath)?, self.uid, self.gid)?;
}
nix::chmod(&path, self.mode.into())?;
nix::chmod(&n_path.to_str().ok_or(Error::BadPath)?, self.mode.into())?;
}
FileType::HardLink(ref t) => {
let target = if let Some(prefix) = prefix {
@ -283,7 +302,13 @@ impl Node {
} else {
t.to_string()
};
fs::hard_link(target, &path)?;
if !PathBuf::from(&target).exists() {
let _f = fs::File::create(&target)?;
}
if PathBuf::from(&n_path).exists() {
fs::remove_file(&n_path)?;
}
fs::hard_link(target, &n_path)?;
}
FileType::SoftLink(ref t) => {
if n_path.exists() {
@ -292,7 +317,7 @@ impl Node {
symlink(t, &n_path)?;
}
FileType::Directory => {
self.mkdir(&PathBuf::from(&path))?;
self.mkdir(&n_path)?;
}
}
Ok(())
@ -542,4 +567,25 @@ mod tests {
let tgt = fs::read_link("test/output/test/lilnk.txt").unwrap();
assert_eq!(tgt, PathBuf::from("li.txt"));
}
#[test]
fn extract_hardlink() {
let links = Mutex::new(HashMap::new());
if !PathBuf::from("test/lihlnk.txt").exists() {
fs::hard_link("test/li.txt", "test/lihlnk.txt").unwrap();
}
let node0 = Node::from_path("test/li.txt", Algorithm::Sha256, &links).unwrap();
let FileType::Normal(_) = node0.filetype else {
eprintln!("Created wrong filetype for node0: {:?}", node0.filetype);
panic!();
};
let node1 = Node::from_path("test/lihlnk.txt", Algorithm::Sha256, &links).unwrap();
let FileType::HardLink(ref tgt) = node1.filetype else {
eprintln!("Created wrong filetype for node1: {:?}", node1.filetype);
panic!();
};
assert_eq!(tgt, "test/li.txt");
node1.extract(Some("test/output")).unwrap();
node0.extract(Some("test/output")).unwrap();
}
}