#!/bin/bash # Integration tests for Traefik deployment modes # Tests bundled, upstream, and none modes # # Usage: # ./traefik.test.sh [bundled|upstream|none|all] # # Requirements: # - Docker and Docker Compose installed # - jq for JSON parsing # - curl for HTTP testing set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Test counters TESTS_RUN=0 TESTS_PASSED=0 TESTS_FAILED=0 # Test result tracking declare -a FAILED_TESTS=() # Logging functions log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } log_test() { echo -e "\n${YELLOW}[TEST]${NC} $1" ((TESTS_RUN++)) } log_pass() { echo -e "${GREEN}[PASS]${NC} $1" ((TESTS_PASSED++)) } log_fail() { echo -e "${RED}[FAIL]${NC} $1" ((TESTS_FAILED++)) FAILED_TESTS+=("$1") } # Cleanup function cleanup() { log_info "Cleaning up test environment..." docker compose -f docker-compose.test.yml down -v 2>/dev/null || true docker network rm traefik-public-test 2>/dev/null || true rm -f .env.test docker-compose.test.yml } # Trap cleanup on exit trap cleanup EXIT # Check prerequisites check_prerequisites() { log_info "Checking prerequisites..." if ! command -v docker &> /dev/null; then log_error "Docker is not installed" exit 1 fi if ! command -v docker compose &> /dev/null; then log_error "Docker Compose is not installed" exit 1 fi if ! command -v jq &> /dev/null; then log_error "jq is not installed (required for JSON parsing)" exit 1 fi if ! command -v curl &> /dev/null; then log_error "curl is not installed" exit 1 fi log_pass "All prerequisites satisfied" } # Test bundled Traefik mode test_bundled_mode() { log_info "==========================================" log_info "Testing Bundled Traefik Mode" log_info "==========================================" # Create test environment file cat > .env.test < /dev/null; then log_pass "Traefik dashboard is accessible" else log_fail "Traefik dashboard not accessible" fi log_test "Verifying Traefik API endpoint" if curl -sf http://localhost:8080/api/overview | jq -e '.http.routers' > /dev/null; then log_pass "Traefik API is responding" else log_fail "Traefik API not responding correctly" fi log_test "Verifying API service has Traefik labels" LABELS=$(docker inspect mosaic-api --format='{{json .Config.Labels}}') if echo "$LABELS" | jq -e '."traefik.enable"' > /dev/null; then log_pass "API service has Traefik labels" else log_fail "API service missing Traefik labels" fi log_test "Verifying Web service has Traefik labels" LABELS=$(docker inspect mosaic-web --format='{{json .Config.Labels}}') if echo "$LABELS" | jq -e '."traefik.enable"' > /dev/null; then log_pass "Web service has Traefik labels" else log_fail "Web service missing Traefik labels" fi log_test "Checking Traefik routes configuration" ROUTES=$(curl -sf http://localhost:8080/api/http/routers | jq -r 'keys[]') if echo "$ROUTES" | grep -q "mosaic-api"; then log_pass "API route registered with Traefik" else log_fail "API route not found in Traefik" fi if echo "$ROUTES" | grep -q "mosaic-web"; then log_pass "Web route registered with Traefik" else log_fail "Web route not found in Traefik" fi # Cleanup docker compose -f docker-compose.test.yml --env-file .env.test down -v } # Test upstream Traefik mode test_upstream_mode() { log_info "==========================================" log_info "Testing Upstream Traefik Mode" log_info "==========================================" # Create external network for upstream Traefik log_test "Creating external Traefik network" if docker network create traefik-public-test 2>/dev/null; then log_pass "External network created" else log_warn "Network already exists or creation failed" fi # Create test environment file cat > .env.test < /dev/null && \ echo "$LABELS" | jq -e '."traefik.docker.network"' > /dev/null; then log_pass "API service has correct upstream Traefik labels" else log_fail "API service missing or incorrect upstream Traefik labels" fi # Cleanup docker compose -f docker-compose.test.yml --env-file .env.test down -v docker network rm traefik-public-test 2>/dev/null || true } # Test none mode (direct port exposure) test_none_mode() { log_info "==========================================" log_info "Testing None Mode (Direct Ports)" log_info "==========================================" # Create test environment file cat > .env.test < /dev/null; then log_pass "API service Traefik labels correctly disabled" else log_fail "API service Traefik labels should be disabled" fi log_test "Verifying direct port access to API" MAX_RETRIES=30 RETRY_COUNT=0 while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do if curl -sf http://localhost:3001/health > /dev/null 2>&1; then log_pass "API accessible via direct port 3001" break fi ((RETRY_COUNT++)) sleep 2 done if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then log_fail "API not accessible via direct port 3001" fi # Cleanup docker compose -f docker-compose.test.yml --env-file .env.test down -v } # Print test summary print_summary() { echo "" log_info "==========================================" log_info "Test Summary" log_info "==========================================" echo "Total tests run: $TESTS_RUN" echo -e "${GREEN}Passed: $TESTS_PASSED${NC}" echo -e "${RED}Failed: $TESTS_FAILED${NC}" if [ $TESTS_FAILED -gt 0 ]; then echo "" log_error "Failed tests:" for test in "${FAILED_TESTS[@]}"; do echo " - $test" done echo "" exit 1 else echo "" log_pass "All tests passed!" exit 0 fi } # Main execution main() { TEST_MODE="${1:-all}" log_info "Mosaic Stack - Traefik Integration Tests" log_info "Test mode: $TEST_MODE" echo "" check_prerequisites case "$TEST_MODE" in bundled) test_bundled_mode ;; upstream) test_upstream_mode ;; none) test_none_mode ;; all) test_bundled_mode test_upstream_mode test_none_mode ;; *) log_error "Invalid test mode: $TEST_MODE" log_info "Usage: $0 [bundled|upstream|none|all]" exit 1 ;; esac print_summary } main "$@"