From e4c497db729d3f8cd5e6a4e8e2d03136c40f3fa2 Mon Sep 17 00:00:00 2001 From: Luca Sacchi Ricciardi Date: Tue, 24 Mar 2026 22:32:23 +0100 Subject: [PATCH] feat(02-03): create infrastructure verification script - Test 1: docker-compose.yml is valid YAML - Test 2: Dockerfile exists and has USER directive - Test 3: docker-compose.yml has user directive (1000:1000) - Test 4: Docker image builds successfully - Test 5: Container runs as non-root (labuser) - Test 6: docker-compose service verification GREEN phase check: All infrastructure tests pass Co-Authored-By: Claude Opus 4.6 --- .../tests/04-verify-infrastructure.sh | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100755 labs/lab-01-iam/tests/04-verify-infrastructure.sh diff --git a/labs/lab-01-iam/tests/04-verify-infrastructure.sh b/labs/lab-01-iam/tests/04-verify-infrastructure.sh new file mode 100755 index 0000000..97f2b74 --- /dev/null +++ b/labs/lab-01-iam/tests/04-verify-infrastructure.sh @@ -0,0 +1,163 @@ +#!/bin/bash +# Infrastructure Verification: Lab 01 +# Verifies that docker-compose.yml and Dockerfile satisfy all requirements +# This is the GREEN phase check - tests should pass after infrastructure implementation + +set -euo pipefail + +# Helper function for incrementing counters that works with set -e +inc_pass() { ((pass_count++)) || true; } +inc_fail() { ((fail_count++)) || true; } + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# TEST_DIR is labs/lab-01-iam/tests, so .. gives us labs/lab-01-iam +LAB_DIR="$(cd "$TEST_DIR/.." && pwd)" +PROJECT_ROOT="$(cd "$LAB_DIR/../.." && pwd)" + +cd "$LAB_DIR" + +echo -e "${BLUE}========================================${NC}" +echo -e "${BLUE}Lab 01 Infrastructure Verification${NC}" +echo -e "${BLUE}GREEN Phase Check${NC}" +echo -e "${BLUE}========================================${NC}" +echo "" + +pass_count=0 +fail_count=0 + +# Test 1: docker-compose.yml is valid +echo -e "${BLUE}[1/6] Checking docker-compose.yml syntax...${NC}" +if docker compose config >/dev/null 2>&1; then + echo -e " ${GREEN}✓${NC} docker-compose.yml is valid YAML" + inc_pass +else + echo -e " ${RED}✗${NC} docker-compose.yml has syntax errors" + inc_fail +fi +echo "" + +# Test 2: Dockerfile exists and is readable +echo -e "${BLUE}[2/6] Checking Dockerfile...${NC}" +if [ -f "Dockerfile" ]; then + echo -e " ${GREEN}✓${NC} Dockerfile exists" + + # Check for USER directive + if grep -q "^USER" Dockerfile; then + user_line=$(grep "^USER" Dockerfile) + echo -e " ${GREEN}✓${NC} USER directive found: $user_line" + inc_pass + else + echo -e " ${RED}✗${NC} No USER directive found in Dockerfile" + inc_fail + fi +else + echo -e " ${RED}✗${NC} Dockerfile not found" + inc_fail +fi +echo "" + +# Test 3: docker-compose.yml has user directive +echo -e "${BLUE}[3/6] Checking docker-compose.yml user directive...${NC}" +if grep -q "user:" docker-compose.yml; then + user_value=$(grep "user:" docker-compose.yml | head -1 | sed 's/.*user: *//' | tr -d '"') + echo -e " ${GREEN}✓${NC} user directive found: $user_value" + + # Verify it's not root (0:0) + if [[ "$user_value" != *"0:0"* ]] && [[ "$user_value" != *"root"* ]]; then + echo -e " ${GREEN}✓${NC} User is not root (INF-01 compliant)" + inc_pass + else + echo -e " ${RED}✗${NC} User is root (INF-01 violation)" + inc_fail + fi +else + echo -e " ${RED}✗${NC} No user directive in docker-compose.yml" + inc_fail +fi +echo "" + +# Test 4: Build Docker image +echo -e "${BLUE}[4/6] Building Docker image...${NC}" +if docker build -t lab01-non-root -q . >/dev/null 2>&1; then + echo -e " ${GREEN}✓${NC} Docker image built successfully" + inc_pass +else + echo -e " ${RED}✗${NC} Docker image build failed" + inc_fail +fi +echo "" + +# Test 5: Verify container runs as non-root +echo -e "${BLUE}[5/6] Verifying non-root execution...${NC}" +if docker run --rm lab01-non-root whoami 2>/dev/null | grep -q "labuser"; then + echo -e " ${GREEN}✓${NC} Container runs as non-root user (labuser)" + inc_pass +else + echo -e " ${RED}✗${NC} Container not running as labuser" + inc_fail +fi +echo "" + +# Test 6: Verify docker-compose service +echo -e "${BLUE}[6/6] Verifying docker-compose service...${NC}" +# Start container in detached mode +if docker compose up -d >/dev/null 2>&1; then + echo -e " ${GREEN}✓${NC} docker-compose service started" + + # Wait for container to be ready + sleep 3 + + # Check container is running + if docker ps --format "{{.Names}}" | grep -q "^lab01-iam-test$"; then + echo -e " ${GREEN}✓${NC} Container is running" + + # Verify user + actual_user=$(docker exec lab01-iam-test whoami 2>/dev/null || echo "unknown") + if [ "$actual_user" = "labuser" ]; then + echo -e " ${GREEN}✓${NC} docker-compose container runs as non-root" + inc_pass + else + echo -e " ${RED}✗${NC} docker-compose container running as $actual_user (expected labuser)" + inc_fail + fi + else + echo -e " ${RED}✗${NC} Container not running" + inc_fail + fi + + # Cleanup + docker compose down --volumes >/dev/null 2>&1 +else + echo -e " ${RED}✗${NC} Failed to start docker-compose service" + inc_fail +fi +echo "" + +# Summary +echo -e "${BLUE}========================================${NC}" +echo -e "${BLUE}Verification Summary${NC}" +echo -e "${BLUE}========================================${NC}" +echo "Passed: $pass_count/6" +echo "Failed: $fail_count/6" +echo "" + +if [ $fail_count -eq 0 ]; then + echo -e "${GREEN}All checks passed!${NC}" + echo -e "${GREEN}GREEN phase complete - infrastructure satisfies tests${NC}" + echo "" + echo "Next: Run full test suite" + echo " bash labs/lab-01-iam/tests/run-all-tests.sh" + echo -e "${BLUE}========================================${NC}" + exit 0 +else + echo -e "${RED}Some checks failed${NC}" + echo -e "${RED}Infrastructure needs fixes before tests will pass${NC}" + echo -e "${BLUE}========================================${NC}" + exit 1 +fi