93d33ecb0c
SLICE-08 (devops-engineer): .env.example updated with Proxmox deployment vars (documented, sourced from ~/coreci/.env.secrets per D-026), PRAXIS_CLIENT_DIST for StaticFiles, PRAXIS_SCENARIO. config.json secrets.scopes already extended in SPECIFY (proxmox + voice scopes). SLICE-09 (devops-engineer): 10 bats test files (G-106 fix: 10 not 9) covering all proxmox scripts — 121 tests, 114 pass + 7 skipped (e2e). Mocked curl/pct/ssh; no live cluster needed for unit tests. SLICE-10 (devops-engineer): e2e-deploy.sh — sources secrets from both coreci + praxis .env.secrets, runs full deploy, verifies /health + client HTML serving. REQ-DEPLOY-15 covered. All 6 grill binding decisions addressed: G-101 MUST: GITEA_TOKEN baked into snippet (stage-snippet.sh) G-102 MUST: PRAXIS_DB_PATH env read (db/store.py + db/migrate.py) G-103 FIX: all 16 env vars in injection list (install-service.sh) G-104 FIX: health-check timeout 600s (health-check.sh) G-105 FIX: Dockerfile copy ordering (pyproject before source) G-106 FIX: bats test count = 10 REQ-DEPLOY-12, 14, 15 covered. All 20 REQ-IDs now implemented. ---ci--- project: praxis phase: 1 milestone: v0.2 status: execute slice: 08-10 wave: 4 ---/ci---
146 lines
6.3 KiB
Bash
146 lines
6.3 KiB
Bash
#!/usr/bin/env bats
|
|
# Bats END-TO-END integration suite for the praxis v0.2 Proxmox deploy
|
|
# stack (SLICE-09 capstone).
|
|
#
|
|
# Run (live): PRAXIS_E2E_LIVE=1 bats scripts/proxmox/test/e2e-deploy.bats
|
|
# Run (default, skipped): bats scripts/proxmox/test/e2e-deploy.bats
|
|
#
|
|
# Unlike the per-script orchestrator tests (lxc-deploy.bats) which stub
|
|
# every sibling, this suite runs the REAL lxc-deploy.sh + its REAL
|
|
# sibling scripts against a LIVE Proxmox cluster to prove the full
|
|
# deploy sequence works end-to-end:
|
|
#
|
|
# stage-snippet → clone → config → start → health-check → success
|
|
# → (rollback on any failure)
|
|
#
|
|
# These tests are SKIPPED by default (no live cluster in CI). Set
|
|
# PRAXIS_E2E_LIVE=1 + the PROXMOX_* + GITEA_TOKEN env vars to run them
|
|
# against a real cluster. The skip guard emits a clear message so a
|
|
# plain `bats` invocation doesn't silently no-op.
|
|
#
|
|
# Required env (when PRAXIS_E2E_LIVE=1):
|
|
# PROXMOX_API_URL — https://proxmox:8006/api2/json
|
|
# PROXMOX_API_TOKEN — USER@REALM!TOKENID=SECRET
|
|
# PROXMOX_NODE — target node name
|
|
# PROXMOX_STORAGE — storage holding the template
|
|
# PROXMOX_TEMPLATE_VOLID — local:vztmpl/debian-12-template.tar.zst
|
|
# GITEA_TOKEN — bearer token for the private Gitea repo
|
|
# PROXMOX_LXC_VMID — target CT VMID (auto-allocated if unset)
|
|
#
|
|
# Optional env:
|
|
# PRAXIS_E2E_LIVE — set to 1 to run these tests (default: skip)
|
|
# PRAXIS_VERSION — git ref to deploy (default: main)
|
|
# PRAXIS_PORT — server HTTP port (default: 8789)
|
|
# PRAXIS_HEALTH_URL — override health-check URL
|
|
# PRAXIS_HEALTH_TIMEOUT — health-check timeout (default: 600)
|
|
|
|
# Skip guard: unless PRAXIS_E2E_LIVE=1, skip every test in this file
|
|
# with a clear message. This keeps `bats scripts/proxmox/test/` safe to
|
|
# run in CI (no live cluster, no accidental destroys).
|
|
setup() {
|
|
if [ "${PRAXIS_E2E_LIVE:-0}" != "1" ]; then
|
|
skip "PRAXIS_E2E_LIVE!=1 — set PRAXIS_E2E_LIVE=1 + PROXMOX_* env to run live e2e tests"
|
|
fi
|
|
SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
# Resolve the deploy script from the real source tree.
|
|
DEPLOY="${SCRIPT_DIR}/lxc-deploy.sh"
|
|
[ -x "$DEPLOY" ] || skip "lxc-deploy.sh not found at ${DEPLOY}"
|
|
|
|
# Validate required live env vars are present.
|
|
for var in PROXMOX_API_URL PROXMOX_API_TOKEN PROXMOX_NODE \
|
|
PROXMOX_STORAGE PROXMOX_TEMPLATE_VOLID GITEA_TOKEN; do
|
|
eval "val=\"\${${var}:-}\""
|
|
[ -n "$val" ] || skip "${var} is required for live e2e (PRAXIS_E2E_LIVE=1)"
|
|
done
|
|
|
|
# Use a dedicated VMID for e2e to avoid clobbering a production CT.
|
|
# If PROXMOX_LXC_VMID is unset, default to a high number + warn.
|
|
if [ -z "${PROXMOX_LXC_VMID:-}" ]; then
|
|
export PROXMOX_LXC_VMID="900"
|
|
echo "e2e: PROXMOX_LXC_VMID unset — defaulting to 900 for live test" >&2
|
|
fi
|
|
echo "e2e: targeting VMID ${PROXMOX_LXC_VMID} on node ${PROXMOX_NODE}" >&2
|
|
}
|
|
|
|
teardown() {
|
|
# Live teardown: if a test left a CT behind, clean it up so the
|
|
# cluster isn't polluted. Only runs when PRAXIS_E2E_LIVE=1.
|
|
if [ "${PRAXIS_E2E_LIVE:-0}" = "1" ] && [ -n "${PROXMOX_LXC_VMID:-}" ]; then
|
|
SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
if [ -x "${SCRIPT_DIR}/rollback.sh" ]; then
|
|
"${SCRIPT_DIR}/rollback.sh" "$PROXMOX_LXC_VMID" >/dev/null 2>&1 || true
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# ── Live e2e tests (only run when PRAXIS_E2E_LIVE=1) ─────────────
|
|
|
|
@test "live e2e: full deploy — stage → clone → config → start → health → VMID=<n>" {
|
|
run "${DEPLOY}"
|
|
[ "$status" -eq 0 ]
|
|
grep -q "^VMID=${PROXMOX_LXC_VMID}$" <<< "$output"
|
|
grep -q 'deploy: praxis deployed successfully' <<< "$output"
|
|
# No rollback on success.
|
|
! grep -q 'deploy: FAILED' <<< "$output"
|
|
}
|
|
|
|
@test "live e2e: idempotent re-deploy — same VMID healthy → skip clone" {
|
|
# First deploy (the previous test should have left a healthy CT, OR
|
|
# this test is run in isolation after a successful deploy).
|
|
run "${DEPLOY}"
|
|
[ "$status" -eq 0 ]
|
|
# Either it skipped (already healthy) or it deployed fresh.
|
|
case "" in
|
|
"$(grep 'already running + healthy' <<< "$output")")
|
|
grep -q 'skipping clone/config/start (idempotent re-deploy)' <<< "$output"
|
|
;;
|
|
esac
|
|
grep -q "^VMID=${PROXMOX_LXC_VMID}$" <<< "$output"
|
|
! grep -q 'deploy: FAILED' <<< "$output"
|
|
}
|
|
|
|
@test "live e2e: --recreate — rollback + redeploy succeeds" {
|
|
run "${DEPLOY}" --recreate
|
|
[ "$status" -eq 0 ]
|
|
grep -q -- '--recreate' <<< "$output"
|
|
grep -q "^VMID=${PROXMOX_LXC_VMID}$" <<< "$output"
|
|
! grep -q 'deploy: FAILED' <<< "$output"
|
|
}
|
|
|
|
@test "live e2e: unknown flag → exit 2 (usage)" {
|
|
run "${DEPLOY}" --bogus-flag
|
|
[ "$status" -eq 2 ]
|
|
grep -q 'unknown argument: --bogus-flag' <<< "$output"
|
|
}
|
|
|
|
@test "live e2e: health-check against the deployed CT passes (praxis healthy)" {
|
|
# Run health-check.sh directly against the deployed CT. If the CT
|
|
# was destroyed by a prior teardown, this skips.
|
|
SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
[ -x "${SCRIPT_DIR}/health-check.sh" ] || skip "health-check.sh not found"
|
|
run "${SCRIPT_DIR}/health-check.sh" "${PROXMOX_LXC_VMID}"
|
|
[ "$status" -eq 0 ]
|
|
grep -q 'health-check: praxis healthy' <<< "$output"
|
|
}
|
|
|
|
@test "live e2e: rollback.sh cleans up the CT (idempotent, 404-tolerant)" {
|
|
SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
[ -x "${SCRIPT_DIR}/rollback.sh" ] || skip "rollback.sh not found"
|
|
run "${SCRIPT_DIR}/rollback.sh" "${PROXMOX_LXC_VMID}"
|
|
[ "$status" -eq 0 ]
|
|
grep -q 'rollback: VMID .* cleaned up' <<< "$output"
|
|
# A second rollback must be 404-tolerant (idempotent).
|
|
run "${SCRIPT_DIR}/rollback.sh" "${PROXMOX_LXC_VMID}"
|
|
[ "$status" -eq 0 ]
|
|
grep -q 'rollback: VMID .* cleaned up' <<< "$output"
|
|
}
|
|
|
|
@test "live e2e: rollback.sh on a never-existed VMID → exit 0 (404-tolerant)" {
|
|
SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
[ -x "${SCRIPT_DIR}/rollback.sh" ] || skip "rollback.sh not found"
|
|
# Pick a VMID that definitely doesn't exist (high random range).
|
|
nonexistent="99999"
|
|
run "${SCRIPT_DIR}/rollback.sh" "$nonexistent"
|
|
[ "$status" -eq 0 ]
|
|
grep -q "rollback: VMID ${nonexistent} cleaned up" <<< "$output"
|
|
} |