From b4f39cb51ab5c6970a77f515bd75240e2770cef7 Mon Sep 17 00:00:00 2001 From: autonomic-bot Date: Fri, 29 May 2026 18:13:20 +0100 Subject: [PATCH] =?UTF-8?q?fix(2):=20plausible=20install=20overlay=20?= =?UTF-8?q?=E2=80=94=20assert=20/api/health=20subsystems,=20not=20`/`=20(a?= =?UTF-8?q?uth=5Fcontroller=20500s=20under=20headless=20DISABLE=5FAUTH;=20?= =?UTF-8?q?/=20is=20not=20a=20valid=20readiness=20probe)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- tests/plausible/test_install.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/tests/plausible/test_install.py b/tests/plausible/test_install.py index 3fe3e06..c30725c 100644 --- a/tests/plausible/test_install.py +++ b/tests/plausible/test_install.py @@ -1,13 +1,32 @@ -"""plausible — INSTALL overlay (Phase 1d): reuse generic serving, then assert the SPA shell serves.""" +"""plausible — INSTALL overlay (Phase 1d): reuse generic serving, then assert plausible's own +/api/health reports BOTH datastores + the sites_cache as ready. + +We do NOT probe `/`: under the headless CI config (DISABLE_AUTH=true, no user) plausible's `/` +auth_controller 500s (it tries to render a dashboard for a non-existent session/user), so `/` is not +a valid readiness signal. /api/health is plausible's dedicated readiness endpoint and is a STRONGER +assertion than a bare status code — it confirms the postgres metadata store, the ClickHouse events +store, and the in-memory sites_cache are all reachable, which is exactly what "installed and serving" +means for an analytics app.""" import os import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "runner")) -from harness import generic, lifecycle # noqa: E402 +from harness import generic # noqa: E402 +from harness import http as harness_http # noqa: E402 def test_serving(live_app, meta): generic.assert_serving(live_app, meta) - status = lifecycle.http_get(live_app, "/") - assert status in (200, 301, 302), f"expected 2xx/3xx from {live_app}, got {status}" + + # plausible-specific readiness: /api/health -> 200 with every subsystem "ok". + status, body = harness_http.retry_http_get( + f"https://{live_app}/api/health", expect_status=(200,), max_wait=60, interval=3 + ) + assert status == 200, f"/api/health on {live_app} returned HTTP {status} (expected 200)" + assert isinstance(body, dict), f"/api/health body is not JSON object: {body!r}" + for subsystem in ("clickhouse", "postgres", "sites_cache"): + assert body.get(subsystem) == "ok", ( + f"/api/health subsystem {subsystem!r} = {body.get(subsystem)!r} (expected 'ok'); " + f"full body: {body!r}" + )