Finish (probably) port to new spec and add more tests
This commit is contained in:
parent
1bf8fd416a
commit
3b46b11153
Binary file not shown.
@ -87,3 +87,57 @@ impl Checksum {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
|
const MD5BUF: [u8; 16] = [
|
||||||
|
102, 95, 170, 95, 1, 29, 157, 44, 184, 244, 181, 209, 47, 30, 223, 21,
|
||||||
|
];
|
||||||
|
|
||||||
|
const SHA1BUF: [u8; 20] = [
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||||
|
];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn load_store_md5() {
|
||||||
|
{
|
||||||
|
let mut fd = File::options()
|
||||||
|
.create(true)
|
||||||
|
.truncate(true)
|
||||||
|
.write(true)
|
||||||
|
.open("test/md5")
|
||||||
|
.unwrap();
|
||||||
|
let cksum = Checksum::Md5(MD5BUF);
|
||||||
|
cksum.write(&mut fd).unwrap();
|
||||||
|
}
|
||||||
|
let mut fd = File::open("test/md5").unwrap();
|
||||||
|
let cksum = Checksum::read(&mut fd).unwrap();
|
||||||
|
match cksum {
|
||||||
|
Checksum::Md5(sum) => assert_eq!(sum, MD5BUF),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn load_store_sha1() {
|
||||||
|
{
|
||||||
|
let mut fd = File::options()
|
||||||
|
.create(true)
|
||||||
|
.truncate(true)
|
||||||
|
.write(true)
|
||||||
|
.open("test/sha1")
|
||||||
|
.unwrap();
|
||||||
|
let cksum = Checksum::Sha1(SHA1BUF);
|
||||||
|
cksum.write(&mut fd).unwrap();
|
||||||
|
}
|
||||||
|
let mut fd = File::open("test/sha1").unwrap();
|
||||||
|
let cksum = Checksum::read(&mut fd).unwrap();
|
||||||
|
match cksum {
|
||||||
|
Checksum::Sha1(sum) => assert_eq!(sum, SHA1BUF),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
32
src/file.rs
32
src/file.rs
@ -84,3 +84,35 @@ impl File {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::fs::File as Fd;
|
||||||
|
|
||||||
|
const SHA1BUF: [u8; 20] = [
|
||||||
|
155, 243, 229, 181, 239, 210, 47, 147, 46, 16, 11, 134, 200, 52, 130, 120, 126, 130, 166,
|
||||||
|
130,
|
||||||
|
];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn load_store() {
|
||||||
|
let file = File {
|
||||||
|
len: 1005,
|
||||||
|
checksum: Checksum::Sha1(SHA1BUF),
|
||||||
|
data: include_bytes!("../test/li.txt").to_vec(),
|
||||||
|
};
|
||||||
|
{
|
||||||
|
let mut fd = Fd::create("test/file").unwrap();
|
||||||
|
file.write(&mut fd).unwrap();
|
||||||
|
}
|
||||||
|
let mut fd = Fd::open("test/file").unwrap();
|
||||||
|
let res = File::read(&mut fd).unwrap();
|
||||||
|
assert_eq!(file.len, res.len);
|
||||||
|
assert_eq!(&file.data, &res.data);
|
||||||
|
match res.checksum {
|
||||||
|
Checksum::Sha1(sum) => assert_eq!(sum, SHA1BUF),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ use {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub(crate) enum Flag {
|
pub(crate) enum Flag {
|
||||||
Normal = 0,
|
Normal = 0,
|
||||||
HardLink = 1,
|
HardLink = 1,
|
||||||
@ -28,7 +29,7 @@ impl TryFrom<u8> for Flag {
|
|||||||
5 => Ok(Self::Block),
|
5 => Ok(Self::Block),
|
||||||
6 => Ok(Self::Fifo),
|
6 => Ok(Self::Fifo),
|
||||||
7 => Ok(Self::Eof),
|
7 => Ok(Self::Eof),
|
||||||
8 => Err(Error::UnknownFileType),
|
_ => Err(Error::UnknownFileType),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,33 +120,14 @@ impl FileType {
|
|||||||
|
|
||||||
pub(crate) fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
pub(crate) fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::Normal(f) => {
|
Self::Normal(f) => f.write(writer)?,
|
||||||
writer.write_all(&[0])?;
|
Self::HardLink(s) | Self::SoftLink(s) => {
|
||||||
f.write(writer)?;
|
|
||||||
}
|
|
||||||
Self::HardLink(s) => {
|
|
||||||
writer.write_all(&[1])?;
|
|
||||||
let len = s.len() as u64;
|
let len = s.len() as u64;
|
||||||
writer.write_all(&len.to_le_bytes())?;
|
writer.write_all(&len.to_le_bytes())?;
|
||||||
writer.write_all(s.as_bytes())?;
|
writer.write_all(s.as_bytes())?;
|
||||||
}
|
}
|
||||||
Self::SoftLink(s) => {
|
Self::Character(s) | Self::Block(s) => s.write(writer)?,
|
||||||
writer.write_all(&[2])?;
|
_ => {}
|
||||||
let len = s.len() as u64;
|
|
||||||
writer.write_all(&len.to_le_bytes())?;
|
|
||||||
writer.write_all(s.as_bytes())?;
|
|
||||||
}
|
|
||||||
Self::Directory => writer.write_all(&[3])?,
|
|
||||||
Self::Character(s) => {
|
|
||||||
writer.write_all(&[4])?;
|
|
||||||
s.write(writer)?;
|
|
||||||
}
|
|
||||||
Self::Block(s) => {
|
|
||||||
writer.write_all(&[5])?;
|
|
||||||
s.write(writer)?;
|
|
||||||
}
|
|
||||||
Self::Fifo => writer.write_all(&[6])?,
|
|
||||||
Self::Eof => {}
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
23
src/node.rs
23
src/node.rs
@ -108,9 +108,8 @@ impl Node {
|
|||||||
let len: u16 = self.name.len().try_into()?;
|
let len: u16 = self.name.len().try_into()?;
|
||||||
writer.write_all(&len.to_le_bytes())?;
|
writer.write_all(&len.to_le_bytes())?;
|
||||||
writer.write_all(self.name.as_bytes())?;
|
writer.write_all(self.name.as_bytes())?;
|
||||||
[self.uid, self.gid]
|
writer.write_all(&self.uid.to_le_bytes())?;
|
||||||
.iter()
|
writer.write_all(&self.gid.to_le_bytes())?;
|
||||||
.try_for_each(|f| writer.write_all(&f.to_le_bytes()))?;
|
|
||||||
writer.write_all(&self.mtime.to_le_bytes())?;
|
writer.write_all(&self.mtime.to_le_bytes())?;
|
||||||
let mode = Flag::from(&self.filetype).append_mode(self.mode);
|
let mode = Flag::from(&self.filetype).append_mode(self.mode);
|
||||||
writer.write_all(&mode.to_le_bytes())?;
|
writer.write_all(&mode.to_le_bytes())?;
|
||||||
@ -207,10 +206,10 @@ impl Node {
|
|||||||
};
|
};
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
name,
|
name,
|
||||||
mode,
|
|
||||||
uid,
|
uid,
|
||||||
gid,
|
gid,
|
||||||
mtime,
|
mtime,
|
||||||
|
mode: (mode & !(0o111 << 13)).try_into()?,
|
||||||
filetype,
|
filetype,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -246,19 +245,19 @@ impl Node {
|
|||||||
match self.filetype {
|
match self.filetype {
|
||||||
FileType::Eof => {}
|
FileType::Eof => {}
|
||||||
FileType::Fifo => {
|
FileType::Fifo => {
|
||||||
nix::mkfifo(&path, self.mode)?;
|
nix::mkfifo(&path, self.mode.into())?;
|
||||||
if euid == 0 {
|
if euid == 0 {
|
||||||
nix::chown(&path, self.uid, self.gid)?;
|
nix::chown(&path, self.uid, self.gid)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FileType::Block(ref b) => {
|
FileType::Block(ref b) => {
|
||||||
if euid == 0 {
|
if euid == 0 {
|
||||||
nix::mknod(&path, self.mode, b.major, b.minor)?;
|
nix::mknod(&path, self.mode.into(), b.major, b.minor)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FileType::Character(ref c) => {
|
FileType::Character(ref c) => {
|
||||||
if euid == 0 {
|
if euid == 0 {
|
||||||
nix::mknod(&path, self.mode, c.major, c.minor)?;
|
nix::mknod(&path, self.mode.into(), c.major, c.minor)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FileType::Normal(ref n) => {
|
FileType::Normal(ref n) => {
|
||||||
@ -274,7 +273,7 @@ impl Node {
|
|||||||
if euid == 0 {
|
if euid == 0 {
|
||||||
nix::chown(&path, self.uid, self.gid)?;
|
nix::chown(&path, self.uid, self.gid)?;
|
||||||
}
|
}
|
||||||
nix::chmod(&path, self.mode)?;
|
nix::chmod(&path, self.mode.into())?;
|
||||||
}
|
}
|
||||||
FileType::HardLink(ref t) => {
|
FileType::HardLink(ref t) => {
|
||||||
let target = if let Some(prefix) = prefix {
|
let target = if let Some(prefix) = prefix {
|
||||||
@ -303,7 +302,7 @@ impl Node {
|
|||||||
}
|
}
|
||||||
nix::chmod(
|
nix::chmod(
|
||||||
dir.to_str().ok_or(Error::BadPath)?,
|
dir.to_str().ok_or(Error::BadPath)?,
|
||||||
self.mode & 0o7777 | 0o100,
|
(self.mode & 0o7777 | 0o100).into(),
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -334,16 +333,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn write() {
|
fn load_store() {
|
||||||
|
{
|
||||||
let fd = std::fs::File::create("test/li.node").unwrap();
|
let fd = std::fs::File::create("test/li.node").unwrap();
|
||||||
let mut writer = std::io::BufWriter::new(fd);
|
let mut writer = std::io::BufWriter::new(fd);
|
||||||
let links = Mutex::new(HashMap::new());
|
let links = Mutex::new(HashMap::new());
|
||||||
let node = Node::from_path("test/li.txt", Algorithm::Sha1, &links).unwrap();
|
let node = Node::from_path("test/li.txt", Algorithm::Sha1, &links).unwrap();
|
||||||
node.write(&mut writer).unwrap();
|
node.write(&mut writer).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn read() {
|
|
||||||
let fd = std::fs::File::open("test/li.node").unwrap();
|
let fd = std::fs::File::open("test/li.node").unwrap();
|
||||||
let mut reader = BufReader::new(fd);
|
let mut reader = BufReader::new(fd);
|
||||||
let node = Node::read(&mut reader).unwrap();
|
let node = Node::read(&mut reader).unwrap();
|
||||||
|
@ -49,3 +49,30 @@ impl Special {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn load_store() {
|
||||||
|
{
|
||||||
|
let mut fd = File::options()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open("test/device")
|
||||||
|
.unwrap();
|
||||||
|
let dev = Special {
|
||||||
|
major: 42,
|
||||||
|
minor: 69,
|
||||||
|
};
|
||||||
|
dev.write(&mut fd).unwrap();
|
||||||
|
}
|
||||||
|
let mut fd = File::open("test/device").unwrap();
|
||||||
|
let dev = Special::read(&mut fd).unwrap();
|
||||||
|
assert_eq!(dev.major, 42);
|
||||||
|
assert_eq!(dev.minor, 69);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BIN
test/device
Normal file
BIN
test/device
Normal file
Binary file not shown.
BIN
test/li.node
BIN
test/li.node
Binary file not shown.
Loading…
Reference in New Issue
Block a user