crates/heimdall-core/tests/workspace.rs
// SPDX-License-Identifier: AGPL-3.0-only
// Copyright (C) 2026 Ignalina ApS and Vetra Automation AB
//! The job workspace in the policy (owner decision 2026-11-01). Heimdall is a
//! defensive sandbox; nothing runs here.
use heimdall_core::*;
#[test]
fn no_workspace_by_default_and_old_policy_json_still_reads() {
assert_eq!(Policy::default().workspace, None);
let p: Policy = serde_json::from_str(
r#"{"read":[],"write":[],"net":null,"limits":{"wall":{"secs":10,"nanos":0},"memory_bytes":268435456,"cpus":1.0,"pids":64,"fuel":null,"table_elements":10000,"instances":1,"tables":1,"memories":1,"stack_bytes":524288,"max_output_files":64,"max_output_file_bytes":67108864,"max_output_total_bytes":268435456,"decoders":1}}"#,
)
.unwrap();
assert_eq!(p.workspace, None);
// Not serialized when absent: an old reader sees the policy it knew.
assert!(!serde_json::to_string(&Policy::default())
.unwrap()
.contains("workspace"));
}
#[test]
fn a_workspace_round_trips_with_exec_off_by_default() {
let w: Workspace = serde_json::from_str(r#"{"bytes":1048576}"#).unwrap();
assert_eq!(
w,
Workspace {
bytes: 1 << 20,
exec: false
}
);
let p = Policy {
workspace: Some(Workspace {
bytes: 5 << 30,
exec: true,
}),
..Policy::default()
};
let back: Policy = serde_json::from_str(&serde_json::to_string(&p).unwrap()).unwrap();
assert_eq!(back, p);
}
#[test]
fn the_size_picks_the_kind_tmpfs_up_to_1_gib_then_a_host_folder() {
let k = |bytes| Workspace { bytes, exec: false }.kind();
assert_eq!(k(1), WorkspaceKind::Tmpfs);
assert_eq!(k(WORKSPACE_TMPFS_MAX), WorkspaceKind::Tmpfs);
assert_eq!(WORKSPACE_TMPFS_MAX, 1 << 30);
assert_eq!(k(WORKSPACE_TMPFS_MAX + 1), WorkspaceKind::HostDir);
assert_eq!(WORKSPACE_PATH, "/work");
}
#[test]
fn a_workspace_kill_round_trips_on_the_wire() {
assert_eq!(codes::LIMIT_WORKSPACE, "heimdall-limit-workspace");
let mut r = JobResult {
job_id: JobId::random(),
nonce: Nonce::random(),
verdict: Verdict::refused(codes::LIMIT_WORKSPACE, "over"),
outputs: vec![],
exit: ExitInfo::exited(0),
started_unix: 1,
finished_unix: 2,
runner: Features {
runner: "heimdall".into(),
container: true,
seccomp: Protection::Default,
landlock: true,
broker: false,
wasm: false,
image_verified_each_start: true,
},
events: vec![],
kernel: None,
};
r.exit.killed = Some(KillReason::Workspace);
assert_eq!(decode_result(&encode_result(&r)).unwrap(), r);
}