Files
laboratori-cloud/labs/lab-03-compute/tests/04-verify-infrastructure.sh
Luca Sacchi Ricciardi 23a9ffe443 feat(lab-03): complete Phase 4 - Compute & EC2 lab
Phase Plans (5 files):
- 04-RESEARCH.md: Domain research on Docker limits, healthchecks, EC2 parallels
- 04-VALIDATION.md: Success criteria and validation strategy
- 04-01-PLAN.md: Test infrastructure (RED phase)
- 04-02-PLAN.md: Diátxis documentation
- 04-03-PLAN.md: Infrastructure implementation (GREEN phase)

Test Scripts (6 files, 1300+ lines):
- 01-resource-limits-test.sh: Validate INF-03 compliance
- 02-healthcheck-test.sh: Validate healthcheck configuration
- 03-enforcement-test.sh: Verify resource limits with docker stats
- 04-verify-infrastructure.sh: Infrastructure verification
- 99-final-verification.sh: End-to-end student verification
- run-all-tests.sh: Test orchestration with fail-fast
- quick-test.sh: Fast validation (<30s)

Documentation (11 files, 2500+ lines):
Tutorials (3):
- 01-set-resource-limits.md: EC2 instance types, Docker limits syntax
- 02-implement-healthchecks.md: ELB health check parallels
- 03-dependencies-with-health.md: depends_on with service_healthy

How-to Guides (4):
- check-resource-usage.md: docker stats monitoring
- test-limits-enforcement.md: Stress testing CPU/memory
- custom-healthcheck.md: HTTP, TCP, database healthchecks
- instance-type-mapping.md: Docker limits → EC2 mapping

Reference (3):
- compose-resources-syntax.md: Complete deploy.resources reference
- healthcheck-syntax.md: All healthcheck parameters
- ec2-instance-mapping.md: Instance type mapping table

Explanation (1):
- compute-ec2-parallels.md: Container=EC2, Limits=Instance Type, Healthcheck=ELB

Infrastructure:
- docker-compose.yml: 5 services (web, app, worker, db, stress-test)
  All services: INF-03 compliant (cpus + memory limits)
  All services: healthcheck configured
  EC2 parallels: t2.nano, t2.micro, t2.small, t2.medium, m5.large
- Dockerfile: Alpine 3.19 + stress tools + non-root user

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 15:16:58 +02:00

85 lines
4.1 KiB
Bash
Executable File

#!/bin/bash
# Infrastructure Verification for Lab 03
# Verifies docker-compose.yml is correctly deployed with resource limits and healthchecks
set -euo pipefail
RED='\033[0;31m'; GREEN='\033[0;32m'; BLUE='\033[0;34m'; YELLOW='\033[1;33m'; BOLD='\033[1m'; NC='\033[0m'
pass_count=0; fail_count=0
inc_pass() { ((pass_count++)) || true; }
inc_fail() { ((fail_count++)) || true; }
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; }
cd "$(dirname "$0")/.."
print_header "Lab 03 Infrastructure Verification"
# File and syntax
print_test "Verifying docker-compose.yml exists and valid"
[[ -f "docker-compose.yml" ]] && print_pass "docker-compose.yml found" || { print_fail "docker-compose.yml not found"; exit 1; }
docker compose config &> /dev/null && print_pass "Syntax valid" || { print_fail "Syntax error"; exit 1; }
# Services and limits
print_test "Checking INF-03 compliance (resource limits)"
SERVICES=$(docker compose config --services 2>/dev/null)
NON_COMPLIANT=0
for s in $SERVICES; do
has_cpu=$(docker compose config 2>/dev/null | grep -A30 "^$s:" | grep -c "cpus:" || echo "0")
has_mem=$(docker compose config 2>/dev/null | grep -A30 "^$s:" | grep -c "memory:" || echo "0")
if [[ $has_cpu -eq 0 || $has_mem -eq 0 ]]; then
print_fail " $s: missing limits"
((NON_COMPLIANT++)) || true
else
cpu_val=$(docker compose config 2>/dev/null | grep -A30 "^$s:" | grep "cpus:" | sed 's/.*cpus: //' | tr -d ' "')
mem_val=$(docker compose config 2>/dev/null | grep -A30 "^$s:" | grep "memory:" | sed 's/.*memory: //' | tr -d " '""")
print_pass " $s: cpus=$cpu_val, memory=$mem_val"
fi
done
[[ $NON_COMPLIANT -eq 0 ]] && print_pass "INF-03 COMPLIANT" || print_fail "INF-03 VIOLATION: $NON_COMPLIANT services"
# Healthchecks
print_test "Verifying healthcheck configuration"
MISSING_HC=0
for s in $SERVICES; do
has_hc=$(docker compose config 2>/dev/null | grep -A50 "^$s:" | grep -c "healthcheck:" || echo "0")
[[ $has_hc -gt 0 ]] && print_pass " $s: healthcheck configured" || { print_fail " $s: missing healthcheck"; ((MISSING_HC++)); }
done
[[ $MISSING_HC -eq 0 ]] && print_pass "All services have healthchecks" || print_fail "$MISSING_HC missing healthchecks"
# Deploy and verify
print_test "Starting services"
docker compose up -d &> /dev/null && print_pass "Services started" && sleep 8 || { print_fail "Failed to start"; exit 1; }
print_test "Checking running containers"
RUNNING=$(docker compose ps --services --filter "status=running" | wc -l)
[[ $RUNNING -ge 4 ]] && print_pass "$RUNNING containers running" || print_fail "Only $RUNNING containers"
# Enforcement
print_test "Verifying resource limits enforced"
ENFORCED=0
for s in $SERVICES; do
c="lab03-$s"
if docker ps --format '{{.Names}}' | grep -q "$c"; then
nano_cpus=$(docker inspect "$c" --format '{{.HostConfig.NanoCpus}}' 2>/dev/null || echo "0")
mem_bytes=$(docker inspect "$c" --format '{{.HostConfig.Memory}}' 2>/dev/null || echo "0")
[[ $nano_cpus -gt 0 && $mem_bytes -gt 0 ]] && print_pass " $c: limits enforced" || print_fail " $c: limits not applied"
[[ $nano_cpus -gt 0 && $mem_bytes -gt 0 ]] && ((ENFORCED++)) || true
fi
done
[[ $ENFORCED -gt 0 ]] && print_pass "Limits enforced for $ENFORCED containers"
# Summary
print_header "Summary"
echo "Tests: $((pass_count + fail_count)) | ${GREEN}Passed: $pass_count${NC} ${RED}Failed: $fail_count${NC}"
[[ $fail_count -eq 0 ]] && { echo -e "\n${GREEN}${BOLD}✓ ALL CHECKS PASSED${NC}\n"; exit 0; } || { echo -e "\n${RED}Some checks failed${NC}\n"; exit 1; }