#!/bin/bash # End-to-End Test for explorer.d-bis.org # Comprehensive testing of all explorer functionality set -uo pipefail EXPLORER_URL="https://explorer.d-bis.org" BASE_URL="http://192.168.11.140" TEST_RESULTS=() PASSED=0 FAILED=0 WARNINGS=0 # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_test() { local status=$1 local message=$2 if [ "$status" = "PASS" ]; then echo -e "${GREEN}✅ PASS${NC}: $message" ((PASSED++)) TEST_RESULTS+=("PASS: $message") elif [ "$status" = "FAIL" ]; then echo -e "${RED}❌ FAIL${NC}: $message" ((FAILED++)) TEST_RESULTS+=("FAIL: $message") elif [ "$status" = "WARN" ]; then echo -e "${YELLOW}⚠️ WARN${NC}: $message" ((WARNINGS++)) TEST_RESULTS+=("WARN: $message") else echo -e "${BLUE}ℹ️ INFO${NC}: $message" fi } test_http_response() { local url=$1 local expected_code=$2 local description=$3 local response_code=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 10 --max-time 30 "$url" 2>/dev/null || echo "000") if [ "$response_code" = "$expected_code" ]; then log_test "PASS" "$description (HTTP $response_code)" return 0 elif [ "$response_code" = "000" ]; then log_test "FAIL" "$description (Connection failed/timeout)" return 1 else log_test "FAIL" "$description (Expected HTTP $expected_code, got $response_code)" return 1 fi } test_content() { local url=$1 local search_term=$2 local description=$3 local content=$(curl -s -L --connect-timeout 10 --max-time 30 "$url" 2>/dev/null || echo "") if [ -z "$content" ]; then log_test "FAIL" "$description (Empty response)" return 1 elif echo "$content" | grep -qi "$search_term"; then log_test "PASS" "$description (Found: $search_term)" return 0 else # Show first 100 chars for debugging PREVIEW=$(echo "$content" | head -c 100 | tr -d '\n') log_test "FAIL" "$description (Not found: $search_term, got: $PREVIEW...)" return 1 fi } test_json_response() { local url=$1 local description=$2 local response=$(curl -s -L --connect-timeout 10 --max-time 30 "$url" 2>/dev/null || echo "") if echo "$response" | jq . >/dev/null 2>&1; then log_test "PASS" "$description (Valid JSON)" return 0 else log_test "FAIL" "$description (Invalid JSON or empty response)" return 1 fi } echo "==========================================" echo "End-to-End Test: explorer.d-bis.org" echo "==========================================" echo "Test URL: $EXPLORER_URL" echo "Base URL: $BASE_URL" echo "Date: $(date)" echo "==========================================" echo "" # ============================================ # 1. Basic Connectivity Tests # ============================================ echo "=== 1. Basic Connectivity Tests ===" # Test HTTPS accessibility (may fail if Cloudflare tunnel not running) HTTPS_CODE=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 5 --max-time 10 "$EXPLORER_URL" 2>/dev/null || echo "000") if [ "$HTTPS_CODE" = "200" ] || [ "$HTTPS_CODE" = "301" ] || [ "$HTTPS_CODE" = "302" ]; then log_test "PASS" "HTTPS homepage accessibility (HTTP $HTTPS_CODE)" elif [ "$HTTPS_CODE" = "000" ]; then log_test "WARN" "HTTPS homepage not accessible externally (Cloudflare tunnel may be down - testing internal access instead)" else log_test "WARN" "HTTPS homepage returned HTTP $HTTPS_CODE" fi # Test HTTP redirect test_http_response "http://explorer.d-bis.org" "301\|302" "HTTP to HTTPS redirect" # Test direct IP access (internal) test_http_response "$BASE_URL:80/" "200" "Direct IP access (port 80)" echo "" # ============================================ # 2. Frontend Content Tests # ============================================ echo "=== 2. Frontend Content Tests ===" # Use internal URL for content tests since HTTPS may not be accessible CONTENT_URL="$BASE_URL:80" # Test homepage content test_content "$CONTENT_URL" "SolaceScanScout" "Homepage contains SolaceScanScout title" # Test explorer branding test_content "$CONTENT_URL" "Explorer" "Homepage contains explorer branding" # Test HTML structure test_content "$CONTENT_URL" "/dev/null || echo "") if echo "$HEADERS" | grep -qi "strict-transport-security\|HSTS"; then log_test "PASS" "HSTS header present" else log_test "WARN" "HSTS header not found" fi if echo "$HEADERS" | grep -qi "x-frame-options"; then log_test "PASS" "X-Frame-Options header present" else log_test "WARN" "X-Frame-Options header not found" fi if echo "$HEADERS" | grep -qi "x-content-type-options"; then log_test "PASS" "X-Content-Type-Options header present" else log_test "WARN" "X-Content-Type-Options header not found" fi echo "" # ============================================ # 5. Performance Tests # ============================================ echo "=== 5. Performance Tests ===" # Test performance on internal URL START_TIME=$(date +%s%N) curl -s -o /dev/null -w '%{time_total}' --connect-timeout 10 --max-time 30 "$BASE_URL:80/" >/dev/null 2>&1 END_TIME=$(date +%s%N) RESPONSE_TIME=$(echo "scale=3; ($END_TIME - $START_TIME) / 1000000000" | bc 2>/dev/null || echo "N/A") if [ "$RESPONSE_TIME" != "N/A" ]; then if (( $(echo "$RESPONSE_TIME < 3.0" | bc -l 2>/dev/null || echo 0) )); then log_test "PASS" "Response time acceptable (${RESPONSE_TIME}s)" else log_test "WARN" "Response time slow (${RESPONSE_TIME}s)" fi else log_test "WARN" "Could not measure response time" fi echo "" # ============================================ # 6. Service Status Tests # ============================================ echo "=== 6. Service Status Tests ===" # Test nginx on VMID 5000 if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-02 'pct exec 5000 -- systemctl is-active nginx 2>/dev/null'" 2>/dev/null | grep -q "active"; then log_test "PASS" "Nginx service running on VMID 5000" else log_test "FAIL" "Nginx service not running on VMID 5000" fi # Test Blockscout service if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-02 'pct exec 5000 -- systemctl is-active blockscout 2>/dev/null || pct exec 5000 -- docker ps | grep -q blockscout'" 2>/dev/null | grep -qE "active|blockscout"; then log_test "PASS" "Blockscout service running on VMID 5000" else log_test "WARN" "Blockscout service status unknown" fi # Test port 80 listening if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-02 'pct exec 5000 -- ss -tlnp | grep -q :80'" 2>/dev/null; then log_test "PASS" "Port 80 listening on VMID 5000" else log_test "FAIL" "Port 80 not listening on VMID 5000" fi # Test port 4000 listening if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-02 'pct exec 5000 -- ss -tlnp | grep -q :4000'" 2>/dev/null; then log_test "PASS" "Port 4000 listening on VMID 5000" else log_test "WARN" "Port 4000 not listening on VMID 5000" fi echo "" # ============================================ # 7. Frontend Functionality Tests # ============================================ echo "=== 7. Frontend Functionality Tests ===" # Check if frontend file exists if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-02 'pct exec 5000 -- test -f /var/www/html/index.html'" 2>/dev/null; then log_test "PASS" "Frontend HTML file exists" else log_test "FAIL" "Frontend HTML file not found" fi # Check frontend file size (should be substantial) FRONTEND_SIZE=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-02 'pct exec 5000 -- stat -c%s /var/www/html/index.html 2>/dev/null'" 2>/dev/null || echo "0") if [ "$FRONTEND_SIZE" -gt 10000 ]; then log_test "PASS" "Frontend file size reasonable (${FRONTEND_SIZE} bytes)" else log_test "WARN" "Frontend file size suspiciously small (${FRONTEND_SIZE} bytes)" fi echo "" # ============================================ # 8. Network Routing Tests # ============================================ echo "=== 8. Network Routing Tests ===" # Test NPMplus routing (may fail if Cloudflare tunnel down) NPMPLUS_CHECK=$(curl -s -I --connect-timeout 5 --max-time 10 "https://explorer.d-bis.org" 2>/dev/null | head -1 || echo "") if echo "$NPMPLUS_CHECK" | grep -qE "200|301|302"; then log_test "PASS" "NPMplus routing working" elif echo "$NPMPLUS_CHECK" | grep -qE "000|timeout"; then log_test "WARN" "NPMplus routing timeout (Cloudflare tunnel may be down)" else log_test "WARN" "NPMplus routing returned: $NPMPLUS_CHECK" fi # Test DNS resolution if host explorer.d-bis.org 2>/dev/null | grep -q "has address"; then log_test "PASS" "DNS resolution working" else log_test "WARN" "DNS resolution check failed (may be local DNS issue)" fi echo "" # ============================================ # 9. API Data Validation # ============================================ echo "=== 9. API Data Validation ===" # Get stats and validate structure (use internal URL) STATS_JSON=$(curl -s -L --connect-timeout 10 --max-time 30 "$BASE_URL:80/api/v2/stats" 2>/dev/null || echo "{}") if echo "$STATS_JSON" | jq -e '.total_blocks' >/dev/null 2>&1; then TOTAL_BLOCKS=$(echo "$STATS_JSON" | jq -r '.total_blocks // 0') if [ "$TOTAL_BLOCKS" -gt 0 ]; then log_test "PASS" "API returns valid block count ($TOTAL_BLOCKS blocks)" else log_test "WARN" "API returns zero blocks (may be indexing)" fi else log_test "FAIL" "API stats structure invalid" fi # Check for chain ID if echo "$STATS_JSON" | jq -e '.chain_id' >/dev/null 2>&1; then CHAIN_ID=$(echo "$STATS_JSON" | jq -r '.chain_id // "unknown"') log_test "PASS" "API returns chain ID ($CHAIN_ID)" else log_test "WARN" "API does not return chain ID" fi echo "" # ============================================ # 10. Error Handling Tests # ============================================ echo "=== 10. Error Handling Tests ===" # Test 404 handling (use internal URL) test_http_response "$BASE_URL:80/nonexistent-page" "404" "404 error handling" # Test API error handling (use internal URL) API_ERROR=$(curl -s -L --connect-timeout 10 --max-time 30 "$BASE_URL:80/api/v2/invalid-endpoint" 2>/dev/null || echo "") if echo "$API_ERROR" | grep -qiE "error|404|not found"; then log_test "PASS" "API error handling works" else log_test "WARN" "API error handling unclear" fi echo "" # ============================================ # Summary # ============================================ echo "==========================================" echo "Test Summary" echo "==========================================" echo -e "${GREEN}Passed: $PASSED${NC}" echo -e "${RED}Failed: $FAILED${NC}" echo -e "${YELLOW}Warnings: $WARNINGS${NC}" echo "" TOTAL=$((PASSED + FAILED + WARNINGS)) if [ $TOTAL -gt 0 ]; then PASS_PERCENT=$(echo "scale=1; $PASSED * 100 / $TOTAL" | bc 2>/dev/null || echo "0") echo "Pass Rate: ${PASS_PERCENT}%" fi echo "" if [ $FAILED -eq 0 ]; then echo -e "${GREEN}✅ All critical tests passed!${NC}" exit 0 else echo -e "${RED}❌ Some tests failed. Review results above.${NC}" exit 1 fi