Files
cc-ci/runner/adv_quickfail_verify.py

50 lines
3.0 KiB
Python

#!/usr/bin/env python3
"""ADVERSARY: after the --quick FAIL run, independently verify the rollback restored the EXACT
known-good (data + healthy app), the known-good was NOT promoted, then leave idle."""
import os, subprocess, sys, hashlib
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from harness import canonical, lifecycle, warmsnap
R="custom-html"; D="warm-custom-html.ci.commoninternet.net"; HTML="/usr/share/nginx/html"
KG_STR="WC2-DATA-MARKER-7f3a9c"; BASE_SNAP_SHA="9ef62bdf11c6060c"
fails=[]
def sh(*c): return lifecycle.exec_in_app(D, list(c), service="app")
def snap_sha():
import glob
t=glob.glob(f"/var/lib/ci-warm/{R}/snapshot/volumes/*.tar")
return hashlib.sha256(open(t[0],"rb").read()).hexdigest()[:16] if t else "NONE"
def code(p):
return subprocess.run(["curl","-sk","--resolve",f"{D}:443:127.0.0.1","-o","/dev/null","-w","%{http_code}",
"--max-time","10",f"https://{D}{p}"],capture_output=True,text=True).stdout.strip()
reg=canonical.read_registry(R) or {}
ssha=snap_sha()
print(f"registry version={reg.get('version')} status={reg.get('status')} snapshot_sha={ssha} (baseline {BASE_SNAP_SHA})")
if reg.get('version')!="1.11.0+1.29.0": fails.append(f"known-good promoted/changed: {reg.get('version')}")
if reg.get('status')!="idle": fails.append(f"not idle: {reg.get('status')}")
if ssha!=BASE_SNAP_SHA: fails.append(f"snapshot changed: {ssha} != {BASE_SNAP_SHA}")
# bring canonical up, confirm restored data + healthy + non-broken image
canonical.deploy_canonical(R)
lifecycle.wait_healthy(D, ok_codes=(200,), path="/", deploy_timeout=300, http_timeout=20)
html=sh("ls",HTML).split()
kg_files=[f for f in html if f=="wc2-marker.txt"]
kg_content=sh("cat",f"{HTML}/wc2-marker.txt").strip() if kg_files else ""
img=subprocess.run(["docker","service","ls","--format","{{.Name}} {{.Image}}"],capture_output=True,text=True).stdout
serving=code("/")
print(f"AFTER deploy: html={html} kg_content={kg_content!r} serving/={serving}")
print(f"image: {[l for l in img.splitlines() if 'custom-html' in l]}")
if not kg_files: fails.append("rollback did NOT restore known-good marker file")
if KG_STR not in kg_content: fails.append(f"restored marker content wrong: {kg_content!r}")
if serving!="200": fails.append(f"rolled-back app not serving 200: {serving}")
if "99.99.99-doesnotexist" in img: fails.append("BROKEN image still deployed after rollback")
if "nginx:1.29.0" not in img: fails.append(f"canonical not on known-good image: {img!r}")
# leave idle
canonical.undeploy_keep_volume(R)
print(f"END status={(canonical.read_registry(R) or {}).get('status')} "
f"service={'custom-html' in subprocess.run(['docker','service','ls','--format','{{.Name}}'],capture_output=True,text=True).stdout}")
print("\nRESULT:", "FAIL: "+"; ".join(fails) if fails else
"PASS — --quick FAIL rolled back to EXACT known-good (marker+content restored, app healthy on nginx:1.29.0, broken image gone), known-good UNCHANGED+snapshot byte-identical (never promoted); left idle")
sys.exit(1 if fails else 0)