refactor(tests): fix clippy warnings

This commit is contained in:
Kristofers Solo 2025-09-28 20:27:43 +03:00
parent ad70a53c75
commit 5abcd400d4
Signed by: kristoferssolo
GPG Key ID: 8687F2D3EEE6F0ED
8 changed files with 106 additions and 74 deletions

View File

@ -82,7 +82,7 @@ pub fn save_trace<P: AsRef<Path>>(trace: &[TraceEvent], path: P) -> Result<(), T
Ok(()) Ok(())
} }
/// Load a trace from a JSON file to Vec<TraceEvent>. /// Load a trace from a JSON file to [`Vec<TraceEvent>`].
/// ///
/// # Errors /// # Errors
/// ///

View File

@ -1,27 +0,0 @@
use captra::{CapabilityManifest, HostState, add_wasm_linker_funcs, load_manifest};
use ed25519_dalek::SigningKey;
use rand::rngs::OsRng;
use wasmtime::{Engine, Linker, Store};
/// Load the example manifest bundled with the repo.
pub fn load_example_manifest() -> CapabilityManifest {
load_manifest("examples/manifest.json").expect("examples/manifest.json must exists")
}
/// Build a HostState with a fixed seed and a fresh SigningKey (OsRng).
pub fn make_host_with_seed(seed: u64) -> HostState {
let manifest = load_example_manifest();
let mut csprng = OsRng;
let keypair = SigningKey::generate(&mut csprng);
HostState::new(manifest, seed, keypair)
}
/// Create a wasmtime engine + linker with your host functions registered,
/// and a Store that owns the given HostState.
pub fn wasm_store_with_hosts(host: HostState) -> (Engine, Linker<HostState>, Store<HostState>) {
let engine = Engine::default();
let mut linker = Linker::new(&engine);
add_wasm_linker_funcs(&mut linker).expect("linker registration");
let store = Store::new(&engine, host);
(engine, linker, store)
}

14
tests/common/host.rs Normal file
View File

@ -0,0 +1,14 @@
use crate::common::manifest::load_example_manifest;
use captra::HostState;
use ed25519_dalek::SigningKey;
use rand::rngs::OsRng;
/// Build a [`HostState`] with a fixed seed and a fresh [`SigningKey`] (`OsRng`).
/// # Panics
#[must_use]
pub fn make_host_with_seed(seed: u64) -> HostState {
let manifest = load_example_manifest();
let mut csprng = OsRng;
let keypair = SigningKey::generate(&mut csprng);
HostState::new(manifest, seed, keypair)
}

9
tests/common/manifest.rs Normal file
View File

@ -0,0 +1,9 @@
use captra::{CapabilityManifest, load_manifest};
/// Load the example manifest bundled with the repo.
/// # Panics
#[inline]
#[must_use]
pub fn load_example_manifest() -> CapabilityManifest {
load_manifest("examples/manifest.json").expect("examples/manifest.json must exists")
}

6
tests/common/mod.rs Normal file
View File

@ -0,0 +1,6 @@
#[allow(dead_code)]
pub mod host;
#[allow(dead_code)]
pub mod manifest;
#[allow(dead_code)]
pub mod wasm;

14
tests/common/wasm.rs Normal file
View File

@ -0,0 +1,14 @@
use captra::{HostState, add_wasm_linker_funcs};
use wasmtime::{Engine, Linker, Store};
/// Create a wasmtime engine + linker with your host functions registered,
/// and a [`Store`] that owns the given [`HostState`].
/// # Panics
#[must_use]
pub fn wasm_store_with_hosts(host: HostState) -> (Engine, Linker<HostState>, Store<HostState>) {
let engine = Engine::default();
let mut linker = Linker::new(&engine);
add_wasm_linker_funcs(&mut linker).expect("linker registration");
let store = Store::new(&engine, host);
(engine, linker, store)
}

View File

@ -1,3 +1,6 @@
mod common;
use crate::common::host::make_host_with_seed;
use base64::{Engine, engine::general_purpose::STANDARD}; use base64::{Engine, engine::general_purpose::STANDARD};
use captra::{ use captra::{
CapError, EventType, HostState, ManifestError, TraceEvent, init_tracing, load_manifest, CapError, EventType, HostState, ManifestError, TraceEvent, init_tracing, load_manifest,
@ -83,67 +86,81 @@ fn manifest_validation_invalid() {
} }
#[test] #[test]
fn host_enforcement_with_trace() { fn host_enforcement_allowed() {
init_tracing(); init_tracing();
let mut host = make_host_with_seed(12_345);
let manifest = assert_ok!(load_manifest("examples/manifest.json"), "Load failed"); let result = assert_ok!(host.execute_plugin("./workspace/config.toml"));
let fixed_seed = 12345; assert!(result);
let mut csprng = OsRng;
let keypair = SigningKey::generate(&mut csprng);
let mut host = HostState::new(manifest, fixed_seed, keypair);
assert_eq!(host.run_id(), "captra-run-12345"); assert_eq!(host.trace().len(), 1);
let ev = assert_some!(host.trace().first());
// allowed - expect a tracing event assert_eq!(ev.run_id, "captra-run-12345");
let out1 = assert_ok!(host.execute_plugin("./workspace/config.toml")); assert_eq!(ev.seq, 1);
assert!(out1); assert_matches!(ev.event_type, EventType::CapCall);
// denied - event + entry assert_eq!(ev.input, "./workspace/config.toml");
let out2 = assert_err!(host.execute_plugin("/etc/passwd")); assert!(ev.outcome);
assert_eq!(out2, CapError::GlobMismatch); assert_eq!(ev.ts_seed, 8_166_419_713_379_829_776);
{
assert_eq!(host.trace().len(), 2); // Both allowed/denied log to trace.
let trace1 = assert_some!(host.trace().get(0));
assert_eq!(trace1.seq, 1);
assert_eq!(trace1.event_type, EventType::CapCall);
assert_eq!(trace1.input, "./workspace/config.toml");
assert!(trace1.outcome);
assert_eq!(trace1.ts_seed, 8_166_419_713_379_829_776);
assert_ne!(trace1.ts_seed, 0);
let trace2 = assert_some!(host.trace().get(1));
assert_eq!(trace2.run_id, "captra-run-12345");
assert_eq!(trace2.seq, 2);
assert_eq!(trace2.event_type, EventType::CapCall);
assert!(!trace2.outcome);
assert!(trace2.input.starts_with("glob_mismatch: "));
assert_eq!(trace2.ts_seed, 10_553_447_931_939_622_718);
assert_ne!(trace1.ts_seed, trace2.ts_seed);
} }
#[test]
fn host_enforcement_denied() {
init_tracing();
let mut host = make_host_with_seed(12_345);
let err = assert_err!(host.execute_plugin("/etc/passwd"));
assert_matches!(err, CapError::GlobMismatch);
assert_eq!(host.trace().len(), 1);
let ev = assert_some!(host.trace().first());
assert_eq!(ev.run_id, "captra-run-12345");
assert_eq!(ev.seq, 1);
assert_matches!(ev.event_type, EventType::CapCall);
assert!(!ev.outcome);
assert!(ev.input.starts_with("glob_mismatch: "));
assert_eq!(ev.ts_seed, 8_166_419_713_379_829_776);
}
#[test]
fn host_enforcement_signed() {
init_tracing();
let mut host = make_host_with_seed(12_345);
let _ = assert_ok!(host.execute_plugin("./workspace/config.toml"));
let signed = assert_ok!(host.sign_current_trace()); let signed = assert_ok!(host.sign_current_trace());
assert_eq!(signed.run_id, "captra-run-12345"); assert_eq!(signed.run_id, "captra-run-12345");
let sig_bytes = STANDARD.decode(&signed.signature).expect("Base64 decode"); let sig_bytes = STANDARD.decode(&signed.signature).expect("base64 decode");
assert_eq!(sig_bytes.len(), 64); assert_eq!(sig_bytes.len(), 64);
assert!(!signed.trace_json.is_empty()); // Nonempty JSON assert!(!signed.trace_json.is_empty()); // Nonempty JSON
}
// Save/load roundtrip #[test]
let tmp_dir = tempdir().expect("Temp dir failed"); fn host_enforcement_save_round_trip() {
init_tracing();
let mut host = make_host_with_seed(12_345);
let _ = assert_ok!(host.execute_plugin("./workspace/config.toml"));
let _ = assert_err!(host.execute_plugin("/etc/passwd"));
let tmp_dir = tempdir().expect("tempdir");
let tmp_path = tmp_dir.as_ref().join("trace.json"); let tmp_path = tmp_dir.as_ref().join("trace.json");
// Save and laod
assert_ok!(host.save_current_trace(&tmp_path), "Save failed"); assert_ok!(host.save_current_trace(&tmp_path), "Save failed");
let loaded_trace = assert_ok!(load_trace(tmp_path), "Load failed"); let loaded = assert_ok!(load_trace(tmp_path), "Load failed");
assert_eq!(loaded_trace.len(), 2); assert_eq!(loaded.len(), 2);
let trace1_refetched = assert_some!(host.trace().get(0)); let current_trace = host.trace();
let trace2_refetched = assert_some!(host.trace().get(1)); assert_eq!(loaded, current_trace);
let loaded_trace1 = assert_some!(loaded_trace.get(0));
let loaded_trace2 = assert_some!(loaded_trace.get(1));
assert_eq!(trace1_refetched, loaded_trace1); let loaded_first = assert_some!(loaded.first());
assert_eq!(trace2_refetched, loaded_trace2); let current_first = assert_some!(current_trace.first());
assert_eq!(loaded_first, current_first);
} }
#[test] #[test]
@ -152,7 +169,7 @@ fn trace_reproducibility() {
let manifest = assert_ok!(load_manifest("examples/manifest.json"), "Load failed"); let manifest = assert_ok!(load_manifest("examples/manifest.json"), "Load failed");
let fixed_seed = 12345; let fixed_seed = 12_345;
let mut csprng1 = OsRng; let mut csprng1 = OsRng;
let keypair1 = SigningKey::generate(&mut csprng1); let keypair1 = SigningKey::generate(&mut csprng1);

View File

@ -1,11 +1,10 @@
mod common; mod common;
use crate::common::{host::make_host_with_seed, wasm::wasm_store_with_hosts};
use captra::HostStatus; use captra::HostStatus;
use claims::{assert_ok, assert_some}; use claims::{assert_ok, assert_some};
use wasmtime::Module; use wasmtime::Module;
use crate::common::{make_host_with_seed, wasm_store_with_hosts};
#[test] #[test]
fn wasm_integration_allowed() { fn wasm_integration_allowed() {
let host = make_host_with_seed(12345); let host = make_host_with_seed(12345);
@ -28,7 +27,7 @@ fn wasm_integration_allowed() {
) )
) )
"#, "#,
len = path.as_bytes().len() len = path.len()
); );
let module = assert_ok!(Module::new(&engine, &wat)); let module = assert_ok!(Module::new(&engine, &wat));