rpki/tests/test_cli_run_offline_m18.rs

262 lines
9.4 KiB
Rust

use std::process::Command;
#[test]
fn cli_run_offline_mode_executes_and_writes_json_and_ccr() {
let db_dir = tempfile::tempdir().expect("db tempdir");
let repo_dir = tempfile::tempdir().expect("repo tempdir");
let out_dir = tempfile::tempdir().expect("out tempdir");
let report_path = out_dir.path().join("report.json");
let ccr_path = out_dir.path().join("result.ccr");
let policy_path = out_dir.path().join("policy.toml");
std::fs::write(&policy_path, "sync_preference = \"rsync_only\"\n").expect("write policy");
let tal_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/tal/apnic-rfc7730-https.tal");
let ta_path =
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/ta/apnic-ta.cer");
let argv = vec![
"rpki".to_string(),
"--db".to_string(),
db_dir.path().to_string_lossy().to_string(),
"--policy".to_string(),
policy_path.to_string_lossy().to_string(),
"--tal-path".to_string(),
tal_path.to_string_lossy().to_string(),
"--ta-path".to_string(),
ta_path.to_string_lossy().to_string(),
"--rsync-local-dir".to_string(),
repo_dir.path().to_string_lossy().to_string(),
"--max-depth".to_string(),
"0".to_string(),
"--max-instances".to_string(),
"1".to_string(),
"--report-json".to_string(),
report_path.to_string_lossy().to_string(),
"--ccr-out".to_string(),
ccr_path.to_string_lossy().to_string(),
];
rpki::cli::run(&argv).expect("cli run");
let bytes = std::fs::read(&report_path).expect("read report json");
let v: serde_json::Value = serde_json::from_slice(&bytes).expect("parse report json");
assert_eq!(v["format_version"], 2);
}
#[test]
fn cli_run_offline_mode_writes_decodable_ccr() {
let db_dir = tempfile::tempdir().expect("db tempdir");
let repo_dir = tempfile::tempdir().expect("repo tempdir");
let out_dir = tempfile::tempdir().expect("out tempdir");
let ccr_path = out_dir.path().join("result.ccr");
let tal_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/tal/apnic-rfc7730-https.tal");
let ta_path =
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/ta/apnic-ta.cer");
let argv = vec![
"rpki".to_string(),
"--db".to_string(),
db_dir.path().to_string_lossy().to_string(),
"--tal-path".to_string(),
tal_path.to_string_lossy().to_string(),
"--ta-path".to_string(),
ta_path.to_string_lossy().to_string(),
"--rsync-local-dir".to_string(),
repo_dir.path().to_string_lossy().to_string(),
"--max-depth".to_string(),
"0".to_string(),
"--max-instances".to_string(),
"1".to_string(),
"--ccr-out".to_string(),
ccr_path.to_string_lossy().to_string(),
];
rpki::cli::run(&argv).expect("cli run");
let bytes = std::fs::read(&ccr_path).expect("read ccr");
let ccr = rpki::ccr::decode_content_info(&bytes).expect("decode ccr");
assert!(ccr.content.tas.is_some());
}
#[test]
fn cli_run_offline_mode_writes_cir_and_static_pool() {
let db_dir = tempfile::tempdir().expect("db tempdir");
let repo_dir = tempfile::tempdir().expect("repo tempdir");
let out_dir = tempfile::tempdir().expect("out tempdir");
let cir_path = out_dir.path().join("result.cir");
let static_root = out_dir.path().join("static");
let policy_path = out_dir.path().join("policy.toml");
std::fs::write(&policy_path, "sync_preference = \"rsync_only\"\n").expect("write policy");
let tal_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/tal/apnic-rfc7730-https.tal");
let ta_path =
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/ta/apnic-ta.cer");
let argv = vec![
"rpki".to_string(),
"--db".to_string(),
db_dir.path().to_string_lossy().to_string(),
"--policy".to_string(),
policy_path.to_string_lossy().to_string(),
"--tal-path".to_string(),
tal_path.to_string_lossy().to_string(),
"--ta-path".to_string(),
ta_path.to_string_lossy().to_string(),
"--rsync-local-dir".to_string(),
repo_dir.path().to_string_lossy().to_string(),
"--max-depth".to_string(),
"0".to_string(),
"--max-instances".to_string(),
"1".to_string(),
"--cir-enable".to_string(),
"--cir-out".to_string(),
cir_path.to_string_lossy().to_string(),
"--cir-static-root".to_string(),
static_root.to_string_lossy().to_string(),
"--cir-tal-uri".to_string(),
"https://example.test/root.tal".to_string(),
];
rpki::cli::run(&argv).expect("cli run");
let bytes = std::fs::read(&cir_path).expect("read cir");
let cir = rpki::cir::decode_cir(&bytes).expect("decode cir");
assert_eq!(cir.tals.len(), 1);
assert_eq!(cir.tals[0].tal_uri, "https://example.test/root.tal");
assert!(
cir.objects
.iter()
.any(|item| item.rsync_uri.contains("apnic-rpki-root-iana-origin.cer"))
);
let mut file_count = 0usize;
let mut stack = vec![static_root.clone()];
while let Some(path) = stack.pop() {
for entry in std::fs::read_dir(path).expect("read_dir") {
let entry = entry.expect("entry");
let path = entry.path();
if path.is_dir() {
stack.push(path);
} else {
file_count += 1;
}
}
}
assert!(file_count >= 1);
}
#[test]
fn cli_run_blackbox_rsync_wrapper_mode_matches_reference_ccr_without_ta_path() {
let real_rsync = std::path::Path::new("/usr/bin/rsync");
if !real_rsync.exists() {
return;
}
let db_dir = tempfile::tempdir().expect("db tempdir");
let out_dir = tempfile::tempdir().expect("out tempdir");
let mirror_root = out_dir.path().join("mirror");
let ref_ccr_path = out_dir.path().join("reference.ccr");
let actual_ccr_path = out_dir.path().join("actual.ccr");
let tal_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/tal/apnic-rfc7730-https.tal");
let ta_path =
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/ta/apnic-ta.cer");
let ta_bytes = std::fs::read(&ta_path).expect("read ta");
std::fs::create_dir_all(mirror_root.join("rpki.apnic.net").join("repository"))
.expect("mkdir mirror");
std::fs::write(
mirror_root
.join("rpki.apnic.net")
.join("repository")
.join("apnic-rpki-root-iana-origin.cer"),
ta_bytes,
)
.expect("write ta into mirror");
let bin = env!("CARGO_BIN_EXE_rpki");
let wrapper =
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("scripts/cir/cir-rsync-wrapper");
let reference = Command::new(bin)
.env("REAL_RSYNC_BIN", real_rsync)
.env("CIR_MIRROR_ROOT", &mirror_root)
.args([
"--db",
db_dir
.path()
.join("reference-db")
.to_string_lossy()
.as_ref(),
"--tal-path",
tal_path.to_string_lossy().as_ref(),
"--ta-path",
ta_path.to_string_lossy().as_ref(),
"--disable-rrdp",
"--rsync-command",
wrapper.to_string_lossy().as_ref(),
"--validation-time",
"2026-04-07T00:00:00Z",
"--max-depth",
"0",
"--max-instances",
"1",
"--ccr-out",
ref_ccr_path.to_string_lossy().as_ref(),
])
.output()
.expect("run reference wrapper mode");
assert!(
reference.status.success(),
"stderr={}",
String::from_utf8_lossy(&reference.stderr)
);
let out = Command::new(bin)
.env("REAL_RSYNC_BIN", real_rsync)
.env("CIR_MIRROR_ROOT", &mirror_root)
.args([
"--db",
db_dir.path().join("actual-db").to_string_lossy().as_ref(),
"--tal-path",
tal_path.to_string_lossy().as_ref(),
"--disable-rrdp",
"--rsync-command",
wrapper.to_string_lossy().as_ref(),
"--validation-time",
"2026-04-07T00:00:00Z",
"--max-depth",
"0",
"--max-instances",
"1",
"--ccr-out",
actual_ccr_path.to_string_lossy().as_ref(),
])
.output()
.expect("run blackbox wrapper mode");
assert!(
out.status.success(),
"stderr={}",
String::from_utf8_lossy(&out.stderr)
);
let reference = rpki::ccr::decode_content_info(&std::fs::read(&ref_ccr_path).unwrap())
.expect("decode reference ccr");
let actual = rpki::ccr::decode_content_info(&std::fs::read(&actual_ccr_path).unwrap())
.expect("decode actual ccr");
assert_eq!(actual.content.version, reference.content.version);
assert_eq!(actual.content.hash_alg, reference.content.hash_alg);
assert_eq!(actual.content.mfts, reference.content.mfts);
assert_eq!(actual.content.vrps, reference.content.vrps);
assert_eq!(actual.content.vaps, reference.content.vaps);
assert_eq!(actual.content.tas, reference.content.tas);
assert_eq!(actual.content.rks, reference.content.rks);
}