use std::path::{Path, PathBuf};
use std::process::Command;
fn repo_root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.and_then(Path::parent)
.expect("repo root")
.to_path_buf()
}
fn cargo() -> Command {
Command::new(env!("CARGO"))
}
#[test]
fn facade_does_not_depend_on_the_probe_daemon_crate() {
let manifest =
std::fs::read_to_string(Path::new(env!("CARGO_MANIFEST_DIR")).join("Cargo.toml"))
.expect("read manifest");
assert!(
!manifest.contains("running-process-probe-daemon"),
"the main crate must not depend on the probe daemon crate — it talks \
to it over IPC"
);
let probe_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("src/probe");
for entry in std::fs::read_dir(&probe_dir).expect("read src/probe") {
let path = entry.expect("dir entry").path();
if path.extension().and_then(|e| e.to_str()) != Some("rs") {
continue;
}
let src = std::fs::read_to_string(&path).expect("read source");
assert!(
!src.contains("running_process_probe_daemon"),
"{} references the probe daemon crate",
path.display()
);
}
}
#[test]
fn schema_dependency_disables_default_features() {
let manifest =
std::fs::read_to_string(Path::new(env!("CARGO_MANIFEST_DIR")).join("Cargo.toml"))
.expect("read manifest");
let line = manifest
.lines()
.find(|l| l.trim_start().starts_with("running-process-probe ="))
.expect("running-process-probe dependency line");
assert!(
line.contains("default-features = false"),
"the probe schema dependency must disable default features so the \
interposer/injection machinery stays out of this crate; got: {line}"
);
assert!(
!line.contains("embed-helper"),
"the main crate must never enable embed-helper; got: {line}"
);
}
#[test]
fn probe_schema_dependency_resolves_with_no_features() {
let output = cargo()
.current_dir(repo_root())
.args([
"tree",
"-p",
"running-process",
"--features",
"probe",
"--no-default-features",
"--edges",
"normal",
"-f",
"{p} :: {f}",
])
.output()
.expect("cargo tree");
assert!(
output.status.success(),
"cargo tree failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let tree = String::from_utf8_lossy(&output.stdout);
let line = tree
.lines()
.find(|l| l.contains("running-process-probe v"))
.unwrap_or_else(|| panic!("schema crate absent from the tree:\n{tree}"));
let features = line.rsplit("::").next().unwrap_or("").trim();
assert!(
features.is_empty(),
"running-process-probe resolved with features `{features}`; the main \
crate must pull it in featureless so the injection vehicles behind \
`embed-helper` are never compiled here"
);
assert!(
!tree.contains("running-process-probe-daemon"),
"the probe daemon crate must never appear in the main crate's graph"
);
}
#[test]
fn facade_has_no_global_constructors() {
let probe_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("src/probe");
for entry in std::fs::read_dir(&probe_dir).expect("read src/probe") {
let path = entry.expect("dir entry").path();
if path.extension().and_then(|e| e.to_str()) != Some("rs") {
continue;
}
let src = std::fs::read_to_string(&path).expect("read source");
let code: String = src
.lines()
.filter(|l| {
let t = l.trim_start();
!t.starts_with("//") && !t.starts_with("/*") && !t.starts_with('*')
})
.collect::<Vec<_>>()
.join("\n");
for forbidden in ["#[ctor]", "ctor::ctor", ".init_array", "lazy_static!"] {
assert!(
!code.contains(forbidden),
"{} contains `{forbidden}` in code; registration must happen \
only via an explicit probe::install() call",
path.display()
);
}
}
}