#[cfg(feature = "dangerous-test-hooks")]
use bvisor::{
BackendRegistry, Boundary, BoundaryRunner, BoundarySpec, BudgetRequirements,
EvidenceRequirements, HostControl, LifecycleError, MinGuarantee, Workload,
};
#[cfg(feature = "dangerous-test-hooks")]
use std::sync::Arc;
#[cfg(feature = "dangerous-test-hooks")]
fn registry() -> BackendRegistry {
let mut registry = BackendRegistry::new();
registry.register(Arc::new(bvisor::__sim::SimBackend::new(Box::new(
bvisor::__sim::OneShotLiar::new(bvisor::__sim::LieMode::Honest),
))));
registry
}
#[cfg(feature = "dangerous-test-hooks")]
fn sim_id() -> bvisor::BackendId {
bvisor::BackendId::new(bvisor::__sim::SimBackend::ID)
}
#[cfg(feature = "dangerous-test-hooks")]
fn spec_running(exe: &str) -> BoundarySpec {
BoundarySpec {
workload: Workload::Process {
exe: exe.to_string(),
args: Vec::new(),
},
capabilities: Vec::new(),
controls: vec![HostControl::LaunchWorkload],
budgets: BudgetRequirements::uniform(64, MinGuarantee::Mediated),
evidence: EvidenceRequirements::default(),
}
}
#[cfg(feature = "dangerous-test-hooks")]
#[test]
fn legal_lifecycle_sequence_runs_end_to_end() {
let registry = registry();
let runner = BoundaryRunner::new(®istry);
let planned = Boundary::propose(spec_running("true"), sim_id())
.plan(®istry)
.expect("zero-confinement spec must plan on the honest sim");
let plan_id = planned.plan_id();
let attempt = bvisor::AttemptId([7u8; 32]);
let started = planned.start(attempt);
assert_eq!(started.attempt(), attempt, "the attempt id is carried");
assert_eq!(
started.started_event().plan.plan_id,
plan_id,
"the 0x001 started event embeds the started plan"
);
let report = runner.run(started.as_plan()).expect("honest sim run seals");
let reported = started
.into_reported(report)
.expect("a report answering this plan is accepted");
assert_eq!(reported.attempt(), attempt, "the attempt survives the seal");
assert_eq!(reported.plan_id(), plan_id, "the plan id survives the seal");
assert_eq!(
reported.report_event().report.body.plan_id,
plan_id,
"the 0x002 report event answers the started plan"
);
let (plan, parts_attempt, parts_report) = reported.into_parts();
assert_eq!(plan.plan_id, plan_id);
assert_eq!(parts_attempt, attempt);
assert_eq!(parts_report.body.plan_id, plan_id);
}
#[cfg(feature = "dangerous-test-hooks")]
#[test]
fn into_reported_rejects_a_report_for_a_different_plan() {
let registry = registry();
let runner = BoundaryRunner::new(®istry);
let started = Boundary::propose(spec_running("true"), sim_id())
.plan(®istry)
.expect("plan A")
.start(bvisor::AttemptId([1u8; 32]));
let other_planned = Boundary::propose(spec_running("false"), sim_id())
.plan(®istry)
.expect("plan B");
assert_ne!(
started.plan_id(),
other_planned.plan_id(),
"the two specs must produce distinct plan ids for this test to bite"
);
let foreign_report = runner.run(other_planned.as_plan()).expect("run B seals");
let foreign_id = foreign_report.body.plan_id;
let started_id = started.plan_id();
let err = started
.into_reported(foreign_report)
.expect_err("a report for plan B must not bind to an attempt on plan A");
assert_eq!(
err,
LifecycleError::ReportPlanMismatch {
expected: started_id,
found: foreign_id,
},
"the mismatch names both plan ids"
);
}