skillhub/scripts/tests/k8s-postgres-storage-test.sh
XiaoSeS bec701e962 test(deploy): wait for final PostgreSQL process
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-07-29 04:21:27 +08:00

128 lines
4.2 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
MANIFEST="$REPO_ROOT/deploy/k8s/overlays/with-infra/postgres-statefulset.yaml"
POSTGRES_IMAGE="${POSTGRES_IMAGE:-postgres:16-alpine}"
RUN_ID="skillhub-k8s-pgdata-$$"
FRESH_VOLUME="${RUN_ID}-fresh"
LEGACY_VOLUME="${RUN_ID}-legacy"
CONTAINERS=()
VOLUMES=("$FRESH_VOLUME" "$LEGACY_VOLUME")
cleanup() {
for container in "${CONTAINERS[@]}"; do
docker stop "$container" >/dev/null 2>&1 || true
done
for volume in "${VOLUMES[@]}"; do
docker volume rm "$volume" >/dev/null 2>&1 || true
done
}
trap cleanup EXIT
for command in docker sed; do
if ! command -v "$command" >/dev/null 2>&1; then
echo "required command not found: $command" >&2
exit 1
fi
done
POSTGRES_START_COMMAND="$(
sed -n '/^ - |$/,/^ ports:$/p' "$MANIFEST" \
| sed '1d;$d;s/^ //'
)"
if [[ -z "$POSTGRES_START_COMMAND" ]]; then
echo "could not extract the PostgreSQL startup command from $MANIFEST" >&2
exit 1
fi
wait_for_postgres() {
local container="$1"
for _ in $(seq 1 30); do
# docker-entrypoint.sh briefly starts a temporary PostgreSQL process while
# initializing a fresh cluster. Wait until PID 1 is the final server so a
# successful readiness probe cannot race with that temporary shutdown.
if docker exec "$container" sh -ec \
'test "$(cat /proc/1/comm)" = postgres' >/dev/null 2>&1 \
&& docker exec "$container" psql -U skillhub -d skillhub -Atqc \
'SELECT 1' >/dev/null 2>&1; then
return 0
fi
sleep 1
done
docker logs "$container" >&2
return 1
}
start_postgres() {
local container="$1"
local volume="$2"
local mode="${3:-default}"
CONTAINERS+=("$container")
if [[ "$mode" == "patched" ]]; then
docker run --detach --rm \
--name "$container" \
--env POSTGRES_DB=skillhub \
--env POSTGRES_USER=skillhub \
--env POSTGRES_PASSWORD=storage-test \
--volume "$volume:/var/lib/postgresql/data" \
--entrypoint sh \
"$POSTGRES_IMAGE" \
-ec "$POSTGRES_START_COMMAND" >/dev/null
else
docker run --detach --rm \
--name "$container" \
--env POSTGRES_DB=skillhub \
--env POSTGRES_USER=skillhub \
--env POSTGRES_PASSWORD=storage-test \
--volume "$volume:/var/lib/postgresql/data" \
"$POSTGRES_IMAGE" >/dev/null
fi
wait_for_postgres "$container"
}
stop_postgres() {
docker stop "$1" >/dev/null
}
assert_marker() {
local container="$1"
local expected="$2"
local actual
actual="$(docker exec "$container" psql -U skillhub -d skillhub -Atqc \
'SELECT value FROM storage_upgrade_verification WHERE id = 1')"
[[ "$actual" == "$expected" ]]
}
docker volume create "$FRESH_VOLUME" >/dev/null
docker run --rm \
--volume "$FRESH_VOLUME:/data" \
--entrypoint sh \
"$POSTGRES_IMAGE" \
-ec 'mkdir -p /data/lost+found'
start_postgres "${RUN_ID}-fresh-1" "$FRESH_VOLUME" patched
docker exec "${RUN_ID}-fresh-1" test -f /var/lib/postgresql/data/pgdata/PG_VERSION
docker exec "${RUN_ID}-fresh-1" psql -U skillhub -d skillhub -v ON_ERROR_STOP=1 -qc \
"CREATE TABLE storage_upgrade_verification (id integer PRIMARY KEY, value text NOT NULL); \
INSERT INTO storage_upgrade_verification VALUES (1, 'fresh-volume');"
stop_postgres "${RUN_ID}-fresh-1"
start_postgres "${RUN_ID}-fresh-2" "$FRESH_VOLUME" patched
assert_marker "${RUN_ID}-fresh-2" "fresh-volume"
stop_postgres "${RUN_ID}-fresh-2"
echo "PASS: fresh volume with lost+found initializes in pgdata and survives restart"
docker volume create "$LEGACY_VOLUME" >/dev/null
start_postgres "${RUN_ID}-legacy-1" "$LEGACY_VOLUME"
docker exec "${RUN_ID}-legacy-1" test -f /var/lib/postgresql/data/PG_VERSION
docker exec "${RUN_ID}-legacy-1" psql -U skillhub -d skillhub -v ON_ERROR_STOP=1 -qc \
"CREATE TABLE storage_upgrade_verification (id integer PRIMARY KEY, value text NOT NULL); \
INSERT INTO storage_upgrade_verification VALUES (1, 'legacy-root');"
stop_postgres "${RUN_ID}-legacy-1"
start_postgres "${RUN_ID}-legacy-2" "$LEGACY_VOLUME" patched
assert_marker "${RUN_ID}-legacy-2" "legacy-root"
stop_postgres "${RUN_ID}-legacy-2"
echo "PASS: legacy root-level cluster remains visible after the manifest upgrade"