# Parity — gitea (phase gtea) Phase-gtea P2 mapping table. The Adversary cold-verifies parity by reading the source `recipe-info/gitea/tests/` 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://`). 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`: creates `ci_admin` user + `ci-marker` repo (auto_init → README.md commit) - `pre_upgrade`: re-asserts marker exists before chaos redeploy - `pre_backup`: re-asserts marker exists before backup - `pre_restore`: DELETES marker (diverges from backup state) - `test_upgrade`: asserts marker survived upgrade (sqlite3 continuity) - `test_backup`: asserts marker present at backup time - `test_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: 1. `compose.lfs.yml` exists in `$ABRA_DIR/recipes/gitea/` — only true on the `lfs-plain-gitea` PR branch (not on `main`). 2. `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.