20260607 完成transport预热、roa cache和finalize长尾优化
This commit is contained in:
@@ -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(¤t.manifest_rsync_uri)
|
||||
.expect("get current projection")
|
||||
.is_none()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user