170 lines
5.0 KiB
Rust

use super::*;
fn all_syscalls() -> Vec<Syscall> {
domains::all_entries().map(|entry| entry.syscall).collect()
}
#[test]
fn every_syscall_has_metadata() {
for sc in all_syscalls() {
let m = meta_for(sc);
assert_eq!(m.id, sc as u32, "id mismatch for {:?}", sc);
assert!(!m.module.is_empty(), "module must be non-empty for id=0x{:08X}", m.id);
assert!(!m.name.is_empty(), "name must be non-empty for id=0x{:08X}", m.id);
assert!(m.version > 0, "version must be > 0 for id=0x{:08X}", m.id);
}
use std::collections::HashSet;
let mut ids = HashSet::new();
let mut identities = HashSet::new();
let mut count = 0usize;
for entry in domains::all_entries() {
count += 1;
assert!(ids.insert(entry.meta.id), "duplicate syscall id 0x{:08X}", entry.meta.id);
let parsed = Syscall::from_u32(entry.meta.id).expect("id not recognized by enum mapping");
assert_eq!(parsed as u32, entry.meta.id);
let key = (entry.meta.module, entry.meta.name, entry.meta.version);
assert!(
identities.insert(key),
"duplicate canonical identity: ({}.{}, v{})",
entry.meta.module,
entry.meta.name,
entry.meta.version
);
}
assert_eq!(count, all_syscalls().len());
}
#[test]
fn resolver_returns_expected_id_for_known_identity() {
let id = resolve_syscall("gfx", "clear", 1).expect("known identity must resolve");
assert_eq!(id.id, 0x1001);
assert_eq!(id.meta.module, "gfx");
assert_eq!(id.meta.name, "clear");
assert_eq!(id.meta.version, 1);
}
#[test]
fn resolver_rejects_unknown_identity() {
let res = resolve_syscall("gfx", "nonexistent", 1);
assert!(res.is_none());
let requested = [SyscallIdentity { module: "gfx", name: "nonexistent", version: 1 }];
let err = resolve_program_syscalls(&requested, 0).unwrap_err();
match err {
LoadError::UnknownSyscall { module, name, version } => {
assert_eq!(module, "gfx");
assert_eq!(name, "nonexistent");
assert_eq!(version, 1);
}
_ => panic!("expected UnknownSyscall error"),
}
}
#[test]
fn resolver_enforces_capabilities() {
let requested = [SyscallIdentity { module: "gfx", name: "clear", version: 1 }];
let err = resolve_program_syscalls(&requested, 0).unwrap_err();
match err {
LoadError::MissingCapability { required, provided, module, name, version } => {
assert_eq!(module, "gfx");
assert_eq!(name, "clear");
assert_eq!(version, 1);
assert_ne!(required, 0);
assert_eq!(provided, 0);
}
_ => panic!("expected MissingCapability error"),
}
let ok = resolve_program_syscalls(&requested, caps::GFX).expect("must resolve with caps");
assert_eq!(ok.len(), 1);
assert_eq!(ok[0].id, 0x1001);
}
#[test]
fn declared_resolver_returns_expected_id_for_known_identity() {
let declared = [prometeu_bytecode::SyscallDecl {
module: "gfx".into(),
name: "clear".into(),
version: 1,
arg_slots: 1,
ret_slots: 0,
}];
let ok =
resolve_declared_program_syscalls(&declared, caps::GFX).expect("must resolve with ABI");
assert_eq!(ok.len(), 1);
assert_eq!(ok[0].id, 0x1001);
}
#[test]
fn declared_resolver_rejects_unknown_identity() {
let declared = [prometeu_bytecode::SyscallDecl {
module: "gfx".into(),
name: "nonexistent".into(),
version: 1,
arg_slots: 1,
ret_slots: 0,
}];
let err = resolve_declared_program_syscalls(&declared, caps::GFX).unwrap_err();
assert_eq!(
err,
DeclaredLoadError::UnknownSyscall {
module: "gfx".into(),
name: "nonexistent".into(),
version: 1,
}
);
}
#[test]
fn declared_resolver_rejects_missing_capability() {
let declared = [prometeu_bytecode::SyscallDecl {
module: "gfx".into(),
name: "clear".into(),
version: 1,
arg_slots: 1,
ret_slots: 0,
}];
let err = resolve_declared_program_syscalls(&declared, caps::NONE).unwrap_err();
assert_eq!(
err,
DeclaredLoadError::MissingCapability {
required: caps::GFX,
provided: caps::NONE,
module: "gfx".into(),
name: "clear".into(),
version: 1,
}
);
}
#[test]
fn declared_resolver_rejects_abi_mismatch() {
let declared = [prometeu_bytecode::SyscallDecl {
module: "gfx".into(),
name: "draw_line".into(),
version: 1,
arg_slots: 4,
ret_slots: 0,
}];
let err = resolve_declared_program_syscalls(&declared, caps::GFX).unwrap_err();
assert_eq!(
err,
DeclaredLoadError::AbiMismatch {
module: "gfx".into(),
name: "draw_line".into(),
version: 1,
declared_arg_slots: 4,
declared_ret_slots: 0,
expected_arg_slots: 5,
expected_ret_slots: 0,
}
);
}