#!/bin/bash # C-Relay Comprehensive Test Suite Runner # This script runs all security and stability tests for the Nostr relay set -e # Configuration RELAY_HOST="127.0.0.1" RELAY_PORT="8888" RELAY_URL="ws://$RELAY_HOST:$RELAY_PORT" TEST_TIMEOUT=30 LOG_FILE="test_results_$(date +%Y%m%d_%H%M%S).log" REPORT_FILE="test_report_$(date +%Y%m%d_%H%M%S).html" # Test keys for authentication (from AGENTS.md) ADMIN_PRIVATE_KEY="6a04ab98d9e4774ad806e302dddeb63bea16b5cb5f223ee77478e861bb583eb3" RELAY_PUBKEY="4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Test results tracking TOTAL_SUITES=0 PASSED_SUITES=0 FAILED_SUITES=0 SKIPPED_SUITES=0 SUITE_RESULTS=() # Function to create authenticated WebSocket connection # Usage: authenticated_websocat authenticated_websocat() { local sub_id="$1" local filter="$2" # Create a temporary script for authenticated connection cat > /tmp/auth_ws_$$.sh << EOF #!/bin/bash # Authenticated WebSocket connection helper # Connect and handle AUTH challenge exec websocat -B 1048576 --no-close ws://$RELAY_HOST:$RELAY_PORT 2>/dev/null << 'INNER_EOF' ["REQ","$sub_id",$filter] INNER_EOF EOF chmod +x /tmp/auth_ws_$$.sh timeout $TEST_TIMEOUT bash /tmp/auth_ws_$$.sh rm -f /tmp/auth_ws_$$.sh } # Function to log messages log() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $*" | tee -a "$LOG_FILE" } # Function to run a test suite run_test_suite() { local suite_name="$1" local suite_script="$2" local description="$3" TOTAL_SUITES=$((TOTAL_SUITES + 1)) log "==========================================" log "Running Test Suite: $suite_name" log "Description: $description" log "==========================================" if [[ ! -f "$suite_script" ]]; then log "${RED}ERROR: Test script $suite_script not found${NC}" FAILED_SUITES=$((FAILED_SUITES + 1)) SUITE_RESULTS+=("$suite_name: FAILED (script not found)") return 1 fi # Make script executable if not already chmod +x "$suite_script" # Run the test suite and capture output local start_time=$(date +%s) if bash "$suite_script" >> "$LOG_FILE" 2>&1; then local end_time=$(date +%s) local duration=$((end_time - start_time)) log "${GREEN}✓ $suite_name PASSED${NC} (Duration: ${duration}s)" PASSED_SUITES=$((PASSED_SUITES + 1)) SUITE_RESULTS+=("$suite_name: PASSED (${duration}s)") return 0 else local end_time=$(date +%s) local duration=$((end_time - start_time)) log "${RED}✗ $suite_name FAILED${NC} (Duration: ${duration}s)" FAILED_SUITES=$((FAILED_SUITES + 1)) SUITE_RESULTS+=("$suite_name: FAILED (${duration}s)") return 1 fi } # Function to check if relay is running check_relay_status() { log "Checking relay status at $RELAY_URL..." # First check if HTTP endpoint is accessible if curl -s -H "Accept: application/nostr+json" "http://$RELAY_HOST:$RELAY_PORT" >/dev/null 2>&1; then log "${GREEN}✓ Relay HTTP endpoint is accessible${NC}" return 0 fi # Fallback: Try WebSocket connection if timeout 5 bash -c " echo '[\"REQ\",\"status_check\",{}]' | websocat -B 1048576 --no-close '$RELAY_URL' >/dev/null 2>&1 " 2>/dev/null; then log "${GREEN}✓ Relay WebSocket endpoint is accessible${NC}" return 0 else log "${RED}✗ Relay is not accessible at $RELAY_URL${NC}" log "Please start the relay first using: ./make_and_restart_relay.sh" return 1 fi } # Function to generate HTML report generate_html_report() { local total_duration=$1 cat > "$REPORT_FILE" << EOF C-Relay Test Report - $(date)

C-Relay Comprehensive Test Report

Generated on: $(date)

Test Environment: $RELAY_URL

Test Summary

Total Suites: $TOTAL_SUITES
Passed: $PASSED_SUITES
Failed: $FAILED_SUITES
Skipped: $SKIPPED_SUITES
Total Duration: ${total_duration}s
Success Rate: $(( (PASSED_SUITES * 100) / TOTAL_SUITES ))%

Test Suite Results

EOF for result in "${SUITE_RESULTS[@]}"; do local suite_name=$(echo "$result" | cut -d: -f1) local status=$(echo "$result" | cut -d: -f2 | cut -d' ' -f1) local duration=$(echo "$result" | cut -d: -f2 | cut -d'(' -f2 | cut -d')' -f1) local css_class="passed" if [[ "$status" == "FAILED" ]]; then css_class="failed" elif [[ "$status" == "SKIPPED" ]]; then css_class="skipped" fi cat >> "$REPORT_FILE" << EOF
$suite_name - $status ($duration)
EOF done cat >> "$REPORT_FILE" << EOF EOF log "HTML report generated: $REPORT_FILE" } # Main execution log "==========================================" log "C-Relay Comprehensive Test Suite Runner" log "==========================================" log "Relay URL: $RELAY_URL" log "Log file: $LOG_FILE" log "Report file: $REPORT_FILE" log "" # Check if relay is running if ! check_relay_status; then log "${RED}Cannot proceed without a running relay. Exiting.${NC}" exit 1 fi log "" log "Starting comprehensive test execution..." log "" # Record start time OVERALL_START_TIME=$(date +%s) # Run Security Test Suites log "${BLUE}=== SECURITY TEST SUITES ===${NC}" run_test_suite "SQL Injection Tests" "tests/sql_injection_tests.sh" "Comprehensive SQL injection vulnerability testing" run_test_suite "Filter Validation Tests" "tests/filter_validation_test.sh" "Input validation for REQ and COUNT messages" run_test_suite "Subscription Validation Tests" "tests/subscription_validation.sh" "Subscription ID and message validation" run_test_suite "Memory Corruption Tests" "tests/memory_corruption_tests.sh" "Buffer overflow and memory safety testing" run_test_suite "Input Validation Tests" "tests/input_validation_tests.sh" "Comprehensive input boundary testing" # Run Performance Test Suites log "" log "${BLUE}=== PERFORMANCE TEST SUITES ===${NC}" run_test_suite "Subscription Limit Tests" "tests/subscription_limits.sh" "Subscription limit enforcement testing" run_test_suite "Load Testing" "tests/load_tests.sh" "High concurrent connection testing" run_test_suite "Stress Testing" "tests/stress_tests.sh" "Resource usage and stability testing" run_test_suite "Rate Limiting Tests" "tests/rate_limiting_tests.sh" "Rate limiting and abuse prevention" # Run Integration Test Suites log "" log "${BLUE}=== INTEGRATION TEST SUITES ===${NC}" run_test_suite "NIP Protocol Tests" "tests/run_nip_tests.sh" "All NIP protocol compliance tests" run_test_suite "Configuration Tests" "tests/config_tests.sh" "Configuration management and persistence" run_test_suite "Authentication Tests" "tests/auth_tests.sh" "NIP-42 authentication testing" # Run Benchmarking Suites log "" log "${BLUE}=== BENCHMARKING SUITES ===${NC}" run_test_suite "Performance Benchmarks" "tests/performance_benchmarks.sh" "Performance metrics and benchmarking" run_test_suite "Resource Monitoring" "tests/resource_monitoring.sh" "Memory and CPU usage monitoring" # Calculate total duration OVERALL_END_TIME=$(date +%s) TOTAL_DURATION=$((OVERALL_END_TIME - OVERALL_START_TIME)) # Generate final report log "" log "==========================================" log "TEST EXECUTION COMPLETE" log "==========================================" log "Total test suites: $TOTAL_SUITES" log "Passed: $PASSED_SUITES" log "Failed: $FAILED_SUITES" log "Skipped: $SKIPPED_SUITES" log "Total duration: ${TOTAL_DURATION}s" log "Success rate: $(( (PASSED_SUITES * 100) / TOTAL_SUITES ))%" log "" log "Detailed log: $LOG_FILE" # Generate HTML report generate_html_report "$TOTAL_DURATION" # Exit with appropriate code if [[ $FAILED_SUITES -eq 0 ]]; then log "${GREEN}✓ ALL TESTS PASSED${NC}" exit 0 else log "${RED}✗ SOME TESTS FAILED${NC}" log "Check $LOG_FILE for detailed error information" exit 1 fi