91 lines
3.2 KiB
Python
Executable File
91 lines
3.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Verification for the workqueue-census artifact.
|
|
|
|
Re-derives the census from the authoritative source WORK-QUEUE.md, compares it
|
|
against the committed workqueue-census.tsv, and checks manifest.json's
|
|
self-reported statistics against the actual artifact. Exits 0 only if every
|
|
check passes.
|
|
"""
|
|
import csv
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
REPO_ROOT = os.path.abspath(os.path.join(HERE, "..", "..", ".."))
|
|
SRC = os.path.join(REPO_ROOT, "WORK-QUEUE.md")
|
|
TSV = os.path.join(HERE, "workqueue-census.tsv")
|
|
MD = os.path.join(HERE, "workqueue-census.md")
|
|
MANIFEST = os.path.join(HERE, "manifest.json")
|
|
|
|
sys.path.insert(0, HERE)
|
|
import extract_workqueue_census as extractor # noqa: E402
|
|
|
|
fails = []
|
|
|
|
|
|
def check(name, cond, detail=""):
|
|
if cond:
|
|
print("PASS " + name)
|
|
else:
|
|
print("FAIL " + name + " " + repr(detail))
|
|
fails.append(name)
|
|
|
|
|
|
# 1. Re-derive from the authoritative source.
|
|
with open(SRC, encoding="utf-8") as fh:
|
|
src_lines = fh.read().splitlines()
|
|
fresh_rows, prepends = extractor.extract(src_lines)
|
|
|
|
# 2. Parse the committed TSV.
|
|
with open(TSV, encoding="utf-8", newline="") as fh:
|
|
committed = list(csv.reader(fh, delimiter="\t"))
|
|
header, committed_rows = committed[0], committed[1:]
|
|
|
|
check("tsv header", header == ["q", "title", "status", "done_implies"], repr(header))
|
|
|
|
check("row count", len(committed_rows) == len(fresh_rows),
|
|
"committed=%d fresh=%d" % (len(committed_rows), len(fresh_rows)))
|
|
|
|
if len(committed_rows) == len(fresh_rows):
|
|
mism = [i for i, (a, b) in enumerate(zip(fresh_rows, committed_rows)) if list(a) != list(b)]
|
|
check("rows identical to fresh re-derive", not mism,
|
|
"first mismatch idx %s" % mism[:1])
|
|
|
|
# 3. Manifest self-consistency.
|
|
with open(MANIFEST, encoding="utf-8") as fh:
|
|
man = json.load(fh)
|
|
|
|
distinct = sorted({r[0] for r in fresh_rows})
|
|
reopened = sorted(q for q in distinct if sum(1 for r in fresh_rows if r[0] == q) > 1)
|
|
|
|
check("manifest.rows", man.get("rows") == len(fresh_rows),
|
|
"manifest=%r actual=%d" % (man.get("rows"), len(fresh_rows)))
|
|
check("manifest.distinct_q_labels",
|
|
man.get("distinct_q_labels") == len(distinct),
|
|
"manifest=%r actual=%d" % (man.get("distinct_q_labels"), len(distinct)))
|
|
check("manifest.reopened_q_labels", man.get("reopened_q_labels") == reopened,
|
|
"manifest=%r actual=%r" % (man.get("reopened_q_labels"), reopened))
|
|
check("manifest.columns",
|
|
man.get("columns") == ["q", "title", "status", "done_implies"],
|
|
repr(man.get("columns")))
|
|
|
|
# 4. Markdown table round-trip (data rows == fresh rows).
|
|
md_lines = open(MD, encoding="utf-8").read().splitlines()
|
|
md_data_rows = [l for l in md_lines if l.startswith("| Q")]
|
|
check("md data rows", len(md_data_rows) == len(fresh_rows),
|
|
"md=%d fresh=%d" % (len(md_data_rows), len(fresh_rows)))
|
|
|
|
# 5. No empty q or title in the committed artifact.
|
|
empty = [r for r in committed_rows if not r[0] or not r[1]]
|
|
check("no empty q/title", not empty, repr(empty[:1]))
|
|
|
|
if fails:
|
|
print("")
|
|
print("%d check(s) FAILED" % len(fails))
|
|
sys.exit(1)
|
|
|
|
print("")
|
|
print("ALL CHECKS PASSED (%d rows, %d distinct labels, %d prepends)"
|
|
% (len(fresh_rows), len(distinct), prepends))
|