Add test for loading and storing symlink nodes and fix multiple logic errors
This commit is contained in:
parent
e226f1982d
commit
455a2d36f9
@ -4,7 +4,7 @@ use {
|
||||
};
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub(crate) enum Flag {
|
||||
Normal = 0,
|
||||
HardLink = 1,
|
||||
@ -52,7 +52,15 @@ impl From<&FileType> for Flag {
|
||||
impl Flag {
|
||||
pub(crate) fn append_mode(&self, mode: u16) -> u16 {
|
||||
let mask: u16 = u16::from(*self as u8) << 13;
|
||||
mode & mask
|
||||
mode | mask
|
||||
}
|
||||
|
||||
pub(crate) fn extract_from_raw(raw: u16) -> Result<(Self, u16), Error> {
|
||||
let mask: u16 = 0b111 << 13;
|
||||
let mode = raw & 0o777;
|
||||
let flag: u8 = ((raw & mask) >> 13).try_into()?;
|
||||
let flag: Self = flag.try_into()?;
|
||||
Ok((flag, mode))
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +98,7 @@ impl FileType {
|
||||
let len = u16::from_le_bytes(len);
|
||||
let mut buf = Vec::with_capacity(len.into());
|
||||
let mut handle = reader.take(len.into());
|
||||
handle.read_exact(&mut buf)?;
|
||||
handle.read_to_end(&mut buf)?;
|
||||
let s = String::from_utf8(buf)?;
|
||||
Ok(Self::HardLink(s))
|
||||
}
|
||||
@ -100,7 +108,7 @@ impl FileType {
|
||||
let len = u16::from_le_bytes(len);
|
||||
let mut buf = Vec::with_capacity(len.into());
|
||||
let mut handle = reader.take(len.into());
|
||||
handle.read_exact(&mut buf)?;
|
||||
handle.read_to_end(&mut buf)?;
|
||||
let s = String::from_utf8(buf)?;
|
||||
Ok(Self::SoftLink(s))
|
||||
}
|
||||
@ -122,7 +130,7 @@ impl FileType {
|
||||
match self {
|
||||
Self::Normal(f) => f.write(writer)?,
|
||||
Self::HardLink(s) | Self::SoftLink(s) => {
|
||||
let len = s.len() as u64;
|
||||
let len = s.len() as u16;
|
||||
writer.write_all(&len.to_le_bytes())?;
|
||||
writer.write_all(s.as_bytes())?;
|
||||
}
|
||||
@ -132,3 +140,28 @@ impl FileType {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn manipulate_mode_softlink() {
|
||||
let mode: u16 = 0o644;
|
||||
let flag = Flag::SoftLink;
|
||||
let raw = flag.append_mode(mode);
|
||||
let (f, m) = Flag::extract_from_raw(raw).unwrap();
|
||||
assert_eq!(m, mode);
|
||||
assert_eq!(f, flag);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn manipulate_mode_normal() {
|
||||
let mode: u16 = 0o755;
|
||||
let flag = Flag::Normal;
|
||||
let raw = flag.append_mode(mode);
|
||||
let (f, m) = Flag::extract_from_raw(raw).unwrap();
|
||||
assert_eq!(m, mode);
|
||||
assert_eq!(f, flag);
|
||||
}
|
||||
}
|
||||
|
45
src/node.rs
45
src/node.rs
@ -85,10 +85,7 @@ impl Node {
|
||||
let mtime: [u8; 8] = buf[8..16].try_into()?;
|
||||
let raw_mode: [u8; 2] = buf[16..18].try_into()?;
|
||||
let raw_mode = u16::from_le_bytes(raw_mode);
|
||||
let mask: u16 = 0b111 << 13;
|
||||
let mode = raw_mode & mask;
|
||||
let flag: u8 = ((raw_mode & !mask) >> 13).try_into()?;
|
||||
let flag: Flag = flag.try_into()?;
|
||||
let (flag, mode) = Flag::extract_from_raw(raw_mode)?;
|
||||
let filetype = FileType::read(reader, flag)?;
|
||||
Ok(Self {
|
||||
name: String::from_utf8(name)?,
|
||||
@ -203,12 +200,13 @@ impl Node {
|
||||
}
|
||||
}
|
||||
};
|
||||
let mode = Flag::from(&filetype).append_mode(u16::try_from(mode & 0o7777)?);
|
||||
Ok(Self {
|
||||
name,
|
||||
uid,
|
||||
gid,
|
||||
mtime,
|
||||
mode: (mode & !(0o111 << 13)).try_into()?,
|
||||
mode,
|
||||
filetype,
|
||||
})
|
||||
}
|
||||
@ -405,12 +403,22 @@ mod tests {
|
||||
let mut writer = std::io::BufWriter::new(fd);
|
||||
let links = Mutex::new(HashMap::new());
|
||||
let node = Node::from_path("test/li.txt", Algorithm::Sha1, &links).unwrap();
|
||||
let FileType::Normal(_) = node.filetype else {
|
||||
eprintln!("Created wrong filetype: {:?}", node.filetype);
|
||||
panic!();
|
||||
};
|
||||
node.write(&mut writer).unwrap();
|
||||
}
|
||||
let meta = fs::metadata("test/li.txt").unwrap();
|
||||
let fd = std::fs::File::open("test/li.node").unwrap();
|
||||
let mut reader = BufReader::new(fd);
|
||||
let node = Node::read(&mut reader).unwrap();
|
||||
assert_eq!(meta.mode() & 0o777, node.mode as u32);
|
||||
assert_eq!(meta.uid(), node.uid);
|
||||
assert_eq!(meta.gid(), node.gid);
|
||||
assert_eq!(meta.mtime(), node.mtime as i64);
|
||||
let FileType::Normal(f) = node.filetype else {
|
||||
eprintln!("Read incorrect filetype: {:?}", node.filetype);
|
||||
panic!()
|
||||
};
|
||||
let Checksum::Sha1(sum) = f.checksum else {
|
||||
@ -424,6 +432,33 @@ mod tests {
|
||||
assert_eq!(LI, f.data);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_store_symlink() {
|
||||
{
|
||||
let _res = remove_file("test/lilnk.txt");
|
||||
symlink("li.txt", "test/lilnk.txt").unwrap();
|
||||
let _res = remove_file("test/lilnk.node");
|
||||
let fd = std::fs::File::create("test/lilnk.node").unwrap();
|
||||
let mut writer = std::io::BufWriter::new(fd);
|
||||
let links = Mutex::new(HashMap::new());
|
||||
let node = Node::from_path("test/lilnk.txt", Algorithm::Sha1, &links).unwrap();
|
||||
let FileType::SoftLink(ref tgt) = node.filetype else {
|
||||
eprintln!("Created wrong filetype: {:?}", node.filetype);
|
||||
panic!();
|
||||
};
|
||||
assert_eq!(tgt, "li.txt");
|
||||
node.write(&mut writer).unwrap();
|
||||
}
|
||||
let fd = std::fs::File::open("test/lilnk.node").unwrap();
|
||||
let mut reader = BufReader::new(fd);
|
||||
let node = Node::read(&mut reader).unwrap();
|
||||
let FileType::SoftLink(ref tgt) = node.filetype else {
|
||||
eprintln!("Read incorrect filetype: {:?}", node.filetype);
|
||||
panic!();
|
||||
};
|
||||
assert_eq!(tgt, "li.txt");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_file() {
|
||||
let links = Mutex::new(HashMap::new());
|
||||
|
Loading…
Reference in New Issue
Block a user