20260715 add configurable max CA depth
This commit is contained in:
parent
9f4f4cf069
commit
7aac4855bd
35
src/cli.rs
35
src/cli.rs
@ -38,7 +38,7 @@ use crate::validation::run_tree_from_tal::{
|
|||||||
run_tree_from_tal_url_parallel_phase2_audit,
|
run_tree_from_tal_url_parallel_phase2_audit,
|
||||||
run_tree_from_tal_url_parallel_phase2_audit_with_timing,
|
run_tree_from_tal_url_parallel_phase2_audit_with_timing,
|
||||||
};
|
};
|
||||||
use crate::validation::tree::TreeRunConfig;
|
use crate::validation::tree::{DEFAULT_MAX_CA_DEPTH, TreeRunConfig};
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use output::write_json;
|
use output::write_json;
|
||||||
use output::{
|
use output::{
|
||||||
@ -168,7 +168,7 @@ pub struct CliArgs {
|
|||||||
pub rsync_mirror_root: Option<PathBuf>,
|
pub rsync_mirror_root: Option<PathBuf>,
|
||||||
pub rsync_scope_policy: RsyncScopePolicy,
|
pub rsync_scope_policy: RsyncScopePolicy,
|
||||||
|
|
||||||
pub max_depth: Option<usize>,
|
pub max_ca_depth: usize,
|
||||||
pub max_instances: Option<usize>,
|
pub max_instances: Option<usize>,
|
||||||
pub validation_time: Option<time::OffsetDateTime>,
|
pub validation_time: Option<time::OffsetDateTime>,
|
||||||
|
|
||||||
@ -259,7 +259,8 @@ Options:
|
|||||||
--rsync-timeout-secs <n> rsync I/O timeout seconds (default: 60)
|
--rsync-timeout-secs <n> rsync I/O timeout seconds (default: 60)
|
||||||
--rsync-mirror-root <path> Persist rsync mirrors under this directory (default: disabled)
|
--rsync-mirror-root <path> Persist rsync mirrors under this directory (default: disabled)
|
||||||
--rsync-scope <policy> rsync scope policy: host, publication-point, or module-root (default: module-root)
|
--rsync-scope <policy> rsync scope policy: host, publication-point, or module-root (default: module-root)
|
||||||
--max-depth <n> Max CA instance depth (0 = root only)
|
--max-ca-depth <n> Maximum CA depth from a trust anchor (root = 0, default: {DEFAULT_MAX_CA_DEPTH})
|
||||||
|
--max-depth <n> Deprecated alias for --max-ca-depth
|
||||||
--max-instances <n> Max number of CA instances to process
|
--max-instances <n> Max number of CA instances to process
|
||||||
--validation-time <rfc3339> Validation time in RFC3339 (default: now UTC)
|
--validation-time <rfc3339> Validation time in RFC3339 (default: now UTC)
|
||||||
--analyze Write timing analysis JSON under target/live/analyze/<timestamp>/
|
--analyze Write timing analysis JSON under target/live/analyze/<timestamp>/
|
||||||
@ -319,7 +320,8 @@ pub fn parse_args(argv: &[String]) -> Result<CliArgs, String> {
|
|||||||
let mut rsync_timeout_secs: u64 = 30;
|
let mut rsync_timeout_secs: u64 = 30;
|
||||||
let mut rsync_mirror_root: Option<PathBuf> = None;
|
let mut rsync_mirror_root: Option<PathBuf> = None;
|
||||||
let mut rsync_scope_policy = RsyncScopePolicy::default();
|
let mut rsync_scope_policy = RsyncScopePolicy::default();
|
||||||
let mut max_depth: Option<usize> = None;
|
let mut max_ca_depth: Option<usize> = None;
|
||||||
|
let mut max_ca_depth_option: Option<&'static str> = None;
|
||||||
let mut max_instances: Option<usize> = None;
|
let mut max_instances: Option<usize> = None;
|
||||||
let mut validation_time: Option<time::OffsetDateTime> = None;
|
let mut validation_time: Option<time::OffsetDateTime> = None;
|
||||||
let mut analyze: bool = false;
|
let mut analyze: bool = false;
|
||||||
@ -661,13 +663,26 @@ pub fn parse_args(argv: &[String]) -> Result<CliArgs, String> {
|
|||||||
let v = argv.get(i).ok_or("--rsync-scope requires a value")?;
|
let v = argv.get(i).ok_or("--rsync-scope requires a value")?;
|
||||||
rsync_scope_policy = RsyncScopePolicy::parse_cli_value(v)?;
|
rsync_scope_policy = RsyncScopePolicy::parse_cli_value(v)?;
|
||||||
}
|
}
|
||||||
"--max-depth" => {
|
"--max-ca-depth" | "--max-depth" => {
|
||||||
i += 1;
|
i += 1;
|
||||||
let v = argv.get(i).ok_or("--max-depth requires a value")?;
|
let option = arg;
|
||||||
max_depth = Some(
|
let v = argv
|
||||||
|
.get(i)
|
||||||
|
.ok_or_else(|| format!("{option} requires a value"))?;
|
||||||
|
if let Some(previous_option) = max_ca_depth_option {
|
||||||
|
return Err(format!(
|
||||||
|
"{option} cannot be combined with {previous_option}; use only --max-ca-depth"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
max_ca_depth = Some(
|
||||||
v.parse::<usize>()
|
v.parse::<usize>()
|
||||||
.map_err(|_| format!("invalid --max-depth: {v}"))?,
|
.map_err(|_| format!("invalid {option}: {v}"))?,
|
||||||
);
|
);
|
||||||
|
max_ca_depth_option = Some(match option {
|
||||||
|
"--max-ca-depth" => "--max-ca-depth",
|
||||||
|
"--max-depth" => "--max-depth",
|
||||||
|
_ => unreachable!("matched CA depth option"),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
"--max-instances" => {
|
"--max-instances" => {
|
||||||
i += 1;
|
i += 1;
|
||||||
@ -989,7 +1004,7 @@ pub fn parse_args(argv: &[String]) -> Result<CliArgs, String> {
|
|||||||
rsync_timeout_secs,
|
rsync_timeout_secs,
|
||||||
rsync_mirror_root,
|
rsync_mirror_root,
|
||||||
rsync_scope_policy,
|
rsync_scope_policy,
|
||||||
max_depth,
|
max_ca_depth: max_ca_depth.unwrap_or(DEFAULT_MAX_CA_DEPTH),
|
||||||
max_instances,
|
max_instances,
|
||||||
validation_time,
|
validation_time,
|
||||||
analyze,
|
analyze,
|
||||||
@ -2032,7 +2047,7 @@ pub fn run(argv: &[String]) -> Result<(), String> {
|
|||||||
Arc::new(RocksStore::open(&args.db_path).map_err(|e| e.to_string())?)
|
Arc::new(RocksStore::open(&args.db_path).map_err(|e| e.to_string())?)
|
||||||
};
|
};
|
||||||
let config = TreeRunConfig {
|
let config = TreeRunConfig {
|
||||||
max_depth: args.max_depth,
|
max_depth: Some(args.max_ca_depth),
|
||||||
max_instances: args.max_instances,
|
max_instances: args.max_instances,
|
||||||
compact_audit: args.skip_report_build
|
compact_audit: args.skip_report_build
|
||||||
&& args.report_json_path.is_none()
|
&& args.report_json_path.is_none()
|
||||||
|
|||||||
@ -21,6 +21,8 @@ fn parse_help_returns_usage() {
|
|||||||
assert!(err.contains("--memory-trim-after-validation"), "{err}");
|
assert!(err.contains("--memory-trim-after-validation"), "{err}");
|
||||||
assert!(err.contains("--enable-roa-validation-cache"), "{err}");
|
assert!(err.contains("--enable-roa-validation-cache"), "{err}");
|
||||||
assert!(err.contains("--resource-validation-mode"), "{err}");
|
assert!(err.contains("--resource-validation-mode"), "{err}");
|
||||||
|
assert!(err.contains("--max-ca-depth"), "{err}");
|
||||||
|
assert!(err.contains("default: 32"), "{err}");
|
||||||
assert!(
|
assert!(
|
||||||
err.contains("--publication-point-cache-observe-only"),
|
err.contains("--publication-point-cache-observe-only"),
|
||||||
"{err}"
|
"{err}"
|
||||||
@ -80,6 +82,51 @@ fn parse_rejects_invalid_max_depth() {
|
|||||||
assert!(err.contains("invalid --max-depth"), "{err}");
|
assert!(err.contains("invalid --max-depth"), "{err}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_rejects_invalid_max_ca_depth() {
|
||||||
|
let argv = vec![
|
||||||
|
"rpki".to_string(),
|
||||||
|
"--db".to_string(),
|
||||||
|
"db".to_string(),
|
||||||
|
"--tal-url".to_string(),
|
||||||
|
"https://example.test/x.tal".to_string(),
|
||||||
|
"--max-ca-depth".to_string(),
|
||||||
|
"nope".to_string(),
|
||||||
|
];
|
||||||
|
let err = parse_args(&argv).unwrap_err();
|
||||||
|
assert!(err.contains("invalid --max-ca-depth"), "{err}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_rejects_both_ca_depth_options() {
|
||||||
|
let argv = vec![
|
||||||
|
"rpki".to_string(),
|
||||||
|
"--db".to_string(),
|
||||||
|
"db".to_string(),
|
||||||
|
"--tal-url".to_string(),
|
||||||
|
"https://example.test/x.tal".to_string(),
|
||||||
|
"--max-ca-depth".to_string(),
|
||||||
|
"32".to_string(),
|
||||||
|
"--max-depth".to_string(),
|
||||||
|
"12".to_string(),
|
||||||
|
];
|
||||||
|
let err = parse_args(&argv).unwrap_err();
|
||||||
|
assert!(err.contains("cannot be combined"), "{err}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_defaults_max_ca_depth_to_32() {
|
||||||
|
let argv = vec![
|
||||||
|
"rpki".to_string(),
|
||||||
|
"--db".to_string(),
|
||||||
|
"db".to_string(),
|
||||||
|
"--tal-url".to_string(),
|
||||||
|
"https://example.test/x.tal".to_string(),
|
||||||
|
];
|
||||||
|
let args = parse_args(&argv).expect("parse");
|
||||||
|
assert_eq!(args.max_ca_depth, 32);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_accepts_ccr_out_path() {
|
fn parse_accepts_ccr_out_path() {
|
||||||
let argv = vec![
|
let argv = vec![
|
||||||
@ -1103,7 +1150,7 @@ fn parse_accepts_offline_mode_requires_ta() {
|
|||||||
assert_eq!(args.ta_paths, vec![PathBuf::from("ta.cer")]);
|
assert_eq!(args.ta_paths, vec![PathBuf::from("ta.cer")]);
|
||||||
assert_eq!(args.tal_path.as_deref(), Some(Path::new("a.tal")));
|
assert_eq!(args.tal_path.as_deref(), Some(Path::new("a.tal")));
|
||||||
assert_eq!(args.ta_path.as_deref(), Some(Path::new("ta.cer")));
|
assert_eq!(args.ta_path.as_deref(), Some(Path::new("ta.cer")));
|
||||||
assert_eq!(args.max_depth, Some(0));
|
assert_eq!(args.max_ca_depth, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -10,6 +10,8 @@ use crate::validation::publication_point::PublicationPointSnapshot;
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::sync::{Arc, OnceLock};
|
use std::sync::{Arc, OnceLock};
|
||||||
|
|
||||||
|
pub const DEFAULT_MAX_CA_DEPTH: usize = 32;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct TreeRunConfig {
|
pub struct TreeRunConfig {
|
||||||
/// Max CA instance depth to process (0 = root only).
|
/// Max CA instance depth to process (0 = root only).
|
||||||
@ -37,7 +39,7 @@ pub struct TreeRunConfig {
|
|||||||
impl Default for TreeRunConfig {
|
impl Default for TreeRunConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
max_depth: None,
|
max_depth: Some(DEFAULT_MAX_CA_DEPTH),
|
||||||
max_instances: None,
|
max_instances: None,
|
||||||
compact_audit: false,
|
compact_audit: false,
|
||||||
persist_vcir: true,
|
persist_vcir: true,
|
||||||
@ -51,6 +53,15 @@ impl Default for TreeRunConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn ca_depth_is_allowed(config: &TreeRunConfig, depth: usize) -> bool {
|
||||||
|
config.max_depth.is_none_or(|max_depth| depth <= max_depth)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn next_allowed_ca_depth(config: &TreeRunConfig, parent_depth: usize) -> Option<usize> {
|
||||||
|
let child_depth = parent_depth.checked_add(1)?;
|
||||||
|
ca_depth_is_allowed(config, child_depth).then_some(child_depth)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum CaCertificateRef {
|
pub enum CaCertificateRef {
|
||||||
InlineDer(Vec<u8>),
|
InlineDer(Vec<u8>),
|
||||||
@ -347,11 +358,9 @@ pub fn run_tree_serial_audit_multi_root(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(max_depth) = config.max_depth {
|
if !ca_depth_is_allowed(config, ca.depth) {
|
||||||
if ca.depth > max_depth {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let res = match runner.run_publication_point(ca) {
|
let res = match runner.run_publication_point(ca) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
@ -393,6 +402,9 @@ pub fn run_tree_serial_audit_multi_root(
|
|||||||
}
|
}
|
||||||
publication_points.push(audit);
|
publication_points.push(audit);
|
||||||
|
|
||||||
|
let Some(child_depth) = next_allowed_ca_depth(config, ca.depth) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
let mut children = res.discovered_children;
|
let mut children = res.discovered_children;
|
||||||
children.sort_by(|a, b| {
|
children.sort_by(|a, b| {
|
||||||
a.handle
|
a.handle
|
||||||
@ -413,7 +425,7 @@ pub fn run_tree_serial_audit_multi_root(
|
|||||||
for child in children {
|
for child in children {
|
||||||
queue.push_back(QueuedCaInstance {
|
queue.push_back(QueuedCaInstance {
|
||||||
id: next_id,
|
id: next_id,
|
||||||
handle: child.handle.with_depth(ca.depth + 1),
|
handle: child.handle.with_depth(child_depth),
|
||||||
parent_id: Some(node.id),
|
parent_id: Some(node.id),
|
||||||
discovered_from: Some(child.discovered_from),
|
discovered_from: Some(child.discovered_from),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -19,8 +19,8 @@ use crate::validation::objects::{
|
|||||||
};
|
};
|
||||||
use crate::validation::tree::{
|
use crate::validation::tree::{
|
||||||
CaInstanceHandle, DiscoveredChildCaInstance, PublicationPointRunResult, PublicationPointRunner,
|
CaInstanceHandle, DiscoveredChildCaInstance, PublicationPointRunResult, PublicationPointRunner,
|
||||||
TreeRunAuditOutput, TreeRunConfig, TreeRunError, TreeRunOutput,
|
TreeRunAuditOutput, TreeRunConfig, TreeRunError, TreeRunOutput, ca_depth_is_allowed,
|
||||||
run_tree_serial_audit_multi_root,
|
next_allowed_ca_depth, run_tree_serial_audit_multi_root,
|
||||||
};
|
};
|
||||||
use crate::validation::tree_runner::{
|
use crate::validation::tree_runner::{
|
||||||
FreshPublicationPointFinalizeOutput, FreshPublicationPointStage, Rpkiv1PublicationPointRunner,
|
FreshPublicationPointFinalizeOutput, FreshPublicationPointStage, Rpkiv1PublicationPointRunner,
|
||||||
@ -659,6 +659,7 @@ pub fn run_tree_parallel_phase2_audit_multi_root(
|
|||||||
&mut finished,
|
&mut finished,
|
||||||
ready,
|
ready,
|
||||||
ready_queue_len_after_pop,
|
ready_queue_len_after_pop,
|
||||||
|
config,
|
||||||
config.compact_audit,
|
config.compact_audit,
|
||||||
);
|
);
|
||||||
ready_batch_metrics.record(metrics);
|
ready_batch_metrics.record(metrics);
|
||||||
@ -916,11 +917,9 @@ fn start_queued_ca_instances(
|
|||||||
if !visited_manifest_uris.insert(node.handle.manifest_rsync_uri.clone()) {
|
if !visited_manifest_uris.insert(node.handle.manifest_rsync_uri.clone()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(max_depth) = config.max_depth {
|
if !ca_depth_is_allowed(config, node.handle.depth) {
|
||||||
if node.handle.depth > max_depth {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
*instances_started += 1;
|
*instances_started += 1;
|
||||||
match repo_runtime.request_publication_point_repo(&node.handle, 0) {
|
match repo_runtime.request_publication_point_repo(&node.handle, 0) {
|
||||||
Ok(RepoSyncRequestStatus::Ready { mut outcome, .. }) => {
|
Ok(RepoSyncRequestStatus::Ready { mut outcome, .. }) => {
|
||||||
@ -959,6 +958,7 @@ fn stage_ready_publication_point(
|
|||||||
finished: &mut Vec<FinishedPublicationPoint>,
|
finished: &mut Vec<FinishedPublicationPoint>,
|
||||||
ready: ReadyCaInstance,
|
ready: ReadyCaInstance,
|
||||||
ready_queue_len_after_pop: usize,
|
ready_queue_len_after_pop: usize,
|
||||||
|
config: &TreeRunConfig,
|
||||||
compact_audit: bool,
|
compact_audit: bool,
|
||||||
) -> ReadyStageMetrics {
|
) -> ReadyStageMetrics {
|
||||||
let publication_point_started = Instant::now();
|
let publication_point_started = Instant::now();
|
||||||
@ -991,6 +991,7 @@ fn stage_ready_publication_point(
|
|||||||
next_id,
|
next_id,
|
||||||
ca_queue,
|
ca_queue,
|
||||||
&ready.node,
|
&ready.node,
|
||||||
|
config,
|
||||||
result.discovered_children.clone(),
|
result.discovered_children.clone(),
|
||||||
);
|
);
|
||||||
metrics.child_enqueue_ms = elapsed_ms(child_enqueue_started);
|
metrics.child_enqueue_ms = elapsed_ms(child_enqueue_started);
|
||||||
@ -1057,6 +1058,7 @@ fn stage_ready_publication_point(
|
|||||||
next_id,
|
next_id,
|
||||||
ca_queue,
|
ca_queue,
|
||||||
&ready.node,
|
&ready.node,
|
||||||
|
config,
|
||||||
result.discovered_children.clone(),
|
result.discovered_children.clone(),
|
||||||
);
|
);
|
||||||
metrics.child_enqueue_ms = elapsed_ms(child_enqueue_started);
|
metrics.child_enqueue_ms = elapsed_ms(child_enqueue_started);
|
||||||
@ -1142,6 +1144,7 @@ fn stage_ready_publication_point(
|
|||||||
next_id,
|
next_id,
|
||||||
ca_queue,
|
ca_queue,
|
||||||
&ready.node,
|
&ready.node,
|
||||||
|
config,
|
||||||
fresh_stage.discovered_children.clone(),
|
fresh_stage.discovered_children.clone(),
|
||||||
);
|
);
|
||||||
metrics.child_enqueue_ms = elapsed_ms(child_enqueue_started);
|
metrics.child_enqueue_ms = elapsed_ms(child_enqueue_started);
|
||||||
@ -1412,8 +1415,13 @@ fn enqueue_discovered_children(
|
|||||||
next_id: &mut u64,
|
next_id: &mut u64,
|
||||||
ca_queue: &mut VecDeque<QueuedCaInstance>,
|
ca_queue: &mut VecDeque<QueuedCaInstance>,
|
||||||
parent: &QueuedCaInstance,
|
parent: &QueuedCaInstance,
|
||||||
|
config: &TreeRunConfig,
|
||||||
mut children: Vec<DiscoveredChildCaInstance>,
|
mut children: Vec<DiscoveredChildCaInstance>,
|
||||||
) {
|
) {
|
||||||
|
let Some(child_depth) = next_allowed_ca_depth(config, parent.handle.depth) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
children.sort_by(|a, b| {
|
children.sort_by(|a, b| {
|
||||||
a.handle
|
a.handle
|
||||||
.manifest_rsync_uri
|
.manifest_rsync_uri
|
||||||
@ -1428,7 +1436,7 @@ fn enqueue_discovered_children(
|
|||||||
let _ = runtime.prefetch_discovered_children(&children);
|
let _ = runtime.prefetch_discovered_children(&children);
|
||||||
}
|
}
|
||||||
for child in children {
|
for child in children {
|
||||||
let mut handle = child.handle.with_depth(parent.handle.depth + 1);
|
let mut handle = child.handle.with_depth(child_depth);
|
||||||
handle.parent_manifest_rsync_uri = Some(parent.handle.manifest_rsync_uri.clone());
|
handle.parent_manifest_rsync_uri = Some(parent.handle.manifest_rsync_uri.clone());
|
||||||
ca_queue.push_back(QueuedCaInstance {
|
ca_queue.push_back(QueuedCaInstance {
|
||||||
id: *next_id,
|
id: *next_id,
|
||||||
|
|||||||
@ -253,6 +253,7 @@ fn tree_enqueues_children_for_fresh_and_current_instance_vcir_results() {
|
|||||||
fn tree_respects_max_depth_and_max_instances() {
|
fn tree_respects_max_depth_and_max_instances() {
|
||||||
let root_manifest = "rsync://example.test/repo/root.mft";
|
let root_manifest = "rsync://example.test/repo/root.mft";
|
||||||
let child_manifest = "rsync://example.test/repo/child.mft";
|
let child_manifest = "rsync://example.test/repo/child.mft";
|
||||||
|
let grandchild_manifest = "rsync://example.test/repo/grandchild.mft";
|
||||||
|
|
||||||
let runner = MockRunner::default()
|
let runner = MockRunner::default()
|
||||||
.with(
|
.with(
|
||||||
@ -301,6 +302,32 @@ fn tree_respects_max_depth_and_max_instances() {
|
|||||||
audit: PublicationPointAudit::default(),
|
audit: PublicationPointAudit::default(),
|
||||||
cir_fresh_objects: Vec::new(),
|
cir_fresh_objects: Vec::new(),
|
||||||
cir_cached_objects: Vec::new(),
|
cir_cached_objects: Vec::new(),
|
||||||
|
discovered_children: vec![discovered_child(child_manifest, grandchild_manifest)],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.with(
|
||||||
|
grandchild_manifest,
|
||||||
|
PublicationPointRunResult {
|
||||||
|
source: PublicationPointSource::Fresh,
|
||||||
|
snapshot: Some(empty_snapshot(
|
||||||
|
grandchild_manifest,
|
||||||
|
"rsync://example.test/repo/grandchild/",
|
||||||
|
)),
|
||||||
|
warnings: Vec::new(),
|
||||||
|
objects: ObjectsOutput {
|
||||||
|
vrps: Vec::new(),
|
||||||
|
aspas: Vec::new(),
|
||||||
|
router_keys: Vec::new(),
|
||||||
|
local_outputs_cache: Vec::new(),
|
||||||
|
warnings: Vec::new(),
|
||||||
|
stats: ObjectsStats::default(),
|
||||||
|
audit: Vec::new(),
|
||||||
|
roa_cache_stats: Default::default(),
|
||||||
|
roa_cache_object_meta: Vec::new(),
|
||||||
|
},
|
||||||
|
audit: PublicationPointAudit::default(),
|
||||||
|
cir_fresh_objects: Vec::new(),
|
||||||
|
cir_cached_objects: Vec::new(),
|
||||||
discovered_children: Vec::new(),
|
discovered_children: Vec::new(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -324,6 +351,62 @@ fn tree_respects_max_depth_and_max_instances() {
|
|||||||
.expect("run tree depth-limited");
|
.expect("run tree depth-limited");
|
||||||
assert_eq!(out.instances_processed, 1);
|
assert_eq!(out.instances_processed, 1);
|
||||||
assert_eq!(out.instances_failed, 0);
|
assert_eq!(out.instances_failed, 0);
|
||||||
|
assert_eq!(runner.called(), vec![root_manifest]);
|
||||||
|
|
||||||
|
let out = run_tree_serial(
|
||||||
|
ca_handle(root_manifest),
|
||||||
|
&runner,
|
||||||
|
&TreeRunConfig {
|
||||||
|
max_depth: Some(1),
|
||||||
|
max_instances: None,
|
||||||
|
compact_audit: false,
|
||||||
|
persist_vcir: true,
|
||||||
|
build_ccr_accumulator: true,
|
||||||
|
enable_roa_validation_cache: false,
|
||||||
|
enable_child_certificate_validation_cache: false,
|
||||||
|
publication_point_cache_observe_only: false,
|
||||||
|
enable_publication_point_validation_cache: false,
|
||||||
|
enable_transport_request_prefetch: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("run tree depth-one-limited");
|
||||||
|
assert_eq!(out.instances_processed, 2);
|
||||||
|
assert_eq!(out.instances_failed, 0);
|
||||||
|
assert_eq!(
|
||||||
|
runner.called(),
|
||||||
|
vec![root_manifest, root_manifest, child_manifest]
|
||||||
|
);
|
||||||
|
|
||||||
|
let out = run_tree_serial(
|
||||||
|
ca_handle(root_manifest),
|
||||||
|
&runner,
|
||||||
|
&TreeRunConfig {
|
||||||
|
max_depth: Some(2),
|
||||||
|
max_instances: None,
|
||||||
|
compact_audit: false,
|
||||||
|
persist_vcir: true,
|
||||||
|
build_ccr_accumulator: true,
|
||||||
|
enable_roa_validation_cache: false,
|
||||||
|
enable_child_certificate_validation_cache: false,
|
||||||
|
publication_point_cache_observe_only: false,
|
||||||
|
enable_publication_point_validation_cache: false,
|
||||||
|
enable_transport_request_prefetch: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("run tree depth-two-limited");
|
||||||
|
assert_eq!(out.instances_processed, 3);
|
||||||
|
assert_eq!(out.instances_failed, 0);
|
||||||
|
assert_eq!(
|
||||||
|
runner.called(),
|
||||||
|
vec![
|
||||||
|
root_manifest,
|
||||||
|
root_manifest,
|
||||||
|
child_manifest,
|
||||||
|
root_manifest,
|
||||||
|
child_manifest,
|
||||||
|
grandchild_manifest,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
let out = run_tree_serial(
|
let out = run_tree_serial(
|
||||||
ca_handle(root_manifest),
|
ca_handle(root_manifest),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user