初始化 Panda RPKI v0.1.0 开源候选版本
Some checks failed
ci / rust (push) Has been cancelled
ci / docker (push) Has been cancelled

This commit is contained in:
Panda RPKI OSS Local
2026-09-09 18:01:15 +08:00
commit 277cbca878
203 changed files with 92495 additions and 0 deletions

113
src/daemon/tests.rs Normal file
View File

@@ -0,0 +1,113 @@
use super::*;
fn args(extra: &[&str]) -> Vec<String> {
[
vec!["--state-root", "data"],
extra.to_vec(),
vec!["--", "--tal", "a.tal", "--ta", "a.cer"],
]
.concat()
.into_iter()
.map(str::to_owned)
.collect()
}
#[test]
fn defaults_and_invalid_controller_options() {
let config = parse(&args(&[])).unwrap();
assert_eq!(
(
config.interval,
config.max_runs,
config.retain,
config.timeout,
config.grace
),
(60, None, 10, 0, 30)
);
for bad in [
vec!["--max-runs", "0"],
vec!["--retain-runs", "0"],
vec!["--interval-secs", "-1"],
vec!["--run-timeout-secs", "bad"],
vec!["--interval-secs", "2", "--interval-secs", "3"],
] {
assert!(parse(&args(&bad)).is_err());
}
let config = parse(&args(&["--interval-secs", "0", "--max-runs", "3"])).unwrap();
assert_eq!((config.interval, config.max_runs), (0, Some(3)));
}
#[test]
fn rejects_child_overrides_and_unknown_flags() {
for flag in [
"--out",
"--rrdp-state-dir",
"--rrdp-sync-mode",
"--ccr-out",
"--unknown",
] {
let mut argv = args(&[]);
argv.extend([flag.into(), "some-value".into()]);
assert!(parse(&argv).is_err(), "{flag}");
}
let mut argv = args(&[]);
argv.extend(["--parallel-phase2-object-workers".into(), "0".into()]);
assert!(parse(&argv).is_err());
}
#[test]
fn protocol_state_selects_snapshot_delta_and_recovery() {
let root = tempfile::tempdir().unwrap();
assert_eq!(sync_mode(root.path(), false).unwrap(), "snapshot");
let db = root.path().join("repository-db");
fs::create_dir(&db).unwrap();
assert_eq!(sync_mode(root.path(), true).unwrap(), "snapshot");
fs::write(db.join("CURRENT"), b"x").unwrap();
assert_eq!(sync_mode(root.path(), true).unwrap(), "delta");
assert_eq!(sync_mode(root.path(), false).unwrap(), "auto");
}
#[test]
fn retention_preserves_unrelated_incomplete_and_symlinked_runs() {
let root = tempfile::tempdir().unwrap();
for seq in 1..=3 {
let path = root.path().join(format!("run_{seq:06}"));
fs::create_dir(&path).unwrap();
write_json_pretty(
&path.join("run-summary.json"),
&json!({
"controller": "panda-rpki-daemon-v1", "run_seq": seq, "status": "success"
}),
)
.unwrap();
}
fs::create_dir(root.path().join("unrelated")).unwrap();
fs::create_dir(root.path().join("run_000004")).unwrap();
let outside = tempfile::tempdir().unwrap();
std::os::unix::fs::symlink(outside.path(), root.path().join("run_000005")).unwrap();
assert_eq!(
apply_retention(root.path(), 1).unwrap(),
["run_000001", "run_000002"]
);
for name in ["run_000003", "run_000004", "run_000005", "unrelated"] {
assert!(root.path().join(name).exists());
}
assert!(regular_directory(&root.path().join("run_000005")).is_err());
}
#[test]
fn atomic_json_writers_and_state_lock() {
let root = tempfile::tempdir().unwrap();
let path = root.path().join("state.json");
write_json_pretty(&path, &json!({"seq": 1})).unwrap();
write_json_pretty(&path, &json!({"seq": 2})).unwrap();
assert_eq!(read_json(&path).unwrap()["seq"], 2);
let lines = root.path().join("summary.jsonl");
append_json_line(&lines, &json!({"seq": 1})).unwrap();
append_json_line(&lines, &json!({"seq": 2})).unwrap();
assert_eq!(fs::read_to_string(lines).unwrap().lines().count(), 2);
let file = File::open(&path).unwrap();
file.try_lock().unwrap();
assert!(File::open(path).unwrap().try_lock().is_err());
}