archy/scripts/test-all-apps.sh

241 lines
6.5 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# test-all-apps.sh — End-to-end integration test for all marketplace apps.
# Tests each app through: install → health check → UI access → stop → restart → uninstall.
#
# Usage: SSH to the server and run:
# ./scripts/test-all-apps.sh
#
# Or run remotely:
# ssh archipelago@192.168.1.228 "cd ~/archy && bash scripts/test-all-apps.sh"
set -euo pipefail
# Configuration
RPC_URL="http://localhost:5678/rpc/"
HEALTH_URL="http://localhost/health"
MAX_WAIT=120 # Max seconds to wait for container healthy
COOKIE_FILE=$(mktemp)
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Counters
PASS=0
FAIL=0
SKIP=0
RESULTS=()
# Apps to test with their docker images
declare -A APP_IMAGES=(
["filebrowser"]="docker.io/filebrowser/filebrowser:v2-s6"
)
# Apps that need archy-net dependencies (skip if dependency not running)
declare -A APP_DEPS=(
["electrs"]="bitcoin-knots"
["mempool"]="bitcoin-knots electrs"
["btcpay"]="bitcoin-knots"
["lnd"]="bitcoin-knots"
)
log() { echo -e "${GREEN}[TEST]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
fail() { echo -e "${RED}[FAIL]${NC} $*"; }
# Authenticate and get session cookie
authenticate() {
log "Authenticating..."
local response
response=$(curl -s -c "$COOKIE_FILE" -X POST "$RPC_URL" \
-H "Content-Type: application/json" \
-d '{"method":"auth.login","params":{"password":"password123"}}')
if echo "$response" | grep -q '"error"'; then
# Try to get CSRF token from cookies
local csrf
csrf=$(grep csrf_token "$COOKIE_FILE" 2>/dev/null | awk '{print $NF}')
if [ -z "$csrf" ]; then
fail "Authentication failed: $response"
exit 1
fi
fi
log "Authenticated"
}
# RPC call helper
rpc() {
local method="$1"
local params="${2:-null}"
local csrf
csrf=$(grep csrf_token "$COOKIE_FILE" 2>/dev/null | awk '{print $NF}' || echo "")
curl -s -b "$COOKIE_FILE" -X POST "$RPC_URL" \
-H "Content-Type: application/json" \
-H "X-CSRF-Token: $csrf" \
-d "{\"method\":\"$method\",\"params\":$params}"
}
# Wait for a container to be running
wait_for_container() {
local app_id="$1"
local timeout="$2"
local elapsed=0
while [ "$elapsed" -lt "$timeout" ]; do
local status
status=$(rpc "container-status" "{\"id\":\"$app_id\"}" 2>/dev/null || echo "")
if echo "$status" | grep -qi '"running"'; then
return 0
fi
# Also check via package list
local packages
packages=$(rpc "container-list" 2>/dev/null || echo "")
if echo "$packages" | grep -qi "\"$app_id\".*running"; then
return 0
fi
sleep 5
elapsed=$((elapsed + 5))
done
return 1
}
# Test a single app lifecycle
test_app() {
local app_id="$1"
local docker_image="$2"
local result="PASS"
echo ""
log "=========================================="
log "Testing: $app_id"
log "=========================================="
# Check dependencies
if [ -n "${APP_DEPS[$app_id]:-}" ]; then
for dep in ${APP_DEPS[$app_id]}; do
local dep_status
dep_status=$(rpc "container-status" "{\"id\":\"$dep\"}" 2>/dev/null || echo "")
if ! echo "$dep_status" | grep -qi '"running"'; then
warn "Skipping $app_id — dependency $dep not running"
SKIP=$((SKIP + 1))
RESULTS+=("SKIP $app_id (needs $dep)")
return
fi
done
fi
# Step 1: Install
log "[$app_id] Installing..."
local install_result
install_result=$(rpc "package.install" "{\"id\":\"$app_id\",\"dockerImage\":\"$docker_image\"}" 2>/dev/null || echo "error")
if echo "$install_result" | grep -qi '"error"'; then
# May already be installed
if echo "$install_result" | grep -qi "already exists"; then
warn "[$app_id] Already installed, continuing..."
else
fail "[$app_id] Install failed: $install_result"
FAIL=$((FAIL + 1))
RESULTS+=("FAIL $app_id (install failed)")
return
fi
fi
# Step 2: Wait for healthy
log "[$app_id] Waiting for container to be running (max ${MAX_WAIT}s)..."
if ! wait_for_container "$app_id" "$MAX_WAIT"; then
fail "[$app_id] Container did not start within ${MAX_WAIT}s"
result="FAIL"
else
log "[$app_id] Container is running"
fi
# Step 3: Stop
log "[$app_id] Stopping..."
rpc "package.stop" "{\"id\":\"$app_id\"}" > /dev/null 2>&1
sleep 3
# Step 4: Restart
log "[$app_id] Restarting..."
rpc "package.start" "{\"id\":\"$app_id\"}" > /dev/null 2>&1
sleep 5
if ! wait_for_container "$app_id" 60; then
fail "[$app_id] Container did not restart"
result="FAIL"
else
log "[$app_id] Restart successful"
fi
# Step 5: Uninstall
log "[$app_id] Uninstalling..."
rpc "package.uninstall" "{\"id\":\"$app_id\"}" > /dev/null 2>&1
sleep 3
# Verify removed
local check
check=$(rpc "container-status" "{\"id\":\"$app_id\"}" 2>/dev/null || echo "")
if echo "$check" | grep -qi '"running"'; then
fail "[$app_id] Container still running after uninstall"
result="FAIL"
fi
if [ "$result" = "PASS" ]; then
log "[$app_id] PASSED"
PASS=$((PASS + 1))
RESULTS+=("PASS $app_id")
else
FAIL=$((FAIL + 1))
RESULTS+=("FAIL $app_id")
fi
}
# Main
echo ""
echo "============================================"
echo " Archipelago App Integration Test Suite"
echo "============================================"
echo ""
# Check backend health
if ! curl -sf "$HEALTH_URL" > /dev/null 2>&1; then
fail "Backend not healthy at $HEALTH_URL"
exit 1
fi
log "Backend is healthy"
authenticate
# Test each app
for app_id in "${!APP_IMAGES[@]}"; do
test_app "$app_id" "${APP_IMAGES[$app_id]}"
done
# Cleanup
rm -f "$COOKIE_FILE"
# Summary
echo ""
echo "============================================"
echo " Test Results"
echo "============================================"
for r in "${RESULTS[@]}"; do
case "$r" in
PASS*) echo -e " ${GREEN}$r${NC}" ;;
FAIL*) echo -e " ${RED}$r${NC}" ;;
SKIP*) echo -e " ${YELLOW}$r${NC}" ;;
esac
done
echo ""
echo " Passed: $PASS Failed: $FAIL Skipped: $SKIP"
echo "============================================"
if [ "$FAIL" -gt 0 ]; then
exit 1
fi