From 0295fd3262bf067c5170d8dd1077d467b0af8c6e Mon Sep 17 00:00:00 2001 From: yuyr Date: Tue, 28 Apr 2026 00:20:12 +0800 Subject: [PATCH] =?UTF-8?q?20260427=5F5=20=E6=94=AF=E6=8C=81all5=20CIR=20r?= =?UTF-8?q?eplay=E5=A4=9ATAL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cir/run_cir_replay_matrix.sh | 13 ++++-- scripts/cir/run_cir_replay_ours.sh | 31 ++++++++++--- scripts/cir/run_cir_replay_routinator.sh | 44 ++++++++++++++++--- scripts/cir/run_cir_replay_rpki_client.sh | 39 ++++++++++------ scripts/cir/run_cir_replay_sequence_ours.sh | 11 +++-- .../cir/run_cir_replay_sequence_routinator.sh | 21 +++++++++ .../run_cir_replay_sequence_rpki_client.sh | 21 +++++++++ src/cli.rs | 27 +++++++++++- tests/test_cir_sequence_replay_m3.rs | 6 +++ 9 files changed, 178 insertions(+), 35 deletions(-) diff --git a/scripts/cir/run_cir_replay_matrix.sh b/scripts/cir/run_cir_replay_matrix.sh index 0ef727b..5b84692 100755 --- a/scripts/cir/run_cir_replay_matrix.sh +++ b/scripts/cir/run_cir_replay_matrix.sh @@ -194,6 +194,9 @@ for name, out_dir in [ "summaryPath": str(out / "compare-summary.json"), "exitCode": timing["exitCode"], "durationMs": timing["durationMs"], + "compareMode": compare.get("compareMode"), + "talCount": compare.get("talCount"), + "talPaths": compare.get("talPaths", []), "vrps": vrps, "vaps": vaps, "match": bool(vrps.get("match")) and bool(vaps.get("match")) and timing["exitCode"] == 0, @@ -219,18 +222,20 @@ lines = [ f"- `reference_ccr`: `{reference_ccr}`", f"- `all_match`: `{all_match}`", "", - "| Participant | Exit | Duration (ms) | VRP actual/ref | VRP match | VAP actual/ref | VAP match | Log |", - "| --- | ---: | ---: | --- | --- | --- | --- | --- |", + "| Participant | Exit | Duration (ms) | TALs | Compare mode | VRP actual/ref | VRP match | VAP actual/ref | VAP match | Log |", + "| --- | ---: | ---: | ---: | --- | --- | --- | --- | --- | --- |", ] for participant in participants: vrps = participant["vrps"] or {} vaps = participant["vaps"] or {} log_path = participant["logPaths"][0] if participant["logPaths"] else "" lines.append( - "| {name} | {exit_code} | {duration_ms} | {vrp_actual}/{vrp_ref} | {vrp_match} | {vap_actual}/{vap_ref} | {vap_match} | `{log_path}` |".format( + "| {name} | {exit_code} | {duration_ms} | {tal_count} | {compare_mode} | {vrp_actual}/{vrp_ref} | {vrp_match} | {vap_actual}/{vap_ref} | {vap_match} | `{log_path}` |".format( name=participant["name"], exit_code=participant["exitCode"], duration_ms=participant["durationMs"], + tal_count=participant.get("talCount") if participant.get("talCount") is not None else "-", + compare_mode=participant.get("compareMode") or "-", vrp_actual=vrps.get("actual", "-"), vrp_ref=vrps.get("reference", "-"), vrp_match=vrps.get("match", False), @@ -258,6 +263,8 @@ for participant in participants: f"- `mirror_path`: `{participant['mirrorPath']}`", f"- `summary_path`: `{participant['summaryPath']}`", f"- `timing_path`: `{participant['timingPath']}`", + f"- `compare_mode`: `{participant.get('compareMode')}`", + f"- `tal_count`: `{participant.get('talCount')}`", f"- `log_paths`: `{', '.join(participant['logPaths'])}`", f"- `vrps`: `actual={vrps.get('actual', '-')}` `reference={vrps.get('reference', '-')}` `match={vrps.get('match', False)}`", f"- `vaps`: `actual={vaps.get('actual', '-')}` `reference={vaps.get('reference', '-')}` `match={vaps.get('match', False)}`", diff --git a/scripts/cir/run_cir_replay_ours.sh b/scripts/cir/run_cir_replay_ours.sh index 4f66b30..8e8eb21 100755 --- a/scripts/cir/run_cir_replay_ours.sh +++ b/scripts/cir/run_cir_replay_ours.sh @@ -10,6 +10,7 @@ Usage: --out-dir \ --reference-ccr \ [--keep-db] \ + [--report-json-compact] \ [--rpki-bin ] \ [--real-rsync-bin ] EOF @@ -22,6 +23,7 @@ REPO_BYTES_DB="" OUT_DIR="" REFERENCE_CCR="" KEEP_DB=0 +REPORT_JSON_COMPACT=0 RPKI_BIN="${RPKI_BIN:-$ROOT_DIR/target/release/rpki}" CIR_MATERIALIZE_BIN="${CIR_MATERIALIZE_BIN:-$ROOT_DIR/target/release/cir_materialize}" CIR_EXTRACT_INPUTS_BIN="${CIR_EXTRACT_INPUTS_BIN:-$ROOT_DIR/target/release/cir_extract_inputs}" @@ -36,6 +38,7 @@ while [[ $# -gt 0 ]]; do --out-dir) OUT_DIR="$2"; shift 2 ;; --reference-ccr) REFERENCE_CCR="$2"; shift 2 ;; --keep-db) KEEP_DB=1; shift ;; + --report-json-compact) REPORT_JSON_COMPACT=1; shift ;; --rpki-bin) RPKI_BIN="$2"; shift 2 ;; --real-rsync-bin) REAL_RSYNC_BIN="$2"; shift 2 ;; -h|--help) usage; exit 0 ;; @@ -86,11 +89,16 @@ import json,sys print(json.load(open(sys.argv[1]))["validationTime"]) PY )" -FIRST_TAL="$(python3 - <<'PY' "$META_JSON" -import json,sys -print(json.load(open(sys.argv[1]))["talFiles"][0]["path"]) +mapfile -t TAL_PATHS < <(python3 - <<'PY' "$META_JSON" +import json, sys +for item in json.load(open(sys.argv[1], encoding="utf-8"))["talFiles"]: + print(item["path"]) PY -)" +) +TAL_ARGS=() +for tal_path in "${TAL_PATHS[@]}"; do + TAL_ARGS+=(--tal-path "$tal_path") +done export CIR_MIRROR_ROOT="$(python3 - <<'PY' "$MIRROR_ROOT" from pathlib import Path @@ -101,20 +109,25 @@ PY export REAL_RSYNC_BIN="$REAL_RSYNC_BIN" export CIR_LOCAL_LINK_MODE=1 +REPORT_JSON_ARGS=(--report-json "$ACTUAL_REPORT") +if [[ "$REPORT_JSON_COMPACT" -eq 1 ]]; then + REPORT_JSON_ARGS+=(--report-json-compact) +fi + "$RPKI_BIN" \ --db "$DB_DIR" \ - --tal-path "$FIRST_TAL" \ + "${TAL_ARGS[@]}" \ --disable-rrdp \ --rsync-command "$WRAPPER" \ --validation-time "$VALIDATION_TIME" \ --ccr-out "$ACTUAL_CCR" \ - --report-json "$ACTUAL_REPORT" \ + "${REPORT_JSON_ARGS[@]}" \ >"$RUN_LOG" 2>&1 "$CCR_TO_COMPARE_VIEWS_BIN" --ccr "$ACTUAL_CCR" --vrps-out "$ACTUAL_VRPS" --vaps-out "$ACTUAL_VAPS" --trust-anchor unknown "$CCR_TO_COMPARE_VIEWS_BIN" --ccr "$REFERENCE_CCR" --vrps-out "$REF_VRPS" --vaps-out "$REF_VAPS" --trust-anchor unknown -python3 - <<'PY' "$ACTUAL_VRPS" "$REF_VRPS" "$ACTUAL_VAPS" "$REF_VAPS" "$COMPARE_JSON" +python3 - <<'PY' "$ACTUAL_VRPS" "$REF_VRPS" "$ACTUAL_VAPS" "$REF_VAPS" "$COMPARE_JSON" "$META_JSON" import csv, json, sys def rows(path): with open(path, newline="") as f: @@ -123,7 +136,11 @@ actual_vrps = {tuple(r) for r in rows(sys.argv[1])} ref_vrps = {tuple(r) for r in rows(sys.argv[2])} actual_vaps = {tuple(r) for r in rows(sys.argv[3])} ref_vaps = {tuple(r) for r in rows(sys.argv[4])} +meta = json.load(open(sys.argv[6], encoding="utf-8")) summary = { + "compareMode": "trust-anchor-agnostic", + "talCount": len(meta["talFiles"]), + "talPaths": [item["path"] for item in meta["talFiles"]], "vrps": { "actual": len(actual_vrps), "reference": len(ref_vrps), diff --git a/scripts/cir/run_cir_replay_routinator.sh b/scripts/cir/run_cir_replay_routinator.sh index e7d3870..cece4b3 100755 --- a/scripts/cir/run_cir_replay_routinator.sh +++ b/scripts/cir/run_cir_replay_routinator.sh @@ -53,6 +53,10 @@ done usage >&2 exit 2 } +if [[ ! -x "$ROUTINATOR_BIN" ]]; then + echo "routinator binary not executable: $ROUTINATOR_BIN" >&2 + exit 2 +fi mkdir -p "$OUT_DIR" if [[ ! -x "$CIR_MATERIALIZE_BIN" || ! -x "$CIR_EXTRACT_INPUTS_BIN" || ! -x "$CCR_TO_COMPARE_VIEWS_BIN" ]]; then @@ -106,12 +110,13 @@ import json,sys print(json.load(open(sys.argv[1]))["validationTime"]) PY )" -FIRST_TAL="$(python3 - <<'PY' "$META_JSON" -import json,sys -print(json.load(open(sys.argv[1]))["talFiles"][0]["path"]) +mapfile -t TAL_PATHS < <(python3 - <<'PY' "$META_JSON" +import json, sys +for item in json.load(open(sys.argv[1], encoding="utf-8"))["talFiles"]: + print(item["path"]) PY -)" -TA_NAME="$(basename "$FIRST_TAL" .tal)" +) +COMPARE_TRUST_ANCHOR="unknown" FAKE_EPOCH="$(python3 - <<'PY' "$VALIDATION_TIME" from datetime import datetime, timezone import sys @@ -171,9 +176,30 @@ env \ vrps --noupdate --format json -o "$ACTUAL_VAPS_JSON" >>"$RUN_LOG" 2>&1 python3 "$JSON_TO_VAPS" --input "$ACTUAL_VAPS_JSON" --csv-out "$ACTUAL_VAPS" -"$CCR_TO_COMPARE_VIEWS_BIN" --ccr "$REFERENCE_CCR" --vrps-out "$REF_VRPS" --vaps-out "$REF_VAPS" --trust-anchor "$TA_NAME" -python3 - <<'PY' "$ACTUAL_VRPS" "$REF_VRPS" "$ACTUAL_VAPS" "$REF_VAPS" "$SUMMARY_JSON" +normalize_trust_anchor_csv() { + python3 - <<'PY' "$1" "$2" +import csv +import sys +from pathlib import Path + +path = Path(sys.argv[1]) +trust_anchor = sys.argv[2] +rows = list(csv.reader(path.open(newline="", encoding="utf-8"))) +if rows: + for row in rows[1:]: + if row: + row[-1] = trust_anchor +with path.open("w", newline="", encoding="utf-8") as fh: + csv.writer(fh).writerows(rows) +PY +} + +normalize_trust_anchor_csv "$ACTUAL_VRPS" "$COMPARE_TRUST_ANCHOR" +normalize_trust_anchor_csv "$ACTUAL_VAPS" "$COMPARE_TRUST_ANCHOR" +"$CCR_TO_COMPARE_VIEWS_BIN" --ccr "$REFERENCE_CCR" --vrps-out "$REF_VRPS" --vaps-out "$REF_VAPS" --trust-anchor "$COMPARE_TRUST_ANCHOR" + +python3 - <<'PY' "$ACTUAL_VRPS" "$REF_VRPS" "$ACTUAL_VAPS" "$REF_VAPS" "$SUMMARY_JSON" "$META_JSON" import csv, json, sys def rows(path): with open(path, newline="") as f: @@ -182,7 +208,11 @@ actual_vrps = {tuple(r) for r in rows(sys.argv[1])} ref_vrps = {tuple(r) for r in rows(sys.argv[2])} actual_vaps = {tuple(r) for r in rows(sys.argv[3])} ref_vaps = {tuple(r) for r in rows(sys.argv[4])} +meta = json.load(open(sys.argv[6], encoding="utf-8")) summary = { + "compareMode": "trust-anchor-agnostic", + "talCount": len(meta["talFiles"]), + "talPaths": [item["path"] for item in meta["talFiles"]], "vrps": { "actual": len(actual_vrps), "reference": len(ref_vrps), diff --git a/scripts/cir/run_cir_replay_rpki_client.sh b/scripts/cir/run_cir_replay_rpki_client.sh index 099561e..ad419fd 100755 --- a/scripts/cir/run_cir_replay_rpki_client.sh +++ b/scripts/cir/run_cir_replay_rpki_client.sh @@ -55,6 +55,10 @@ fi if [[ -z "$RPKI_CLIENT_BIN" ]]; then RPKI_CLIENT_BIN="$BUILD_DIR/src/rpki-client" fi +if [[ ! -x "$RPKI_CLIENT_BIN" ]]; then + echo "rpki-client binary not executable: $RPKI_CLIENT_BIN" >&2 + exit 2 +fi mkdir -p "$OUT_DIR" if [[ ! -x "$CIR_MATERIALIZE_BIN" || ! -x "$CIR_EXTRACT_INPUTS_BIN" || ! -x "$CCR_TO_COMPARE_VIEWS_BIN" ]]; then @@ -113,12 +117,17 @@ dt = datetime.fromisoformat(vt.replace("Z", "+00:00")).astimezone(timezone.utc) print(int(dt.timestamp())) PY )" -FIRST_TAL="$(python3 - <<'PY' "$META_JSON" -import json,sys -print(json.load(open(sys.argv[1]))["talFiles"][0]["path"]) +mapfile -t TAL_PATHS < <(python3 - <<'PY' "$META_JSON" +import json, sys +for item in json.load(open(sys.argv[1], encoding="utf-8"))["talFiles"]: + print(item["path"]) PY -)" -TA_NAME="$(basename "$FIRST_TAL" .tal)" +) +CLIENT_TAL_ARGS=() +for tal_path in "${TAL_PATHS[@]}"; do + CLIENT_TAL_ARGS+=(-t "$tal_path") +done +COMPARE_TRUST_ANCHOR="unknown" export CIR_MIRROR_ROOT="$(python3 - <<'PY' "$MIRROR_ROOT" from pathlib import Path @@ -135,7 +144,7 @@ chmod -R 0777 "$TMP_ROOT" -R \ -e "$WRAPPER" \ -P "$VALIDATION_EPOCH" \ - -t "$FIRST_TAL" \ + "${CLIENT_TAL_ARGS[@]}" \ -d "$CACHE_DIR" \ "$OUT_CCR_DIR" >"$RUN_LOG" 2>&1 @@ -144,9 +153,9 @@ if [[ -f "$OUT_CCR_DIR/rpki.ccr" ]]; then --ccr "$OUT_CCR_DIR/rpki.ccr" \ --vrps-out "$ACTUAL_VRPS" \ --vaps-out "$ACTUAL_VAPS" \ - --trust-anchor "$TA_NAME" + --trust-anchor "$COMPARE_TRUST_ANCHOR" else - python3 - <<'PY' "$OUT_CCR_DIR/json" "$ACTUAL_VRPS" "$ACTUAL_VAPS" "$TA_NAME" + python3 - <<'PY' "$OUT_CCR_DIR/json" "$ACTUAL_VRPS" "$ACTUAL_VAPS" "$COMPARE_TRUST_ANCHOR" import csv import json import sys @@ -155,7 +164,7 @@ from pathlib import Path json_path = Path(sys.argv[1]) vrps_out = Path(sys.argv[2]) vaps_out = Path(sys.argv[3]) -default_ta = sys.argv[4] +compare_ta = sys.argv[4] if not json_path.is_file(): raise SystemExit(f"rpki-client output has neither rpki.ccr nor json: {json_path}") @@ -171,7 +180,7 @@ with vrps_out.open("w", newline="", encoding="utf-8") as fh: f"AS{roa['asn']}", roa["prefix"], str(roa["maxLength"]), - roa.get("ta") or default_ta, + compare_ta, ]) with vaps_out.open("w", newline="", encoding="utf-8") as fh: @@ -182,7 +191,7 @@ with vaps_out.open("w", newline="", encoding="utf-8") as fh: writer.writerow([ f"AS{aspa['customer_asid']}", providers, - aspa.get("ta") or default_ta, + compare_ta, ]) PY fi @@ -197,9 +206,9 @@ json.dump({"count": count_rows(sys.argv[1])}, open(sys.argv[3], "w"), indent=2) json.dump({"count": count_rows(sys.argv[2])}, open(sys.argv[4], "w"), indent=2) PY -"$CCR_TO_COMPARE_VIEWS_BIN" --ccr "$REFERENCE_CCR" --vrps-out "$REF_VRPS" --vaps-out "$REF_VAPS" --trust-anchor "$TA_NAME" +"$CCR_TO_COMPARE_VIEWS_BIN" --ccr "$REFERENCE_CCR" --vrps-out "$REF_VRPS" --vaps-out "$REF_VAPS" --trust-anchor "$COMPARE_TRUST_ANCHOR" -python3 - <<'PY' "$ACTUAL_VRPS" "$REF_VRPS" "$ACTUAL_VAPS" "$REF_VAPS" "$SUMMARY_JSON" +python3 - <<'PY' "$ACTUAL_VRPS" "$REF_VRPS" "$ACTUAL_VAPS" "$REF_VAPS" "$SUMMARY_JSON" "$META_JSON" import csv, json, sys def rows(path): with open(path, newline="") as f: @@ -208,7 +217,11 @@ actual_vrps = {tuple(r) for r in rows(sys.argv[1])} ref_vrps = {tuple(r) for r in rows(sys.argv[2])} actual_vaps = {tuple(r) for r in rows(sys.argv[3])} ref_vaps = {tuple(r) for r in rows(sys.argv[4])} +meta = json.load(open(sys.argv[6], encoding="utf-8")) summary = { + "compareMode": "trust-anchor-agnostic", + "talCount": len(meta["talFiles"]), + "talPaths": [item["path"] for item in meta["talFiles"]], "vrps": { "actual": len(actual_vrps), "reference": len(ref_vrps), diff --git a/scripts/cir/run_cir_replay_sequence_ours.sh b/scripts/cir/run_cir_replay_sequence_ours.sh index 900c304..1297211 100755 --- a/scripts/cir/run_cir_replay_sequence_ours.sh +++ b/scripts/cir/run_cir_replay_sequence_ours.sh @@ -92,6 +92,9 @@ for step in steps: "outDir": str(out_dir), "comparePath": str(out_dir / "compare-summary.json"), "timingPath": str(out_dir / "timing.json"), + "compareMode": compare.get("compareMode"), + "talCount": compare.get("talCount"), + "talPaths": compare.get("talPaths", []), "compare": compare, "timing": timing, "match": bool(compare["vrps"]["match"]) and bool(compare["vaps"]["match"]), @@ -117,16 +120,18 @@ lines = [ f"- `step_count`: `{len(results)}`", f"- `all_match`: `{all_match}`", "", - "| Step | Kind | VRP actual/ref | VRP match | VAP actual/ref | VAP match | Duration (ms) |", - "| --- | --- | --- | --- | --- | --- | ---: |", + "| Step | Kind | TALs | Compare mode | VRP actual/ref | VRP match | VAP actual/ref | VAP match | Duration (ms) |", + "| --- | --- | ---: | --- | --- | --- | --- | --- | ---: |", ] for item in results: compare = item["compare"] timing = item.get("timing") or {} lines.append( - "| {step} | {kind} | {va}/{vr} | {vm} | {aa}/{ar} | {am} | {dur} |".format( + "| {step} | {kind} | {tal_count} | {compare_mode} | {va}/{vr} | {vm} | {aa}/{ar} | {am} | {dur} |".format( step=item["stepId"], kind=item["kind"], + tal_count=item.get("talCount") if item.get("talCount") is not None else "-", + compare_mode=item.get("compareMode") or "-", va=compare["vrps"]["actual"], vr=compare["vrps"]["reference"], vm=compare["vrps"]["match"], diff --git a/scripts/cir/run_cir_replay_sequence_routinator.sh b/scripts/cir/run_cir_replay_sequence_routinator.sh index e397ddd..8d91ce5 100755 --- a/scripts/cir/run_cir_replay_sequence_routinator.sh +++ b/scripts/cir/run_cir_replay_sequence_routinator.sh @@ -97,6 +97,9 @@ for step in steps: "validationTime": step["validationTime"], "outDir": str(out_dir), "comparePath": str(out_dir / "compare-summary.json"), + "compareMode": compare.get("compareMode"), + "talCount": compare.get("talCount"), + "talPaths": compare.get("talPaths", []), "match": match, "compare": compare, } @@ -118,7 +121,25 @@ lines = [ f"- `step_count`: `{len(results)}`", f"- `all_match`: `{all_match}`", "", + "| Step | Kind | TALs | Compare mode | VRP actual/ref | VRP match | VAP actual/ref | VAP match |", + "| --- | --- | ---: | --- | --- | --- | --- | --- |", ] +for item in results: + compare = item["compare"] + lines.append( + "| {step} | {kind} | {tal_count} | {compare_mode} | {va}/{vr} | {vm} | {aa}/{ar} | {am} |".format( + step=item["stepId"], + kind=item["kind"], + tal_count=item.get("talCount") if item.get("talCount") is not None else "-", + compare_mode=item.get("compareMode") or "-", + va=compare["vrps"]["actual"], + vr=compare["vrps"]["reference"], + vm=compare["vrps"]["match"], + aa=compare["vaps"]["actual"], + ar=compare["vaps"]["reference"], + am=compare["vaps"]["match"], + ) + ) summary_md.write_text("\n".join(lines), encoding="utf-8") PY diff --git a/scripts/cir/run_cir_replay_sequence_rpki_client.sh b/scripts/cir/run_cir_replay_sequence_rpki_client.sh index 54998ef..f46e271 100755 --- a/scripts/cir/run_cir_replay_sequence_rpki_client.sh +++ b/scripts/cir/run_cir_replay_sequence_rpki_client.sh @@ -96,6 +96,9 @@ for step in steps: "validationTime": step["validationTime"], "outDir": str(out_dir), "comparePath": str(out_dir / "compare-summary.json"), + "compareMode": compare.get("compareMode"), + "talCount": compare.get("talCount"), + "talPaths": compare.get("talPaths", []), "match": match, "compare": compare, } @@ -117,7 +120,25 @@ lines = [ f"- `step_count`: `{len(results)}`", f"- `all_match`: `{all_match}`", "", + "| Step | Kind | TALs | Compare mode | VRP actual/ref | VRP match | VAP actual/ref | VAP match |", + "| --- | --- | ---: | --- | --- | --- | --- | --- |", ] +for item in results: + compare = item["compare"] + lines.append( + "| {step} | {kind} | {tal_count} | {compare_mode} | {va}/{vr} | {vm} | {aa}/{ar} | {am} |".format( + step=item["stepId"], + kind=item["kind"], + tal_count=item.get("talCount") if item.get("talCount") is not None else "-", + compare_mode=item.get("compareMode") or "-", + va=compare["vrps"]["actual"], + vr=compare["vrps"]["reference"], + vm=compare["vrps"]["match"], + aa=compare["vaps"]["actual"], + ar=compare["vaps"]["reference"], + am=compare["vaps"]["match"], + ) + ) summary_md.write_text("\n".join(lines), encoding="utf-8") PY diff --git a/src/cli.rs b/src/cli.rs index 6f7bd70..d249929 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -461,8 +461,7 @@ pub fn parse_args(argv: &[String]) -> Result { )); } if !tal_paths.is_empty() { - let strict_pairing_required = tal_paths.len() > 1 || !ta_paths.is_empty(); - if strict_pairing_required { + if !ta_paths.is_empty() { if ta_paths.len() != tal_paths.len() { return Err(format!( "--tal-path and --ta-path counts must match in file mode\n\n{}", @@ -2170,6 +2169,30 @@ mod tests { ); } + #[test] + fn parse_accepts_multiple_tal_paths_without_ta_when_disable_rrdp() { + let argv = vec![ + "rpki".to_string(), + "--db".to_string(), + "db".to_string(), + "--tal-path".to_string(), + "a.tal".to_string(), + "--tal-path".to_string(), + "b.tal".to_string(), + "--disable-rrdp".to_string(), + "--rsync-command".to_string(), + "/tmp/fake-rsync".to_string(), + ]; + let args = parse_args(&argv).expect("parse"); + assert_eq!( + args.tal_paths, + vec![PathBuf::from("a.tal"), PathBuf::from("b.tal")] + ); + assert!(args.ta_paths.is_empty()); + assert_eq!(args.tal_inputs.len(), 2); + assert!(args.disable_rrdp); + } + #[test] fn parse_accepts_payload_delta_replay_mode_with_offline_tal_and_ta() { let argv = vec![ diff --git a/tests/test_cir_sequence_replay_m3.rs b/tests/test_cir_sequence_replay_m3.rs index 4a58f91..2216358 100644 --- a/tests/test_cir_sequence_replay_m3.rs +++ b/tests/test_cir_sequence_replay_m3.rs @@ -204,4 +204,10 @@ fn ours_sequence_replay_script_replays_all_steps() { .unwrap(); assert_eq!(summary["stepCount"], 3); assert_eq!(summary["allMatch"], true); + for step in summary["steps"].as_array().expect("steps array") { + assert_eq!(step["talCount"], 1); + assert_eq!(step["compareMode"], "trust-anchor-agnostic"); + assert_eq!(step["compare"]["talCount"], 1); + assert_eq!(step["compare"]["compareMode"], "trust-anchor-agnostic"); + } }