Newer
Older
openstack-caracal-ipv4 / tests / repo-lint / run-tests.sh
#!/usr/bin/env bash
# tests/repo-lint/run-tests.sh -- offline harness for repo_lint.py (DOCFIX-074).
# Builds throwaway fixture repos with planted violations; asserts each lint class
# fires, and that a clean fixture passes. Mutates nothing outside $TMP.
# Exit: 0 all pass | 1 any case failed.  ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO="$(cd "$HERE/../.." && pwd)"
TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT
PASS=0; FAIL=0

mkrepo() { # mkrepo <name>  -> minimal clean fixture repo
  local d="$TMP/$1"; mkdir -p "$d/runbooks" "$d/scripts" "$d/docs"
  printf '# readme\n' > "$d/README.md"
  printf 'applications: {}\n' > "$d/bundle.yaml"
  printf '## D-001\ntext\n' > "$d/docs/design-decisions.md"
  printf '#!/usr/bin/env bash\necho ok\n' > "$d/scripts/real.sh"
  printf '# phase\n```bash\nbash scripts/real.sh\n```\n' > "$d/runbooks/phase-x.md"
  echo "$d"
}
run() { # run <want_rc> <regex> <label> <dir>
  local out rc
  out="$(python3 "$REPO/scripts/repo_lint.py" "$4" 2>&1)"; rc=$?
  if [[ "$rc" == "$1" ]] && grep -qE "$2" <<<"$out"; then
    echo "  PASS  $3"; PASS=$((PASS+1))
  else
    echo "  FAIL  $3 (rc=$rc want=$1)"; echo "$out" | sed 's/^/        /' | head -5; FAIL=$((FAIL+1))
  fi
}

D=$(mkrepo clean);            run 0 'PASS: repo lint' "T1 clean fixture passes" "$D"
D=$(mkrepo l1); printf 'line with \xe2\x80\x94 dash\n' >> "$D/runbooks/phase-x.md"
                              run 1 'L1 .*non-ASCII' "T2 L1 non-ASCII FAILS" "$D"
D=$(mkrepo l1b); printf 'crlf line\r\n' >> "$D/scripts/real.sh"
                              run 1 'L1 .*CR byte' "T3 L1 CRLF FAILS" "$D"
D=$(mkrepo l2); printf 'bind to provider-vip here\n' >> "$D/runbooks/phase-x.md"
                              run 1 'L2 .*retired space' "T4 L2 stale space FAILS" "$D"
D=$(mkrepo l2b); printf 'the provider-vip plane is retired (D-060)\n' >> "$D/runbooks/phase-x.md"
                              run 0 'PASS' "T5 L2 historical context EXEMPT" "$D"
D=$(mkrepo l3); printf 'run scripts/ghost.sh now\n' >> "$D/runbooks/phase-x.md"
                              run 1 'L3 .*missing scripts/ghost.sh' "T6 L3 ghost ref FAILS" "$D"
D=$(mkrepo l4); printf 'use phase-00-teardown.sh --apply\n' >> "$D/runbooks/phase-x.md"
                              run 1 'L4 .*deprecated' "T7 L4 deprecated ref FAILS" "$D"
D=$(mkrepo l5); printf '## D-001\ndupe\n' >> "$D/docs/design-decisions.md"
                              run 1 'L5 D-001 defined 2' "T8 L5 numbering collision FAILS" "$D"
D=$(mkrepo l6); printf '```bash\nscripts/real.sh --apply\n```\n' >> "$D/runbooks/phase-x.md"
                              run 1 'L6 .*bare script invocation' "T9 L6 bare invoke FAILS" "$D"

# ---- L7 clientdocs sweep-on-change receipt (DOCFIX-104) ----
mkcd() { # mkcd <name> -> clean fixture WITH clientdocs + tenant-facing files
  local d; d=$(mkrepo "$1")
  mkdir -p "$d/clientdocs"
  printf '# welcome\n' > "$d/clientdocs/welcome.md"
  printf '#!/usr/bin/env bash\necho onboard\n' > "$d/scripts/tenant-onboard.sh"
  printf '# contract\n' > "$d/docs/tenant-onboarding-contract.md"
  echo "$d"
}
rec() { python3 "$REPO/scripts/repo_lint.py" --record-clientdocs-sweep "$1" >/dev/null 2>&1; }

D=$(mkcd l7a);                run 1 'L7 clientdocs/ exists without sweep-receipt' \
                                    "T10 L7 missing receipt FAILS" "$D"
D=$(mkcd l7b); rec "$D";      run 0 'PASS: repo lint' "T11 L7 recorded receipt PASSES" "$D"
D=$(mkcd l7c); rec "$D"; printf 'echo changed\n' >> "$D/scripts/tenant-onboard.sh"
                              run 1 'L7 scripts/tenant-onboard.sh changed since the recorded clientdocs sweep' \
                                    "T12 L7 stale marker FAILS" "$D"
D=$(mkcd l7d); rec "$D"; printf 'echo changed\n' >> "$D/scripts/tenant-onboard.sh"; rec "$D"
                              run 0 'PASS: repo lint' "T13 L7 marker bump PASSES again" "$D"
D=$(mkcd l7e); rec "$D"; printf 'unrelated\n' >> "$D/README.md"
                              run 0 'PASS: repo lint' "T14 L7 unrelated change does NOT fire" "$D"
D=$(mkcd l7f); rec "$D"; printf '# pricing\n' > "$D/clientdocs/pricing.md"
                              run 1 'L7 tenant-facing clientdocs/pricing.md is not in the sweep receipt' \
                                    "T15 L7 uncovered new tenant-facing file FAILS" "$D"
D=$(mkcd l7g); rec "$D"; rm "$D/scripts/tenant-onboard.sh"
                              run 1 'L7 sweep receipt pins missing file scripts/tenant-onboard.sh' \
                                    "T16 L7 pinned file removed FAILS" "$D"
D=$(mkcd l7h); rec "$D"; printf 'not-a-hash-line\n' >> "$D/clientdocs/sweep-receipt.txt"
                              run 1 'L7 .*malformed line' "T17 L7 malformed receipt line FAILS" "$D"

# clientdocs/scripts/* is auto-covered like clientdocs/*.md (starter-kit files)
D=$(mkcd l7i); rec "$D"; mkdir -p "$D/clientdocs/scripts"
printf '#!/usr/bin/env bash\necho smoke\n' > "$D/clientdocs/scripts/smoke.sh"
                              run 1 'L7 tenant-facing clientdocs/scripts/smoke.sh is not in the sweep receipt' \
                                    "T18 L7 uncovered clientdocs/scripts file FAILS" "$D"
D=$(mkcd l7j); mkdir -p "$D/clientdocs/scripts"
printf '#!/usr/bin/env bash\necho smoke\n' > "$D/clientdocs/scripts/smoke.sh"; rec "$D"
                              run 0 'PASS: repo lint' "T19 L7 recorded clientdocs/scripts file PASSES" "$D"
D=$(mkcd l7k); mkdir -p "$D/clientdocs/scripts"
printf '#!/usr/bin/env bash\necho smoke\n' > "$D/clientdocs/scripts/smoke.sh"; rec "$D"
printf 'echo changed\n' >> "$D/clientdocs/scripts/smoke.sh"
                              run 1 'L7 clientdocs/scripts/smoke.sh changed since the recorded clientdocs sweep' \
                                    "T20 L7 clientdocs/scripts drift FAILS" "$D"
# *.md in ANY clientdocs subdir is auto-covered (tenant-skill/ package)
D=$(mkcd l7l); rec "$D"; mkdir -p "$D/clientdocs/tenant-skill/references"
printf '# skill ref\n' > "$D/clientdocs/tenant-skill/references/ops.md"
                              run 1 'L7 tenant-facing clientdocs/tenant-skill/references/ops.md is not in the sweep receipt' \
                                    "T21 L7 uncovered clientdocs subdir .md FAILS" "$D"
D=$(mkcd l7m); mkdir -p "$D/clientdocs/tenant-skill/references"
printf '# skill ref\n' > "$D/clientdocs/tenant-skill/references/ops.md"; rec "$D"
                              run 0 'PASS: repo lint' "T22 L7 recorded subdir .md PASSES" "$D"
# .claude/ (agent worktrees, hooks) is session-local, never linted
D=$(mkcd l1c); rec "$D"; mkdir -p "$D/.claude/worktrees/agent-x/docs"
printf '# em\xe2\x80\x94dash noise\n' > "$D/.claude/worktrees/agent-x/docs/design-decisions.md"
                              run 0 'PASS: repo lint' "T23 .claude/ contents excluded from lint" "$D"

echo; echo "RESULT: PASS=$PASS FAIL=$FAIL"
[[ "$FAIL" -eq 0 ]] && { echo "ALL PASS"; exit 0; } || exit 1