Catalog: setup.mirror and logs.tree-tail-export leave; the catalog's address in forgetest-ci

Two catalog tests leave for the host proofs that carry them; the catalog
goes from 83 to 81 (81 @test in forgetest/forgetest/suite/).

- setup.mirror, for forgectrl's tests/host_ext.sh (0086e65): with a
  temporary account and two logins, a package's check that session A
  starts is owned and A's, owned and not B's, and the token's with no
  session; B's abort is 409 and the run goes on; B's takeover makes it
  B's; B's abort ends it aborted. Its section header, "the lifecycle",
  held only it. setup.check-sensors and setup.account-login stay.
- logs.tree-tail-export, for forgectrl's tests/host_guard.sh (0086e65):
  GET /logs names forgectrl, the tail carries a line just written, an
  unknown logger is 404, and the export carries README.txt, the
  installer's directory (a probe without its MAC or IP address, and
  install.log) and system/extensions.json, with neither the panel token
  nor the camera key in any member. _LOG_COVERS, the _PROBE_ constants,
  and the gzip, io, and tarfile imports, which only it read, go, and so
  does logs.routing's requires on it. logs.routing stays.

forgectrl.lease stays. Its proof passed (forgectrl's tests/host_lease.sh,
0086e65), but its deletion left forgectrl src/events.c and src/events.h
uncovered, a path outside the two this chunk may row, so it does not
land.

The coverage lint then named forgectrl src/sanitize.c, src/sanitize.h,
src/extpkg.c and src/extpkg.h, and nothing else. Two HOST_TESTED rows
take them, to forgectrl:tests/sanitize_test.c and
forgectrl:tests/extpkg_test.c on forgectrl:.github/workflows/build.yml,
which the pin c274f19 runs (./build/sanitize_test, ./build/extpkg_test).

forgetest-ci, after the tree-manifest step: the key comparison moves
there unchanged, and a step beside it checks the catalog's address.
From forgectrl-pin.inc's SRCREV it reads src/extpkg.h out of the
manifest cache (git show) and takes EXTPKG_INDEX_URL; from the
checked-out catalog's tools/publish.py it takes the basename of the file
passed to gh release create; the define must be exactly
https://github.com/openglow-org/forgefirm-extensions-catalog/releases/latest/download/
and that basename. A missing pin, define, or basename fails. Nothing
requests the address or fetches the asset. The step's run text, taken
from the workflow, passes from the tree root (c274f19's address and
index-1.ffi) and on a /tmp copy of the tree; controls on that copy,
publish.py passing index-2.ffi and extpkg.h naming another repository:
each fails the comparison. The key step's text is unchanged and was not
run again.

test_manifest.py (34) passes. The coverage lint on the tree manifest
finds no uncovered path and no host-tested row problem across the 81
tests; its one finding is setup.check-lens's empty src/lensfind.*
entry. pyflakes reports nothing on setup.py, logs.py or manifest.py.
The full forgetest suite was not run.

Fingerprints, measured against the parent: 23 tests move with
setup.py's and logs.py's shared text: the 5 left in setup.py, the 12 in
the modules that read setup.py (setup_dark.py's 9, setup_burns.py's 2,
bedsize.py's setup.check-envelope), the 5 left in exthost.py, which
reads it too, and logs.routing. The pending pin bumps from forgectrl
c274f19 and forgeext 2d0391e already owe 21 of them, and
exthost.platform has been owed since 30c0a05. This adds one:
setup.machine-name, which no pinned change selects. releases/ and
TEST-AUDIT.md are unchanged.
This commit is contained in:
ScottW514
2026-10-14 17:09:32 -04:00
parent b90299acdc
commit 70e13bdd88
4 changed files with 75 additions and 241 deletions
+64 -7
View File
@@ -14,6 +14,10 @@
# - the extension key: the public key the image installs for the official
# tier is byte-identical to the one the extension catalog publishes
# (keys/forgefirm-ext.pub on its main branch)
# - the catalog's address: EXTPKG_INDEX_URL in the pinned forgectrl's
# src/extpkg.h is the catalog's latest-release download of the file its
# tools/publish.py passes to gh release create; read, never requested
# (every request of it is counted as a download)
# - coverage lint: every source path of every component pinned by the
# recipes must be selected by some catalog test's coverage globs or by a
# host-tested row naming the host test that proves it (the tree manifest
@@ -60,6 +64,15 @@ jobs:
ref: main
path: forgefirm-extensions-catalog
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Tree manifest from the recipe pins (also fetches the pinned app sources the needle check reads)
working-directory: forgefirm
run: python scripts/manifest-from-tree.py --out tree-manifest.json
- name: The image's extension key is the catalog's published key
run: |
image=forgefirm/meta-forgefirm/recipes-forgefirm/forgefirm-keys/files/ext/forgefirm-ext.pub
@@ -69,14 +82,58 @@ jobs:
done
cmp -s "$image" "$published" || { echo "$image is not $published"; exit 1; }
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: The catalog's address in the pinned forgectrl is the file the catalog publishes (read, never requested)
run: |
python3 - <<'EOF'
import ast, glob, os, re, subprocess, sys
- name: Tree manifest from the recipe pins (also fetches the pinned app sources the needle check reads)
working-directory: forgefirm
run: python scripts/manifest-from-tree.py --out tree-manifest.json
PREFIX = "https://github.com/openglow-org/forgefirm-extensions-catalog/releases/latest/download/"
def fail(why):
print(why)
sys.exit(1)
# forgectrl's pin, and its src/extpkg.h from the tree manifest's cache
pin = open("forgefirm/meta-forgefirm/recipes-forgefirm/forgectrl/forgectrl-pin.inc").read()
m = re.search(r'^SRCREV = "([0-9a-f]{40})"$', pin, re.M)
if not m:
fail("forgectrl-pin.inc names no SRCREV")
rev = m.group(1)
header = None
for repo in sorted(glob.glob("forgefirm/.manifest-cache/*")):
p = subprocess.run(["git", "-C", repo, "show", rev + ":src/extpkg.h"], capture_output=True, text=True)
if p.returncode == 0:
header = p.stdout
break
if header is None:
fail("forgectrl %s is not in forgefirm/.manifest-cache" % rev)
m = re.search(r'#define\s+EXTPKG_INDEX_URL\s*(?:\\\n\s*)?"([^"]*)"', header)
if not m:
fail("forgectrl %s's src/extpkg.h defines no EXTPKG_INDEX_URL" % rev[:7])
url = m.group(1)
# the file the catalog's publish tool passes to gh release create
tree = ast.parse(open("forgefirm-extensions-catalog/tools/publish.py").read())
assigned = {n.targets[0].id: n.value for n in ast.walk(tree)
if isinstance(n, ast.Assign) and len(n.targets) == 1 and isinstance(n.targets[0], ast.Name)}
def file_name(v):
if isinstance(v, ast.Name):
v = assigned.get(v.id)
if isinstance(v, ast.Call) and v.args:
v = v.args[-1]
return os.path.basename(v.value) if isinstance(v, ast.Constant) and isinstance(v.value, str) else None
names = [file_name(n.args[3]) if len(n.args) > 3 else None for n in ast.walk(tree)
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and n.func.id == "gh"
and [a.value for a in n.args[:2] if isinstance(a, ast.Constant)] == ["release", "create"]]
if len(names) != 1 or not names[0]:
fail("tools/publish.py passes no one file to gh release create: %s" % names)
print("forgectrl %s: %s; the catalog publishes %s" % (rev[:7], url, names[0]))
if url != PREFIX + names[0]:
fail("the address is not %s" % (PREFIX + names[0]))
EOF
- name: Unit tests
working-directory: forgefirm/forgetest