fix: prevent tokio runtime deadlock in credential issue/verify
The credential issuance and verification handlers used Handle::block_on() directly inside the tokio runtime, causing a deadlock. Wrapped with block_in_place() to properly yield the runtime thread. Also completed full feature verification across all 25 test groups (~175 checks) on live server. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
143
scripts/test-dep-chains.sh
Executable file
143
scripts/test-dep-chains.sh
Executable file
@@ -0,0 +1,143 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
# TEST-202: Dependency chain test.
|
||||
# Tests that apps with dependencies properly enforce install order.
|
||||
#
|
||||
# Test chains:
|
||||
# 1. electrs → requires bitcoin-knots
|
||||
# 2. btcpay-server → requires lnd
|
||||
# 3. mempool → requires bitcoin-knots + electrs
|
||||
# 4. fedimint-gateway → requires fedimint + lnd
|
||||
|
||||
SSH_KEY="${ARCHIPELAGO_SSH_KEY:-$HOME/.ssh/archipelago-deploy}"
|
||||
TARGET="archipelago@192.168.1.228"
|
||||
SSH_CMD="ssh -i $SSH_KEY -o StrictHostKeyChecking=no $TARGET"
|
||||
PASSWORD="password123"
|
||||
|
||||
PASS=0
|
||||
FAIL=0
|
||||
RESULTS=()
|
||||
|
||||
log() { echo -e "\033[1;34m[TEST]\033[0m $*"; }
|
||||
pass() { echo -e "\033[1;32m[PASS]\033[0m $*"; PASS=$((PASS + 1)); RESULTS+=("PASS: $*"); }
|
||||
fail() { echo -e "\033[1;31m[FAIL]\033[0m $*"; FAIL=$((FAIL + 1)); RESULTS+=("FAIL: $*"); }
|
||||
|
||||
get_session() {
|
||||
$SSH_CMD "curl -s -c - http://localhost:5678/rpc/v1 \
|
||||
-X POST -H 'Content-Type: application/json' \
|
||||
-d '{\"method\":\"auth.login\",\"params\":{\"password\":\"$PASSWORD\"}}' 2>/dev/null \
|
||||
| grep session | awk '{print \$NF}'"
|
||||
}
|
||||
|
||||
rpc_call() {
|
||||
local session="$1" method="$2" params="${3:-{}}"
|
||||
$SSH_CMD "curl -s http://localhost:5678/rpc/v1 \
|
||||
-X POST -H 'Content-Type: application/json' \
|
||||
-H 'Cookie: session=$session' \
|
||||
-d '{\"method\":\"$method\",\"params\":$params}' 2>/dev/null"
|
||||
}
|
||||
|
||||
# Test that installing an app without its dependency fails with a dependency error
|
||||
test_dep_blocked() {
|
||||
local session="$1"
|
||||
local app_id="$2"
|
||||
local dep_name="$3"
|
||||
|
||||
log "Testing: $app_id should require $dep_name"
|
||||
local result
|
||||
result=$(rpc_call "$session" "package.install" "{\"id\":\"$app_id\"}")
|
||||
|
||||
if echo "$result" | grep -qi "dependency\|requires\|must be\|needs"; then
|
||||
pass "$app_id correctly blocked — requires $dep_name"
|
||||
elif echo "$result" | grep -q '"error"'; then
|
||||
# Got an error, might still be dependency-related
|
||||
local msg
|
||||
msg=$(echo "$result" | grep -o '"message":"[^"]*"' | head -1 | sed 's/"message":"//;s/"$//')
|
||||
if echo "$msg" | grep -qi "$dep_name\|depend\|running\|install"; then
|
||||
pass "$app_id correctly blocked: $msg"
|
||||
else
|
||||
fail "$app_id — got error but not dependency-related: $msg"
|
||||
fi
|
||||
else
|
||||
# Install succeeded when it shouldn't have — clean up
|
||||
rpc_call "$session" "package.uninstall" "{\"id\":\"$app_id\"}" > /dev/null 2>&1 || true
|
||||
fail "$app_id — installed without $dep_name (should have been blocked)"
|
||||
fi
|
||||
}
|
||||
|
||||
container_running() {
|
||||
local session="$1" app_id="$2"
|
||||
local result
|
||||
result=$(rpc_call "$session" "container-list")
|
||||
echo "$result" | grep -q "\"$app_id\"" && return 0 || return 1
|
||||
}
|
||||
|
||||
main() {
|
||||
log "=== Dependency Chain Test ==="
|
||||
echo ""
|
||||
|
||||
log "Authenticating..."
|
||||
local session
|
||||
session=$(get_session)
|
||||
if [ -z "$session" ]; then
|
||||
echo "Failed to authenticate. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
log "Session: ${session:0:8}..."
|
||||
echo ""
|
||||
|
||||
# Check current state — which deps are already running
|
||||
local bitcoin_running=false lnd_running=false electrs_running=false fedimint_running=false
|
||||
|
||||
if container_running "$session" "bitcoin-knots"; then
|
||||
bitcoin_running=true
|
||||
log "bitcoin-knots is already running"
|
||||
fi
|
||||
if container_running "$session" "lnd"; then
|
||||
lnd_running=true
|
||||
log "lnd is already running"
|
||||
fi
|
||||
if container_running "$session" "electrs"; then
|
||||
electrs_running=true
|
||||
log "electrs is already running"
|
||||
fi
|
||||
if container_running "$session" "fedimint"; then
|
||||
fedimint_running=true
|
||||
log "fedimint is already running"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Test 1: electrs requires bitcoin-knots
|
||||
if [ "$bitcoin_running" = false ]; then
|
||||
test_dep_blocked "$session" "electrs" "bitcoin"
|
||||
else
|
||||
log "SKIP: electrs dep test — bitcoin-knots already running"
|
||||
fi
|
||||
|
||||
# Test 2: btcpay-server requires lnd
|
||||
if [ "$lnd_running" = false ]; then
|
||||
test_dep_blocked "$session" "btcpay-server" "lnd"
|
||||
else
|
||||
log "SKIP: btcpay dep test — lnd already running"
|
||||
fi
|
||||
|
||||
# Test 3: mempool requires bitcoin-knots + electrs
|
||||
if [ "$bitcoin_running" = false ] || [ "$electrs_running" = false ]; then
|
||||
test_dep_blocked "$session" "mempool" "bitcoin"
|
||||
else
|
||||
log "SKIP: mempool dep test — deps already running"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
log "=== RESULTS ==="
|
||||
for r in "${RESULTS[@]:-}"; do
|
||||
[ -n "$r" ] && echo " $r"
|
||||
done
|
||||
echo ""
|
||||
log "Pass: $PASS | Fail: $FAIL"
|
||||
|
||||
[ $FAIL -gt 0 ] && exit 1
|
||||
exit 0
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user