- tests/gitea/recipe_meta.py: updated from dep-provider stub to dual-role (dep + recipe-under-test).
Adds BACKUP_CAPABLE=True, READY_PROBE (/api/v1/version), SCREENSHOT (sign-in page), LFS-
conditional EXTRA_ENV (compose.lfs.yml + GITEA_LFS_START_SERVER only when RECIPE=gitea AND
overlay present — dep path unchanged). All existing dep keys preserved; 10/10 dep unit tests pass.
- tests/gitea/ops.py: NEW — admin user creation via gitea CLI (ci_admin, creds in /tmp per-domain
file), marker repo lifecycle (pre_install/pre_upgrade/pre_backup create; pre_restore deletes to
diverge from backup state).
- tests/gitea/test_{install,upgrade,backup,restore}.py: NEW — lifecycle overlays. Install checks
API + admin auth + Playwright sign-in. Upgrade/backup/restore assert marker repo continuity.
- tests/gitea/custom/: NEW — test_health.py (parity: HTTP 200 root), test_git_push.py (parity:
create→clone→push→verify→delete), test_admin_api.py (beyond-parity: user+org+token CRUD),
test_lfs_roundtrip.py (LFS OID round-trip + JWT stability; skips on main, runs on PR #1 head).
- tests/gitea/PARITY.md: NEW — mapping table, source note (recipe-info corpus not upstream repo),
beyond-parity rationale, backup/restore real-tier note, DB choice, dep-split mechanism, LFS skip.
- machine-docs/STATUS-gtea.md: NEW — phase status (building M1).
- machine-docs/BACKLOG-gtea.md: merged with Adversary init.
- machine-docs/JOURNAL-gtea.md: Builder log with design decisions + unit test results.
- machine-docs/REVIEW-gtea.md: kept Adversary init content.
- machine-docs/DECISIONS.md: appended gtea section (LFS split, admin mgmt, marker design).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.0 KiB
Parity — gitea (phase gtea)
Phase-gtea P2 mapping table. The Adversary cold-verifies parity by reading the source
recipe-info/gitea/tests/<file> and the cc-ci file side-by-side.
Source note: recipe-maintainers/gitea (git.autonomic.zone) has no tests/ directory on
main or lfs-plain-gitea. The reference tests exist ONLY in the local
references/recipe-maintainer/recipe-info/gitea/tests/ corpus (the recipe-info collection kept on
the orchestrator VM for parity reference). They are not part of the upstream recipe repo itself.
The cc-ci implementations are ports of those reference tests, not of upstream recipe-repo tests.
| recipe-info source file | cc-ci file | what's verified | status |
|---|---|---|---|
references/recipe-maintainer/recipe-info/gitea/tests/health_check.py |
tests/gitea/custom/test_health.py |
HTTP 200 from the root URL (https://<domain>). Original: resolves domain from testsecrets/. cc-ci port: uses live_app fixture (ephemeral per-run domain). Assertion shape preserved. |
ported from recipe-info corpus |
references/recipe-maintainer/recipe-info/gitea/tests/git_push.py |
tests/gitea/custom/test_git_push.py |
Create repo via API → clone → commit → push over HTTPS → verify commit landed via API → delete. Original: reads admin creds from CLI args/testsecrets. cc-ci port: admin creds from ops.admin_creds() (the ci_admin user created by ops.pre_install). Full SCM round-trip exercised. |
ported from recipe-info corpus |
Recipe-specific tests (≥2 beyond parity)
| cc-ci file | what's verified | rationale |
|---|---|---|
tests/gitea/custom/test_admin_api.py |
Beyond-parity. Admin API CRUD lifecycle: create user + org + API token → read-back via the generated token (authenticates as test user) → delete all. Tests two distinct auth paths (admin basic-auth + user token). | Proves the full admin-API contract: user management, org management, and token issuance. Non-vacuous: a broken DB or broken API router fails at least one assertion. Not covered by any upstream recipe-info test. |
tests/gitea/custom/test_lfs_roundtrip.py |
Beyond-parity + PR #1 capstone. Git LFS object upload→download OID round-trip + JWT-secret stability across abra app restart. Skips when compose.lfs.yml is absent (gitea main — LFS not deployed). Runs and must pass on lfs-plain-gitea (PR #1 head). |
The mechanism that PROVES PR #1: red/skipped on main (feature absent), green on PR head (feature present). A rotating JWT secret fails the stability assertion (the exact regression the PR fixes). See §3 of the phase plan. |
Backup / restore — REAL tiers
compose.yml carries backupbot.backup=true labels. BACKUP_CAPABLE = True is set explicitly
in recipe_meta.py. Backup and restore are REAL tiers (not N/A skips). Data integrity is proved
by the marker-repo mechanism (see ops.py):
pre_install: createsci_adminuser +ci-markerrepo (auto_init → README.md commit)pre_upgrade: re-asserts marker exists before chaos redeploypre_backup: re-asserts marker exists before backuppre_restore: DELETES marker (diverges from backup state)test_upgrade: asserts marker survived upgrade (sqlite3 continuity)test_backup: asserts marker present at backup timetest_restore: asserts marker returned (restore reverted deletion — non-vacuous: a no-op restore leaves it absent)
Database choice
sqlite3 (compose.sqlite3.yml) — matches the dep config (drone uses gitea with sqlite3), minimal
footprint. No MariaDB/Postgres dependency needed for the CI test suite.
Dep-vs-recipe-under-test split (§2 of phase plan)
EXTRA_ENV(ctx) applies to BOTH roles (dep deploy for drone AND recipe-under-test). The split
mechanism uses TWO conditions to guard LFS-overlay activation:
compose.lfs.ymlexists in$ABRA_DIR/recipes/gitea/— only true on thelfs-plain-giteaPR branch (not onmain).RECIPE=gitea— set by the orchestrator only when gitea is the recipe-under-test.
Both conditions required: this ensures the dep path is byte-for-byte identical regardless of whether the LFS PR branch is checked out, and ensures recipe-under-test with LFS overlay doesn't accidentally activate for a dep deploy on the PR branch. Documented in DECISIONS.md (phase gtea).
LFS capstone — EXPECTED_NA on main
The LFS test (test_lfs_roundtrip.py) uses pytest.skip() when compose.lfs.yml is absent:
Skips when compose.lfs.yml absent in gitea recipe checkout — LFS is not enabled on this branch.
This test runs on lfs-plain-gitea (PR #1) and is EXPECTED_NA on main.
No EXPECTED_NA key in recipe_meta.py because this is a custom-tier test that self-skips, not
a lifecycle rung. The phase M1 gate (suite green on main) is met WITH the LFS test skipped.
The phase M2 gate requires the LFS test GREEN on the lfs-plain-gitea PR head.
Screenshot
SCREENSHOT hook in recipe_meta.py navigates to /user/login — the sign-in page. This is
credential-free and shows the gitea UI (form, branding). Default capture covers the install tier.