diff --git a/tests/lifecycle/bats/immich.bats b/tests/lifecycle/bats/immich.bats new file mode 100644 index 00000000..cec680c2 --- /dev/null +++ b/tests/lifecycle/bats/immich.bats @@ -0,0 +1,122 @@ +#!/usr/bin/env bats +# tests/lifecycle/bats/immich.bats +# +# Lifecycle tests for the immich stack (manifest-driven: immich + immich-postgres +# + immich-redis, installed via the orchestrator — NOT the legacy install_immich_stack). +# +# Tiers: +# - Read-only (always): presence + valid state of all 3 members +# - Destructive (ARCHY_ALLOW_DESTRUCTIVE=1): stop → start → restart the server +# - Cascade (ARCHY_ALLOW_CASCADE_DESTRUCTIVE=1): uninstall → reinstall the stack +# (preserve_data so the photo library + DB survive) +# +# All checks are RPC-based so the suite is correct whether run on the host or +# against a remote ARCHY_HOST. + +load '../lib/rpc.bash' + +IMMICH_IMAGE="146.59.87.168:3000/lfg2025/immich-server:release" + +setup_file() { + : "${ARCHY_PASSWORD:?Set ARCHY_PASSWORD env var to the UI password}" + export ARCHY_FORCE_LOGIN=1 + rpc_login + unset ARCHY_FORCE_LOGIN +} + +teardown_file() { + rpc_logout_local +} + +container_state() { + rpc_result container-list | jq -r --arg n "$1" '.[] | select(.name == $n) | .state' +} + +# ──────────────────────────────────────────────────────────────────── +# Read-only tier +# ──────────────────────────────────────────────────────────────────── + +@test "container-list includes the immich stack members" { + run rpc_result container-list + [ "$status" -eq 0 ] + echo "$output" | jq -e '.[] | select(.name == "immich")' >/dev/null + echo "$output" | jq -e '.[] | select(.name == "immich-postgres")' >/dev/null + echo "$output" | jq -e '.[] | select(.name == "immich-redis")' >/dev/null +} + +@test "immich stack members report valid states" { + for c in immich immich-postgres immich-redis; do + local state + state=$(container_state "$c") + [[ "$state" =~ ^(running|stopped|exited|created|paused)$ ]] || { + echo "unexpected state for $c: $state"; return 1 + } + done +} + +@test "no legacy underscore immich containers (immich_postgres/_redis/_server)" { + # The legacy install_immich_stack named members with underscores. The + # manifest-driven stack uses hyphenated app_id names. Underscore containers + # mean a botched migration (or a fallback to the legacy installer). + run rpc_result container-list + [ "$status" -eq 0 ] + echo "$output" | jq -e '[.[] | select(.name | test("^immich_"))] | length == 0' >/dev/null +} + +# ──────────────────────────────────────────────────────────────────── +# Destructive tier (stop → start → restart the server) +# ──────────────────────────────────────────────────────────────────── + +@test "package.stop transitions immich to stopped" { + [[ "${ARCHY_ALLOW_DESTRUCTIVE:-0}" == "1" ]] || skip "ARCHY_ALLOW_DESTRUCTIVE not set" + run rpc_result package.stop '{"id":"immich"}' + [ "$status" -eq 0 ] + run wait_for_container_status immich stopped 60 + [ "$status" -eq 0 ] +} + +@test "package.start brings immich back to running" { + [[ "${ARCHY_ALLOW_DESTRUCTIVE:-0}" == "1" ]] || skip "ARCHY_ALLOW_DESTRUCTIVE not set" + run rpc_result package.start '{"id":"immich"}' + [ "$status" -eq 0 ] + run wait_for_container_status immich running 120 + [ "$status" -eq 0 ] +} + +@test "package.restart leaves immich in running state" { + [[ "${ARCHY_ALLOW_DESTRUCTIVE:-0}" == "1" ]] || skip "ARCHY_ALLOW_DESTRUCTIVE not set" + run rpc_result package.restart '{"id":"immich"}' + [ "$status" -eq 0 ] + run wait_for_container_status immich running 120 + [ "$status" -eq 0 ] +} + +@test "postgres + redis stay running across an immich server restart" { + [[ "${ARCHY_ALLOW_DESTRUCTIVE:-0}" == "1" ]] || skip "ARCHY_ALLOW_DESTRUCTIVE not set" + [ "$(container_state immich-postgres)" == "running" ] + [ "$(container_state immich-redis)" == "running" ] +} + +# ──────────────────────────────────────────────────────────────────── +# Cascade tier (uninstall + reinstall the stack) +# ──────────────────────────────────────────────────────────────────── + +@test "package.uninstall removes the immich stack (data preserved)" { + [[ "${ARCHY_ALLOW_CASCADE_DESTRUCTIVE:-0}" == "1" ]] || skip "ARCHY_ALLOW_CASCADE_DESTRUCTIVE not set" + run rpc_result package.uninstall '{"id":"immich","preserve_data":true}' + [ "$status" -eq 0 ] + run wait_for_container_status immich absent 120 + [ "$status" -eq 0 ] +} + +@test "package.install immich brings the whole stack back to running" { + [[ "${ARCHY_ALLOW_CASCADE_DESTRUCTIVE:-0}" == "1" ]] || skip "ARCHY_ALLOW_CASCADE_DESTRUCTIVE not set" + run rpc_result package.install "{\"id\":\"immich\",\"dockerImage\":\"${IMMICH_IMAGE}\"}" + [ "$status" -eq 0 ] + run wait_for_container_status immich running 180 + [ "$status" -eq 0 ] + run wait_for_container_status immich-postgres running 120 + [ "$status" -eq 0 ] + run wait_for_container_status immich-redis running 120 + [ "$status" -eq 0 ] +}