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---
173 lines
5.5 KiB
Bash
173 lines
5.5 KiB
Bash
#!/usr/bin/env bats
|
|
# Bats tests for scripts/proxmox/lxc-clone.sh (praxis CT clone).
|
|
#
|
|
# Run: bats scripts/proxmox/test/lxc-clone.bats
|
|
#
|
|
# lxc-clone.sh creates a CT from a template via POST /nodes/{node}/lxc
|
|
# (create-from-template), then polls the returned UPID. These tests
|
|
# exercise the real lxc-clone.sh with a mocked api.sh (pve_curl records
|
|
# its argv to $CALL_LOG then returns STUB_UPID; pve_poll records the
|
|
# UPID) so the POST body shape + UPID-poll + empty-UPID error path are
|
|
# verified without a live Proxmox endpoint.
|
|
#
|
|
# Praxis v0.2 (vs coreci) key differences asserted here:
|
|
# - hostname defaults to "praxis" (NOT "coreci")
|
|
# - memory defaults to 4096 (NOT 2048)
|
|
# - rootfs is <storage>:16 (NOT <storage>:8)
|
|
# - features=nesting=1, net0=name=eth0,bridge=vmbr0,ip=dhcp
|
|
|
|
setup() {
|
|
SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
CLONE="${SCRIPT_DIR}/lxc-clone.sh"
|
|
|
|
STUB_DIR="$(mktemp -d)"
|
|
export STUB_DIR
|
|
LOG="${STUB_DIR}/calls.log"
|
|
export CALL_LOG="$LOG"
|
|
: > "$LOG" 2>/dev/null || true
|
|
|
|
# Sandbox: <ROOT>/lxc-clone.sh (SCRIPT_DIR) + <ROOT>/api.sh (sourced).
|
|
ROOT="${STUB_DIR}/root"
|
|
mkdir -p "$ROOT"
|
|
cp "$CLONE" "${ROOT}/lxc-clone.sh"
|
|
|
|
# Mocked api.sh — pve_env no-op; pve_curl records method + path +
|
|
# every form-data pair to $CALL_LOG then returns STUB_UPID; pve_poll
|
|
# records the UPID it was asked to wait on.
|
|
cat > "${ROOT}/api.sh" <<'ASTUB'
|
|
pve_env() { :; }
|
|
pve_curl() {
|
|
method="$1"; path="$2"; shift 2
|
|
printf '%s\n' "${method} ${path} $*" >> "$CALL_LOG"
|
|
printf '%s\n' "${STUB_UPID:-null}"
|
|
}
|
|
pve_poll() {
|
|
printf 'poll:%s\n' "$1" >> "$CALL_LOG"
|
|
}
|
|
pve_tls_insecure() { :; }
|
|
pve_auth_header() { :; }
|
|
ASTUB
|
|
|
|
chmod +x "${ROOT}"/*.sh
|
|
|
|
export PROXMOX_API_URL="https://proxmox.test:8006/api2/json"
|
|
export PROXMOX_API_TOKEN="root@pam!test=secret"
|
|
export PROXMOX_NODE="testnode"
|
|
export PROXMOX_STORAGE="local"
|
|
export PROXMOX_TEMPLATE_VOLID="local:vztmpl/debian-12-template.tar.zst"
|
|
}
|
|
|
|
teardown() {
|
|
[ -n "${STUB_DIR:-}" ] && rm -rf "$STUB_DIR"
|
|
}
|
|
|
|
@test "clone: create-from-template POST shape (vmid, ostemplate, hostname=praxis, storage, rootfs=16, memory=4096, net0, arch, features)" {
|
|
STUB_UPID="UPID:testnode:00012345:ABCDEF"
|
|
export STUB_UPID
|
|
run "${ROOT}/lxc-clone.sh" 200
|
|
[ "$status" -eq 0 ]
|
|
# The new VMID is echoed on stdout.
|
|
grep -q '^200$' <<< "$output"
|
|
# pve_curl POST to /nodes/testnode/lxc recorded with the full body.
|
|
grep -q '^POST /nodes/testnode/lxc vmid=200 ostemplate=local:vztmpl/debian-12-template.tar.zst hostname=praxis storage=local rootfs=local:16 memory=4096 net0=name=eth0,bridge=vmbr0,ip=dhcp arch=amd64 features=nesting=1$' "$LOG"
|
|
# UPID was polled.
|
|
grep -q '^poll:UPID:testnode:00012345:ABCDEF$' "$LOG"
|
|
grep -q 'lxc-clone: CT 200 created' <<< "$output"
|
|
}
|
|
|
|
@test "clone: hostname is 'praxis' (NOT 'coreci') — G-106 praxis rebrand" {
|
|
STUB_UPID="UPID:h:1"
|
|
export STUB_UPID
|
|
run "${ROOT}/lxc-clone.sh" 201
|
|
[ "$status" -eq 0 ]
|
|
grep -q ' hostname=praxis ' "$LOG"
|
|
! grep -q 'hostname=coreci' "$LOG"
|
|
}
|
|
|
|
@test "clone: memory defaults to 4096 (NOT 2048) — praxis v0.2 sizing" {
|
|
STUB_UPID="UPID:m:1"
|
|
export STUB_UPID
|
|
run "${ROOT}/lxc-clone.sh" 202
|
|
[ "$status" -eq 0 ]
|
|
grep -q ' memory=4096 ' "$LOG"
|
|
! grep -q 'memory=2048' "$LOG"
|
|
}
|
|
|
|
@test "clone: rootfs is <storage>:16 (NOT :8) — praxis v0.2 disk sizing" {
|
|
STUB_UPID="UPID:r:1"
|
|
export STUB_UPID
|
|
run "${ROOT}/lxc-clone.sh" 203
|
|
[ "$status" -eq 0 ]
|
|
grep -q ' rootfs=local:16 ' "$LOG"
|
|
! grep -q 'rootfs=local:8' "$LOG"
|
|
}
|
|
|
|
@test "clone: features=nesting=1 (Docker-in-LXC requires nesting)" {
|
|
STUB_UPID="UPID:f:1"
|
|
export STUB_UPID
|
|
run "${ROOT}/lxc-clone.sh" 204
|
|
[ "$status" -eq 0 ]
|
|
grep -q 'features=nesting=1' "$LOG"
|
|
}
|
|
|
|
@test "clone: net0 uses bridge=vmbr0,ip=dhcp" {
|
|
STUB_UPID="UPID:n:1"
|
|
export STUB_UPID
|
|
run "${ROOT}/lxc-clone.sh" 205
|
|
[ "$status" -eq 0 ]
|
|
grep -q 'net0=name=eth0,bridge=vmbr0,ip=dhcp' "$LOG"
|
|
}
|
|
|
|
@test "clone: PRAXIS_HOSTNAME override flows into hostname field" {
|
|
STUB_UPID="UPID:h:2"
|
|
export STUB_UPID
|
|
PRAXIS_HOSTNAME="praxis-staging" run "${ROOT}/lxc-clone.sh" 206
|
|
[ "$status" -eq 0 ]
|
|
grep -q 'hostname=praxis-staging' "$LOG"
|
|
}
|
|
|
|
@test "clone: PROXMOX_MEMORY_MB override flows into memory field" {
|
|
STUB_UPID="UPID:m:2"
|
|
export STUB_UPID
|
|
PROXMOX_MEMORY_MB=8192 run "${ROOT}/lxc-clone.sh" 207
|
|
[ "$status" -eq 0 ]
|
|
grep -q 'memory=8192' "$LOG"
|
|
}
|
|
|
|
@test "clone: empty UPID (null) → exit 1, no poll, error logged" {
|
|
STUB_UPID="null"
|
|
export STUB_UPID
|
|
run "${ROOT}/lxc-clone.sh" 208
|
|
[ "$status" -ne 0 ]
|
|
grep -q 'failed to start create (empty UPID)' <<< "$output"
|
|
! grep -q '^poll:' "$LOG"
|
|
}
|
|
|
|
@test "clone: empty-string UPID → exit 1, no poll" {
|
|
STUB_UPID=""
|
|
export STUB_UPID
|
|
run "${ROOT}/lxc-clone.sh" 209
|
|
[ "$status" -ne 0 ]
|
|
grep -q 'failed to start create (empty UPID)' <<< "$output"
|
|
! grep -q '^poll:' "$LOG"
|
|
}
|
|
|
|
@test "clone: missing VMID arg → exit non-zero (usage)" {
|
|
run "${ROOT}/lxc-clone.sh"
|
|
[ "$status" -ne 0 ]
|
|
grep -q 'usage: lxc-clone.sh' <<< "$output"
|
|
}
|
|
|
|
@test "clone: pve_env fails on missing PROXMOX_STORAGE → exit non-zero" {
|
|
STUB_UPID="UPID:e:1"
|
|
export STUB_UPID
|
|
run env -u PROXMOX_STORAGE "${ROOT}/lxc-clone.sh" 210
|
|
[ "$status" -ne 0 ]
|
|
}
|
|
|
|
@test "clone: pve_env fails on missing PROXMOX_TEMPLATE_VOLID → exit non-zero" {
|
|
STUB_UPID="UPID:e:2"
|
|
export STUB_UPID
|
|
run env -u PROXMOX_TEMPLATE_VOLID "${ROOT}/lxc-clone.sh" 211
|
|
[ "$status" -ne 0 ]
|
|
} |