Implement domain and endpoint modules with capability management, message passing, and scheduling features

This commit is contained in:
2026-10-17 23:09:21 +02:00
parent 667bc7f7f7
commit 06b51b6712
25 changed files with 1064 additions and 24 deletions

View File

@@ -0,0 +1,152 @@
use super::*;
use types::generation::Generation;
use types::id::{EndpointId, RegionId};
use types::permission::{Permission, PermissionSet};
fn perms(permissions: &[Permission]) -> PermissionSet {
permissions
.iter()
.fold(PermissionSet::empty(), |set, &p| set.with(p))
}
fn endpoint_cap(id: u16, permissions: &[Permission]) -> Capability {
Capability::new(
Resource::Endpoint(EndpointId::from_raw(id)),
perms(permissions),
Generation::initial(),
)
}
fn memory_cap(id: u16, permissions: &[Permission]) -> Capability {
Capability::new(
Resource::Memory(RegionId::from_raw(id)),
perms(permissions),
Generation::initial(),
)
}
#[test]
fn new_table_is_empty() {
let table = CapabilityTable::new();
let slot = CapSlot::new(0).unwrap();
assert!(table.get(slot).is_err());
}
#[test]
fn insert_and_get() {
let mut table = CapabilityTable::new();
let slot = table.insert(endpoint_cap(1, &[Permission::Read])).unwrap();
let retrieved = table.get(slot).unwrap();
assert!(retrieved.permissions().allows(Permission::Read));
assert!(!retrieved.permissions().allows(Permission::Write));
}
#[test]
fn remove_then_get_fails() {
let mut table = CapabilityTable::new();
let slot = table.insert(endpoint_cap(1, &[Permission::Read])).unwrap();
table.remove(slot).unwrap();
assert!(table.get(slot).is_err());
}
#[test]
fn remove_invalid_slot_fails() {
let mut table = CapabilityTable::new();
let slot = CapSlot::new(5).unwrap();
assert!(table.remove(slot).is_err());
}
#[test]
fn insert_reuses_removed_slot() {
let mut table = CapabilityTable::new();
let slot = table.insert(endpoint_cap(1, &[Permission::Read])).unwrap();
table.remove(slot).unwrap();
let new_slot = table.insert(endpoint_cap(2, &[Permission::Write])).unwrap();
assert_eq!(slot, new_slot);
}
#[test]
fn full_table_returns_no_free_slot() {
let mut table = CapabilityTable::new();
for i in 0..MAX_CAPS_PER_PROCESS {
assert!(
table
.insert(endpoint_cap(i as u16, &[Permission::Read]))
.is_ok()
);
}
assert!(table.insert(endpoint_cap(999, &[])).is_err());
}
#[test]
fn generation_mismatch_detected() {
let gen_v1 = Generation::initial();
let gen_v2 = gen_v1.next();
assert!(gen_v1.is_valid_against(&gen_v1));
assert!(!gen_v1.is_valid_against(&gen_v2));
}
#[test]
fn restrict_to_never_escalates() {
let full = perms(&[Permission::Read, Permission::Write, Permission::Execute]);
let read_only = perms(&[Permission::Read]);
let restricted = full.restrict_to(&read_only);
assert!(restricted.allows(Permission::Read));
assert!(!restricted.allows(Permission::Write));
assert!(!restricted.allows(Permission::Execute));
}
#[test]
fn restrict_to_cannot_add_permissions() {
let read_only = perms(&[Permission::Read]);
let wants_everything = perms(&[
Permission::Read,
Permission::Write,
Permission::Execute,
Permission::Delegate,
Permission::Revoke,
]);
let result = read_only.restrict_to(&wants_everything);
assert!(result.allows(Permission::Read));
assert!(!result.allows(Permission::Write));
assert!(!result.allows(Permission::Execute));
assert!(!result.allows(Permission::Delegate));
assert!(!result.allows(Permission::Revoke));
}
#[test]
fn is_subset_of() {
let rw = perms(&[Permission::Read, Permission::Write]);
let read_only = perms(&[Permission::Read]);
assert!(read_only.is_subset_of(&rw));
assert!(!rw.is_subset_of(&read_only));
}
#[test]
fn empty_permission_set_allows_nothing() {
let empty = PermissionSet::empty();
assert!(!empty.allows(Permission::Read));
assert!(!empty.allows(Permission::Write));
assert!(!empty.allows(Permission::Execute));
assert!(!empty.allows(Permission::Delegate));
assert!(!empty.allows(Permission::Revoke));
}
#[test]
fn capability_preserves_resource_and_permissions() {
let permissions = [Permission::Read, Permission::Write];
let expected_permissions = perms(&permissions);
let cap = memory_cap(42, &permissions);
assert_eq!(cap.permissions(), &expected_permissions);
assert_eq!(cap.generation(), &Generation::initial());
}