Pulse/scripts/test-release.sh
Pulse Monitor 9e35ce833c test: update existing test scripts to handle auth modes properly
- Updated test-security.sh to detect and handle DISABLE_AUTH mode
- Fixed test-release.sh to properly check for compiled binary
- Updated test-proxy-scenarios.sh arithmetic operations for bash compatibility
- All tests now properly detect authentication state and adapt accordingly
2025-08-27 11:08:11 +00:00

281 lines
No EOL
8.8 KiB
Bash
Executable file

#!/bin/bash
# Comprehensive release testing script for Pulse
# Tests actual deployments, not just unit tests
set -e
VERSION=${1:-$(cat VERSION)}
PULSE_URL=${PULSE_URL:-http://localhost:7655}
API_TOKEN=${API_TOKEN:-""}
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo "================================================"
echo "Pulse Release Test Suite v${VERSION}"
echo "================================================"
# Detect if auth is disabled
AUTH_DISABLED=false
security_status=$(curl -s "$PULSE_URL/api/security/status" 2>/dev/null || echo "{}")
if echo "$security_status" | grep -q '"disabled":true'; then
AUTH_DISABLED=true
echo ""
echo -e "${YELLOW}Note: Authentication is DISABLED (DISABLE_AUTH mode)${NC}"
fi
# Track test results
FAILED_TESTS=()
PASSED_TESTS=()
# Test function
run_test() {
local test_name="$1"
local test_command="$2"
echo -n "Testing: $test_name... "
if eval "$test_command" > /dev/null 2>&1; then
echo -e "${GREEN}${NC}"
PASSED_TESTS+=("$test_name")
else
echo -e "${RED}${NC}"
FAILED_TESTS+=("$test_name")
fi
}
# Test function with output
run_test_verbose() {
local test_name="$1"
local test_command="$2"
echo "Testing: $test_name..."
if eval "$test_command"; then
echo -e "${GREEN}$test_name passed${NC}"
PASSED_TESTS+=("$test_name")
else
echo -e "${RED}$test_name failed${NC}"
FAILED_TESTS+=("$test_name")
fi
}
echo ""
echo "1. HTTP/ROUTING TESTS"
echo "===================="
# Critical: Test root without trailing slash (catches issue #334)
run_test "Root path without trailing slash (no redirect)" \
"curl -s -I ${PULSE_URL} | grep -q 'HTTP/1.1 200'"
run_test "Root path with trailing slash" \
"curl -s -I ${PULSE_URL}/ | grep -q 'HTTP/1.1 200'"
# Check for unwanted redirects
run_test "No relative path redirects" \
"! curl -s -I ${PULSE_URL} | grep -q 'Location: ./'"
# Test static assets (get actual filenames from index.html)
JS_FILE=$(curl -s ${PULSE_URL}/ | grep -o '/assets/index-[^"]*\.js' | head -1)
CSS_FILE=$(curl -s ${PULSE_URL}/ | grep -o '/assets/index-[^"]*\.css' | head -1)
if [ -n "$JS_FILE" ]; then
run_test "JavaScript assets load" \
"curl -s -I ${PULSE_URL}${JS_FILE} | grep -q 'Content-Type: application/javascript'"
else
echo -e "${RED}✗ Could not find JS file${NC}"
FAILED_TESTS+=("JavaScript assets load")
fi
if [ -n "$CSS_FILE" ]; then
run_test "CSS assets load" \
"curl -s -I ${PULSE_URL}${CSS_FILE} | grep -q 'Content-Type: text/css'"
else
echo -e "${RED}✗ Could not find CSS file${NC}"
FAILED_TESTS+=("CSS assets load")
fi
# Test various access patterns
run_test "Empty path handling" \
"curl -s -o /dev/null -w '%{http_code}' ${PULSE_URL} | grep -q '200'"
if [ "$AUTH_DISABLED" != true ]; then
run_test "SPA routes require authentication" \
"curl -s ${PULSE_URL}/settings | grep -q 'Authentication required'"
else
run_test "SPA routes accessible (auth disabled)" \
"curl -s ${PULSE_URL}/settings | grep -q '<div id=\"root\">'"
fi
echo ""
echo "2. API ENDPOINT TESTS"
echo "===================="
# Public endpoints (should work without auth)
run_test "API health endpoint" \
"curl -s ${PULSE_URL}/api/health | grep -q 'healthy'"
run_test "API version endpoint" \
"curl -s ${PULSE_URL}/api/version | grep -q 'version'"
# If API token provided, test protected endpoints
if [ -n "$API_TOKEN" ]; then
echo "Testing with API token..."
run_test "API state with token" \
"curl -s -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/state | grep -q 'nodes'"
run_test "API config/nodes with token" \
"curl -s -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/config/nodes | jq -e '. | type == \"array\"'"
run_test "API export requires passphrase" \
"curl -s -X POST -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/config/export -d '{}' | grep -q 'Passphrase is required'"
else
echo -e "${YELLOW}Skipping auth tests (no API_TOKEN provided)${NC}"
fi
echo ""
echo "3. WEBSOCKET TESTS"
echo "=================="
# Test WebSocket endpoint availability
run_test "WebSocket endpoint responds" \
"curl -s -I -H 'Upgrade: websocket' ${PULSE_URL}/ws | grep -q 'HTTP/1.1'"
echo ""
echo "4. REVERSE PROXY SIMULATION"
echo "==========================="
# Simulate reverse proxy headers
run_test "Handles X-Forwarded headers" \
"curl -s -H 'X-Forwarded-For: 10.0.0.1' -H 'X-Forwarded-Proto: https' ${PULSE_URL}/api/health | grep -q 'healthy'"
run_test "Handles proxy without trailing slash" \
"curl -s -H 'X-Forwarded-Host: proxy.example.com' ${PULSE_URL} | grep -q '<title>'"
echo ""
echo "5. DOCKER DEPLOYMENT TEST (if Docker available)"
echo "=============================================="
if false && command -v docker &> /dev/null; then # Temporarily disabled - hanging
echo "Testing Docker deployment..."
# Stop any existing test container
docker stop pulse-test 2>/dev/null || true
docker rm pulse-test 2>/dev/null || true
# Run test container
echo "Starting Docker container..."
docker run -d --name pulse-test \
-p 7656:7655 \
-e API_TOKEN=test123 \
rcourtman/pulse:v${VERSION} > /dev/null 2>&1
# Wait for container to start
sleep 5
run_test "Docker container running" \
"docker ps | grep -q pulse-test"
run_test "Docker health endpoint" \
"curl -s http://localhost:7656/api/health | grep -q 'healthy'"
run_test "Docker UI loads" \
"curl -s http://localhost:7656 | grep -q '<title>Pulse</title>'"
# Cleanup
docker stop pulse-test > /dev/null 2>&1
docker rm pulse-test > /dev/null 2>&1
else
echo -e "${YELLOW}Docker not available, skipping Docker tests${NC}"
fi
echo ""
echo "6. LXC DEPLOYMENT TEST (if on Proxmox)"
echo "====================================="
if command -v pct &> /dev/null; then
echo "Would test LXC deployment (implement based on environment)"
# This would create a test container, install Pulse, and verify
else
echo -e "${YELLOW}Not on Proxmox, skipping LXC tests${NC}"
fi
echo ""
echo "7. UPDATE MECHANISM TEST"
echo "======================="
# Update check
if [ "$AUTH_DISABLED" = true ]; then
run_test "Update check endpoint (auth disabled)" \
"curl -s ${PULSE_URL}/api/updates/check | jq -e '.currentVersion'"
elif [ -n "$API_TOKEN" ]; then
run_test "Update check endpoint with auth" \
"curl -s -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/updates/check | jq -e '.currentVersion'"
else
run_test "Update check requires auth" \
"curl -s ${PULSE_URL}/api/updates/check | grep -q 'Authentication required'"
fi
echo ""
echo "8. PERFORMANCE TESTS"
echo "==================="
# Test response times
RESPONSE_TIME=$(curl -s -o /dev/null -w '%{time_total}' ${PULSE_URL}/api/health)
if (( $(echo "$RESPONSE_TIME < 1" | bc -l) )); then
echo -e "${GREEN}✓ API response time: ${RESPONSE_TIME}s${NC}"
PASSED_TESTS+=("API response time")
else
echo -e "${RED}✗ API slow: ${RESPONSE_TIME}s${NC}"
FAILED_TESTS+=("API response time")
fi
echo ""
echo "9. ERROR HANDLING TESTS"
echo "======================"
# 401 is returned before 404 when not authenticated (auth checked first)
if [ "$AUTH_DISABLED" = true ]; then
run_test "404 for non-existent endpoint" \
"curl -s -o /dev/null -w '%{http_code}' ${PULSE_URL}/api/nonexistent | grep -q '404'"
elif [ -n "$API_TOKEN" ]; then
run_test "404 for non-existent API endpoint" \
"curl -s -o /dev/null -w '%{http_code}' -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/nonexistent | grep -q '404'"
else
run_test "401 for non-existent endpoint (auth first)" \
"curl -s -o /dev/null -w '%{http_code}' ${PULSE_URL}/api/nonexistent | grep -q '401'"
fi
run_test "405 for wrong method" \
"curl -s -X DELETE -o /dev/null -w '%{http_code}' ${PULSE_URL}/api/health | grep -q '405'"
echo ""
echo "================================================"
echo "TEST RESULTS SUMMARY"
echo "================================================"
echo -e "${GREEN}Passed: ${#PASSED_TESTS[@]} tests${NC}"
echo -e "${RED}Failed: ${#FAILED_TESTS[@]} tests${NC}"
if [ ${#FAILED_TESTS[@]} -gt 0 ]; then
echo ""
echo "Failed tests:"
for test in "${FAILED_TESTS[@]}"; do
echo " - $test"
done
echo ""
echo -e "${RED}⚠️ RELEASE TESTS FAILED - DO NOT RELEASE!${NC}"
exit 1
else
echo ""
echo -e "${GREEN}✅ All tests passed! Safe to release.${NC}"
fi
echo ""
echo "Additional manual tests recommended:"
echo " 1. Test behind actual reverse proxy (nginx/traefik)"
echo " 2. Test with Cloudflare tunnel"
echo " 3. Test ProxmoxVE 'update' command"
echo " 4. Test on different architectures (ARM)"
echo " 5. Test upgrade from previous version"