Files
owui-tools/tests/test_vm_release_contents.py
2026-09-15 15:24:03 -04:00

182 lines
7.5 KiB
Python

#!/usr/bin/env python3
"""A release carries the work, not the debris left beside it.
python3 tests/test_vm_release_contents.py
WHAT WENT WRONG, MEASURED
Release `v3` of the project `windows-troubleshooting-toolkit` held ten
files:
_build.ps1 _launch.bat _structcheck.ps1 _w_diagnostics.ps1
_w_network.ps1 _w_performance.ps1 _w_system.ps1 check_disp.ps1
check_disp2.ps1 check_disp3.ps1
Every one of them scratch, and not one of them the 34 KB
`TroubleshootingToolkit.ps1` the session had been asked to build. Two
causes, compounding: `git add -A` commits whatever the agent left lying
in the project folder, and the asset list sorts `_build` ahead of
`TroubleshootingToolkit` before stopping at ten.
WHY THE FIX IS AT THE COMMIT AND NOT AT THE RELEASE
Gitea builds a release's "Source code (zip)" from the tree its tag points
at, and that archive is the only thing on the page that downloads -
measured, `Content-Disposition: attachment`, where every uploaded asset
including a `.zip` comes back `inline`. So curating the asset list alone
would leave the actual download full of scratch. Filtering at the commit
cleans the repository, the assets and the archive together.
THE RISK THIS FILTER CARRIES, AND THE TWO GUARDS ON IT
Excluding by name can exclude the wrong thing. So: the patterns stay
narrow enough that `find_duplicates.py` and `Check-AutoStartServices.ps1`
- both real deliverables from real sessions - survive; a project that
would otherwise publish nothing at all publishes everything instead,
because then the tests were the job; and whatever is held back is named
back to the agent in tool output.
"""
import os
import subprocess
import sys
import tempfile
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(HERE, "..", "vm", "vmd"))
import gitea # noqa: E402
FAILS: list[str] = []
def check(label: str, condition: bool, detail: str = "") -> None:
if condition:
print(f"ok {label}")
else:
FAILS.append(f"{label}: {detail}")
print(f"FAIL {label}\n {detail}")
def make_tree(root: str, names: list[str]) -> None:
for name in names:
full = os.path.join(root, name)
os.makedirs(os.path.dirname(full), exist_ok=True)
with open(full, "w") as handle:
handle.write("x\n")
def committed(repo: str) -> set[str]:
result = gitea._git(repo, "ls-tree", "-r", "--name-only", "HEAD")
return {n for n in result.stdout.split("\n") if n}
# --- the session that went wrong, rebuilt ---------------------------------
#
# The real file list from that project, verbatim.
TOOLKIT = "TroubleshootingToolkit.ps1"
REAL_SESSION = [
TOOLKIT,
"_build.ps1", "_launch.bat", "_structcheck.ps1", "_w_diagnostics.ps1",
"_w_network.ps1", "_w_performance.ps1", "_w_system.ps1",
"check_disp.ps1", "check_disp2.ps1", "check_disp3.ps1",
"csharp_out.txt", "csharp_thread.txt", "smoke.ps1", "t_out.txt",
"test_concurrency.ps1", "test_cs.cs", "test_cs.exe", "test_job.ps1",
"test_net.ps1", "test_thread.ps1", "test_pump.ps1",
]
with tempfile.TemporaryDirectory() as tmp:
repo = os.path.join(tmp, "windows-troubleshooting-toolkit")
os.makedirs(repo)
make_tree(repo, REAL_SESSION)
gitea.init(repo, "windows-troubleshooting-toolkit")
skipped = gitea.held_back(repo)
check("the toolkit is not held back", TOOLKIT not in skipped, str(skipped[:5]))
for name in ("_build.ps1", "_w_system.ps1", "test_cs.exe", "test_job.ps1",
"smoke.ps1", "t_out.txt"):
check(f"held back: {name}", name in skipped, f"held back: {skipped}")
sha = gitea.commit(repo, "the session's work")
check("the commit happened", bool(sha), f"returned {sha!r}")
tree = committed(repo)
check("THE DELIVERABLE IS IN THE RELEASE", TOOLKIT in tree,
"this is the exact failure: the release did not contain the toolkit")
check("and the scratch is not",
not ({"_build.ps1", "test_cs.exe", "smoke.ps1"} & tree),
f"committed: {sorted(tree)}")
assets = gitea.tracked_files(repo, limit=gitea.RELEASE_ASSETS_MAX)
# `check_disp*.ps1` and `csharp_thread.txt` survive, and that is the
# deliberate half of the trade: the patterns stay narrow enough that
# `check_disk.py` from a "check disk health" job would survive too.
# What matters is that the deliverable can no longer be crowded out.
check("THE DELIVERABLE IS AN ASSET", TOOLKIT in assets, str(assets))
check("and the cap can no longer push it out",
len(assets) < gitea.RELEASE_ASSETS_MAX, f"{len(assets)} assets")
check("scratch alone is not a reason to commit again",
not gitea.has_changes(repo),
"a tree holding only untracked scratch has nothing to publish")
# --- the guard against excluding a real deliverable ------------------------
with tempfile.TemporaryDirectory() as tmp:
repo = os.path.join(tmp, "dup-finder")
os.makedirs(repo)
# Both of these are real deliverables from real sessions, and both
# read as scratch to a filter that is one pattern too greedy.
make_tree(repo, ["find_duplicates.py", "Check-AutoStartServices.ps1",
"README.md", "latest/notes.md", "src/main.py"])
gitea.init(repo, "dup-finder")
gitea.commit(repo, "work")
tree = committed(repo)
for name in ("find_duplicates.py", "Check-AutoStartServices.ps1",
"README.md", "latest/notes.md", "src/main.py"):
check(f"kept, because it is the work: {name}", name in tree, str(sorted(tree)))
# --- when the tests WERE the job ------------------------------------------
with tempfile.TemporaryDirectory() as tmp:
repo = os.path.join(tmp, "write-some-tests")
os.makedirs(repo)
make_tree(repo, ["test_parser.py", "test_lexer.py"])
gitea.init(repo, "write-some-tests")
gitea.commit(repo, "the tests are the deliverable")
tree = committed(repo)
check("a project with nothing but tests publishes them",
{"test_parser.py", "test_lexer.py"} <= tree,
f"published nothing at all: {sorted(tree)}")
# --- a project resumed after collecting scratch under the old rules --------
with tempfile.TemporaryDirectory() as tmp:
repo = os.path.join(tmp, "resumed")
os.makedirs(repo)
make_tree(repo, ["Toolkit.ps1", "test_old.ps1"])
gitea.init(repo, "resumed")
# Committed the way the previous version of this code would have.
gitea._git(repo, "add", "-A", "--", ".")
subprocess.run(["/usr/bin/git", "-C", repo, *gitea._SAFE_FLAGS,
"commit", "--no-verify", "-q", "-m", "legacy"],
capture_output=True,
env={"PATH": "/usr/bin:/bin", "HOME": "/nonexistent", **gitea._SAFE_ENV},
check=False)
check("the legacy commit really does carry the scratch",
"test_old.ps1" in committed(repo), "the premise of this case is wrong")
check("and the next session notices", gitea.has_changes(repo),
"already-published scratch has to count as something to change")
make_tree(repo, ["Toolkit.ps1"])
gitea.commit(repo, "this session")
tree = committed(repo)
check("a resumed project stops publishing its old scratch",
"test_old.ps1" not in tree and "Toolkit.ps1" in tree, str(sorted(tree)))
check("but the file is still on the array to work with",
os.path.exists(os.path.join(repo, "test_old.ps1")),
"--cached: it stops being published, it is not deleted")
print()
if FAILS:
print(f"{len(FAILS)} failed")
for line in FAILS:
print(" -", line)
sys.exit(1)
print("all release-contents checks passed")