Files
khadhroony-solana-project/crates/ksp-config-lib/tests/ownership.rs
2026-08-20 17:08:32 +02:00

344 lines
14 KiB
Rust

// file: crates/ksp-config-lib/tests/ownership.rs
// version: 4
//! Workspace ownership audits for KSP application configuration boundaries.
fn workspace_root() -> std::path::PathBuf {
let manifest_directory = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let root = manifest_directory.parent().and_then(std::path::Path::parent);
return match root {
std::option::Option::Some(value) => value.to_path_buf(),
std::option::Option::None => manifest_directory,
};
}
fn collect_rust_files(directory: &std::path::Path, files: &mut std::vec::Vec<std::path::PathBuf>) {
let entries = std::fs::read_dir(directory);
let entries = match entries {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
for entry in entries {
let entry = match entry {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => continue,
};
let path = entry.path();
if path.is_dir() {
collect_rust_files(path.as_path(), files);
continue;
}
if path.extension().and_then(std::ffi::OsStr::to_str) == std::option::Option::Some("rs") {
files.push(path);
}
}
}
fn collect_json_files(directory: &std::path::Path, files: &mut std::vec::Vec<std::path::PathBuf>) {
let entries = std::fs::read_dir(directory);
let entries = match entries {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
for entry in entries {
let entry = match entry {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => continue,
};
let path = entry.path();
if path.is_dir() {
collect_json_files(path.as_path(), files);
continue;
}
if path.extension().and_then(std::ffi::OsStr::to_str) == std::option::Option::Some("json") {
files.push(path);
}
}
}
fn non_comment_source(source: &str) -> String {
let mut filtered = String::new();
for line in source.lines() {
let trimmed = line.trim_start();
if trimmed.starts_with("//") {
continue;
}
filtered.push_str(line);
filtered.push('\n');
}
return filtered;
}
fn collect_environment_names(source: &str, names: &mut std::collections::BTreeSet<String>) {
let bytes = source.as_bytes();
let mut index: usize = 0;
while index < bytes.len() {
let prefix_length = if bytes[index..].starts_with(b"KSPB_") {
5
} else if bytes[index..].starts_with(b"KSP_") {
4
} else {
index += 1;
continue;
};
let mut end = index + prefix_length;
while end < bytes.len() {
let byte = bytes[end];
if byte.is_ascii_uppercase() || byte.is_ascii_digit() || byte == b'_' {
end += 1;
} else {
break;
}
}
let candidate = std::str::from_utf8(&bytes[index..end]);
if let std::result::Result::Ok(candidate) = candidate
&& candidate.len() > prefix_length
&& !candidate.ends_with('_')
&& !is_environment_namespace_label(candidate)
{
names.insert(candidate.to_owned());
}
index = end;
}
}
fn is_environment_namespace_label(candidate: &str) -> bool {
return matches!(candidate, "KSP_PUBLIC" | "KSP_SECRET" | "KSPB_PUBLIC" | "KSPB_SECRET");
}
fn dotenv_example_assignments(source: &str) -> std::collections::BTreeMap<String, usize> {
let mut assignments = std::collections::BTreeMap::<String, usize>::new();
for (line_index, line) in source.lines().enumerate() {
let mut candidate = line.trim();
if let std::option::Option::Some(commented) = candidate.strip_prefix('#') {
candidate = commented.trim_start();
}
let separator = candidate.find('=');
let separator = match separator {
std::option::Option::Some(value) => value,
std::option::Option::None => continue,
};
let name = candidate[..separator].trim();
if (name.starts_with("KSP_") || name.starts_with("KSPB_")) && !name.ends_with('_') {
assignments.insert(name.to_owned(), line_index);
}
}
return assignments;
}
fn has_preceding_explanatory_comment(source: &str, assignment_line_index: usize) -> bool {
let lines: std::vec::Vec<&str> = source.lines().collect();
if assignment_line_index == 0 || assignment_line_index > lines.len() {
return false;
}
let mut index = assignment_line_index;
while index > 0 {
index -= 1;
let trimmed = lines[index].trim();
if trimmed.is_empty() {
continue;
}
if !trimmed.starts_with('#') {
return false;
}
let comment = trimmed.trim_start_matches('#').trim_start();
if comment.starts_with("file:") || comment.starts_with("version:") {
return false;
}
if comment.contains('=') && (comment.starts_with("KSP_") || comment.starts_with("KSPB_")) {
return false;
}
return true;
}
return false;
}
#[test]
fn foundational_dependency_direction_does_not_point_back_to_config() {
let root = workspace_root();
for crate_name in ["ksp-core-lib", "ksp-logging-lib"] {
let manifest_path = root.join("crates").join(crate_name).join("Cargo.toml");
let manifest = std::fs::read_to_string(manifest_path.as_path());
assert!(manifest.is_ok(), "unable to read {}", manifest_path.display());
if let std::result::Result::Ok(manifest) = manifest {
assert!(!manifest.contains("ksp-config-lib"), "{} must not depend on ksp-config-lib", manifest_path.display());
}
}
}
#[test]
fn workspace_crates_do_not_read_ksp_environment_directly() {
let root = workspace_root();
let crates_directory = root.join("crates");
let entries = std::fs::read_dir(crates_directory.as_path());
assert!(entries.is_ok(), "unable to inspect workspace crates at {}", crates_directory.display());
let entries = match entries {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
for entry in entries {
let entry = match entry {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => continue,
};
if !entry.path().is_dir() || entry.file_name() == std::ffi::OsStr::new("ksp-config-lib") {
continue;
}
let mut rust_files = std::vec::Vec::new();
collect_rust_files(entry.path().as_path(), &mut rust_files);
for rust_file in rust_files {
let source = std::fs::read_to_string(rust_file.as_path());
assert!(source.is_ok(), "unable to read {}", rust_file.display());
let source = match source {
std::result::Result::Ok(value) => non_comment_source(value.as_str()),
std::result::Result::Err(_) => continue,
};
let forbidden = [
"std::env::var(\"KSP_",
"std::env::var(\"KSPB_",
"std::env::var_os(\"KSP_",
"std::env::var_os(\"KSPB_",
"env::var(\"KSP_",
"env::var(\"KSPB_",
"env::var_os(\"KSP_",
"env::var_os(\"KSPB_",
"std::env::vars()",
"std::env::vars_os()",
];
for token in forbidden {
assert!(!source.contains(token), "{} bypasses ksp-config-lib for KSP/KSPB environment access via {token}", rust_file.display());
}
}
}
}
#[test]
fn workspace_crates_do_not_hardcode_config_managed_physical_files() {
let root = workspace_root();
let crates_directory = root.join("crates");
let entries = std::fs::read_dir(crates_directory.as_path());
assert!(entries.is_ok(), "unable to inspect workspace crates at {}", crates_directory.display());
let entries = match entries {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
for entry in entries {
let entry = match entry {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => continue,
};
if !entry.path().is_dir() || entry.file_name() == std::ffi::OsStr::new("ksp-config-lib") {
continue;
}
let mut rust_files = std::vec::Vec::new();
collect_rust_files(entry.path().as_path(), &mut rust_files);
for rust_file in rust_files {
let source = std::fs::read_to_string(rust_file.as_path());
assert!(source.is_ok(), "unable to read {}", rust_file.display());
let source = match source {
std::result::Result::Ok(value) => non_comment_source(value.as_str()),
std::result::Result::Err(_) => continue,
};
for token in [
"\".env\"",
"\"composite.ksp-app-wallet-desk.json\"",
"\"composite.schema.json\"",
"\"std.logging.json\"",
"\"std.logging.schema.json\"",
"\"std.transport.json\"",
"\"std.transport.schema.json\"",
"\"std.wallet.json\"",
"\"std.wallet.schema.json\"",
] {
assert!(!source.contains(token), "{} hardcodes Config-managed physical resource {token}; use ksp-config-lib contracts", rust_file.display());
}
}
}
}
#[test]
fn environment_name_scanner_ignores_namespace_labels_but_keeps_concrete_names() {
let source = r#"
const KSP_PUBLIC_LABEL: &str = "KSP_PUBLIC";
const KSP_SECRET_LABEL: &str = "KSP_SECRET";
const KSPB_PUBLIC_LABEL: &str = "KSPB_PUBLIC";
const KSPB_SECRET_LABEL: &str = "KSPB_SECRET";
const KSP_PUBLIC_RPC_URL: &str = "KSP_PUBLIC_RPC_URL";
const KSP_SECRET_API_KEY: &str = "KSP_SECRET_API_KEY";
const KSPB_PUBLIC_ENDPOINT: &str = "KSPB_PUBLIC_ENDPOINT";
const KSPB_SECRET_TOKEN: &str = "KSPB_SECRET_TOKEN";
"#;
let mut names = std::collections::BTreeSet::<String>::new();
collect_environment_names(source, &mut names);
assert!(!names.contains("KSP_PUBLIC"));
assert!(!names.contains("KSP_SECRET"));
assert!(!names.contains("KSPB_PUBLIC"));
assert!(!names.contains("KSPB_SECRET"));
assert!(names.contains("KSP_PUBLIC_RPC_URL"));
assert!(names.contains("KSP_SECRET_API_KEY"));
assert!(names.contains("KSPB_PUBLIC_ENDPOINT"));
assert!(names.contains("KSPB_SECRET_TOKEN"));
}
#[test]
fn dotenv_example_covers_runtime_environment_names_with_comments() {
let root = workspace_root();
let mut runtime_names = std::collections::BTreeSet::<String>::new();
let config_directory = root.join("config");
let mut json_files = std::vec::Vec::new();
collect_json_files(config_directory.as_path(), &mut json_files);
for json_file in json_files {
let source = std::fs::read_to_string(json_file.as_path());
assert!(source.is_ok(), "unable to read {}", json_file.display());
if let std::result::Result::Ok(source) = source {
collect_environment_names(source.as_str(), &mut runtime_names);
}
}
let crates_directory = root.join("crates");
let crate_entries = std::fs::read_dir(crates_directory.as_path());
assert!(crate_entries.is_ok(), "unable to inspect workspace crates at {}", crates_directory.display());
let crate_entries = match crate_entries {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
for entry in crate_entries {
let entry = match entry {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => continue,
};
let source_directory = entry.path().join("src");
if !source_directory.is_dir() {
continue;
}
let mut rust_files = std::vec::Vec::new();
collect_rust_files(source_directory.as_path(), &mut rust_files);
for rust_file in rust_files {
let source = std::fs::read_to_string(rust_file.as_path());
assert!(source.is_ok(), "unable to read {}", rust_file.display());
if let std::result::Result::Ok(source) = source {
let source = non_comment_source(source.as_str());
collect_environment_names(source.as_str(), &mut runtime_names);
}
}
}
let example_path = root.join(ksp_config_lib::DEFAULT_DOTENV_EXAMPLE_PATH);
let example = std::fs::read_to_string(example_path.as_path());
assert!(example.is_ok(), "unable to read canonical environment inventory {}", example_path.display());
let example = match example {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
let assignments = dotenv_example_assignments(example.as_str());
assert!(!runtime_names.is_empty(), "runtime environment audit should discover at least one concrete KSP/KSPB variable");
for variable_name in runtime_names {
let assignment_line = assignments.get(variable_name.as_str());
assert!(assignment_line.is_some(), ".env.example is missing runtime variable {variable_name}");
if let std::option::Option::Some(line_index) = assignment_line {
assert!(
has_preceding_explanatory_comment(example.as_str(), *line_index),
".env.example variable {variable_name} must be preceded by an explanatory comment",
);
}
}
}