From 34e1b4c3d33e5c863fd4e8e3198dd2e4aa143df2 Mon Sep 17 00:00:00 2001 From: Acho Arnold Date: Mon, 18 May 2026 09:54:55 +0300 Subject: [PATCH 1/8] docs: add design spec for CockroachDB integration tests Replace PostgreSQL with CockroachDB in the integration test Docker Compose to match the production database environment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ...18-cockroachdb-integration-tests-design.md | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-18-cockroachdb-integration-tests-design.md diff --git a/docs/superpowers/specs/2026-05-18-cockroachdb-integration-tests-design.md b/docs/superpowers/specs/2026-05-18-cockroachdb-integration-tests-design.md new file mode 100644 index 00000000..9ec1d892 --- /dev/null +++ b/docs/superpowers/specs/2026-05-18-cockroachdb-integration-tests-design.md @@ -0,0 +1,67 @@ +# Replace PostgreSQL with CockroachDB in Integration Tests + +**Date:** 2026-05-18 +**Status:** Approved +**Goal:** Align the integration test database with production (CockroachDB). + +## Context + +Production httpSMS uses CockroachDB. The integration test suite (`tests/docker-compose.yml`) currently uses `postgres:alpine`. This mismatch means tests don't exercise CockroachDB-specific behavior (e.g., serializable isolation by default, distributed SQL quirks). The API's GORM `postgres` driver is already wire-compatible with CockroachDB, so no application code changes are needed. + +## Design + +### Docker Compose Changes (`tests/docker-compose.yml`) + +1. **Replace `postgres` service with `cockroachdb`:** + + - Image: `cockroachdb/cockroach:latest` + - Command: `start-single-node --insecure --store=type=mem,size=256MiB` + - Ports: `26257:26257` (SQL), `8081:8080` (admin UI — remapped to avoid wiremock conflict) + - Healthcheck: `curl -f http://localhost:8080/health?ready=1` + +2. **Add `cockroachdb-init` service** (runs once after cockroachdb is healthy): + + - Uses same CockroachDB image + - Creates the `httpsms` database: `cockroach sql --insecure --host=cockroachdb --execute="CREATE DATABASE IF NOT EXISTS httpsms;"` + +3. **Update `seed` service:** + + - Image: `cockroachdb/cockroach:latest` (instead of `postgres:alpine`) + - Entrypoint: `cockroach sql --insecure --host=cockroachdb --database=httpsms --file=/seed.sql` + - Depends on `api` (healthy) so GORM migrations run first + +4. **Update `api` service:** + - `depends_on`: replace `postgres` with `cockroachdb-init` + +### Environment Changes (`tests/.env.test`) + +``` +DATABASE_URL=postgresql://root@cockroachdb:26257/httpsms?sslmode=disable +DATABASE_URL_DEDICATED=postgresql://root@cockroachdb:26257/httpsms?sslmode=disable +``` + +### Seed SQL (`tests/seed.sql`) + +No changes required. `INSERT ... ON CONFLICT ... DO NOTHING` and `NOW()` are supported by CockroachDB. + +### What Does NOT Change + +- API application code (GORM postgres driver works with CockroachDB) +- Integration test Go code +- Redis, MongoDB, Wiremock services +- API Dockerfile + +## Key Decisions + +| Decision | Rationale | +| ----------------------------------- | --------------------------------------------------------------------------------------------- | +| Single-node insecure mode | Simplest for tests; no TLS cert management | +| In-memory store (`type=mem`) | Faster startup, no persistent volume needed for tests | +| Separate `cockroachdb-init` service | CockroachDB doesn't support `POSTGRES_DB`-style env vars; database must be created explicitly | +| Remap admin UI to 8081 | Avoids port conflict with wiremock on 8080 | +| Use `cockroach sql` for seeding | Native client; avoids pulling a separate postgres image | + +## Risks + +- **GORM migration compatibility:** CockroachDB may handle some DDL differently (e.g., `ALTER TABLE` constraints). The existing `DATABASE_MIGRATION_CONSTRAINT_FIX` env var handles known issues — we'll enable it in `.env.test`. +- **Startup time:** CockroachDB takes slightly longer to start than PostgreSQL (~5-10s). The healthcheck handles this. From ea534b89c950901b63d5998eb07532f4aa822296 Mon Sep 17 00:00:00 2001 From: Acho Arnold Date: Mon, 18 May 2026 10:00:29 +0300 Subject: [PATCH 2/8] docs: add implementation plan for cockroachdb integration tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ...026-05-18-cockroachdb-integration-tests.md | 396 ++++++++++++++++++ 1 file changed, 396 insertions(+) create mode 100644 docs/superpowers/plans/2026-05-18-cockroachdb-integration-tests.md diff --git a/docs/superpowers/plans/2026-05-18-cockroachdb-integration-tests.md b/docs/superpowers/plans/2026-05-18-cockroachdb-integration-tests.md new file mode 100644 index 00000000..6a723df8 --- /dev/null +++ b/docs/superpowers/plans/2026-05-18-cockroachdb-integration-tests.md @@ -0,0 +1,396 @@ +# CockroachDB Integration Tests Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace PostgreSQL with CockroachDB in the integration test Docker Compose so the test environment matches production. + +**Architecture:** Swap the `postgres:alpine` container for `cockroachdb/cockroach:latest` in single-node insecure mode with in-memory storage. Add a one-shot init container to create the database (CockroachDB has no `POSTGRES_DB` env var equivalent). Update connection strings and seed service. + +**Tech Stack:** Docker Compose, CockroachDB (single-node), GORM (postgres driver — wire-compatible) + +--- + +## File Map + +| File | Action | Responsibility | +| -------------------------- | ------ | ------------------------------------------------------------------------- | +| `tests/docker-compose.yml` | Modify | Replace postgres service, add cockroachdb + init, update seed and api | +| `tests/.env.test` | Modify | Update DATABASE_URL connection strings, add migration fix flag | +| `tests/README.md` | Modify | Update architecture diagram and references from PostgreSQL to CockroachDB | + +--- + +### Task 1: Replace PostgreSQL with CockroachDB in Docker Compose + +**Files:** + +- Modify: `tests/docker-compose.yml` + +- [ ] **Step 1: Replace the `postgres` service with `cockroachdb`** + +Replace lines 1–15 of `tests/docker-compose.yml` (the `postgres` service) with: + +```yaml +services: + cockroachdb: + image: cockroachdb/cockroach:latest + command: start-single-node --insecure --store=type=mem,size=256MiB + ports: + - "26257:26257" + - "8081:8080" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/health?ready=1"] + interval: 5s + timeout: 5s + retries: 10 + start_period: 10s +``` + +- [ ] **Step 2: Add `cockroachdb-init` service after `cockroachdb`** + +Add this service immediately after the `cockroachdb` service: + +```yaml +cockroachdb-init: + image: cockroachdb/cockroach:latest + depends_on: + cockroachdb: + condition: service_healthy + entrypoint: + [ + "cockroach", + "sql", + "--insecure", + "--host=cockroachdb", + "--execute=CREATE DATABASE IF NOT EXISTS httpsms;", + ] + restart: "no" +``` + +- [ ] **Step 3: Update `api` service `depends_on`** + +Replace the `depends_on` block of the `api` service. Change: + +```yaml +depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + wiremock: + condition: service_healthy + mongodb: + condition: service_healthy +``` + +To: + +```yaml +depends_on: + cockroachdb-init: + condition: service_completed_successfully + redis: + condition: service_healthy + wiremock: + condition: service_healthy + mongodb: + condition: service_healthy +``` + +- [ ] **Step 4: Update `seed` service** + +Replace the entire `seed` service. Change: + +```yaml +seed: + image: postgres:alpine + depends_on: + api: + condition: service_healthy + environment: + PGPASSWORD: dbpassword + volumes: + - ./seed.sql:/seed.sql:ro + entrypoint: + [ + "psql", + "-h", + "postgres", + "-U", + "dbusername", + "-d", + "httpsms", + "-f", + "/seed.sql", + ] + restart: "no" +``` + +To: + +```yaml +seed: + image: cockroachdb/cockroach:latest + depends_on: + api: + condition: service_healthy + volumes: + - ./seed.sql:/seed.sql:ro + entrypoint: + [ + "cockroach", + "sql", + "--insecure", + "--host=cockroachdb", + "--database=httpsms", + "--file=/seed.sql", + ] + restart: "no" +``` + +- [ ] **Step 5: Verify the final `docker-compose.yml` structure** + +The final file should contain these services in order: + +1. `cockroachdb` — database server +2. `cockroachdb-init` — creates the database (one-shot) +3. `redis` — unchanged +4. `mongodb` — unchanged +5. `wiremock` — unchanged +6. `api` — depends on `cockroachdb-init` instead of `postgres` +7. `seed` — uses `cockroach sql` instead of `psql` + +- [ ] **Step 6: Commit** + +```bash +git add tests/docker-compose.yml +git commit -m "test: replace postgres with cockroachdb in integration tests + +Use cockroachdb/cockroach:latest in single-node insecure mode with +in-memory storage. Add cockroachdb-init service to create the database +and update the seed service to use cockroach sql CLI." +``` + +--- + +### Task 2: Update Environment Variables + +**Files:** + +- Modify: `tests/.env.test` + +- [ ] **Step 1: Update DATABASE_URL** + +Change line 11: + +``` +DATABASE_URL=postgresql://dbusername:dbpassword@postgres:5432/httpsms +``` + +To: + +``` +DATABASE_URL=postgresql://root@cockroachdb:26257/httpsms?sslmode=disable +``` + +- [ ] **Step 2: Update DATABASE_URL_DEDICATED** + +Change line 12: + +``` +DATABASE_URL_DEDICATED=postgresql://dbusername:dbpassword@postgres:5432/httpsms +``` + +To: + +``` +DATABASE_URL_DEDICATED=postgresql://root@cockroachdb:26257/httpsms?sslmode=disable +``` + +- [ ] **Step 3: Add DATABASE_MIGRATION_CONSTRAINT_FIX** + +Add the following line after `DATABASE_URL_DEDICATED`: + +``` +DATABASE_MIGRATION_CONSTRAINT_FIX=1 +``` + +This enables the GORM migration workaround for CockroachDB constraint handling (already used in production, see `api/pkg/di/container.go:369-376`). + +- [ ] **Step 4: Commit** + +```bash +git add tests/.env.test +git commit -m "test: update env vars for cockroachdb connection + +Point DATABASE_URL at cockroachdb:26257 with root user (insecure mode). +Enable DATABASE_MIGRATION_CONSTRAINT_FIX for CockroachDB compatibility." +``` + +--- + +### Task 3: Update README Documentation + +**Files:** + +- Modify: `tests/README.md` + +- [ ] **Step 1: Update architecture diagram** + +Replace the ASCII diagram (lines 7–25) — change `PostgreSQL` to `CockroachDB` and port `5435` to `26257`: + +``` +┌──────────────┐ HTTP ┌──────────────┐ +│ Test Runner │─────────────▶│ API (Go) │ +│ (Go test) │ │ Port 8000 │ +└──────────────┘ └──────┬───────┘ + │ + FCM Push │ Events + (HTTP) │ (HTTP) + ▼ + ┌──────────────┐ + │ Emulator │ + │ (Fiber v3) │ + │ Port 9090 │ + └──────────────┘ + │ + ┌──────┴───────┐ + │ CockroachDB │ │ Redis │ + │ Port 26257 │ │ Port 6379 │ + └──────────────┘ └─────────────┘ +``` + +- [ ] **Step 2: Update Components table** + +Change the row: + +```markdown +| **PostgreSQL** | Database for the API | +``` + +To: + +```markdown +| **CockroachDB** | Database for the API (single-node, insecure mode) | +``` + +And change: + +```markdown +| **Seed** | One-shot container that seeds test data into PostgreSQL | +``` + +To: + +```markdown +| **Seed** | One-shot container that seeds test data into CockroachDB | +``` + +- [ ] **Step 3: Update "Start the Stack" section** + +In the "3. Start the Stack" section (line 85-89), the command stays the same (`docker compose up -d --build --wait`) but update the description: + +Change: + +``` +This starts PostgreSQL, Redis, the API, and the emulator. The `--wait` flag blocks until all health checks pass. +``` + +To: + +``` +This starts CockroachDB, Redis, the API, and the emulator. The `--wait` flag blocks until all health checks pass. +``` + +- [ ] **Step 4: Update "Wait for Seeding" description** + +Change line 98: + +``` +The seed container inserts test users, phones, and API keys into PostgreSQL after the API has run its GORM migrations. +``` + +To: + +``` +The seed container inserts test users, phones, and API keys into CockroachDB after the API has run its GORM migrations. +``` + +- [ ] **Step 5: Update Troubleshooting section** + +In "API fails to start" common issues (line 185), change: + +``` +- PostgreSQL not ready (increase `start_period` in healthcheck) +``` + +To: + +``` +- CockroachDB not ready (increase `start_period` in healthcheck) +``` + +- [ ] **Step 6: Commit** + +```bash +git add tests/README.md +git commit -m "docs: update integration test README for cockroachdb + +Replace all PostgreSQL references with CockroachDB in the architecture +diagram, components table, and troubleshooting section." +``` + +--- + +### Task 4: Validate the Stack + +- [ ] **Step 1: Generate Firebase credentials (if not already present)** + +```bash +cd tests && bash generate-firebase-credentials.sh +``` + +- [ ] **Step 2: Set the environment variable** + +```bash +export FIREBASE_CREDENTIALS=$(jq -c . firebase-credentials.json) +``` + +- [ ] **Step 3: Start the stack** + +```bash +docker compose up -d --build --wait +``` + +Expected: All services start. CockroachDB reports healthy. cockroachdb-init exits with code 0. API starts and passes healthcheck. + +- [ ] **Step 4: Verify seed ran successfully** + +```bash +docker compose wait seed && docker compose logs seed +``` + +Expected: Output shows `INSERT` statements succeeded (no errors). + +- [ ] **Step 5: Run integration tests** + +```bash +go test -v -timeout 120s ./... +``` + +Expected: All tests pass (same tests as before — no test code changed). + +- [ ] **Step 6: Tear down** + +```bash +docker compose down -v +``` + +- [ ] **Step 7: Final commit (if any fixes were needed)** + +If any adjustments were required during validation, commit them: + +```bash +git add -A +git commit -m "test: fix integration test issues found during validation" +``` From 324c4e396e4c63177096389a86abcf62c61457d9 Mon Sep 17 00:00:00 2001 From: Acho Arnold Date: Mon, 18 May 2026 10:05:21 +0300 Subject: [PATCH 3/8] test: replace postgres with cockroachdb in integration tests Use cockroachdb/cockroach:latest in single-node insecure mode with in-memory storage. Add cockroachdb-init service to create the database and update the seed service to use cockroach sql CLI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/docker-compose.yml | 54 +++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index 515b6298..e31312c0 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -1,18 +1,31 @@ services: - postgres: - image: postgres:alpine - environment: - POSTGRES_DB: httpsms - POSTGRES_PASSWORD: dbpassword - POSTGRES_USER: dbusername + cockroachdb: + image: cockroachdb/cockroach:latest + command: start-single-node --insecure --store=type=mem,size=256MiB ports: - - "5435:5432" + - "26257:26257" + - "8081:8080" healthcheck: - test: ["CMD-SHELL", "pg_isready -U dbusername -d httpsms"] + test: ["CMD", "curl", "-f", "http://localhost:8080/health?ready=1"] interval: 5s timeout: 5s retries: 10 - start_period: 5s + start_period: 10s + + cockroachdb-init: + image: cockroachdb/cockroach:latest + depends_on: + cockroachdb: + condition: service_healthy + entrypoint: + [ + "cockroach", + "sql", + "--insecure", + "--host=cockroachdb", + "--execute=CREATE DATABASE IF NOT EXISTS httpsms;", + ] + restart: "no" redis: image: redis:latest @@ -61,8 +74,8 @@ services: ports: - "8000:8000" depends_on: - postgres: - condition: service_healthy + cockroachdb-init: + condition: service_completed_successfully redis: condition: service_healthy wiremock: @@ -81,24 +94,19 @@ services: start_period: 30s seed: - image: postgres:alpine + image: cockroachdb/cockroach:latest depends_on: api: condition: service_healthy - environment: - PGPASSWORD: dbpassword volumes: - ./seed.sql:/seed.sql:ro entrypoint: [ - "psql", - "-h", - "postgres", - "-U", - "dbusername", - "-d", - "httpsms", - "-f", - "/seed.sql", + "cockroach", + "sql", + "--insecure", + "--host=cockroachdb", + "--database=httpsms", + "--file=/seed.sql", ] restart: "no" From 389dd3d6d702f7035bfd628fdea20a2dc6946c03 Mon Sep 17 00:00:00 2001 From: Acho Arnold Date: Mon, 18 May 2026 10:06:15 +0300 Subject: [PATCH 4/8] test: update env vars for cockroachdb connection Point DATABASE_URL at cockroachdb:26257 with root user (insecure mode). Enable DATABASE_MIGRATION_CONSTRAINT_FIX for CockroachDB compatibility. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/.env.test | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/.env.test b/tests/.env.test index 0e2b1a5c..5692e7fe 100644 --- a/tests/.env.test +++ b/tests/.env.test @@ -8,8 +8,9 @@ EVENTS_QUEUE_ENDPOINT=http://localhost:8000/v1/events EVENTS_QUEUE_USER_API_KEY=system-user-api-key EVENTS_QUEUE_USER_ID=system-user-id FCM_ENDPOINT=http://wiremock:8080 -DATABASE_URL=postgresql://dbusername:dbpassword@postgres:5432/httpsms -DATABASE_URL_DEDICATED=postgresql://dbusername:dbpassword@postgres:5432/httpsms +DATABASE_URL=postgresql://root@cockroachdb:26257/httpsms?sslmode=disable +DATABASE_URL_DEDICATED=postgresql://root@cockroachdb:26257/httpsms?sslmode=disable +DATABASE_MIGRATION_CONSTRAINT_FIX=1 REDIS_URL=redis://@redis:6379 APP_PORT=8000 APP_NAME=httpSMS From fc1b5f7f593a5f2ed03b7c1bb9f1f4ecd33cb175 Mon Sep 17 00:00:00 2001 From: Acho Arnold Date: Mon, 18 May 2026 10:06:47 +0300 Subject: [PATCH 5/8] docs: update integration test README for cockroachdb Replace all PostgreSQL references with CockroachDB in the architecture diagram, components table, and troubleshooting section. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/README.md b/tests/README.md index c914982d..a37653e5 100644 --- a/tests/README.md +++ b/tests/README.md @@ -20,21 +20,21 @@ End-to-end integration tests for the httpSMS API. These tests validate the compl └──────────────┘ │ ┌──────┴───────┐ - │ PostgreSQL │ │ Redis │ - │ Port 5435 │ │ Port 6379 │ + │ CockroachDB │ │ Redis │ + │ Port 26257 │ │ Port 6379 │ └──────────────┘ └─────────────┘ ``` ### Components -| Component | Description | -| --------------- | ------------------------------------------------------- | -| **API** | The httpSMS Go API server running in Docker | -| **Emulator** | A Fiber v3 Go service that simulates an Android phone | -| **PostgreSQL** | Database for the API | -| **Redis** | Cache and queue backend | -| **Seed** | One-shot container that seeds test data into PostgreSQL | -| **Test Runner** | Go test binary that runs on the host machine | +| Component | Description | +| --------------- | -------------------------------------------------------- | +| **API** | The httpSMS Go API server running in Docker | +| **Emulator** | A Fiber v3 Go service that simulates an Android phone | +| **CockroachDB** | Database for the API (single-node, insecure mode) | +| **Redis** | Cache and queue backend | +| **Seed** | One-shot container that seeds test data into CockroachDB | +| **Test Runner** | Go test binary that runs on the host machine | ### How It Works @@ -86,7 +86,7 @@ export FIREBASE_CREDENTIALS=$(jq -c . firebase-credentials.json) docker compose up -d --build --wait ``` -This starts PostgreSQL, Redis, the API, and the emulator. The `--wait` flag blocks until all health checks pass. +This starts CockroachDB, Redis, the API, and the emulator. The `--wait` flag blocks until all health checks pass. ### 4. Wait for Seeding @@ -95,7 +95,7 @@ docker compose wait seed sleep 2 ``` -The seed container inserts test users, phones, and API keys into PostgreSQL after the API has run its GORM migrations. +The seed container inserts test users, phones, and API keys into CockroachDB after the API has run its GORM migrations. ### 5. Run Tests @@ -181,7 +181,7 @@ docker compose logs api Common issues: - `FIREBASE_CREDENTIALS` env var not set or malformed -- PostgreSQL not ready (increase `start_period` in healthcheck) +- CockroachDB not ready (increase `start_period` in healthcheck) ### Tests timeout waiting for `delivered` status From fed39a7414692bd240bebed94f2b30d2acb201a7 Mon Sep 17 00:00:00 2001 From: Acho Arnold Date: Mon, 18 May 2026 10:13:49 +0300 Subject: [PATCH 6/8] chore: add docs/ to .gitignore Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .gitignore | 2 + ...026-05-18-cockroachdb-integration-tests.md | 396 ------------------ ...18-cockroachdb-integration-tests-design.md | 67 --- 3 files changed, 2 insertions(+), 463 deletions(-) delete mode 100644 docs/superpowers/plans/2026-05-18-cockroachdb-integration-tests.md delete mode 100644 docs/superpowers/specs/2026-05-18-cockroachdb-integration-tests-design.md diff --git a/.gitignore b/.gitignore index b7c1baed..0aa9dfff 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ tests/emulator/emulator.exe SECURITY_AUDIT_REPORT.md *.exe + +docs/ diff --git a/docs/superpowers/plans/2026-05-18-cockroachdb-integration-tests.md b/docs/superpowers/plans/2026-05-18-cockroachdb-integration-tests.md deleted file mode 100644 index 6a723df8..00000000 --- a/docs/superpowers/plans/2026-05-18-cockroachdb-integration-tests.md +++ /dev/null @@ -1,396 +0,0 @@ -# CockroachDB Integration Tests Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Replace PostgreSQL with CockroachDB in the integration test Docker Compose so the test environment matches production. - -**Architecture:** Swap the `postgres:alpine` container for `cockroachdb/cockroach:latest` in single-node insecure mode with in-memory storage. Add a one-shot init container to create the database (CockroachDB has no `POSTGRES_DB` env var equivalent). Update connection strings and seed service. - -**Tech Stack:** Docker Compose, CockroachDB (single-node), GORM (postgres driver — wire-compatible) - ---- - -## File Map - -| File | Action | Responsibility | -| -------------------------- | ------ | ------------------------------------------------------------------------- | -| `tests/docker-compose.yml` | Modify | Replace postgres service, add cockroachdb + init, update seed and api | -| `tests/.env.test` | Modify | Update DATABASE_URL connection strings, add migration fix flag | -| `tests/README.md` | Modify | Update architecture diagram and references from PostgreSQL to CockroachDB | - ---- - -### Task 1: Replace PostgreSQL with CockroachDB in Docker Compose - -**Files:** - -- Modify: `tests/docker-compose.yml` - -- [ ] **Step 1: Replace the `postgres` service with `cockroachdb`** - -Replace lines 1–15 of `tests/docker-compose.yml` (the `postgres` service) with: - -```yaml -services: - cockroachdb: - image: cockroachdb/cockroach:latest - command: start-single-node --insecure --store=type=mem,size=256MiB - ports: - - "26257:26257" - - "8081:8080" - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8080/health?ready=1"] - interval: 5s - timeout: 5s - retries: 10 - start_period: 10s -``` - -- [ ] **Step 2: Add `cockroachdb-init` service after `cockroachdb`** - -Add this service immediately after the `cockroachdb` service: - -```yaml -cockroachdb-init: - image: cockroachdb/cockroach:latest - depends_on: - cockroachdb: - condition: service_healthy - entrypoint: - [ - "cockroach", - "sql", - "--insecure", - "--host=cockroachdb", - "--execute=CREATE DATABASE IF NOT EXISTS httpsms;", - ] - restart: "no" -``` - -- [ ] **Step 3: Update `api` service `depends_on`** - -Replace the `depends_on` block of the `api` service. Change: - -```yaml -depends_on: - postgres: - condition: service_healthy - redis: - condition: service_healthy - wiremock: - condition: service_healthy - mongodb: - condition: service_healthy -``` - -To: - -```yaml -depends_on: - cockroachdb-init: - condition: service_completed_successfully - redis: - condition: service_healthy - wiremock: - condition: service_healthy - mongodb: - condition: service_healthy -``` - -- [ ] **Step 4: Update `seed` service** - -Replace the entire `seed` service. Change: - -```yaml -seed: - image: postgres:alpine - depends_on: - api: - condition: service_healthy - environment: - PGPASSWORD: dbpassword - volumes: - - ./seed.sql:/seed.sql:ro - entrypoint: - [ - "psql", - "-h", - "postgres", - "-U", - "dbusername", - "-d", - "httpsms", - "-f", - "/seed.sql", - ] - restart: "no" -``` - -To: - -```yaml -seed: - image: cockroachdb/cockroach:latest - depends_on: - api: - condition: service_healthy - volumes: - - ./seed.sql:/seed.sql:ro - entrypoint: - [ - "cockroach", - "sql", - "--insecure", - "--host=cockroachdb", - "--database=httpsms", - "--file=/seed.sql", - ] - restart: "no" -``` - -- [ ] **Step 5: Verify the final `docker-compose.yml` structure** - -The final file should contain these services in order: - -1. `cockroachdb` — database server -2. `cockroachdb-init` — creates the database (one-shot) -3. `redis` — unchanged -4. `mongodb` — unchanged -5. `wiremock` — unchanged -6. `api` — depends on `cockroachdb-init` instead of `postgres` -7. `seed` — uses `cockroach sql` instead of `psql` - -- [ ] **Step 6: Commit** - -```bash -git add tests/docker-compose.yml -git commit -m "test: replace postgres with cockroachdb in integration tests - -Use cockroachdb/cockroach:latest in single-node insecure mode with -in-memory storage. Add cockroachdb-init service to create the database -and update the seed service to use cockroach sql CLI." -``` - ---- - -### Task 2: Update Environment Variables - -**Files:** - -- Modify: `tests/.env.test` - -- [ ] **Step 1: Update DATABASE_URL** - -Change line 11: - -``` -DATABASE_URL=postgresql://dbusername:dbpassword@postgres:5432/httpsms -``` - -To: - -``` -DATABASE_URL=postgresql://root@cockroachdb:26257/httpsms?sslmode=disable -``` - -- [ ] **Step 2: Update DATABASE_URL_DEDICATED** - -Change line 12: - -``` -DATABASE_URL_DEDICATED=postgresql://dbusername:dbpassword@postgres:5432/httpsms -``` - -To: - -``` -DATABASE_URL_DEDICATED=postgresql://root@cockroachdb:26257/httpsms?sslmode=disable -``` - -- [ ] **Step 3: Add DATABASE_MIGRATION_CONSTRAINT_FIX** - -Add the following line after `DATABASE_URL_DEDICATED`: - -``` -DATABASE_MIGRATION_CONSTRAINT_FIX=1 -``` - -This enables the GORM migration workaround for CockroachDB constraint handling (already used in production, see `api/pkg/di/container.go:369-376`). - -- [ ] **Step 4: Commit** - -```bash -git add tests/.env.test -git commit -m "test: update env vars for cockroachdb connection - -Point DATABASE_URL at cockroachdb:26257 with root user (insecure mode). -Enable DATABASE_MIGRATION_CONSTRAINT_FIX for CockroachDB compatibility." -``` - ---- - -### Task 3: Update README Documentation - -**Files:** - -- Modify: `tests/README.md` - -- [ ] **Step 1: Update architecture diagram** - -Replace the ASCII diagram (lines 7–25) — change `PostgreSQL` to `CockroachDB` and port `5435` to `26257`: - -``` -┌──────────────┐ HTTP ┌──────────────┐ -│ Test Runner │─────────────▶│ API (Go) │ -│ (Go test) │ │ Port 8000 │ -└──────────────┘ └──────┬───────┘ - │ - FCM Push │ Events - (HTTP) │ (HTTP) - ▼ - ┌──────────────┐ - │ Emulator │ - │ (Fiber v3) │ - │ Port 9090 │ - └──────────────┘ - │ - ┌──────┴───────┐ - │ CockroachDB │ │ Redis │ - │ Port 26257 │ │ Port 6379 │ - └──────────────┘ └─────────────┘ -``` - -- [ ] **Step 2: Update Components table** - -Change the row: - -```markdown -| **PostgreSQL** | Database for the API | -``` - -To: - -```markdown -| **CockroachDB** | Database for the API (single-node, insecure mode) | -``` - -And change: - -```markdown -| **Seed** | One-shot container that seeds test data into PostgreSQL | -``` - -To: - -```markdown -| **Seed** | One-shot container that seeds test data into CockroachDB | -``` - -- [ ] **Step 3: Update "Start the Stack" section** - -In the "3. Start the Stack" section (line 85-89), the command stays the same (`docker compose up -d --build --wait`) but update the description: - -Change: - -``` -This starts PostgreSQL, Redis, the API, and the emulator. The `--wait` flag blocks until all health checks pass. -``` - -To: - -``` -This starts CockroachDB, Redis, the API, and the emulator. The `--wait` flag blocks until all health checks pass. -``` - -- [ ] **Step 4: Update "Wait for Seeding" description** - -Change line 98: - -``` -The seed container inserts test users, phones, and API keys into PostgreSQL after the API has run its GORM migrations. -``` - -To: - -``` -The seed container inserts test users, phones, and API keys into CockroachDB after the API has run its GORM migrations. -``` - -- [ ] **Step 5: Update Troubleshooting section** - -In "API fails to start" common issues (line 185), change: - -``` -- PostgreSQL not ready (increase `start_period` in healthcheck) -``` - -To: - -``` -- CockroachDB not ready (increase `start_period` in healthcheck) -``` - -- [ ] **Step 6: Commit** - -```bash -git add tests/README.md -git commit -m "docs: update integration test README for cockroachdb - -Replace all PostgreSQL references with CockroachDB in the architecture -diagram, components table, and troubleshooting section." -``` - ---- - -### Task 4: Validate the Stack - -- [ ] **Step 1: Generate Firebase credentials (if not already present)** - -```bash -cd tests && bash generate-firebase-credentials.sh -``` - -- [ ] **Step 2: Set the environment variable** - -```bash -export FIREBASE_CREDENTIALS=$(jq -c . firebase-credentials.json) -``` - -- [ ] **Step 3: Start the stack** - -```bash -docker compose up -d --build --wait -``` - -Expected: All services start. CockroachDB reports healthy. cockroachdb-init exits with code 0. API starts and passes healthcheck. - -- [ ] **Step 4: Verify seed ran successfully** - -```bash -docker compose wait seed && docker compose logs seed -``` - -Expected: Output shows `INSERT` statements succeeded (no errors). - -- [ ] **Step 5: Run integration tests** - -```bash -go test -v -timeout 120s ./... -``` - -Expected: All tests pass (same tests as before — no test code changed). - -- [ ] **Step 6: Tear down** - -```bash -docker compose down -v -``` - -- [ ] **Step 7: Final commit (if any fixes were needed)** - -If any adjustments were required during validation, commit them: - -```bash -git add -A -git commit -m "test: fix integration test issues found during validation" -``` diff --git a/docs/superpowers/specs/2026-05-18-cockroachdb-integration-tests-design.md b/docs/superpowers/specs/2026-05-18-cockroachdb-integration-tests-design.md deleted file mode 100644 index 9ec1d892..00000000 --- a/docs/superpowers/specs/2026-05-18-cockroachdb-integration-tests-design.md +++ /dev/null @@ -1,67 +0,0 @@ -# Replace PostgreSQL with CockroachDB in Integration Tests - -**Date:** 2026-05-18 -**Status:** Approved -**Goal:** Align the integration test database with production (CockroachDB). - -## Context - -Production httpSMS uses CockroachDB. The integration test suite (`tests/docker-compose.yml`) currently uses `postgres:alpine`. This mismatch means tests don't exercise CockroachDB-specific behavior (e.g., serializable isolation by default, distributed SQL quirks). The API's GORM `postgres` driver is already wire-compatible with CockroachDB, so no application code changes are needed. - -## Design - -### Docker Compose Changes (`tests/docker-compose.yml`) - -1. **Replace `postgres` service with `cockroachdb`:** - - - Image: `cockroachdb/cockroach:latest` - - Command: `start-single-node --insecure --store=type=mem,size=256MiB` - - Ports: `26257:26257` (SQL), `8081:8080` (admin UI — remapped to avoid wiremock conflict) - - Healthcheck: `curl -f http://localhost:8080/health?ready=1` - -2. **Add `cockroachdb-init` service** (runs once after cockroachdb is healthy): - - - Uses same CockroachDB image - - Creates the `httpsms` database: `cockroach sql --insecure --host=cockroachdb --execute="CREATE DATABASE IF NOT EXISTS httpsms;"` - -3. **Update `seed` service:** - - - Image: `cockroachdb/cockroach:latest` (instead of `postgres:alpine`) - - Entrypoint: `cockroach sql --insecure --host=cockroachdb --database=httpsms --file=/seed.sql` - - Depends on `api` (healthy) so GORM migrations run first - -4. **Update `api` service:** - - `depends_on`: replace `postgres` with `cockroachdb-init` - -### Environment Changes (`tests/.env.test`) - -``` -DATABASE_URL=postgresql://root@cockroachdb:26257/httpsms?sslmode=disable -DATABASE_URL_DEDICATED=postgresql://root@cockroachdb:26257/httpsms?sslmode=disable -``` - -### Seed SQL (`tests/seed.sql`) - -No changes required. `INSERT ... ON CONFLICT ... DO NOTHING` and `NOW()` are supported by CockroachDB. - -### What Does NOT Change - -- API application code (GORM postgres driver works with CockroachDB) -- Integration test Go code -- Redis, MongoDB, Wiremock services -- API Dockerfile - -## Key Decisions - -| Decision | Rationale | -| ----------------------------------- | --------------------------------------------------------------------------------------------- | -| Single-node insecure mode | Simplest for tests; no TLS cert management | -| In-memory store (`type=mem`) | Faster startup, no persistent volume needed for tests | -| Separate `cockroachdb-init` service | CockroachDB doesn't support `POSTGRES_DB`-style env vars; database must be created explicitly | -| Remap admin UI to 8081 | Avoids port conflict with wiremock on 8080 | -| Use `cockroach sql` for seeding | Native client; avoids pulling a separate postgres image | - -## Risks - -- **GORM migration compatibility:** CockroachDB may handle some DDL differently (e.g., `ALTER TABLE` constraints). The existing `DATABASE_MIGRATION_CONSTRAINT_FIX` env var handles known issues — we'll enable it in `.env.test`. -- **Startup time:** CockroachDB takes slightly longer to start than PostgreSQL (~5-10s). The healthcheck handles this. From 9c7ce712dcab845ee7838b812b23813a4036b03d Mon Sep 17 00:00:00 2001 From: Acho Arnold Date: Mon, 18 May 2026 10:14:54 +0300 Subject: [PATCH 7/8] fix: use cockroach sql for healthcheck instead of curl The CockroachDB Docker image does not include curl. Use 'cockroach sql --execute=SELECT 1' for the healthcheck instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/docker-compose.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index e31312c0..95656f78 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -6,7 +6,15 @@ services: - "26257:26257" - "8081:8080" healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8080/health?ready=1"] + test: + [ + "CMD", + "cockroach", + "sql", + "--insecure", + "--host=localhost", + "--execute=SELECT 1;", + ] interval: 5s timeout: 5s retries: 10 From a680f97e73e3b2f3b1ca3ab163b258e5954f9e90 Mon Sep 17 00:00:00 2001 From: Acho Arnold Date: Mon, 18 May 2026 10:20:41 +0300 Subject: [PATCH 8/8] fix: increase cockroachdb memory store to minimum 640MiB CockroachDB requires at least 640 MiB for in-memory storage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index 95656f78..3d82d47c 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -1,7 +1,7 @@ services: cockroachdb: image: cockroachdb/cockroach:latest - command: start-single-node --insecure --store=type=mem,size=256MiB + command: start-single-node --insecure --store=type=mem,size=640MiB ports: - "26257:26257" - "8081:8080"