From 02efff83ce6666b370defc67906131ba753da602 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 1 Jun 2026 22:45:17 +1000 Subject: [PATCH] test: isolate tests on void_test DB (stop resetDb wiping prod void) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resetDb() DROPs schema; dev DATABASE_URL pointed at the shared prod void DB on .215. setup.js now forces a dedicated void_test DB (TEST_DATABASE_URL or derived) and throws if it would target prod. Created void_test + pg_hba rule on CT 310. Verified: full suite green, prod void space count unchanged (2→2). Co-Authored-By: Claude Opus 4.8 --- docs/testing.md | 51 ++++++++++++++++++++++++++++++++++++++++++ tests/helpers/setup.js | 23 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 docs/testing.md diff --git a/docs/testing.md b/docs/testing.md new file mode 100644 index 0000000..aca177c --- /dev/null +++ b/docs/testing.md @@ -0,0 +1,51 @@ +# Testing — database isolation + +## TL;DR + +Tests run `resetDb()` → **`DROP SCHEMA public CASCADE`**. They MUST run against a +dedicated **`void_test`** database, never the prod `void` DB. This is enforced +in code (`tests/helpers/setup.js` throws if the resolved URL still targets +`/void`). + +## Why + +The void2 Postgres cluster on `192.168.1.215` (CT 310) is shared: the prod app +(CT 311) and dev runs both use it. The dev `DATABASE_URL` points at the prod +`void` database. Before isolation, `npm test` wiped production data on every run +(spaces/tasks/etc. gone; migrations + the seeded `companion` agent re-created by +`migrateUp`, which masked the damage). + +## Setup (already done — 2026-06-01) + +1. **`void_test` database** created on the `.215` cluster, owned by `void`: + ```sql + -- run while connected to the `void` db (the `postgres` maintenance db is + -- not reachable from the dev box per pg_hba.conf): + CREATE DATABASE void_test OWNER void; + ``` +2. **`pg_hba.conf`** on CT 310 (`/etc/postgresql/16/main/pg_hba.conf`) — added a + rule mirroring the `void` one, then `systemctl reload postgresql@16-main`: + ``` + host void_test void 192.168.1.0/24 scram-sha-256 + ``` +3. **`tests/helpers/setup.js`** (vitest `setupFiles`) forces the test DB and + guards against prod: + - uses `TEST_DATABASE_URL` if set, else derives it by swapping `/void` → + `/void_test` in `DATABASE_URL`; + - **throws** if the resolved URL still points at `/void`. +4. Dev **`.env`** has `TEST_DATABASE_URL=postgres://void:…@192.168.1.215:5432/void_test`. + +## Running tests + +```bash +npm test # vitest; binds the pool to void_test via setup.js +``` + +`resetDb()` + `migrateUp()` rebuild `void_test`'s schema each run. Prod `void` +is never touched. The guard makes a misconfiguration fail loudly instead of +silently wiping prod. + +## Note + +`.env` (incl. `TEST_DATABASE_URL`) is git-ignored and not deployed — this is a +dev-box concern only. Prod (CT 311) never runs the test suite. diff --git a/tests/helpers/setup.js b/tests/helpers/setup.js index 0b172b7..16ac7c4 100644 --- a/tests/helpers/setup.js +++ b/tests/helpers/setup.js @@ -1 +1,24 @@ import 'dotenv/config'; + +// SAFETY GUARD — tests call resetDb() which runs `DROP SCHEMA public CASCADE`. +// The dev DATABASE_URL points at the prod "void" database on the shared .215 +// cluster, so running tests against it WIPES PRODUCTION. Force a dedicated test +// database here, and refuse to run if we'd still be pointed at "void". +// +// Resolution order: +// 1. TEST_DATABASE_URL (explicit), else +// 2. derive from DATABASE_URL by swapping the "/void" db name for "/void_test". +const resolved = + process.env.TEST_DATABASE_URL || + (process.env.DATABASE_URL || '').replace(/\/void(\?|$)/, '/void_test$1'); + +if (!resolved || /\/void(\?|$)/.test(resolved)) { + throw new Error( + 'Refusing to run tests: would target the prod "void" database. ' + + 'Set TEST_DATABASE_URL to a dedicated test DB (e.g. .../void_test).' + ); +} + +// pool.js reads process.env.DATABASE_URL on first import; this setupFile runs +// before the test module graph loads, so the pool binds to the test DB. +process.env.DATABASE_URL = resolved;