diff --git a/audit/single_tran.md b/audit/single_tran.md index fa0b2b4..d212f67 100644 --- a/audit/single_tran.md +++ b/audit/single_tran.md @@ -95,7 +95,8 @@ - DONE P6: funcspec. `OnTxBegin`, `HookContext.SetTx`, `Handler.runInTx` for `SqlQuery` and `SqlQueryList`. `BeforeResponse` now runs in a second short tx (`Tx` is no longer the pool). `BeforeOp` is unchanged (still per statement). A begin/`OnTxBegin`/commit failure answers 500 `transaction_error` / "Transaction failed" (before, it returned with no response); body failures still answer via `sendError`. Tests: `pkg/funcspec/tx_test.go`. - DONE (AfterRead, decided by user): restheadspec `AfterRead` now runs in a second short tx. Test: `pkg/restheadspec/read_tx_test.go`. - DONE P7: `pkg/security/txsettings.go`: `SecurityList.SetTxSettings(fn)`, `StampTxSettings`, `ApplyTxSettings` (configurable map, decided by user; `set_config(name, value, true)`, value hex-encoded, name validated, Postgres only, fail closed). Every spec's `RegisterSecurityHooks` registers it on `OnTxBegin`. Tests: `pkg/security/txsettings_test.go`, `pkg/resolvespec/tx_settings_test.go`. Docs: `pkg/common/TRANSACTIONS.md`. -- NEXT: extra tests (create/update for other specs, `dbtrace` `pooled == 0` on real Postgres). +- DONE real-Postgres check (resolvespec, testserver via compose): create `tx=1 pooled=0`, read `tx=1 pooled=0`, update `tx=2 pooled=0` (was `pooled=1`), single delete `tx=1 pooled=0`, batch create/delete `tx=1 pooled=0`. Compose now uses host networking (bridge fails here): testserver on 8123, Postgres on 8124 (was 8080/5434); integration test DSNs updated. Smoke script covers read and update. websocketspec/mqttspec/resolvemcp/restheadspec/funcspec not measured on real Postgres. +- NEXT: extra per-spec create/update tests (optional). ## Tests - Existing: per-spec `handler_test.go`, `hooks_test.go`, `integration_test.go`; models in `pkg/testmodels/business.go`; `dbtrace` unit tests. diff --git a/docker-compose.yml b/docker-compose.yml index 4f5c819..4304ead 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,17 +6,17 @@ services: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres - ports: - - "5434:5432" + # Host networking (bridge networks are unavailable in some environments): + # postgres listens directly on host port 8124. + network_mode: host + command: ["postgres", "-p", "8124"] volumes: - postgres-test-data:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] + test: ["CMD-SHELL", "pg_isready -U postgres -p 8124"] interval: 5s timeout: 5s retries: 5 - networks: - - resolvespec-test testserver: build: @@ -27,18 +27,12 @@ services: RESOLVESPEC_DB_TRACE_ENABLED: "true" RESOLVESPEC_DB_TRACE_MIN_CALLS: "1" RESOLVESPEC_DB_TRACE_POOL_LOG: "true" - ports: - - "8080:8080" + # Serves on host port 8123 (docker/testserver.config.yaml). + network_mode: host depends_on: postgres-test: condition: service_healthy - networks: - - resolvespec-test volumes: postgres-test-data: driver: local - -networks: - resolvespec-test: - driver: bridge diff --git a/docker/Dockerfile.testserver b/docker/Dockerfile.testserver index f937a3b..50c7a50 100644 --- a/docker/Dockerfile.testserver +++ b/docker/Dockerfile.testserver @@ -9,5 +9,5 @@ FROM alpine:3.20 RUN apk add --no-cache ca-certificates COPY --from=build /out/testserver /usr/local/bin/testserver COPY docker/testserver.config.yaml /etc/resolvespec/config.yaml -EXPOSE 8080 +EXPOSE 8123 ENTRYPOINT ["testserver"] diff --git a/docker/testserver.config.yaml b/docker/testserver.config.yaml index 5a8fa98..9613e53 100644 --- a/docker/testserver.config.yaml +++ b/docker/testserver.config.yaml @@ -12,7 +12,7 @@ servers: main: name: "main" host: "0.0.0.0" - port: 8080 + port: 8123 description: "Main server instance" gzip: true tags: @@ -79,8 +79,8 @@ dbmanager: default: name: "default" type: "postgres" - host: "postgres-test" - port: 5432 + host: "localhost" + port: 8124 user: "postgres" password: "postgres" database: "postgres" diff --git a/pkg/resolvespec/integration_test.go b/pkg/resolvespec/integration_test.go index b7b8c6c..01042e0 100644 --- a/pkg/resolvespec/integration_test.go +++ b/pkg/resolvespec/integration_test.go @@ -67,7 +67,7 @@ func setupTestDB(t *testing.T) *gorm.DB { // Get connection string from environment or use default dsn := os.Getenv("TEST_DATABASE_URL") if dsn == "" { - dsn = "host=localhost user=postgres password=postgres dbname=resolvespec_test port=5434 sslmode=disable" + dsn = "host=localhost user=postgres password=postgres dbname=resolvespec_test port=8124 sslmode=disable" } db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{ diff --git a/pkg/restheadspec/integration_test.go b/pkg/restheadspec/integration_test.go index 4cdbf96..1a1d2d6 100644 --- a/pkg/restheadspec/integration_test.go +++ b/pkg/restheadspec/integration_test.go @@ -67,7 +67,7 @@ func setupTestDB(t *testing.T) *gorm.DB { // Get connection string from environment or use default dsn := os.Getenv("TEST_DATABASE_URL") if dsn == "" { - dsn = "host=localhost user=postgres password=postgres dbname=restheadspec_test port=5434 sslmode=disable" + dsn = "host=localhost user=postgres password=postgres dbname=restheadspec_test port=8124 sslmode=disable" } db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{ diff --git a/scripts/testserver-smoke.sh b/scripts/testserver-smoke.sh index de72346..30967f1 100755 --- a/scripts/testserver-smoke.sh +++ b/scripts/testserver-smoke.sh @@ -3,7 +3,7 @@ # Usage: scripts/testserver-smoke.sh [base_url] (COMPOSE overrides the compose command) set -euo pipefail -BASE="${1:-http://localhost:8080}" +BASE="${1:-http://localhost:8123}" if [ -z "${COMPOSE:-}" ]; then if command -v podman >/dev/null 2>&1; then COMPOSE="podman compose"; else COMPOSE="docker compose"; fi fi @@ -24,6 +24,8 @@ ids() { grep -o '"id":[0-9]*' "$BODY" | cut -d: -f2; } expect create 200 "$(call "{\"operation\":\"create\",\"data\":{\"name\":\"Smoke\",\"code\":\"S$TS\"}}")" ID="$(ids | head -1)" +expect read 200 "$(call '{"operation":"read"}' "/$ID")" +expect update 200 "$(call '{"operation":"update","data":{"name":"Smoke2"}}' "/$ID")" expect delete 200 "$(call '{"operation":"delete"}' "/$ID")" expect delete-again 404 "$(call '{"operation":"delete"}' "/$ID")"