use std::path::PathBuf;
fn ci_yml() -> String {
let workspace_root = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.and_then(|p| p.parent())
.expect("workspace layout: crates/core/../../ should resolve")
.to_path_buf();
let path = workspace_root.join(".github/workflows/ci.yml");
std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("failed to read {path:?}: {e}"))
}
fn nextest_commands(yml: &str) -> Vec<String> {
let mut commands = Vec::new();
let mut current: Option<String> = None;
for line in yml.lines().map(str::trim) {
if line.starts_with('#') {
continue;
}
let (body, continues) = match line.strip_suffix('\\') {
Some(body) => (body.trim_end(), true),
None => (line, false),
};
match current.as_mut() {
Some(acc) => {
acc.push(' ');
acc.push_str(body);
if !continues {
commands.push(current.take().expect("just matched Some"));
}
}
None if body.contains("cargo nextest run") => {
if continues {
current = Some(body.to_string());
} else {
commands.push(body.to_string());
}
}
None => {}
}
}
if let Some(acc) = current {
commands.push(acc);
}
commands
}
#[test]
fn the_workspace_test_job_still_enables_the_trace_feature() {
let yml = ci_yml();
let commands = nextest_commands(&yml);
assert!(
!commands.is_empty(),
"no `cargo nextest run` commands found in ci.yml — did the workflow move \
or change shape? This guard must be updated so it keeps protecting the \
host-clock deprecation warning's only real test."
);
let explicit: Vec<&String> = commands
.iter()
.filter(|c| c.contains("--no-default-features") && c.contains("--features"))
.collect();
assert!(
!explicit.is_empty(),
"no `cargo nextest run --no-default-features --features ...` command in \
ci.yml. If the workspace test job stopped opting out of default \
features then `trace` comes from the crate default and this guard is \
moot — but confirm that before deleting it, because `wasm_runtime::\
tests::host_clock` silently does not run without it.\n\
Commands found:\n {}",
commands.join("\n ")
);
for command in explicit {
let features = command
.split("--features")
.nth(1)
.and_then(|rest| rest.split_whitespace().next())
.unwrap_or_else(|| {
panic!("`--features` with no value in ci.yml command:\n {command}")
});
assert!(
features.split(',').any(|f| f == "trace"),
"ci.yml runs the workspace tests without the `trace` feature, so \
`wasm_runtime::tests::host_clock` is not compiled and NOTHING \
checks that the #5465 deprecation warning is emitted at WARN \
rather than DEBUG. Re-add `trace` to this command's feature \
list.\n command: {command}\n features: {features}"
);
}
}
#[test]
fn the_host_clock_test_module_is_still_gated_on_trace() {
let tests_rs = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/wasm_runtime/tests.rs");
let src = std::fs::read_to_string(&tests_rs)
.unwrap_or_else(|e| panic!("failed to read {tests_rs:?}: {e}"));
let code: String = src
.lines()
.filter(|l| !l.trim_start().starts_with("//"))
.collect::<Vec<_>>()
.join("\n");
assert!(
code.contains("#[cfg(feature = \"trace\")]\nmod host_clock;"),
"`mod host_clock;` in wasm_runtime/tests.rs is no longer immediately \
preceded by `#[cfg(feature = \"trace\")]`. If the gate was removed, the \
ci.yml feature guard in this file is obsolete and should be deleted \
with it; if the module was renamed, update both."
);
}