Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I082de335ed2b2bf53d687d81db0901ef6a6a6964
117 lines
3.1 KiB
Rust
117 lines
3.1 KiB
Rust
//! Manifest verification integration test.
|
|
#![expect(clippy::expect_used)]
|
|
|
|
use konservejo::{
|
|
core::pipeline::Pipeline,
|
|
crypto::manifest::{
|
|
compute_merkle_root,
|
|
get_inclusion_proof,
|
|
verify_inclusion_proof,
|
|
},
|
|
storage::Storage,
|
|
};
|
|
|
|
mod common;
|
|
use common::{
|
|
MockRepo,
|
|
TestContext,
|
|
create_test_archive,
|
|
load_config,
|
|
setup_mock_server,
|
|
};
|
|
|
|
#[tokio::test]
|
|
async fn test_manifest_root_computed_correctly() {
|
|
let archive1 = create_test_archive("repo1");
|
|
let archive2 = create_test_archive("repo2");
|
|
|
|
let repos = vec![
|
|
MockRepo::new("test-org", "repo1", archive1),
|
|
MockRepo::new("test-org", "repo2", archive2),
|
|
];
|
|
let (_server, mock_url) = setup_mock_server(repos).await;
|
|
|
|
let ctx = TestContext::new(mock_url);
|
|
ctx.write_config(&["test-org".to_string()], &[], 4, 1, 10);
|
|
|
|
let config = load_config(&ctx).expect("Failed to load config");
|
|
let pipeline = Pipeline::new(config)
|
|
.await
|
|
.expect("Failed to create pipeline");
|
|
|
|
let run_id = pipeline.run().await.expect("Backup failed");
|
|
|
|
let db_url = format!("sqlite://{}", ctx.db_path().display());
|
|
let storage = Storage::new(&db_url)
|
|
.await
|
|
.expect("Failed to connect to DB");
|
|
let jobs = storage
|
|
.list_jobs_by_run(&run_id)
|
|
.await
|
|
.expect("Failed to list jobs");
|
|
|
|
assert_eq!(jobs.len(), 2);
|
|
|
|
let leaf_hashes: Vec<_> =
|
|
jobs.iter().map(|j| j.artifact_hash.clone()).collect();
|
|
let computed_root =
|
|
compute_merkle_root(&leaf_hashes).expect("Failed to compute root");
|
|
|
|
let stored_root = storage
|
|
.get_manifest_root(&run_id)
|
|
.await
|
|
.expect("Failed to get manifest root")
|
|
.expect("Should have stored root");
|
|
|
|
assert_eq!(
|
|
stored_root.as_ref(),
|
|
computed_root.as_ref(),
|
|
"Stored root should match computed root"
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_inclusion_proofs_valid() {
|
|
let archive1 = create_test_archive("proof-repo1");
|
|
let archive2 = create_test_archive("proof-repo2");
|
|
|
|
let repos = vec![
|
|
MockRepo::new("test-org", "repo1", archive1),
|
|
MockRepo::new("test-org", "repo2", archive2),
|
|
];
|
|
let (_server, mock_url) = setup_mock_server(repos).await;
|
|
|
|
let ctx = TestContext::new(mock_url);
|
|
ctx.write_config(&["test-org".to_string()], &[], 4, 1, 10);
|
|
|
|
let config = load_config(&ctx).expect("Failed to load config");
|
|
let pipeline = Pipeline::new(config)
|
|
.await
|
|
.expect("Failed to create pipeline");
|
|
|
|
let run_id = pipeline.run().await.expect("Backup failed");
|
|
|
|
let db_url = format!("sqlite://{}", ctx.db_path().display());
|
|
let storage = Storage::new(&db_url)
|
|
.await
|
|
.expect("Failed to connect to DB");
|
|
let jobs = storage
|
|
.list_jobs_by_run(&run_id)
|
|
.await
|
|
.expect("Failed to list jobs");
|
|
|
|
let leaf_hashes: Vec<_> =
|
|
jobs.iter().map(|j| j.artifact_hash.clone()).collect();
|
|
let computed_root =
|
|
compute_merkle_root(&leaf_hashes).expect("Failed to compute root");
|
|
|
|
for (i, job) in jobs.iter().enumerate() {
|
|
let proof =
|
|
get_inclusion_proof(&leaf_hashes, i).expect("Failed to generate proof");
|
|
|
|
let valid =
|
|
verify_inclusion_proof(&computed_root, &job.artifact_hash, &proof);
|
|
|
|
assert!(valid, "Proof for job {i} should be valid");
|
|
}
|
|
}
|