fix(plausible): register a team so v3 ingests events; widen post-restore health wait #17

Merged
autonomic-bot merged 2 commits from fix/plausible-v3-custom-tests into main 2026-08-11 14:52:07 +00:00
Owner

What

plausible's custom tier has been RED since the v3 upgrade PR
(plausible#5), most recently on
build 1224. install, upgrade, backup and restore all pass; only the three custom tests fail.
Both causes are in the tests, not the recipe.

1. v3 only ingests events for a site that belongs to a TEAM

_register_site inserted a row into sites and nothing else. That was sufficient for v2
(plausible/analytics). Under v3 (ghcr.io/plausible/community-edition) a teamless site is not
"known" to the ingestion path, so every event is discarded — while POST /api/event still returns
202 and the postgres row still exists. The only visible symptom is that nothing ever reaches
ClickHouse, which reads as a silent ingestion stall:

AssertionError: event name='pageview' pathname='/ccci-pageview-roundtrip' ... never reached
ClickHouse events_v2 within 210s (last POST status=202, last count=0)

ClickHouse records the real reason itself, in ingest_counters. Verified on cc-ci against v3.2.1,
same site row both times:

site state ingest_counters events_v2
no team (what the test did) dropped_not_found 0
team linked buffered rows land

_register_site now provisions a team and links the site. The block is guarded on the schema
actually having teams + sites.team_id, so it is a no-op on v2 — which matters because the
upgrade tier deploys the older base version first.

2. The post-restore health wait was too short for v3

test_plausible_root_serves waited 60s for /api/health. The custom tier runs after
backup/restore, which disrupts postgres under the app and restarts it, and v3 boots through
sleep 10db createdbdb migrate → cache warmers before health flips to 200. Widened to
300s, still far inside the recipe's own declared HTTP_TIMEOUT = 1200.

What this does NOT do

Neither change weakens an assertion. The event tests still require the row to arrive in ClickHouse
and match what was sent (name, pathname, hostname); the health test still requires a hard 200
from the real readiness endpoint. Only the fixture and the wait changed.

Verification

Full cold suite against the recipe PR head (upgrade-4.0.0+v3.2.1, 867ebfaf) with this branch:

install : pass    upgrade : pass    backup : pass    restore : pass    custom : pass
level=5 of 5
VERDICT: GREEN

All three previously-failing tests pass:
test_pageview_event_roundtrip, test_custom_event_roundtrip, test_plausible_root_serves.

Dependent pair

This is the CI half of a pair. !testme on plausible#5 runs the deployed cc-ci tests, so that PR
stays RED until this one merges. Merge this first, then re-run !testme there.

Not merged by automation — for operator review.

## What `plausible`'s custom tier has been RED since the v3 upgrade PR ([plausible#5](https://git.autonomic.zone/recipe-maintainers/plausible/pulls/5)), most recently on build 1224. `install`, `upgrade`, `backup` and `restore` all pass; only the three custom tests fail. Both causes are in the tests, not the recipe. ### 1. v3 only ingests events for a site that belongs to a TEAM `_register_site` inserted a row into `sites` and nothing else. That was sufficient for v2 (`plausible/analytics`). Under v3 (`ghcr.io/plausible/community-edition`) a teamless site is not "known" to the ingestion path, so every event is discarded — while `POST /api/event` still returns **202** and the postgres row still exists. The only visible symptom is that nothing ever reaches ClickHouse, which reads as a silent ingestion stall: ``` AssertionError: event name='pageview' pathname='/ccci-pageview-roundtrip' ... never reached ClickHouse events_v2 within 210s (last POST status=202, last count=0) ``` ClickHouse records the real reason itself, in `ingest_counters`. Verified on cc-ci against v3.2.1, same site row both times: | site state | `ingest_counters` | `events_v2` | |---|---|---| | no team (what the test did) | `dropped_not_found` | 0 | | team linked | `buffered` | rows land | `_register_site` now provisions a team and links the site. The block is guarded on the schema actually having `teams` + `sites.team_id`, so it is a **no-op on v2** — which matters because the upgrade tier deploys the older base version first. ### 2. The post-restore health wait was too short for v3 `test_plausible_root_serves` waited **60s** for `/api/health`. The custom tier runs *after* backup/restore, which disrupts postgres under the app and restarts it, and v3 boots through `sleep 10` → `db createdb` → `db migrate` → cache warmers before health flips to 200. Widened to **300s**, still far inside the recipe's own declared `HTTP_TIMEOUT = 1200`. ## What this does NOT do Neither change weakens an assertion. The event tests still require the row to arrive in ClickHouse **and** match what was sent (name, pathname, hostname); the health test still requires a hard `200` from the real readiness endpoint. Only the fixture and the wait changed. ## Verification Full cold suite against the recipe PR head (`upgrade-4.0.0+v3.2.1`, `867ebfaf`) with this branch: ``` install : pass upgrade : pass backup : pass restore : pass custom : pass level=5 of 5 VERDICT: GREEN ``` All three previously-failing tests pass: `test_pageview_event_roundtrip`, `test_custom_event_roundtrip`, `test_plausible_root_serves`. ## Dependent pair This is the CI half of a pair. `!testme` on plausible#5 runs the **deployed** cc-ci tests, so that PR stays RED until this one merges. Merge this first, then re-run `!testme` there. Not merged by automation — for operator review.
autonomic-bot added 1 commit 2026-08-11 05:23:52 +00:00
plausible v3 (community-edition) only ingests events for a site that belongs to
a TEAM. The custom tier registered a site row and nothing else, which was enough
for v2 — under v3 the POST still acks 202 and the row still exists in postgres,
but every event is discarded. ClickHouse records the reason itself in
ingest_counters as dropped_not_found, and events_v2 stays empty, so it presents
as a silent ingestion stall.

Verified on cc-ci against v3.2.1: identical site row with no team ->
dropped_not_found and 0 rows; with a team linked -> buffered and the rows land.

_register_site now provisions a team and links the site, guarded on the schema
actually having teams so it stays a no-op on v2 (the upgrade tier deploys the
older base first).

Separately, the custom health check waited 60s for /api/health. That tier runs
after backup/restore, which disrupts postgres under the app and restarts it, and
v3 boots through sleep 10 + createdb + migrate + cache warmers before health
flips to 200. Widened to 300s, still far inside the recipe HTTP_TIMEOUT of 1200.
The assertion is unchanged: a hard 200 from the real readiness endpoint.

Neither change weakens a test - the event tests still require the row to arrive
in ClickHouse and match what was sent.
autonomic-bot added 1 commit 2026-08-11 14:50:43 +00:00
The first cut of this fix added a team INSERT next to the existing sites INSERT.
That fixed the symptom and kept the cause: a fixture that knows the apps table
layout breaks whenever the app changes it, which is exactly what happened here.

_register_site now calls Plausible.Sites.create/2 through the app release console,
so the app provisions whatever its data model currently requires - including the
team it introduced in v3. Verified against BOTH versions on cc-ci: the identical
expression works on v2.0.0, which has no teams table at all, and on v3.2.1. No
version gate is needed because the fixture no longer depends on the schema.

The HTTP provisioning API (POST /api/v1/sites) would have been first choice, but
it is gated behind a paid plan and answers :upgrade_required on CE. That is
recorded in the code so the next person does not re-derive it.

tests/STYLE.md writes the rule down, along with the others this failure exercised:
gate on version rather than supporting both schemas (old-version tests can just be
deleted - the older version is only exercised through the upgrade tier); correct
the fixture or the wait but never the assertion; assert stored state rather than a
202 ack; size waits from the recipes declared readiness; and read the apps own
telemetry before deciding a test is stale.

Full cold suite against the recipe PR head: level 5 of 5, GREEN.
Author
Owner

Updated: the fixture no longer touches the database, and a style guide is added

The first cut added a teams INSERT beside the existing sites INSERT. That fixed the symptom and
kept the cause — a fixture that knows the app's table layout breaks whenever the app changes it,
which is precisely what happened here.

_register_site now calls Plausible.Sites.create/2 through the app's release console, so the
app provisions whatever its data model currently requires, including the team it introduced in v3.

Verified against both versions on cc-ci: the identical expression works on v2.0.0, which has
no teams table at all, and on v3.2.1. No version gate is needed, because the fixture no longer
depends on the schema — which is a better outcome than a fixture carefully written to handle both.

The HTTP provisioning API (POST /api/v1/sites) would have been the first choice, but it is gated
behind a paid plan and answers :upgrade_required on CE. That's recorded in the code so nobody
re-derives it.

New: tests/STYLE.md

The rule that would have prevented this — set state up through the app's own interface, not its
database
— is now written down, with this failure as the worked example, along with the others it
exercised: gate on version rather than supporting both schemas (old-version tests can simply be
deleted, since the older version is only exercised through the upgrade tier); correct the fixture or
the wait but never the assertion; assert stored state rather than a 202 ack; size waits from the
recipe's declared readiness; and read the app's own telemetry before deciding a test is stale.

/recipe-upgrade --with-tests, /ci-test-review and /cc-ci-tests-update are all now pointed at it
before they edit a test (orchestrator commit 6c91373).

Re-verified

Full cold suite against the recipe PR head with the rewritten fixture:

install : pass   upgrade : pass   backup : pass   restore : pass   custom : pass
level = 5 of 5   VERDICT: GREEN
### Updated: the fixture no longer touches the database, and a style guide is added The first cut added a `teams` INSERT beside the existing `sites` INSERT. That fixed the symptom and kept the cause — a fixture that knows the app's table layout breaks whenever the app changes it, which is precisely what happened here. `_register_site` now calls **`Plausible.Sites.create/2`** through the app's release console, so the app provisions whatever its data model currently requires, including the team it introduced in v3. **Verified against both versions on cc-ci:** the identical expression works on **v2.0.0**, which has no `teams` table at all, and on **v3.2.1**. No version gate is needed, because the fixture no longer depends on the schema — which is a better outcome than a fixture carefully written to handle both. The HTTP provisioning API (`POST /api/v1/sites`) would have been the first choice, but it is gated behind a paid plan and answers `:upgrade_required` on CE. That's recorded in the code so nobody re-derives it. ### New: `tests/STYLE.md` The rule that would have prevented this — **set state up through the app's own interface, not its database** — is now written down, with this failure as the worked example, along with the others it exercised: gate on version rather than supporting both schemas (old-version tests can simply be deleted, since the older version is only exercised through the upgrade tier); correct the fixture or the wait but never the assertion; assert stored state rather than a 202 ack; size waits from the recipe's declared readiness; and read the app's own telemetry before deciding a test is stale. `/recipe-upgrade --with-tests`, `/ci-test-review` and `/cc-ci-tests-update` are all now pointed at it before they edit a test (orchestrator commit `6c91373`). ### Re-verified Full cold suite against the recipe PR head with the rewritten fixture: ``` install : pass upgrade : pass backup : pass restore : pass custom : pass level = 5 of 5 VERDICT: GREEN ```
autonomic-bot merged commit 8aa21356af into main 2026-08-11 14:52:07 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: recipe-maintainers/cc-ci#17