|
|
|
@@ -14,7 +14,10 @@ Both assert real app state (the event reached the analytics store), not just the
|
|
|
|
|
|
|
|
|
|
plausible only ingests events for *known* sites — the in-memory `sites_cache` gates ingestion and
|
|
|
|
|
drops events for unregistered domains (empirically confirmed: an event for an unregistered domain
|
|
|
|
|
never appears in events_v2). So each test first registers a site row in the metadata postgres, then
|
|
|
|
|
never appears in events_v2). From v3 (community-edition) a site is only "known" once it belongs to a
|
|
|
|
|
TEAM; a teamless site is dropped as `dropped_not_found` while the POST still acks 202, so the failure
|
|
|
|
|
looks like a silent ingestion stall. `_register_site` therefore provisions a team as well when the
|
|
|
|
|
schema has one. So each test first registers a site row in the metadata postgres, then
|
|
|
|
|
POSTs repeatedly while polling ClickHouse: the sites_cache must refresh to admit the new site and the
|
|
|
|
|
event write-buffer must flush to ClickHouse, so the first landing is not instantaneous. Re-POSTing the
|
|
|
|
|
same event is safe — we assert the row count is >= 1.
|
|
|
|
@@ -51,11 +54,40 @@ def _ch(domain: str, sql: str) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _register_site(domain: str, site: str) -> None:
|
|
|
|
|
"""Insert a site row into the metadata postgres (`db` service) so plausible will ingest events for
|
|
|
|
|
it. Idempotent (ON CONFLICT DO NOTHING)."""
|
|
|
|
|
"""Register `site` in the metadata postgres so plausible will ingest events for it.
|
|
|
|
|
|
|
|
|
|
Idempotent. Works against BOTH schema generations, because the upgrade tier deploys an older
|
|
|
|
|
base version before upgrading:
|
|
|
|
|
|
|
|
|
|
* v2 (`plausible/analytics`) — a row in `sites` is sufficient.
|
|
|
|
|
* v3 (`ghcr.io/plausible/community-edition`) — sites belong to a TEAM, and ingestion drops
|
|
|
|
|
events for a site whose team is missing. The POST still acks 202 and the row still exists in
|
|
|
|
|
postgres, so the only visible symptom is that nothing ever reaches ClickHouse; the reason is
|
|
|
|
|
recorded in ClickHouse's own `ingest_counters` as `dropped_not_found`. Verified on cc-ci
|
|
|
|
|
against v3.2.1: identical site row, no team → `dropped_not_found`; with a team linked →
|
|
|
|
|
`buffered` and the row appears in `events_v2`.
|
|
|
|
|
|
|
|
|
|
The team block is guarded on the schema actually having teams, so this stays a no-op on v2
|
|
|
|
|
rather than branching on a version string.
|
|
|
|
|
"""
|
|
|
|
|
sql = (
|
|
|
|
|
"INSERT INTO sites (domain, timezone, inserted_at, updated_at, native_stats_start_at) "
|
|
|
|
|
f"VALUES ('{site}','UTC', now(), now(), now()) ON CONFLICT (domain) DO NOTHING; "
|
|
|
|
|
"DO $ccci$ "
|
|
|
|
|
"BEGIN "
|
|
|
|
|
" IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'teams') "
|
|
|
|
|
" AND EXISTS (SELECT 1 FROM information_schema.columns "
|
|
|
|
|
" WHERE table_name = 'sites' AND column_name = 'team_id') THEN "
|
|
|
|
|
" INSERT INTO teams (name, inserted_at, updated_at, accept_traffic_until, setup_complete) "
|
|
|
|
|
" SELECT 'cc-ci', now(), now(), now() + interval '365 days', true "
|
|
|
|
|
" WHERE NOT EXISTS (SELECT 1 FROM teams WHERE name = 'cc-ci'); "
|
|
|
|
|
" UPDATE sites "
|
|
|
|
|
" SET team_id = COALESCE(team_id, (SELECT id FROM teams WHERE name = 'cc-ci' LIMIT 1)), "
|
|
|
|
|
" accept_traffic_until = COALESCE(accept_traffic_until, now() + interval '365 days') "
|
|
|
|
|
f" WHERE domain = '{site}'; "
|
|
|
|
|
" END IF; "
|
|
|
|
|
"END "
|
|
|
|
|
"$ccci$; "
|
|
|
|
|
f"SELECT domain FROM sites WHERE domain = '{site}';"
|
|
|
|
|
)
|
|
|
|
|
out = lifecycle.exec_in_app(
|
|
|
|
|