Some checks failed
continuous-integration/drone/push Build is failing
Enrolls wordpress as a maintained recipe (operator request 2026-08-03): - tests/wordpress/: recipe_meta (install-wizard-aware health 200/302, 900s deploy timeout for mariadb+core-copy first boot, WARM_CANONICAL), custom suite: health check, install-wizard completion + REST API round-trip (?rest_route= vs /wp-json/ splits DB vs .htaccess failure layers), and the sec4.3 post round-trip (XML-RPC write -> REST read -> permalink HTML, unique marker). PARITY.md documents the baseline (no recipe-maintainer parity corpus for wordpress). - nix/modules/bridge.nix: POLL_REPOS += recipe-maintainers/wordpress (!testme bridge enrollment; deploy to the cc-ci host follows separately after the in-flight /upgrade-all run - test-before-switch policy). Mirror recipe-maintainers/wordpress created + main synced to coopcloud upstream (adcd0e9f) with published tags. used-recipes.md gains 'wordpress weekly' in the orchestrator repo.
86 lines
3.4 KiB
Python
86 lines
3.4 KiB
Python
"""Shared wordpress test helper — install-wizard client + admin credentials.
|
|
|
|
A fresh CI deploy of the recipe does NOT run `core_install` (no POST_DEPLOY_CMDS in the CI
|
|
env), so the app serves the WP install wizard until something completes it. The custom tests
|
|
complete it here (run-scoped class-B credentials; the whole app — DB volume + secrets — is
|
|
destroyed at teardown) and then exercise the real APIs (wp-json + XML-RPC) as an installed
|
|
site. `ensure_installed` is idempotent so any custom test can call it first regardless of
|
|
alphabetical ordering.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import ssl
|
|
import urllib.error
|
|
import urllib.parse
|
|
import urllib.request
|
|
|
|
# Per-run *.ci.commoninternet.net domains use the operator wildcard cert via the Traefik file
|
|
# provider; the real-cert chain check is done once in the generic install assertion.
|
|
_CTX = ssl.create_default_context()
|
|
_CTX.check_hostname = False
|
|
_CTX.verify_mode = ssl.CERT_NONE
|
|
|
|
ADMIN_USER = "ccci-admin"
|
|
ADMIN_PW = "Ccci-Wp-Test-Pw-2026!x" # strong so the wizard needs no pw_weak confirmation
|
|
ADMIN_EMAIL = "ccci-admin@ccci.example.com"
|
|
BLOG_TITLE = "CCCI Test Site"
|
|
|
|
|
|
def _open(url: str, data: bytes | None = None, timeout: int = 60) -> tuple[int, str]:
|
|
req = urllib.request.Request(url, data=data)
|
|
if data is not None:
|
|
req.add_header("Content-Type", "application/x-www-form-urlencoded")
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=timeout, context=_CTX) as resp:
|
|
return resp.getcode(), resp.read().decode(errors="replace")
|
|
except urllib.error.HTTPError as e:
|
|
try:
|
|
return e.code, e.read().decode(errors="replace")
|
|
except Exception: # noqa: BLE001
|
|
return e.code, ""
|
|
|
|
|
|
def fetch_text(url: str, timeout: int = 60) -> tuple[int, str]:
|
|
"""GET a URL and return (status, body-text) — for HTML-content assertions."""
|
|
return _open(url, timeout=timeout)
|
|
|
|
|
|
def ensure_installed(domain: str) -> bool:
|
|
"""Complete the WP install wizard if it hasn't been completed yet.
|
|
|
|
Returns True if THIS call ran the install, False if the site was already installed.
|
|
Fails the calling test (assert) if the wizard is reachable but the install POST fails.
|
|
"""
|
|
base = f"https://{domain}"
|
|
status, body = _open(f"{base}/wp-admin/install.php")
|
|
assert status == 200, f"GET /wp-admin/install.php HTTP {status} (body[:200]={body[:200]!r})"
|
|
if "already installed" in body.lower():
|
|
return False
|
|
assert "wordpress" in body.lower(), (
|
|
f"/wp-admin/install.php does not look like the WP installer: {body[:300]!r}"
|
|
)
|
|
assert "database connection" not in body.lower(), (
|
|
"WP installer reports a database connection problem — app→mariadb wiring is broken"
|
|
)
|
|
|
|
form = urllib.parse.urlencode(
|
|
{
|
|
"weblog_title": BLOG_TITLE,
|
|
"user_name": ADMIN_USER,
|
|
"admin_password": ADMIN_PW,
|
|
"admin_password2": ADMIN_PW,
|
|
"admin_email": ADMIN_EMAIL,
|
|
"blog_public": "1",
|
|
"Submit": "Install WordPress",
|
|
"language": "",
|
|
}
|
|
).encode()
|
|
status, body = _open(f"{base}/wp-admin/install.php?step=2", data=form, timeout=180)
|
|
assert status == 200, f"install POST HTTP {status} (body[:300]={body[:300]!r})"
|
|
lowered = body.lower()
|
|
assert "success" in lowered or "wordpress has been installed" in lowered, (
|
|
f"install POST did not report success: {body[:400]!r}"
|
|
)
|
|
return True
|