feat(grid-agent): establish architecture and config (#118)
This commit is contained in:
87
crates/metacrate-grid-agent/tests/dependency_policy.rs
Normal file
87
crates/metacrate-grid-agent/tests/dependency_policy.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
const ALLOWED_DEPENDENCIES: [&str; 6] = [
|
||||
"libremetaverse",
|
||||
"libremetaverse-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"url",
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn package_has_only_reviewed_rust_dependencies_and_no_build_script() {
|
||||
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
assert!(
|
||||
!root.join("build.rs").exists(),
|
||||
"agent must not have a build script"
|
||||
);
|
||||
let manifest = fs::read_to_string(root.join("Cargo.toml")).expect("read package manifest");
|
||||
let dependency_section = manifest
|
||||
.split("[dependencies]")
|
||||
.nth(1)
|
||||
.expect("dependency section")
|
||||
.split("\n[")
|
||||
.next()
|
||||
.expect("end of dependency section");
|
||||
let observed = dependency_section
|
||||
.lines()
|
||||
.filter_map(|line| line.split_once('=').map(|(name, _)| name.trim()))
|
||||
.filter(|name| !name.is_empty())
|
||||
.collect::<BTreeSet<_>>();
|
||||
assert_eq!(
|
||||
observed,
|
||||
ALLOWED_DEPENDENCIES.into_iter().collect(),
|
||||
"every direct dependency needs explicit policy review"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn runtime_source_has_no_subprocess_or_native_abi_escape_hatch() {
|
||||
let source = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src");
|
||||
let mut files = Vec::with_capacity(8);
|
||||
collect_rust_files(&source, &mut files);
|
||||
assert!(
|
||||
files.len() <= 8,
|
||||
"source-file count needs a reviewed bound update"
|
||||
);
|
||||
for path in files {
|
||||
let text = fs::read_to_string(&path).expect("read runtime source");
|
||||
for forbidden in [
|
||||
"std::process::Command",
|
||||
"tokio::process",
|
||||
"Command::new(",
|
||||
"extern \"C\"",
|
||||
"#[link(",
|
||||
"unsafe fn ",
|
||||
"unsafe impl ",
|
||||
] {
|
||||
assert!(
|
||||
!text.contains(forbidden),
|
||||
"{} contains forbidden runtime boundary {forbidden:?}",
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
assert!(
|
||||
!text.lines().any(|line| {
|
||||
let line = line.trim_start();
|
||||
line.starts_with("unsafe {") || line.contains("= unsafe {")
|
||||
}),
|
||||
"{} contains an unsafe block",
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_rust_files(directory: &Path, output: &mut Vec<PathBuf>) {
|
||||
for entry in fs::read_dir(directory).expect("read source directory") {
|
||||
let path = entry.expect("source entry").path();
|
||||
if path.is_dir() {
|
||||
collect_rust_files(&path, output);
|
||||
} else if path.extension().is_some_and(|extension| extension == "rs") {
|
||||
output.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user