#!/bin/bash # Test 02: Healthcheck Configuration # Verifies that docker-compose.yml services have healthchecks configured # Usage: bash labs/lab-03-compute/tests/02-healthcheck-test.sh set -euo pipefail # Color definitions RED='\033[0;31m' GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' BOLD='\033[1m' NC='\033[0m' # Get script directory TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" LAB_DIR="$(cd "$TEST_DIR/.." && pwd)" # Counter helpers pass_count=0 fail_count=0 inc_pass() { ((pass_count++)) || true; } inc_fail() { ((fail_count++)) || true; } # Helper functions print_header() { echo -e "${BLUE}╔═══════════════════════════════════════════════════════════════╗${NC}" echo -e "${BLUE}║${NC} ${BOLD}$1${NC}" echo -e "${BLUE}╚═══════════════════════════════════════════════════════════════╝${NC}" } print_test() { echo -e "\n${BLUE}[TEST]${NC} $1" } print_pass() { echo -e " ${GREEN}[✓]${NC} $1" inc_pass } print_fail() { echo -e " ${RED}[✗]${NC} $1" inc_fail } print_info() { echo -e " ${BLUE}[i]${NC} $1" } # Main verification print_header "Lab 03 Healthcheck Verification" cd "$LAB_DIR" # Test 1: docker-compose.yml exists print_test "Verifying docker-compose.yml exists" if [[ -f "docker-compose.yml" ]]; then print_pass "docker-compose.yml found" else print_fail "docker-compose.yml not found" exit 1 fi # Test 2: docker-compose.yml is valid print_test "Validating docker-compose.yml syntax" if docker compose config &> /dev/null; then print_pass "docker-compose.yml has valid syntax" else print_fail "docker-compose.yml has syntax errors" exit 1 fi # Test 3: Services are defined print_test "Verifying services are defined" SERVICES=$(docker compose config --services 2>/dev/null) SERVICE_COUNT=$(echo "$SERVICES" | wc -l) if [[ $SERVICE_COUNT -gt 0 ]]; then print_pass "Found $SERVICE_COUNT services" else print_fail "No services defined" exit 1 fi # Test 4: Healthcheck configuration check print_test "Checking healthcheck configuration" MISSING_HEALTHCHECK=0 for service in $SERVICES; do # Check for healthcheck section has_healthcheck=$(docker compose config 2>/dev/null | grep -A 50 "^$service:" | grep -c "healthcheck:" || echo "0") if [[ $has_healthcheck -eq 0 ]]; then print_fail " $service: Missing healthcheck section" ((MISSING_HEALTHCHECK++)) || true else # Verify healthcheck has test command has_test=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 5 "healthcheck:" | grep -c "test:" || echo "0") if [[ $has_test -eq 0 ]]; then print_fail " $service: Missing healthcheck test command" ((MISSING_HEALTHCHECK++)) || true else # Extract test command for reporting test_cmd=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 5 "healthcheck:" | grep "test:" | head -1 | sed 's/.*test: //' | tr -d '"') print_pass " $service: healthcheck configured" print_info " test: $test_cmd" fi fi done if [[ $MISSING_HEALTHCHECK -eq 0 ]]; then print_pass "All services have healthchecks configured" else print_fail "$MISSING_HEALTHCHECK services missing healthchecks" fi # Test 5: Healthcheck parameters verification print_test "Verifying healthcheck parameters" PARAMS_OK=0 for service in $SERVICES; do has_healthcheck=$(docker compose config 2>/dev/null | grep -A 50 "^$service:" | grep -c "healthcheck:" || echo "0") if [[ $has_healthcheck -gt 0 ]]; then # Check for interval has_interval=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 10 "healthcheck:" | grep -c "interval:" || echo "0") # Check for timeout has_timeout=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 10 "healthcheck:" | grep -c "timeout:" || echo "0") # Check for retries has_retries=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 10 "healthcheck:" | grep -c "retries:" || echo "0") interval=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 10 "healthcheck:" | grep "interval:" | sed 's/.*interval: //' | tr -d " '"" || echo "N/A") timeout=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 10 "healthcheck:" | grep "timeout:" | sed 's/.*timeout: //' | tr -d " '"" || echo "N/A") retries=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 10 "healthcheck:" | grep "retries:" | sed 's/.*retries: //' | tr -d " '"" || echo "N/A") if [[ $has_interval -gt 0 && $has_timeout -gt 0 && $has_retries -gt 0 ]]; then print_pass " $service: interval=$interval, timeout=$timeout, retries=$retries" ((PARAMS_OK++)) || true else print_info " $service: interval=$interval, timeout=$timeout, retries=$retries" # Check for start_period (optional) has_start_period=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 10 "healthcheck:" | grep -c "start_period:" || echo "0") if [[ $has_start_period -gt 0 ]]; then start_period=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 10 "healthcheck:" | grep "start_period:" | sed 's/.*start_period: //' | tr -d " '"" || echo "") print_info " start_period=$start_period" fi fi fi done if [[ $PARAMS_OK -gt 0 ]]; then print_pass "$PARAMS_OK services have complete healthcheck parameters" else print_fail "No services with complete healthcheck parameters" fi # Test 6: Healthcheck command types print_test "Analyzing healthcheck command types" HTTP_COUNT=0 CMD_SHELL_COUNT=0 CMD_COUNT=0 CUSTOM_COUNT=0 for service in $SERVICES; do has_healthcheck=$(docker compose config 2>/dev/null | grep -A 50 "^$service:" | grep -c "healthcheck:" || echo "0") if [[ $has_healthcheck -gt 0 ]]; then # Get test command test_section=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 10 "healthcheck:" || echo "") if echo "$test_section" | grep -q "CMD-SHELL"; then print_info " $service: CMD-SHELL healthcheck" ((CMD_SHELL_COUNT++)) || true elif echo "$test_section" | grep -q "CMD"; then print_info " $service: CMD healthcheck" ((CMD_COUNT++)) || true else print_info " $service: Custom healthcheck format" ((CUSTOM_COUNT++)) || true fi # Check if HTTP-based if echo "$test_section" | grep -qiE "(wget|curl|http)"; then ((HTTP_COUNT++)) || true fi fi done print_info "Healthcheck types: CMD-SHELL ($CMD_SHELL_COUNT), CMD ($CMD_COUNT), Custom ($CUSTOM_COUNT)" if [[ $HTTP_COUNT -gt 0 ]]; then print_pass "$HTTP_COUNT services use HTTP-based healthchecks" fi # Test 7: ELB Health Check Parallel verification print_test "Verifying ELB Health Check parallelism" ELB_PARALLEL=0 for service in $SERVICES; do has_healthcheck=$(docker compose config 2>/dev/null | grep -A 50 "^$service:" | grep -c "healthcheck:" || echo "0") if [[ $has_healthcheck -gt 0 ]]; then interval=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 10 "healthcheck:" | grep "interval:" | sed 's/.*interval: //' | tr -d " '"" || echo "") timeout=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 10 "healthcheck:" | grep "timeout:" | sed 's/.*timeout: //' | tr -d " '"" || echo "") retries=$(docker compose config 2>/dev/null | grep -A 60 "^$service:" | grep -A 10 "healthcheck:" | grep "retries:" | sed 's/.*retries: //' | tr -d " '"" || echo "") # Map to ELB defaults if [[ "$interval" == "30s" || "$interval" =~ ^30 ]]; then elb_interval="default (30s)" ((ELB_PARALLEL++)) || true else elb_interval="custom ($interval)" fi if [[ "$timeout" == "5s" || "$timeout" =~ ^5 ]]; then elb_timeout="default (5s)" ((ELB_PARALLEL++)) || true else elb_timeout="custom ($timeout)" fi if [[ "$retries" == "3" || "$retries" =~ ^3 ]]; then elb_retries="default (3)" ((ELB_PARALLEL++)) || true else elb_retries="custom ($retries)" fi print_info " $service: ELB parallel (interval: $elb_interval, timeout: $elb_timeout, retries: $elb_retries)" fi done if [[ $ELB_PARALLEL -gt 0 ]]; then print_pass "ELB Health Check parallelism verified" fi # Summary print_header "Healthcheck Verification Summary" echo -e "Tests run: $((pass_count + fail_count))" echo -e "${GREEN}Passed: $pass_count${NC}" if [[ $fail_count -gt 0 ]]; then echo -e "${RED}Failed: $fail_count${NC}" fi if [[ $fail_count -eq 0 ]]; then echo -e "\n${GREEN}${BOLD}✓ ALL HEALTHCHECK CHECKS PASSED${NC}" echo -e "\nHealthcheck configuration verified!" exit 0 else echo -e "\n${RED}Some healthcheck checks failed${NC}" echo -e "Please ensure all services have healthchecks configured." exit 1 fi