#!/bin/bash set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color COMPOSE_FILE="docker-compose.yml" TEST_TIMEOUT=60 CONTAINER_NAME="dyn-ddns-test" VERBOSE=false # Generate unique test identifiers TEST_ID=$(date +%s%N | tail -c 8) TEST_SUBDOMAIN="test${TEST_ID}" CLAIM_SUBDOMAIN="claim${TEST_ID}" PROFANE_TEST="profane${TEST_ID}" RESERVED_TEST="reserved${TEST_ID}" INVALID_TEST="ab${TEST_ID}" # Parse command line arguments while [[ $# -gt 0 ]]; do case $1 in -v|--verbose) VERBOSE=true shift ;; *) echo "Unknown option: $1" echo "Usage: $0 [-v|--verbose]" exit 1 ;; esac done # Verbose logging function log_verbose() { if [ "$VERBOSE" = true ]; then echo -e "${BLUE}[VERBOSE] $1${NC}" fi } dump_logs() { if [ "$VERBOSE" = true ]; then echo -e "${YELLOW}=== Container Logs ===${NC}" $COMPOSE_CMD -f $COMPOSE_FILE -p $CONTAINER_NAME logs --tail=50 || true echo -e "${YELLOW}=== End Logs ===${NC}" fi } echo -e "${YELLOW}=== DDNS Container Integration Test ===${NC}" if [ "$VERBOSE" = true ]; then echo -e "${BLUE}Verbose mode enabled${NC}" fi # Detect compose command if command -v podman-compose &> /dev/null; then COMPOSE_CMD="podman-compose" echo -e "${GREEN}Using podman-compose${NC}" elif command -v docker-compose &> /dev/null; then COMPOSE_CMD="docker-compose" echo -e "${GREEN}Using docker-compose${NC}" else echo -e "${RED}Error: Neither podman-compose nor docker-compose found${NC}" exit 1 fi # Cleanup function cleanup() { echo -e "${YELLOW}Cleaning up...${NC}" dump_logs $COMPOSE_CMD -f $COMPOSE_FILE -p $CONTAINER_NAME down -v 2>/dev/null || true rm -f .env.test } # Set trap for cleanup on exit trap cleanup EXIT # Create test environment file cat > .env.test << EOF SERVER_PORT=8080 DATABASE_PATH=/data/dyn.db TECHNITIUM_URL=http://mock-dns:8080 TECHNITIUM_TOKEN=test-token BASE_DOMAIN=test.rip SPACE_SUBDOMAIN=space RATE_LIMIT_PER_IP=100 RATE_LIMIT_PER_TOKEN=100 EOF log_verbose "Environment file created:" log_verbose "$(cat .env.test)" echo -e "${YELLOW}Starting services...${NC}" $COMPOSE_CMD -f $COMPOSE_FILE -p $CONTAINER_NAME --env-file .env.test up -d --build --renew-anon-volumes 2>&1 | tee /tmp/compose-build.log log_verbose "Build log saved to /tmp/compose-build.log" # Wait for services to be ready echo -e "${YELLOW}Waiting for services to start (timeout: ${TEST_TIMEOUT}s)...${NC}" for i in $(seq 1 $TEST_TIMEOUT); do if curl -s http://localhost:8080/ > /dev/null 2>&1; then echo -e "${GREEN}Services are ready!${NC}" break fi if [ $i -eq $TEST_TIMEOUT ]; then echo -e "${RED}Timeout waiting for services${NC}" dump_logs exit 1 fi sleep 1 done echo -e "${YELLOW}Running integration tests...${NC}" # Test 1: Health check echo -n "Test 1: Health check... " log_verbose "Running: curl -v http://localhost:8080/" if [ "$VERBOSE" = true ]; then HTTP_RESPONSE=$(curl -v http://localhost:8080/ 2>&1) echo "$HTTP_RESPONSE" | tee /tmp/test1.log else HTTP_RESPONSE=$(curl -s http://localhost:8080/) fi if echo "$HTTP_RESPONSE" | grep -q "DWS Dynamic DNS"; then echo -e "${GREEN}PASS${NC}" else echo -e "${RED}FAIL${NC}" log_verbose "Response: $HTTP_RESPONSE" exit 1 fi # Test 2: Check subdomain availability echo -n "Test 2: Check subdomain availability... " log_verbose "Running: curl -v http://localhost:8080/api/check?subdomain=testspace" if [ "$VERBOSE" = true ]; then RESPONSE=$(curl -v "http://localhost:8080/api/check?subdomain=testspace" 2>&1) echo "$RESPONSE" | tee /tmp/test2.log else RESPONSE=$(curl -s "http://localhost:8080/api/check?subdomain=testspace") fi log_verbose "Response: $RESPONSE" if echo "$RESPONSE" | grep -q '"available":true'; then echo -e "${GREEN}PASS${NC}" else echo -e "${RED}FAIL${NC} - Response: $RESPONSE" exit 1 fi # Test 3: Claim space echo -n "Test 3: Claim space... " log_verbose "Running: curl -v -X POST http://localhost:8080/api/claim" if [ "$VERBOSE" = true ]; then RESPONSE=$(curl -v -X POST http://localhost:8080/api/claim \ -H "Content-Type: application/json" \ -d "{\"subdomain\":\"$CLAIM_SUBDOMAIN\"}" 2>&1) echo "$RESPONSE" | tee /tmp/test3.log else RESPONSE=$(curl -s -X POST http://localhost:8080/api/claim \ -H "Content-Type: application/json" \ -d "{\"subdomain\":\"$CLAIM_SUBDOMAIN\"}") fi log_verbose "Response: $RESPONSE" # Check for HTTP 201 Created status and valid token format if echo "$RESPONSE" | grep -q 'HTTP/1.1 201 Created' && echo "$RESPONSE" | grep -q '"token":"[A-Za-z0-9_-]\+"'; then TOKEN=$(echo "$RESPONSE" | grep -o '"token":"[^"]*"' | cut -d'"' -f4) echo -e "${GREEN}PASS${NC} (token: ${TOKEN:0:20}...)" log_verbose "Full token: $TOKEN" else echo -e "${RED}FAIL${NC} - Response: $RESPONSE" exit 1 fi # Test 4: Check claimed subdomain is not available echo -n "Test 4: Check claimed subdomain unavailable... " log_verbose "Running: curl -v http://localhost:8080/api/check?subdomain=$CLAIM_SUBDOMAIN" if [ "$VERBOSE" = true ]; then RESPONSE=$(curl -v "http://localhost:8080/api/check?subdomain=$CLAIM_SUBDOMAIN" 2>&1) echo "$RESPONSE" | tee /tmp/test4.log else RESPONSE=$(curl -s "http://localhost:8080/api/check?subdomain=$CLAIM_SUBDOMAIN") fi log_verbose "Response: $RESPONSE" if echo "$RESPONSE" | grep -q '"available":false'; then echo -e "${GREEN}PASS${NC}" else echo -e "${RED}FAIL${NC} - Response: $RESPONSE" exit 1 fi # Test 5: DynDNS update (mocked - will fail DNS but test auth) echo -n "Test 5: DynDNS update endpoint... " log_verbose "Running: curl -v -u none: http://localhost:8080/api/nic/update?hostname=$CLAIM_SUBDOMAIN.space.test.rip&myip=192.168.1.100" if [ "$VERBOSE" = true ]; then RESPONSE=$(curl -v -u "none:$TOKEN" \ "http://localhost:8080/api/nic/update?hostname=$CLAIM_SUBDOMAIN.space.test.rip&myip=192.168.1.100" 2>&1) echo "$RESPONSE" | tee /tmp/test5.log else RESPONSE=$(curl -s -u "none:$TOKEN" \ "http://localhost:8080/api/nic/update?hostname=$CLAIM_SUBDOMAIN.space.test.rip&myip=192.168.1.100") fi log_verbose "Response: $RESPONSE" # We expect 911 since there's no real DNS server, but auth should work if [ $? -eq 0 ]; then echo -e "${GREEN}PASS${NC} (endpoint reachable, response: $(echo "$RESPONSE" | head -c 50))" else echo -e "${RED}FAIL${NC}" exit 1 fi # Test 6: Profanity filter echo -n "Test 6: Profanity filter... " log_verbose "Running: curl -v -X POST http://localhost:8080/api/claim with profane subdomain" if [ "$VERBOSE" = true ]; then RESPONSE=$(curl -v -X POST http://localhost:8080/api/claim \ -H "Content-Type: application/json" \ -d '{"subdomain":"fuck"}' 2>&1) echo "$RESPONSE" | tee /tmp/test6.log else RESPONSE=$(curl -s -X POST http://localhost:8080/api/claim \ -H "Content-Type: application/json" \ -d '{"subdomain":"fuck"}') fi log_verbose "Response: $RESPONSE" if echo "$RESPONSE" | grep -q 'inappropriate'; then echo -e "${GREEN}PASS${NC}" else echo -e "${RED}FAIL${NC} - Response: $RESPONSE" exit 1 fi # Test 7: Custom filter (DWS terms) echo -n "Test 7: Custom filter (DWS terms)... " log_verbose "Running: curl -v -X POST http://localhost:8080/api/claim with reserved subdomain" if [ "$VERBOSE" = true ]; then RESPONSE=$(curl -v -X POST http://localhost:8080/api/claim \ -H "Content-Type: application/json" \ -d '{"subdomain":"dws"}' 2>&1) echo "$RESPONSE" | tee /tmp/test7.log else RESPONSE=$(curl -s -X POST http://localhost:8080/api/claim \ -H "Content-Type: application/json" \ -d '{"subdomain":"dws"}') fi log_verbose "Response: $RESPONSE" if echo "$RESPONSE" | grep -q 'reserved'; then echo -e "${GREEN}PASS${NC}" else echo -e "${RED}FAIL${NC} - Response: $RESPONSE" exit 1 fi # Test 8: Invalid subdomain format echo -n "Test 8: Invalid subdomain format... " log_verbose "Running: curl -v -X POST http://localhost:8080/api/claim with invalid subdomain" if [ "$VERBOSE" = true ]; then RESPONSE=$(curl -v -X POST http://localhost:8080/api/claim \ -H "Content-Type: application/json" \ -d '{"subdomain":"ab"}' 2>&1) echo "$RESPONSE" | tee /tmp/test8.log else RESPONSE=$(curl -s -X POST http://localhost:8080/api/claim \ -H "Content-Type: application/json" \ -d '{"subdomain":"ab"}') fi log_verbose "Response: $RESPONSE" if echo "$RESPONSE" | grep -q 'Invalid'; then echo -e "${GREEN}PASS${NC}" else echo -e "${RED}FAIL${NC} - Response: $RESPONSE" exit 1 fi echo -e "${GREEN}=== All tests passed! ===${NC}" if [ "$VERBOSE" = true ]; then echo -e "${BLUE}=== Detailed logs saved to: ===${NC}" ls -la /tmp/test*.log 2>/dev/null || echo "No detailed logs found" fi