--- name: pg-integration-tests description: Write and run pgLab tests against a real PostgreSQL server (14–17) using the pgintegration harness (DbTest fixture, template database, REQUIRE_PG_AT_LEAST). Use whenever a test needs a live server, e.g. catalog introspection, generated SQL that must be executed, version-specific behaviour, or when the user mentions integration tests, IntegrationTests, docker-compose Postgres or TEST_DATABASE_URL. --- # Integration tests against real PostgreSQL Build/run commands live in `AGENTS.md` (Build and test); don't duplicate them here. ## When to use Use for behaviour that depends on a real server: catalog queries, `pg_get_*` output, executing generated SQL, version differences. Pure string/logic tests belong in `PgsqlTests` / `pglabtests` instead. ## Layout - `tests/pgintegration/` – static lib: `PgEnv` (global environment, builds template DB `tmpl_` from `fixtures/schema.sql`), `DbTest` fixture, helpers. - `tests/integration/` – `IntegrationTests` executable, `tst_*.cpp`, `fixtures/schema.sql`, `docker-compose.yml`. - The binary only reads `TEST_DATABASE_URL`; unset means every `DbTest` skips. ## Writing a test ```cpp #include "DbTest.h" #include "PgTestEnvironment.h" class MyFeature : public pgtest::DbTest {}; TEST_F(MyFeature, Works) { REQUIRE_PG_AT_LEAST(15); // skip on older servers auto r = conn().query("SELECT 1"); // Pgsql::Connection, throws on SQL error EXPECT_EQ(r.rows(), 1); } ``` - Derive from `pgtest::DbTest`. Each test gets a fresh database (`t__`) cloned from the template and dropped afterwards, so never rely on state from another test and freely modify data/schema. - `conn()` is the test connection, `dbUrl()` gives a URL for code under test that opens its own connection (close those before the test ends; teardown uses `DROP DATABASE ... WITH (FORCE)`). - Gate version-specific features with `REQUIRE_PG_AT_LEAST(v)`; use `pgtest::serverVersionNum()` for finer checks. Also test graceful behaviour on PG 14. - `query()` throws on error; use `EXPECT_THROW` for expected failures. ## Adding things - New test file: add it to the `add_executable(IntegrationTests ...)` list in `tests/integration/CMakeLists.txt` (no globbing). - Shared schema: extend `tests/integration/fixtures/schema.sql` (plain multi-statement SQL, loaded once per process into the template). Keep it small; it must work on all of 14–17. Version-specific schema should be created inside the test. - Cluster-wide objects (roles, tablespaces) are not isolated by cloning: use unique names (include `pgtest::processId()`) and drop them in `TearDown`. ## Running and checking - One version manually: set `TEST_DATABASE_URL` and use `--gtest_filter` (see AGENTS.md); start servers with `docker compose -f tests/integration/docker-compose.yml up -d --wait pg16`, stop with `down -v`. - After a run no `t_*` or `tmpl_*` databases should remain: `psql -Atc "select datname from pg_database where datname ~ '^(t|tmpl)_'"`.