feat: add tests for untyped

This commit is contained in:
Paul Pan 2024-04-28 21:52:31 +08:00
parent 5ea8a56611
commit 95dc7144c6

View File

@ -130,3 +130,100 @@ impl UntypedCap<'_> {
Ok(()) Ok(())
} }
} }
#[cfg(test)]
mod tests {
use super::*;
use crate::{arch::vspace::KERNEL_ALLOCATOR, objects::cap::CapEntry};
use core::alloc::Layout;
use log::info;
fn alloc_mem(size: usize) -> PhysAddr {
assert!(size.is_power_of_two());
let layout = Layout::from_size_align(size, 1).unwrap();
KERNEL_ALLOCATOR.lock().alloc(layout).unwrap()
}
fn create_untyped_cte(size: usize, is_device: bool) -> CapEntry {
let ptr = alloc_mem(size);
let raw = UntypedCap::mint(0, size.ilog2() as usize, is_device, ptr);
CapEntry::new(raw)
}
fn create_cnode_cte(size: usize, guard_size: usize, guard: usize) -> CapEntry {
let ptr = alloc_mem(size);
let radix = size.ilog2() as usize - ObjectType::CNode.bits(0);
let raw = CNodeCap::mint(radix, guard_size, guard, ptr);
CapEntry::new(raw)
}
#[test_case]
fn test_untyped_retype_cnode() {
// create untyped
let untyped_cte = create_untyped_cte(4 * ObjectType::CNode.size(2), false); // 4 cnode (4 entries each)
let mut untyped = UntypedCap::try_from(&untyped_cte).unwrap();
// create root cnode
let cnode_cte = create_cnode_cte(ObjectType::CNode.size(4), 3, 0b110); // 1 cnode (16 entries)
let mut cnode = CNodeCap::try_from(&cnode_cte).unwrap();
// slots
let slots = cnode.as_object_mut();
// retype untyped to cnode
info!("Retyping to ObjectType::CNode");
untyped.retype(ObjectType::CNode, 2, &mut slots[1..2]).unwrap();
untyped.retype(ObjectType::CNode, 2, &mut slots[9..12]).unwrap();
// check untyped
info!("Checking remain space in untyped");
assert_eq!(untyped.free_offset(), untyped.block_size());
assert!(untyped.retype(ObjectType::CNode, 1, &mut slots[0..1]).is_err());
// check cnode
info!("Checking retyped cnode length");
for addr in [1, 9, 10, 11] {
let cte = cnode.resolve_address_bits(0b110_0000 | addr, 7).unwrap();
let cap = CNodeCap::try_from(cte).unwrap();
let len = cap.as_object().len();
assert_eq!(len, 4);
}
info!("Make sure other cnodes are not modified");
for addr in 0..16 {
if [1, 9, 10, 11].contains(&addr) {
continue;
}
let cte = cnode.resolve_address_bits(0b110_0000 | addr, 7).unwrap();
NullCap::try_from(cte).unwrap();
}
}
#[test_case]
fn test_untyped_retype_device_err() {
// create untyped
let untyped_cte = create_untyped_cte(ObjectType::CNode.size(1), true);
let mut untyped = UntypedCap::try_from(&untyped_cte).unwrap();
// create root cnode
let cnode_cte = create_cnode_cte(ObjectType::CNode.size(1), 3, 0b110);
let mut cnode = CNodeCap::try_from(&cnode_cte).unwrap();
// slots
let slots = cnode.as_object_mut();
// allocate fail
info!("Retyping to ObjectType::CNode with device memory");
untyped
.retype(ObjectType::CNode, 1, &mut slots[0..1])
.is_err()
.then_ok((), ())
.unwrap();
// nothing should be changed
info!("Make sure nothing is changed");
assert_eq!(untyped.free_offset(), 0);
NullCap::try_from(&slots[0]).unwrap();
}
// TODO: more tests
}