holger-build-thing/tests/tree_native_equals_wasm.rs
//! **One source, two link targets, one answer.** The same `HolgerBuildThing`
//! is called natively and — compiled to `wasm32-unknown-unknown` and loaded
//! through the plugin host — over the ABI, and the three tree ops
//! (`options`, `try_toggle`, `actions`) must answer IDENTICALLY. If they did
//! not, the ⚒ pane (which reads the wasm) and the CLI (which links natively)
//! could disagree about the same click.
//!
//! Also the `fetch` capability: a coordinate the host did not offer is
//! REFUSED by name through the wasm boundary (the module must not see an empty
//! artifact), and one it did offer arrives byte-identical.
use holger_build_thing::HolgerBuildThing;
use nornir_build_thing::plugin::BuildThing;
use nornir_build_thing::plugin_host::{HostFacts, Limits, PluginHandle};
use nornir_build_thing::tree::{SettingsTree, ToggleRequest};
use nornir_build_thing::variant::ArtifactKind;
#[test]
fn options_try_toggle_and_actions_answer_the_same_natively_and_over_wasm() {
let wasm = traits::test_support::wasm_guest("holger-build-thing");
let native = HolgerBuildThing;
let mut plugin =
PluginHandle::load_file_with(&wasm, Limits::default(), HostFacts::at_rev("test", false))
.expect("the plugin loads");
let set = native.variants();
let forest = SettingsTree::forest(&set);
assert!(
!forest.is_empty(),
"holger declares variants, so it has trees"
);
let mut compared = 0usize;
for tree in &forest {
let over_wasm = plugin
.options(&tree.variant, "")
.expect("options over the ABI");
assert_eq!(
over_wasm.as_ref(),
Some(tree),
"options({}) differs native vs wasm",
tree.variant
);
assert_eq!(native.options(&tree.variant, ""), over_wasm);
for node in tree.walk() {
// Every node: the subtree and, for a feature, both toggles.
let sub_native = native.options(&tree.variant, &node.path);
let sub_wasm = plugin.options(&tree.variant, &node.path).unwrap();
assert_eq!(
sub_native, sub_wasm,
"options({}, {}) differs",
tree.variant, node.path
);
for on in [true, false] {
let req = ToggleRequest::new(&tree.variant, &node.path, on);
let d_native = native.try_toggle(&req);
let d_wasm = plugin.try_toggle(&req).unwrap();
assert_eq!(
d_native, d_wasm,
"try_toggle({}, {}, {on}) differs",
tree.variant, node.path
);
compared += 1;
}
}
}
assert!(
compared > 0,
"nothing was compared — a vacuous identity proves nothing"
);
// An unknown variant and an unknown path answer the same refusal on both sides.
assert_eq!(
native.options("ghost", ""),
plugin.options("ghost", "").unwrap()
);
let req = ToggleRequest::new("ghost", "x", false);
assert_eq!(native.try_toggle(&req), plugin.try_toggle(&req).unwrap());
for kind in [
ArtifactKind::Exe,
ArtifactKind::Lib,
ArtifactKind::Wasm,
ArtifactKind::Container,
ArtifactKind::Vm,
ArtifactKind::Iso,
ArtifactKind::Installer,
ArtifactKind::Service,
ArtifactKind::Kernel,
] {
assert_eq!(
native.actions(kind),
plugin.actions(kind).unwrap(),
"actions({kind:?}) differs"
);
}
eprintln!(
"native == wasm over {} trees, {compared} toggles, 9 kinds",
forest.len()
);
}