82 lines
2.4 KiB
Rust
82 lines
2.4 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),
|
|
});
|
|
assert!(matches!(
|
|
outcome,
|
|
SyscallOutcome::Complete(SyscallResult::Value(_))
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn spawn_thread_preserves_entry_and_stack() {
|
|
let (mut k, _) = kernel_with_process();
|
|
let tid = match k.handle_syscall(Syscall::SpawnThread {
|
|
entry: EntryPoint::from_raw(0xDEAD),
|
|
stack: StackPointer::from_raw(0xBEEF),
|
|
}) {
|
|
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);
|
|
}
|
|
|
|
#[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)
|
|
));
|
|
}
|