20260607 完成transport预热、roa cache和finalize长尾优化

This commit is contained in:
2026-06-07 20:35:47 +08:00
parent 4045f9a3a5
commit 8e6e2f1318
24 changed files with 2377 additions and 155 deletions

View File

@@ -298,6 +298,61 @@ fn vcir_ccr_manifest_projection_validate_rejects_invalid_fields() {
));
}
#[test]
fn roa_cache_projection_from_vcir_keeps_only_roa_vrp_outputs() {
let vcir = sample_vcir("rsync://example.test/repo/current.mft");
let projection = RoaCacheProjection::from_vcir(&vcir)
.expect("projection build")
.expect("projection exists");
assert_eq!(projection.manifest_rsync_uri, vcir.manifest_rsync_uri);
assert_eq!(projection.instance_effective_until, pack_time(12));
assert_eq!(projection.crl_sha256_by_uri.len(), 1);
assert_eq!(projection.entries.len(), 1);
assert_eq!(
projection.entries[0].source_object_uri,
"rsync://example.test/repo/object.roa"
);
assert_eq!(projection.entries[0].outputs.len(), 1);
assert!(matches!(
projection.entries[0].outputs[0].payload,
VcirLocalOutputPayload::Vrp { .. }
));
}
#[test]
fn roa_cache_projection_groups_multiple_outputs_by_roa_uri() {
let mut vcir = sample_vcir("rsync://example.test/repo/current.mft");
let mut second = vcir.local_outputs[0].clone();
second.rule_hash = sha256_32(b"vrp-rule-2");
if let VcirLocalOutputPayload::Vrp { max_length, .. } = &mut second.payload {
*max_length = 25;
}
vcir.local_outputs.push(second);
vcir.summary.local_vrp_count = 2;
let projection = RoaCacheProjection::from_vcir(&vcir)
.expect("projection build")
.expect("projection exists");
assert_eq!(projection.entries.len(), 1);
assert_eq!(projection.entries[0].outputs.len(), 2);
}
#[test]
fn roa_cache_projection_rejects_duplicate_uri_with_different_hash() {
let mut vcir = sample_vcir("rsync://example.test/repo/current.mft");
let mut duplicate = vcir.local_outputs[0].clone();
duplicate.source_object_hash = sha256_32(b"different-roa");
duplicate.rule_hash = sha256_32(b"vrp-rule-2");
vcir.local_outputs.push(duplicate);
vcir.summary.local_vrp_count = 2;
let err = RoaCacheProjection::from_vcir(&vcir)
.expect_err("same ROA URI with different hash must fail");
assert!(err.to_string().contains("source object hash mismatch"));
}
fn sample_rrdp_source_record(notify_uri: &str) -> RrdpSourceRecord {
RrdpSourceRecord {
notify_uri: notify_uri.to_string(),
@@ -777,6 +832,16 @@ fn vcir_roundtrip_and_validation_failures_are_reported() {
updated_at_validation_time: vcir.last_successful_validation_time.clone(),
}
);
let projection = store
.get_roa_cache_projection(&vcir.manifest_rsync_uri)
.expect("get roa cache projection")
.expect("roa cache projection exists");
assert_eq!(projection.manifest_rsync_uri, vcir.manifest_rsync_uri);
assert_eq!(projection.entries.len(), 1);
assert_eq!(
projection.entries[0].source_object_uri,
"rsync://example.test/repo/object.roa"
);
let mut invalid = sample_vcir("rsync://example.test/repo/invalid.mft");
invalid.summary.local_vrp_count = 9;
@@ -807,6 +872,65 @@ fn vcir_roundtrip_and_validation_failures_are_reported() {
.expect("get deleted manifest replay meta")
.is_none()
);
assert!(
store
.get_roa_cache_projection(&vcir.manifest_rsync_uri)
.expect("get deleted roa cache projection")
.is_none()
);
}
#[test]
fn transport_prefetch_snapshot_roundtrips() {
use crate::parallel::transport_prefetch::{
TransportPrefetchDedupKey, TransportPrefetchMode, TransportPrefetchRepoIdentity,
TransportPrefetchRequest, TransportPrefetchRequester, TransportPrefetchSnapshot,
};
use crate::policy::SyncPreference;
let td = tempfile::tempdir().expect("tempdir");
let store = RocksStore::open(td.path()).expect("open rocksdb");
assert!(
store
.get_transport_prefetch_snapshot()
.expect("get empty prefetch snapshot")
.is_none()
);
let snapshot = TransportPrefetchSnapshot::new(
SyncPreference::RrdpThenRsync,
vec![TransportPrefetchRequest {
dedup_key: TransportPrefetchDedupKey::RrdpNotify {
notification_uri: "https://example.test/notification.xml".to_string(),
},
rsync_scope_uri: "rsync://example.test/repo/".to_string(),
rsync_failure_scope_uri: Some("rsync://example.test/".to_string()),
repo_identity: TransportPrefetchRepoIdentity {
notification_uri: Some("https://example.test/notification.xml".to_string()),
rsync_base_uri: "rsync://example.test/repo/".to_string(),
},
mode: TransportPrefetchMode::Rrdp,
tal_id: "apnic".to_string(),
rir_id: "apnic".to_string(),
priority: 0,
requesters: vec![TransportPrefetchRequester {
tal_id: "apnic".to_string(),
rir_id: "apnic".to_string(),
parent_node_id: None,
ca_instance_handle_id: "apnic:rsync://example.test/repo/root.mft".to_string(),
publication_point_rsync_uri: "rsync://example.test/repo/".to_string(),
manifest_rsync_uri: "rsync://example.test/repo/root.mft".to_string(),
}],
}],
);
store
.put_transport_prefetch_snapshot(&snapshot)
.expect("put prefetch snapshot");
let got = store
.get_transport_prefetch_snapshot()
.expect("get prefetch snapshot")
.expect("snapshot exists");
assert_eq!(got, snapshot);
}
#[test]
@@ -925,9 +1049,18 @@ fn replace_vcir_and_manifest_replay_meta_replaces_current_entry() {
.expect("store previous vcir");
assert!(previous_timing.vcir_value_bytes > 0);
assert!(previous_timing.replay_meta_value_bytes > 0);
assert!(previous_timing.roa_cache_projection_value_bytes > 0);
assert_eq!(
previous_timing.total_encoded_bytes,
previous_timing.vcir_value_bytes + previous_timing.replay_meta_value_bytes
previous_timing.vcir_value_bytes
+ previous_timing.replay_meta_value_bytes
+ previous_timing.roa_cache_projection_value_bytes
);
assert!(
store
.get_roa_cache_projection(&previous.manifest_rsync_uri)
.expect("get previous projection")
.is_some()
);
let mut current = sample_vcir("rsync://example.test/repo/current.mft");
@@ -951,6 +1084,7 @@ fn replace_vcir_and_manifest_replay_meta_replaces_current_entry() {
.expect("replace vcir and replay meta");
assert!(current_timing.vcir_value_bytes > 0);
assert!(current_timing.replay_meta_value_bytes > 0);
assert_eq!(current_timing.roa_cache_projection_value_bytes, 0);
assert_eq!(
current_timing.total_encoded_bytes,
current_timing.vcir_value_bytes + current_timing.replay_meta_value_bytes
@@ -973,6 +1107,12 @@ fn replace_vcir_and_manifest_replay_meta_replaces_current_entry() {
replay_meta.manifest_sha256,
current.ccr_manifest_projection.manifest_sha256
);
assert!(
store
.get_roa_cache_projection(&current.manifest_rsync_uri)
.expect("get current projection")
.is_none()
);
}
#[test]