maint: fix broken tests

This commit is contained in:
Mark Poliakov 2025-01-09 20:34:13 +02:00
parent ab71cac6fa
commit 6ad8024ca0
5 changed files with 99 additions and 70 deletions

View File

@ -95,6 +95,9 @@ split-debuginfo = "packed"
lto = "thin"
panic = "abort"
[profile.test]
split-debuginfo = "none"
[profile.dev.package."*"]
opt-level = 3

View File

@ -655,7 +655,7 @@ mod tests {
impls::const_value_node,
node::{AccessToken, CommonImpl, DirectoryImpl, Node, NodeFlags, NodeRef, RegularImpl},
traits::{Read, Seek, Write},
FileReadiness, InstanceData,
FileReadiness, Filename, InstanceData,
};
#[test]
@ -717,12 +717,23 @@ mod tests {
let d = Node::directory(
D {
entries: Vec::from_iter([
("f1".to_owned(), Node::regular(F, NodeFlags::empty())),
("f2".to_owned(), Node::regular(F, NodeFlags::empty())),
("f3".to_owned(), Node::regular(F, NodeFlags::empty())),
(
"f1".to_owned(),
Node::regular(F, NodeFlags::empty(), None, None),
),
(
"f2".to_owned(),
Node::regular(F, NodeFlags::empty(), None, None),
),
(
"f3".to_owned(),
Node::regular(F, NodeFlags::empty(), None, None),
),
]),
},
NodeFlags::empty(),
None,
None,
);
let f = d.open_directory(AccessToken::test_authorized()).unwrap();
@ -766,10 +777,11 @@ mod tests {
}
}
let d = Node::directory(D, NodeFlags::empty());
let child = Node::directory(D, NodeFlags::empty());
let d = Node::directory(D, NodeFlags::empty(), None, None);
let child = Node::directory(D, NodeFlags::empty(), None, None);
d.add_child("child1", child).unwrap();
d.add_child(Filename::new("child1").unwrap(), child)
.unwrap();
let f = d.open_directory(AccessToken::test_authorized()).unwrap();
@ -853,7 +865,7 @@ mod tests {
}
let data = Arc::new(Mutex::new(vec![]));
let node = Node::regular(F { data: data.clone() }, NodeFlags::empty());
let node = Node::regular(F { data: data.clone() }, NodeFlags::empty(), None, None);
let file = node
.open(
OpenOptions::READ | OpenOptions::WRITE,

View File

@ -108,29 +108,15 @@ impl IoContext {
pub fn check_access(&self, node: &NodeRef, mode: AccessMode) -> Result<AccessToken, Error> {
let metadata = node.metadata()?;
if mode.contains(AccessMode::READ)
&& !(self.uid.is_root()
| metadata.user_read(self.uid)
| metadata.group_read(self.gid)
| metadata.other_read())
{
if mode.contains(AccessMode::READ) && !metadata.is_readable(self.uid, self.gid) {
return Err(Error::PermissionDenied);
}
if mode.contains(AccessMode::WRITE)
&& !(self.uid.is_root()
| metadata.user_write(self.uid)
| metadata.group_write(self.gid)
| metadata.other_write())
{
if mode.contains(AccessMode::WRITE) && !metadata.is_writeable(self.uid, self.gid) {
return Err(Error::PermissionDenied);
}
if mode.contains(AccessMode::EXEC)
&& !(metadata.user_exec(self.uid)
| metadata.group_exec(self.gid)
| metadata.other_exec())
{
if mode.contains(AccessMode::EXEC) && !metadata.is_executable(self.uid, self.gid) {
return Err(Error::PermissionDenied);
}
@ -169,11 +155,17 @@ impl IoContext {
let target = target.as_ref();
if !target.is_absolute() {
todo!();
return Err(Error::InvalidArgument);
}
let target_node = self._find(self.root.clone(), target.trim_start_separators(), true)?;
target_node.mount(create_fs)
// Replace the root
if target_node.is_root() {
self.root = create_fs()?;
Ok(())
} else {
target_node.mount(create_fs)
}
}
/// Locates a [crate::Node] at given path and opens it with requested access options. If no
@ -194,6 +186,7 @@ impl IoContext {
let (parent, name) = path.split_right();
let parent = self.find(at, parent, true)?;
let filename = Filename::new(name)?;
let access = self.check_access(&parent, AccessMode::WRITE)?;
let create_info = CreateInfo {
name: filename,
mode: mode & !self.umask,
@ -201,7 +194,6 @@ impl IoContext {
gid: self.gid,
ty: CreateFileType::File,
};
let access = self.check_access(&parent, AccessMode::WRITE)?;
parent.create(create_info, access)?
}
Err(err) => return Err(err),
@ -720,7 +712,9 @@ mod tests {
let mut ioctx = IoContext::new(root.clone());
ioctx.cwd_node = d0.clone();
ioctx.cwd_path = PathBuf::from_str("/already");
ioctx.mount("/already/mountpoint", fs2.clone()).unwrap();
ioctx
.mount("/already/mountpoint", || Ok(fs2.clone()))
.unwrap();
for (input, expected, expected_node) in tests {
let (output, node) = ioctx.normalize(input, true).unwrap();
@ -729,7 +723,7 @@ mod tests {
}
}
#[test]
#[test_log::test]
fn access() {
let f1 = const_value_node("file1");
let f2 = const_value_node("file2");
@ -755,12 +749,22 @@ mod tests {
.unwrap();
// 0:1, 0644
f2.set_access(None, Some(gid), None, AccessToken::test_authorized())
.unwrap();
f2.set_access(
None,
Some(gid),
Some(FileMode::new(0o644)),
AccessToken::test_authorized(),
)
.unwrap();
// 1:1, 0644
f3.set_access(Some(uid), Some(gid), None, AccessToken::test_authorized())
.unwrap();
f3.set_access(
Some(uid),
Some(gid),
Some(FileMode::new(0o644)),
AccessToken::test_authorized(),
)
.unwrap();
// f1, read-only
ioctx
@ -780,7 +784,7 @@ mod tests {
let err = ioctx
.open(None, "/f2", OpenOptions::WRITE, FileMode::empty())
.unwrap_err();
assert_eq!(err, Error::ReadOnly);
assert_eq!(err, Error::PermissionDenied);
// f3, read-only
ioctx
@ -846,7 +850,7 @@ mod tests {
let node = ioctx.find(None, "/f1", true).unwrap();
assert!(Arc::ptr_eq(&node, &root1_f1));
ioctx.mount("/", root2.clone()).unwrap();
ioctx.mount("/", || Ok(root2.clone())).unwrap();
let node = ioctx.find(None, "/f1", true).unwrap();
assert!(Arc::ptr_eq(&node, &root2_f1));

View File

@ -13,40 +13,24 @@ pub struct AccessToken(PhantomData<()>);
#[allow(missing_docs)]
impl Metadata {
pub fn user_read(&self, uid: UserId) -> bool {
self.uid == uid && self.mode.contains(FileMode::USER_READ)
pub fn is_writeable(&self, uid: UserId, gid: GroupId) -> bool {
uid.is_root()
|| (uid == self.uid && self.mode.contains(FileMode::USER_WRITE))
|| (gid == self.gid && self.mode.contains(FileMode::GROUP_WRITE))
|| self.mode.contains(FileMode::OTHER_WRITE)
}
pub fn user_write(&self, uid: UserId) -> bool {
self.uid == uid && self.mode.contains(FileMode::USER_WRITE)
pub fn is_readable(&self, uid: UserId, gid: GroupId) -> bool {
uid.is_root()
|| (uid == self.uid && self.mode.contains(FileMode::USER_READ))
|| (gid == self.gid && self.mode.contains(FileMode::GROUP_READ))
|| self.mode.contains(FileMode::OTHER_READ)
}
pub fn user_exec(&self, uid: UserId) -> bool {
self.uid == uid && self.mode.contains(FileMode::USER_EXEC)
}
pub fn group_read(&self, gid: GroupId) -> bool {
self.gid == gid && self.mode.contains(FileMode::GROUP_READ)
}
pub fn group_write(&self, gid: GroupId) -> bool {
self.gid == gid && self.mode.contains(FileMode::GROUP_WRITE)
}
pub fn group_exec(&self, gid: GroupId) -> bool {
self.gid == gid && self.mode.contains(FileMode::GROUP_EXEC)
}
pub fn other_read(&self) -> bool {
self.mode.contains(FileMode::OTHER_READ)
}
pub fn other_write(&self) -> bool {
self.mode.contains(FileMode::OTHER_WRITE)
}
pub fn other_exec(&self) -> bool {
self.mode.contains(FileMode::OTHER_EXEC)
pub fn is_executable(&self, uid: UserId, gid: GroupId) -> bool {
(uid == self.uid && self.mode.contains(FileMode::USER_READ))
|| (gid == self.gid && self.mode.contains(FileMode::GROUP_READ))
|| self.mode.contains(FileMode::OTHER_READ)
}
}
@ -77,3 +61,27 @@ impl Add for AccessToken {
impl AddAssign for AccessToken {
fn add_assign(&mut self, _rhs: Self) {}
}
#[cfg(test)]
mod tests {
use yggdrasil_abi::io::{FileMode, GroupId, UserId};
use crate::vfs::Metadata;
#[test]
fn access_check() {
let m = unsafe {
Metadata {
uid: UserId::from_raw(1),
gid: GroupId::from_raw(2),
..Metadata::now_root(FileMode::new(0o644))
}
};
unsafe {
assert!(!m.is_writeable(UserId::from_raw(3), GroupId::from_raw(3)));
assert!(!m.is_writeable(UserId::from_raw(2), GroupId::from_raw(2)));
assert!(m.is_writeable(UserId::from_raw(0), GroupId::from_raw(1)));
assert!(m.is_writeable(UserId::from_raw(1), GroupId::from_raw(2)));
}
}
}

View File

@ -508,7 +508,7 @@ mod tests {
use core::any::Any;
use std::sync::Arc;
use crate::vfs::node::NodeFlags;
use crate::vfs::{node::NodeFlags, Filename};
use super::{CommonImpl, DirectoryImpl, Node, RegularImpl};
@ -539,12 +539,14 @@ mod tests {
assert!(Arc::ptr_eq(&f1.parent(), &f1));
assert_eq!(d1.children_len().unwrap(), 0);
d1.add_child("f1", f1.clone()).unwrap();
d1.add_child(Filename::new("f1").unwrap(), f1.clone())
.unwrap();
assert!(Arc::ptr_eq(&f1.parent(), &d1));
assert_eq!(d1.children_len().unwrap(), 1);
assert!(Arc::ptr_eq(&d2.parent(), &d2));
d2.add_child("d1", d1.clone()).unwrap();
d2.add_child(Filename::new("d1").unwrap(), d1.clone())
.unwrap();
assert!(Arc::ptr_eq(&f1.parent(), &d1));
assert!(Arc::ptr_eq(&d1.parent(), &d2));
assert_eq!(d1.children_len().unwrap(), 1);
@ -559,7 +561,7 @@ mod tests {
let name = format!("f{}", i);
let node = Node::regular(DummyFile, NodeFlags::empty(), None, None);
d.add_child(name, node).unwrap();
d.add_child(Filename::new(&name).unwrap(), node).unwrap();
assert_eq!(d.size().unwrap(), d.children_len().unwrap() as u64);
}
}