feat(\db-tool\): introduce unified db-tool package with postgres harness and tests (T0-T8)

This commit is contained in:
2026-04-30 09:06:44 +00:00
parent 395bddee94
commit b5dcbf08a1
27 changed files with 2417 additions and 1 deletions

View File

@@ -0,0 +1,19 @@
# shellcheck shell=dash
HECTIC_NAMESPACE=test-db-tool-help
log notice "test case: database --help exits 0"
if ! database --help > /tmp/help-out.txt 2>&1; then
log error "test failed: database --help exited non-zero"
exit 1
fi
for tok in deploy pull_staging cleanup check log init migrator; do
if ! grep -qF "$tok" /tmp/help-out.txt; then
log error "test failed: --help output missing token: $tok"
cat /tmp/help-out.txt >&2
exit 1
fi
done
log notice "test passed"

View File

@@ -0,0 +1,19 @@
# shellcheck shell=dash
HECTIC_NAMESPACE=test-db-tool-missing-dir
export PGURL=""
unset LOCAL_DIR DATABASE_DIR DB_URL 2>/dev/null || true
log notice "test case: database deploy fails without LOCAL_DIR"
set +e
database deploy 2>/tmp/missing-err.txt
code=$?
set -e
if [ "$code" = 0 ]; then
log error "test failed: database deploy exited 0 without LOCAL_DIR"
exit 1
fi
log notice "test passed: exited $code"

View File

@@ -0,0 +1,19 @@
# shellcheck shell=dash
HECTIC_NAMESPACE=test-db-tool-deploy-basic
pg_harness_start
LOCAL_DIR=$(mktemp -d)
export LOCAL_DIR
mkdir -p "$LOCAL_DIR/devshell"
printf '#!/bin/dash\nexit 0\n' > "$LOCAL_DIR/devshell/postgres-init.sh"
chmod +x "$LOCAL_DIR/devshell/postgres-init.sh"
log notice "test case: database deploy --no-hydrate --no-patch exits 0"
if ! database deploy --no-hydrate --no-patch; then
log error "database deploy failed"
exit 1
fi
log notice "test passed"

View File

@@ -0,0 +1,20 @@
# shellcheck shell=dash
HECTIC_NAMESPACE=test-db-tool-deploy-cleanup-flag
pg_harness_start
LOCAL_DIR=$(mktemp -d)
export LOCAL_DIR
mkdir -p "$LOCAL_DIR/devshell"
printf '#!/bin/dash\nexit 0\n' > "$LOCAL_DIR/devshell/postgres-init.sh"
printf '#!/bin/dash\nexit 0\n' > "$LOCAL_DIR/devshell/postgres-cleanup.sh"
chmod +x "$LOCAL_DIR/devshell/postgres-init.sh" "$LOCAL_DIR/devshell/postgres-cleanup.sh"
log notice "test case: database deploy --no-hydrate --no-patch --cleanup exits 0"
if ! database deploy --no-hydrate --no-patch --cleanup; then
log error "database deploy --cleanup failed"
exit 1
fi
log notice "test passed"

View File

@@ -0,0 +1,36 @@
# shellcheck shell=dash
HECTIC_NAMESPACE=test-db-tool-init-cleanup-roundtrip
PG_WORKING_DIR=$(mktemp -d)
export PG_WORKING_DIR PG_DATABASE=testdb PG_PORT=5432 PG_SHARED_PRELOAD_LIBRARIES=''
cleanup() {
postgres-cleanup
rm -rf "$PG_WORKING_DIR"
}
trap 'cleanup' EXIT INT TERM
log notice "test case: postgres-init starts cluster"
if ! postgres-init; then
log error "postgres-init failed"
exit 1
fi
pgurl="postgresql://$(id -un)@/testdb?host=${PG_WORKING_DIR}/sock&port=5432"
log notice "verifying connection"
if ! psql "$pgurl" -c 'SELECT 1;' >/dev/null 2>&1; then
log error "connection failed after postgres-init"
exit 1
fi
log notice "test case: postgres-cleanup stops cluster"
postgres-cleanup
log notice "verifying cluster stopped"
if pg_isready -h "${PG_WORKING_DIR}/sock" -p 5432 >/dev/null 2>&1; then
log error "postgres still running after cleanup"
exit 1
fi
log notice "test passed"

View File

@@ -0,0 +1,18 @@
# shellcheck shell=dash
HECTIC_NAMESPACE=test-db-tool-log-subcommand
PG_WORKING_DIR=$(mktemp -d)
LOCAL_DIR=$(mktemp -d)
export PG_WORKING_DIR LOCAL_DIR PGURL='postgresql://localhost/db'
mkdir -p "$PG_WORKING_DIR/data/log"
trap 'rm -rf "$PG_WORKING_DIR" "$LOCAL_DIR"' EXIT INT TERM
log notice "test case: database log list exits 0 with empty log dir"
if ! database log list; then
log error "database log list failed"
exit 1
fi
log notice "test passed"

View File

@@ -0,0 +1,19 @@
# shellcheck shell=dash
HECTIC_NAMESPACE=test-db-tool-postgres-cleanup-stale-pidfile
PG_WORKING_DIR=$(mktemp -d)
export PG_WORKING_DIR
mkdir -p "$PG_WORKING_DIR/data"
printf '99999999\n' > "$PG_WORKING_DIR/data/postmaster.pid"
trap 'rm -rf "$PG_WORKING_DIR"' EXIT INT TERM
log notice "test case: postgres-cleanup exits 0 with stale pidfile"
if ! postgres-cleanup; then
log error "postgres-cleanup failed with stale pidfile"
exit 1
fi
log notice "test passed"

View File

@@ -0,0 +1,42 @@
# shellcheck shell=dash
HECTIC_NAMESPACE=test-db-tool-postgres-init-busy-socket
PG_WORKING_DIR=$(mktemp -d)
export PG_WORKING_DIR PG_DATABASE=testdb PG_PORT=5432 PG_SHARED_PRELOAD_LIBRARIES=''
trap 'pg_harness_stop; rm -rf "$PG_WORKING_DIR"' EXIT INT TERM
log notice "setup: creating initial postgres cluster"
if ! postgres-init; then
log error "setup failed: initial postgres-init failed"
exit 1
fi
log notice "setup: stopping postgres to free socket"
postgres-cleanup
log notice "setup: occupying socket with netcat"
pg_harness__start_busy_socket "$PG_WORKING_DIR/sock"
i=0
while [ "$i" -lt 50 ] && ! [ -S "$PG_HARNESS_BUSY_SOCKET_PATH" ]; do
sleep 0.1
i=$((i + 1))
done
[ -S "$PG_HARNESS_BUSY_SOCKET_PATH" ] || { log error "busy socket not ready"; exit 1; }
printf '%d\n' "$PG_HARNESS_BUSY_SOCKET_PID" > "${PG_HARNESS_BUSY_SOCKET_PATH}.lock"
log notice "test case: postgres-init fails when socket is pre-occupied"
PG_REUSE=1
export PG_REUSE
set +e
postgres-init
code=$?
set -e
if [ "$code" = 0 ]; then
log error "test failed: postgres-init exited 0 with busy socket"
exit 1
fi
log notice "test passed: exited $code"

View File

@@ -0,0 +1,23 @@
# shellcheck shell=dash
HECTIC_NAMESPACE=test-db-tool-postgres-init-corrupt-pgdata
pg_harness_start_corrupt_dir
export PG_WORKING_DIR="$PG_HARNESS_PGDATA_OVERRIDE"
export PG_SHARED_PRELOAD_LIBRARIES=''
trap 'pg_harness_stop' EXIT INT TERM
log notice "test case: postgres-init fails when PG_WORKING_DIR is a regular file"
set +e
postgres-init
code=$?
set -e
if [ "$code" = 0 ]; then
log error "test failed: postgres-init exited 0 with corrupt dir"
exit 1
fi
log notice "test passed: exited $code"

View File

@@ -0,0 +1,26 @@
# shellcheck shell=dash
HECTIC_NAMESPACE=test-db-tool-pull-staging
export PGURL=""
unset STAGING_SSH_HOST STAGING_DB_URL STAGING_USER STAGING_HOST 2>/dev/null || true
log notice "test case: database pull_staging exits 3 without STAGING_SSH_HOST"
set +e
database pull_staging 2>/build/staging-err.txt
code=$?
set -e
if [ "$code" != 3 ]; then
log error "test failed: expected exit 3, got $code"
exit 1
fi
if ! grep -q 'STAGING_SSH_HOST' /build/staging-err.txt; then
log error "test failed: stderr does not mention STAGING_SSH_HOST"
exit 1
fi
log notice "test passed"
log notice "test passed"

View File

@@ -0,0 +1,16 @@
# shellcheck shell=dash
HECTIC_NAMESPACE=test-db-tool-unknown
log notice "test case: database nonsense exits non-zero (expected 1)"
set +e
database nonsense 2>/dev/null
code=$?
set -e
if [ "$code" = 0 ]; then
log error "test failed: database nonsense exited 0 (should be non-zero)"
exit 1
fi
log notice "test passed: exited $code"