20260427_5 支持all5 CIR replay多TAL
This commit is contained in:
parent
e2901df3ac
commit
0295fd3262
@ -194,6 +194,9 @@ for name, out_dir in [
|
|||||||
"summaryPath": str(out / "compare-summary.json"),
|
"summaryPath": str(out / "compare-summary.json"),
|
||||||
"exitCode": timing["exitCode"],
|
"exitCode": timing["exitCode"],
|
||||||
"durationMs": timing["durationMs"],
|
"durationMs": timing["durationMs"],
|
||||||
|
"compareMode": compare.get("compareMode"),
|
||||||
|
"talCount": compare.get("talCount"),
|
||||||
|
"talPaths": compare.get("talPaths", []),
|
||||||
"vrps": vrps,
|
"vrps": vrps,
|
||||||
"vaps": vaps,
|
"vaps": vaps,
|
||||||
"match": bool(vrps.get("match")) and bool(vaps.get("match")) and timing["exitCode"] == 0,
|
"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"- `reference_ccr`: `{reference_ccr}`",
|
||||||
f"- `all_match`: `{all_match}`",
|
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:
|
for participant in participants:
|
||||||
vrps = participant["vrps"] or {}
|
vrps = participant["vrps"] or {}
|
||||||
vaps = participant["vaps"] or {}
|
vaps = participant["vaps"] or {}
|
||||||
log_path = participant["logPaths"][0] if participant["logPaths"] else ""
|
log_path = participant["logPaths"][0] if participant["logPaths"] else ""
|
||||||
lines.append(
|
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"],
|
name=participant["name"],
|
||||||
exit_code=participant["exitCode"],
|
exit_code=participant["exitCode"],
|
||||||
duration_ms=participant["durationMs"],
|
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_actual=vrps.get("actual", "-"),
|
||||||
vrp_ref=vrps.get("reference", "-"),
|
vrp_ref=vrps.get("reference", "-"),
|
||||||
vrp_match=vrps.get("match", False),
|
vrp_match=vrps.get("match", False),
|
||||||
@ -258,6 +263,8 @@ for participant in participants:
|
|||||||
f"- `mirror_path`: `{participant['mirrorPath']}`",
|
f"- `mirror_path`: `{participant['mirrorPath']}`",
|
||||||
f"- `summary_path`: `{participant['summaryPath']}`",
|
f"- `summary_path`: `{participant['summaryPath']}`",
|
||||||
f"- `timing_path`: `{participant['timingPath']}`",
|
f"- `timing_path`: `{participant['timingPath']}`",
|
||||||
|
f"- `compare_mode`: `{participant.get('compareMode')}`",
|
||||||
|
f"- `tal_count`: `{participant.get('talCount')}`",
|
||||||
f"- `log_paths`: `{', '.join(participant['logPaths'])}`",
|
f"- `log_paths`: `{', '.join(participant['logPaths'])}`",
|
||||||
f"- `vrps`: `actual={vrps.get('actual', '-')}` `reference={vrps.get('reference', '-')}` `match={vrps.get('match', False)}`",
|
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)}`",
|
f"- `vaps`: `actual={vaps.get('actual', '-')}` `reference={vaps.get('reference', '-')}` `match={vaps.get('match', False)}`",
|
||||||
|
|||||||
@ -10,6 +10,7 @@ Usage:
|
|||||||
--out-dir <path> \
|
--out-dir <path> \
|
||||||
--reference-ccr <path> \
|
--reference-ccr <path> \
|
||||||
[--keep-db] \
|
[--keep-db] \
|
||||||
|
[--report-json-compact] \
|
||||||
[--rpki-bin <path>] \
|
[--rpki-bin <path>] \
|
||||||
[--real-rsync-bin <path>]
|
[--real-rsync-bin <path>]
|
||||||
EOF
|
EOF
|
||||||
@ -22,6 +23,7 @@ REPO_BYTES_DB=""
|
|||||||
OUT_DIR=""
|
OUT_DIR=""
|
||||||
REFERENCE_CCR=""
|
REFERENCE_CCR=""
|
||||||
KEEP_DB=0
|
KEEP_DB=0
|
||||||
|
REPORT_JSON_COMPACT=0
|
||||||
RPKI_BIN="${RPKI_BIN:-$ROOT_DIR/target/release/rpki}"
|
RPKI_BIN="${RPKI_BIN:-$ROOT_DIR/target/release/rpki}"
|
||||||
CIR_MATERIALIZE_BIN="${CIR_MATERIALIZE_BIN:-$ROOT_DIR/target/release/cir_materialize}"
|
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}"
|
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 ;;
|
--out-dir) OUT_DIR="$2"; shift 2 ;;
|
||||||
--reference-ccr) REFERENCE_CCR="$2"; shift 2 ;;
|
--reference-ccr) REFERENCE_CCR="$2"; shift 2 ;;
|
||||||
--keep-db) KEEP_DB=1; shift ;;
|
--keep-db) KEEP_DB=1; shift ;;
|
||||||
|
--report-json-compact) REPORT_JSON_COMPACT=1; shift ;;
|
||||||
--rpki-bin) RPKI_BIN="$2"; shift 2 ;;
|
--rpki-bin) RPKI_BIN="$2"; shift 2 ;;
|
||||||
--real-rsync-bin) REAL_RSYNC_BIN="$2"; shift 2 ;;
|
--real-rsync-bin) REAL_RSYNC_BIN="$2"; shift 2 ;;
|
||||||
-h|--help) usage; exit 0 ;;
|
-h|--help) usage; exit 0 ;;
|
||||||
@ -86,11 +89,16 @@ import json,sys
|
|||||||
print(json.load(open(sys.argv[1]))["validationTime"])
|
print(json.load(open(sys.argv[1]))["validationTime"])
|
||||||
PY
|
PY
|
||||||
)"
|
)"
|
||||||
FIRST_TAL="$(python3 - <<'PY' "$META_JSON"
|
mapfile -t TAL_PATHS < <(python3 - <<'PY' "$META_JSON"
|
||||||
import json,sys
|
import json, sys
|
||||||
print(json.load(open(sys.argv[1]))["talFiles"][0]["path"])
|
for item in json.load(open(sys.argv[1], encoding="utf-8"))["talFiles"]:
|
||||||
|
print(item["path"])
|
||||||
PY
|
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"
|
export CIR_MIRROR_ROOT="$(python3 - <<'PY' "$MIRROR_ROOT"
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -101,20 +109,25 @@ PY
|
|||||||
export REAL_RSYNC_BIN="$REAL_RSYNC_BIN"
|
export REAL_RSYNC_BIN="$REAL_RSYNC_BIN"
|
||||||
export CIR_LOCAL_LINK_MODE=1
|
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" \
|
"$RPKI_BIN" \
|
||||||
--db "$DB_DIR" \
|
--db "$DB_DIR" \
|
||||||
--tal-path "$FIRST_TAL" \
|
"${TAL_ARGS[@]}" \
|
||||||
--disable-rrdp \
|
--disable-rrdp \
|
||||||
--rsync-command "$WRAPPER" \
|
--rsync-command "$WRAPPER" \
|
||||||
--validation-time "$VALIDATION_TIME" \
|
--validation-time "$VALIDATION_TIME" \
|
||||||
--ccr-out "$ACTUAL_CCR" \
|
--ccr-out "$ACTUAL_CCR" \
|
||||||
--report-json "$ACTUAL_REPORT" \
|
"${REPORT_JSON_ARGS[@]}" \
|
||||||
>"$RUN_LOG" 2>&1
|
>"$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 "$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
|
"$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
|
import csv, json, sys
|
||||||
def rows(path):
|
def rows(path):
|
||||||
with open(path, newline="") as f:
|
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])}
|
ref_vrps = {tuple(r) for r in rows(sys.argv[2])}
|
||||||
actual_vaps = {tuple(r) for r in rows(sys.argv[3])}
|
actual_vaps = {tuple(r) for r in rows(sys.argv[3])}
|
||||||
ref_vaps = {tuple(r) for r in rows(sys.argv[4])}
|
ref_vaps = {tuple(r) for r in rows(sys.argv[4])}
|
||||||
|
meta = json.load(open(sys.argv[6], encoding="utf-8"))
|
||||||
summary = {
|
summary = {
|
||||||
|
"compareMode": "trust-anchor-agnostic",
|
||||||
|
"talCount": len(meta["talFiles"]),
|
||||||
|
"talPaths": [item["path"] for item in meta["talFiles"]],
|
||||||
"vrps": {
|
"vrps": {
|
||||||
"actual": len(actual_vrps),
|
"actual": len(actual_vrps),
|
||||||
"reference": len(ref_vrps),
|
"reference": len(ref_vrps),
|
||||||
|
|||||||
@ -53,6 +53,10 @@ done
|
|||||||
usage >&2
|
usage >&2
|
||||||
exit 2
|
exit 2
|
||||||
}
|
}
|
||||||
|
if [[ ! -x "$ROUTINATOR_BIN" ]]; then
|
||||||
|
echo "routinator binary not executable: $ROUTINATOR_BIN" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
mkdir -p "$OUT_DIR"
|
mkdir -p "$OUT_DIR"
|
||||||
if [[ ! -x "$CIR_MATERIALIZE_BIN" || ! -x "$CIR_EXTRACT_INPUTS_BIN" || ! -x "$CCR_TO_COMPARE_VIEWS_BIN" ]]; then
|
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"])
|
print(json.load(open(sys.argv[1]))["validationTime"])
|
||||||
PY
|
PY
|
||||||
)"
|
)"
|
||||||
FIRST_TAL="$(python3 - <<'PY' "$META_JSON"
|
mapfile -t TAL_PATHS < <(python3 - <<'PY' "$META_JSON"
|
||||||
import json,sys
|
import json, sys
|
||||||
print(json.load(open(sys.argv[1]))["talFiles"][0]["path"])
|
for item in json.load(open(sys.argv[1], encoding="utf-8"))["talFiles"]:
|
||||||
|
print(item["path"])
|
||||||
PY
|
PY
|
||||||
)"
|
)
|
||||||
TA_NAME="$(basename "$FIRST_TAL" .tal)"
|
COMPARE_TRUST_ANCHOR="unknown"
|
||||||
FAKE_EPOCH="$(python3 - <<'PY' "$VALIDATION_TIME"
|
FAKE_EPOCH="$(python3 - <<'PY' "$VALIDATION_TIME"
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
import sys
|
import sys
|
||||||
@ -171,9 +176,30 @@ env \
|
|||||||
vrps --noupdate --format json -o "$ACTUAL_VAPS_JSON" >>"$RUN_LOG" 2>&1
|
vrps --noupdate --format json -o "$ACTUAL_VAPS_JSON" >>"$RUN_LOG" 2>&1
|
||||||
|
|
||||||
python3 "$JSON_TO_VAPS" --input "$ACTUAL_VAPS_JSON" --csv-out "$ACTUAL_VAPS"
|
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
|
import csv, json, sys
|
||||||
def rows(path):
|
def rows(path):
|
||||||
with open(path, newline="") as f:
|
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])}
|
ref_vrps = {tuple(r) for r in rows(sys.argv[2])}
|
||||||
actual_vaps = {tuple(r) for r in rows(sys.argv[3])}
|
actual_vaps = {tuple(r) for r in rows(sys.argv[3])}
|
||||||
ref_vaps = {tuple(r) for r in rows(sys.argv[4])}
|
ref_vaps = {tuple(r) for r in rows(sys.argv[4])}
|
||||||
|
meta = json.load(open(sys.argv[6], encoding="utf-8"))
|
||||||
summary = {
|
summary = {
|
||||||
|
"compareMode": "trust-anchor-agnostic",
|
||||||
|
"talCount": len(meta["talFiles"]),
|
||||||
|
"talPaths": [item["path"] for item in meta["talFiles"]],
|
||||||
"vrps": {
|
"vrps": {
|
||||||
"actual": len(actual_vrps),
|
"actual": len(actual_vrps),
|
||||||
"reference": len(ref_vrps),
|
"reference": len(ref_vrps),
|
||||||
|
|||||||
@ -55,6 +55,10 @@ fi
|
|||||||
if [[ -z "$RPKI_CLIENT_BIN" ]]; then
|
if [[ -z "$RPKI_CLIENT_BIN" ]]; then
|
||||||
RPKI_CLIENT_BIN="$BUILD_DIR/src/rpki-client"
|
RPKI_CLIENT_BIN="$BUILD_DIR/src/rpki-client"
|
||||||
fi
|
fi
|
||||||
|
if [[ ! -x "$RPKI_CLIENT_BIN" ]]; then
|
||||||
|
echo "rpki-client binary not executable: $RPKI_CLIENT_BIN" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
mkdir -p "$OUT_DIR"
|
mkdir -p "$OUT_DIR"
|
||||||
if [[ ! -x "$CIR_MATERIALIZE_BIN" || ! -x "$CIR_EXTRACT_INPUTS_BIN" || ! -x "$CCR_TO_COMPARE_VIEWS_BIN" ]]; then
|
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()))
|
print(int(dt.timestamp()))
|
||||||
PY
|
PY
|
||||||
)"
|
)"
|
||||||
FIRST_TAL="$(python3 - <<'PY' "$META_JSON"
|
mapfile -t TAL_PATHS < <(python3 - <<'PY' "$META_JSON"
|
||||||
import json,sys
|
import json, sys
|
||||||
print(json.load(open(sys.argv[1]))["talFiles"][0]["path"])
|
for item in json.load(open(sys.argv[1], encoding="utf-8"))["talFiles"]:
|
||||||
|
print(item["path"])
|
||||||
PY
|
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"
|
export CIR_MIRROR_ROOT="$(python3 - <<'PY' "$MIRROR_ROOT"
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -135,7 +144,7 @@ chmod -R 0777 "$TMP_ROOT"
|
|||||||
-R \
|
-R \
|
||||||
-e "$WRAPPER" \
|
-e "$WRAPPER" \
|
||||||
-P "$VALIDATION_EPOCH" \
|
-P "$VALIDATION_EPOCH" \
|
||||||
-t "$FIRST_TAL" \
|
"${CLIENT_TAL_ARGS[@]}" \
|
||||||
-d "$CACHE_DIR" \
|
-d "$CACHE_DIR" \
|
||||||
"$OUT_CCR_DIR" >"$RUN_LOG" 2>&1
|
"$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" \
|
--ccr "$OUT_CCR_DIR/rpki.ccr" \
|
||||||
--vrps-out "$ACTUAL_VRPS" \
|
--vrps-out "$ACTUAL_VRPS" \
|
||||||
--vaps-out "$ACTUAL_VAPS" \
|
--vaps-out "$ACTUAL_VAPS" \
|
||||||
--trust-anchor "$TA_NAME"
|
--trust-anchor "$COMPARE_TRUST_ANCHOR"
|
||||||
else
|
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 csv
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
@ -155,7 +164,7 @@ from pathlib import Path
|
|||||||
json_path = Path(sys.argv[1])
|
json_path = Path(sys.argv[1])
|
||||||
vrps_out = Path(sys.argv[2])
|
vrps_out = Path(sys.argv[2])
|
||||||
vaps_out = Path(sys.argv[3])
|
vaps_out = Path(sys.argv[3])
|
||||||
default_ta = sys.argv[4]
|
compare_ta = sys.argv[4]
|
||||||
|
|
||||||
if not json_path.is_file():
|
if not json_path.is_file():
|
||||||
raise SystemExit(f"rpki-client output has neither rpki.ccr nor json: {json_path}")
|
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']}",
|
f"AS{roa['asn']}",
|
||||||
roa["prefix"],
|
roa["prefix"],
|
||||||
str(roa["maxLength"]),
|
str(roa["maxLength"]),
|
||||||
roa.get("ta") or default_ta,
|
compare_ta,
|
||||||
])
|
])
|
||||||
|
|
||||||
with vaps_out.open("w", newline="", encoding="utf-8") as fh:
|
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([
|
writer.writerow([
|
||||||
f"AS{aspa['customer_asid']}",
|
f"AS{aspa['customer_asid']}",
|
||||||
providers,
|
providers,
|
||||||
aspa.get("ta") or default_ta,
|
compare_ta,
|
||||||
])
|
])
|
||||||
PY
|
PY
|
||||||
fi
|
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)
|
json.dump({"count": count_rows(sys.argv[2])}, open(sys.argv[4], "w"), indent=2)
|
||||||
PY
|
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
|
import csv, json, sys
|
||||||
def rows(path):
|
def rows(path):
|
||||||
with open(path, newline="") as f:
|
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])}
|
ref_vrps = {tuple(r) for r in rows(sys.argv[2])}
|
||||||
actual_vaps = {tuple(r) for r in rows(sys.argv[3])}
|
actual_vaps = {tuple(r) for r in rows(sys.argv[3])}
|
||||||
ref_vaps = {tuple(r) for r in rows(sys.argv[4])}
|
ref_vaps = {tuple(r) for r in rows(sys.argv[4])}
|
||||||
|
meta = json.load(open(sys.argv[6], encoding="utf-8"))
|
||||||
summary = {
|
summary = {
|
||||||
|
"compareMode": "trust-anchor-agnostic",
|
||||||
|
"talCount": len(meta["talFiles"]),
|
||||||
|
"talPaths": [item["path"] for item in meta["talFiles"]],
|
||||||
"vrps": {
|
"vrps": {
|
||||||
"actual": len(actual_vrps),
|
"actual": len(actual_vrps),
|
||||||
"reference": len(ref_vrps),
|
"reference": len(ref_vrps),
|
||||||
|
|||||||
@ -92,6 +92,9 @@ for step in steps:
|
|||||||
"outDir": str(out_dir),
|
"outDir": str(out_dir),
|
||||||
"comparePath": str(out_dir / "compare-summary.json"),
|
"comparePath": str(out_dir / "compare-summary.json"),
|
||||||
"timingPath": str(out_dir / "timing.json"),
|
"timingPath": str(out_dir / "timing.json"),
|
||||||
|
"compareMode": compare.get("compareMode"),
|
||||||
|
"talCount": compare.get("talCount"),
|
||||||
|
"talPaths": compare.get("talPaths", []),
|
||||||
"compare": compare,
|
"compare": compare,
|
||||||
"timing": timing,
|
"timing": timing,
|
||||||
"match": bool(compare["vrps"]["match"]) and bool(compare["vaps"]["match"]),
|
"match": bool(compare["vrps"]["match"]) and bool(compare["vaps"]["match"]),
|
||||||
@ -117,16 +120,18 @@ lines = [
|
|||||||
f"- `step_count`: `{len(results)}`",
|
f"- `step_count`: `{len(results)}`",
|
||||||
f"- `all_match`: `{all_match}`",
|
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:
|
for item in results:
|
||||||
compare = item["compare"]
|
compare = item["compare"]
|
||||||
timing = item.get("timing") or {}
|
timing = item.get("timing") or {}
|
||||||
lines.append(
|
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"],
|
step=item["stepId"],
|
||||||
kind=item["kind"],
|
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"],
|
va=compare["vrps"]["actual"],
|
||||||
vr=compare["vrps"]["reference"],
|
vr=compare["vrps"]["reference"],
|
||||||
vm=compare["vrps"]["match"],
|
vm=compare["vrps"]["match"],
|
||||||
|
|||||||
@ -97,6 +97,9 @@ for step in steps:
|
|||||||
"validationTime": step["validationTime"],
|
"validationTime": step["validationTime"],
|
||||||
"outDir": str(out_dir),
|
"outDir": str(out_dir),
|
||||||
"comparePath": str(out_dir / "compare-summary.json"),
|
"comparePath": str(out_dir / "compare-summary.json"),
|
||||||
|
"compareMode": compare.get("compareMode"),
|
||||||
|
"talCount": compare.get("talCount"),
|
||||||
|
"talPaths": compare.get("talPaths", []),
|
||||||
"match": match,
|
"match": match,
|
||||||
"compare": compare,
|
"compare": compare,
|
||||||
}
|
}
|
||||||
@ -118,7 +121,25 @@ lines = [
|
|||||||
f"- `step_count`: `{len(results)}`",
|
f"- `step_count`: `{len(results)}`",
|
||||||
f"- `all_match`: `{all_match}`",
|
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")
|
summary_md.write_text("\n".join(lines), encoding="utf-8")
|
||||||
PY
|
PY
|
||||||
|
|
||||||
|
|||||||
@ -96,6 +96,9 @@ for step in steps:
|
|||||||
"validationTime": step["validationTime"],
|
"validationTime": step["validationTime"],
|
||||||
"outDir": str(out_dir),
|
"outDir": str(out_dir),
|
||||||
"comparePath": str(out_dir / "compare-summary.json"),
|
"comparePath": str(out_dir / "compare-summary.json"),
|
||||||
|
"compareMode": compare.get("compareMode"),
|
||||||
|
"talCount": compare.get("talCount"),
|
||||||
|
"talPaths": compare.get("talPaths", []),
|
||||||
"match": match,
|
"match": match,
|
||||||
"compare": compare,
|
"compare": compare,
|
||||||
}
|
}
|
||||||
@ -117,7 +120,25 @@ lines = [
|
|||||||
f"- `step_count`: `{len(results)}`",
|
f"- `step_count`: `{len(results)}`",
|
||||||
f"- `all_match`: `{all_match}`",
|
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")
|
summary_md.write_text("\n".join(lines), encoding="utf-8")
|
||||||
PY
|
PY
|
||||||
|
|
||||||
|
|||||||
27
src/cli.rs
27
src/cli.rs
@ -461,8 +461,7 @@ pub fn parse_args(argv: &[String]) -> Result<CliArgs, String> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
if !tal_paths.is_empty() {
|
if !tal_paths.is_empty() {
|
||||||
let strict_pairing_required = tal_paths.len() > 1 || !ta_paths.is_empty();
|
if !ta_paths.is_empty() {
|
||||||
if strict_pairing_required {
|
|
||||||
if ta_paths.len() != tal_paths.len() {
|
if ta_paths.len() != tal_paths.len() {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"--tal-path and --ta-path counts must match in file mode\n\n{}",
|
"--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]
|
#[test]
|
||||||
fn parse_accepts_payload_delta_replay_mode_with_offline_tal_and_ta() {
|
fn parse_accepts_payload_delta_replay_mode_with_offline_tal_and_ta() {
|
||||||
let argv = vec![
|
let argv = vec![
|
||||||
|
|||||||
@ -204,4 +204,10 @@ fn ours_sequence_replay_script_replays_all_steps() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(summary["stepCount"], 3);
|
assert_eq!(summary["stepCount"], 3);
|
||||||
assert_eq!(summary["allMatch"], true);
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user