Files
k-os/crates/kernel/src/tests/lifecycle.rs

89 lines
2.5 KiB
Rust

use super::*;
use crate::{SyscallOutcome, SyscallResult};
use domain::syscall::Syscall;
use types::address::{DataRef, EntryPoint, StackPointer};
use types::bounded::CapSlot;
use types::id::ThreadId;
#[test]
fn spawn_thread_creates_ready_thread() {
let (mut k, _) = kernel_with_process();
let outcome = k.handle_syscall(Syscall::SpawnThread {
entry: EntryPoint::from_raw(0x1000),
stack: StackPointer::from_raw(0x2000),
arg: 0,
});
assert!(matches!(
outcome,
SyscallOutcome::Complete(SyscallResult::Value(_))
));
}
#[test]
fn spawn_thread_preserves_entry_stack_and_arg() {
let (mut k, _) = kernel_with_process();
let tid = match k.handle_syscall(Syscall::SpawnThread {
entry: EntryPoint::from_raw(0xDEAD),
stack: StackPointer::from_raw(0xBEEF),
arg: 0x5107,
}) {
SyscallOutcome::Complete(SyscallResult::Value(v)) => ThreadId::from_raw(v as u16),
_ => panic!("expected Value"),
};
let ctx = k.thread_context(tid).unwrap();
assert_eq!(ctx.program_counter(), 0xDEAD);
assert_eq!(ctx.registers()[2], 0xBEEF);
assert_eq!(
ctx.registers()[10],
0x5107,
"the start argument arrives in a0"
);
}
#[test]
fn create_process_with_cap_succeeds() {
let (mut k, _) = kernel_with_process();
// boot() grants ProcessCreate cap at slot 0
let outcome = k.handle_syscall(Syscall::CreateProcess {
create_cap: CapSlot::new(0).unwrap(),
image: DataRef::empty(),
});
assert!(matches!(
outcome,
SyscallOutcome::Complete(SyscallResult::Slot(_))
));
}
#[test]
fn create_process_without_cap_fails() {
let (mut k, _) = kernel_with_process();
// slot 5 doesn't exist
let outcome = k.handle_syscall(Syscall::CreateProcess {
create_cap: CapSlot::new(5).unwrap(),
image: DataRef::empty(),
});
assert!(matches!(
outcome,
SyscallOutcome::Complete(SyscallResult::Error(_))
));
}
#[test]
fn kill_removes_process() {
let (mut k, _pid) = kernel_with_process();
// Create a second process, get cap for it
let slot = match k.handle_syscall(Syscall::CreateProcess {
create_cap: CapSlot::new(0).unwrap(),
image: DataRef::empty(),
}) {
SyscallOutcome::Complete(SyscallResult::Slot(s)) => s,
_ => panic!("expected slot"),
};
let outcome = k.handle_syscall(Syscall::Kill { process: slot });
assert!(matches!(
outcome,
SyscallOutcome::Complete(SyscallResult::Ok)
));
}