#!/usr/bin/env bash set -euo pipefail usage() { cat <<'EOF' Usage: ./scripts/periodic/compare_ccr_round.sh \ --ours-ccr \ --rpki-client-ccr \ --out-dir \ [--trust-anchor ] EOF } ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" OURS_CCR="" CLIENT_CCR="" OUT_DIR="" TRUST_ANCHOR="unknown" CCR_TO_COMPARE_VIEWS_BIN="$ROOT_DIR/target/release/ccr_to_compare_views" while [[ $# -gt 0 ]]; do case "$1" in --ours-ccr) OURS_CCR="$2"; shift 2 ;; --rpki-client-ccr) CLIENT_CCR="$2"; shift 2 ;; --out-dir) OUT_DIR="$2"; shift 2 ;; --trust-anchor) TRUST_ANCHOR="$2"; shift 2 ;; -h|--help) usage; exit 0 ;; *) echo "unknown argument: $1" >&2; usage; exit 2 ;; esac done [[ -n "$OURS_CCR" && -n "$CLIENT_CCR" && -n "$OUT_DIR" ]] || { usage >&2; exit 2; } mkdir -p "$OUT_DIR" if [[ ! -x "$CCR_TO_COMPARE_VIEWS_BIN" ]]; then ( cd "$ROOT_DIR" cargo build --release --bin ccr_to_compare_views ) fi OURS_VRPS="$OUT_DIR/ours-vrps.csv" OURS_VAPS="$OUT_DIR/ours-vaps.csv" CLIENT_VRPS="$OUT_DIR/rpki-client-vrps.csv" CLIENT_VAPS="$OUT_DIR/rpki-client-vaps.csv" SUMMARY_JSON="$OUT_DIR/compare-summary.json" SUMMARY_MD="$OUT_DIR/compare-summary.md" "$CCR_TO_COMPARE_VIEWS_BIN" \ --ccr "$OURS_CCR" \ --vrps-out "$OURS_VRPS" \ --vaps-out "$OURS_VAPS" \ --trust-anchor "$TRUST_ANCHOR" "$CCR_TO_COMPARE_VIEWS_BIN" \ --ccr "$CLIENT_CCR" \ --vrps-out "$CLIENT_VRPS" \ --vaps-out "$CLIENT_VAPS" \ --trust-anchor "$TRUST_ANCHOR" python3 - <<'PY' "$OURS_VRPS" "$CLIENT_VRPS" "$OURS_VAPS" "$CLIENT_VAPS" "$SUMMARY_JSON" "$SUMMARY_MD" import csv import json import sys from pathlib import Path ours_vrps_path, client_vrps_path, ours_vaps_path, client_vaps_path, json_out, md_out = sys.argv[1:] def rows(path): with open(path, newline="") as f: return list(csv.reader(f))[1:] ours_vrps = {tuple(r) for r in rows(ours_vrps_path)} client_vrps = {tuple(r) for r in rows(client_vrps_path)} ours_vaps = {tuple(r) for r in rows(ours_vaps_path)} client_vaps = {tuple(r) for r in rows(client_vaps_path)} summary = { "vrps": { "ours": len(ours_vrps), "rpkiClient": len(client_vrps), "match": ours_vrps == client_vrps, "onlyInOurs": sorted(ours_vrps - client_vrps)[:20], "onlyInRpkiClient": sorted(client_vrps - ours_vrps)[:20], }, "vaps": { "ours": len(ours_vaps), "rpkiClient": len(client_vaps), "match": ours_vaps == client_vaps, "onlyInOurs": sorted(ours_vaps - client_vaps)[:20], "onlyInRpkiClient": sorted(client_vaps - ours_vaps)[:20], }, } summary["allMatch"] = summary["vrps"]["match"] and summary["vaps"]["match"] Path(json_out).write_text(json.dumps(summary, indent=2), encoding="utf-8") lines = [ "# Round Compare Summary", "", f"- `allMatch`: `{summary['allMatch']}`", f"- `vrpMatch`: `{summary['vrps']['match']}`", f"- `vapMatch`: `{summary['vaps']['match']}`", f"- `ours_vrps`: `{summary['vrps']['ours']}`", f"- `rpki_client_vrps`: `{summary['vrps']['rpkiClient']}`", f"- `ours_vaps`: `{summary['vaps']['ours']}`", f"- `rpki_client_vaps`: `{summary['vaps']['rpkiClient']}`", "", "## Sample Differences", "", f"- `vrps.onlyInOurs`: `{len(summary['vrps']['onlyInOurs'])}`", f"- `vrps.onlyInRpkiClient`: `{len(summary['vrps']['onlyInRpkiClient'])}`", f"- `vaps.onlyInOurs`: `{len(summary['vaps']['onlyInOurs'])}`", f"- `vaps.onlyInRpkiClient`: `{len(summary['vaps']['onlyInRpkiClient'])}`", ] Path(md_out).write_text("\n".join(lines) + "\n", encoding="utf-8") PY echo "$OUT_DIR"