Implement Lab 02 with Docker bridge networks simulating VPC/Subnets. Test Infrastructure (RED phase): - 6 bash test scripts for network creation, isolation, INF-02 compliance - Fail-fast orchestration with run-all-tests.sh - Quick validation script for development Documentation (Diátaxis framework): - 3 tutorials: VPC creation, container deployment, isolation verification - 4 how-to guides: create network, inspect config, test isolation, cleanup - 3 reference docs: Docker network commands, Compose syntax, VPC mapping - 1 explanation: Docker ↔ VPC parallels (PARA-01/02/03/04) Infrastructure (GREEN phase): - docker-compose.yml with VPC networks (10.0.1.0/24, 10.0.2.0/24) - 5 services: web, app, db, test-public, test-private - INF-02 compliant: 127.0.0.1 bindings only, no 0.0.0.0 - Private network with --internal flag - Multi-homed app container (public + private networks) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
195 lines
7.4 KiB
Bash
Executable File
195 lines
7.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# Test 01: Network Creation Validation
|
|
# Validates Docker bridge network creation with custom subnets (VPC simulation)
|
|
# Usage: bash labs/lab-02-network/tests/01-network-creation-test.sh
|
|
|
|
set -euo pipefail
|
|
|
|
# Color definitions
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
BLUE='\033[0;34m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
# Get script directory
|
|
TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$TEST_DIR/../.." && pwd)"
|
|
|
|
# Counter helpers to handle set -e
|
|
pass_count=0
|
|
fail_count=0
|
|
skip_count=0
|
|
|
|
inc_pass() { ((pass_count++)) || true; }
|
|
inc_fail() { ((fail_count++)) || true; }
|
|
inc_skip() { ((skip_count++)) || true; }
|
|
|
|
# Test helper functions
|
|
print_header() {
|
|
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
|
|
echo -e "${BLUE}$1${NC}"
|
|
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
|
|
}
|
|
|
|
print_test() {
|
|
echo -e "\n${BLUE}[TEST]${NC} $1"
|
|
}
|
|
|
|
print_pass() {
|
|
echo -e "${GREEN}[PASS]${NC} $1"
|
|
inc_pass
|
|
}
|
|
|
|
print_fail() {
|
|
echo -e "${RED}[FAIL]${NC} $1"
|
|
inc_fail
|
|
}
|
|
|
|
print_skip() {
|
|
echo -e "${YELLOW}[SKIP]${NC} $1"
|
|
inc_skip
|
|
}
|
|
|
|
# Cleanup function
|
|
cleanup() {
|
|
echo -e "\n${BLUE}[*] Cleaning up test networks...${NC}"
|
|
docker network rm test-vpc-public 2>/dev/null || true
|
|
docker network rm test-vpc-private 2>/dev/null || true
|
|
docker network rm test-net1 2>/dev/null || true
|
|
docker network rm test-net2 2>/dev/null || true
|
|
echo -e "${GREEN}[✓] Cleanup complete${NC}"
|
|
}
|
|
|
|
# Set trap for cleanup
|
|
trap cleanup EXIT
|
|
|
|
# Start testing
|
|
print_header "Lab 02 - Test 01: Network Creation Validation"
|
|
|
|
# Test 1: Verify Docker is available
|
|
print_test "Test 1: Verify Docker is available"
|
|
if command -v docker &> /dev/null; then
|
|
print_pass "Docker command is available"
|
|
docker --version
|
|
else
|
|
print_fail "Docker command not found. Please install Docker."
|
|
exit 1
|
|
fi
|
|
|
|
# Test 2: Create public network with custom subnet (VPC simulation)
|
|
print_test "Test 2: Create public network with custom subnet (10.0.1.0/24)"
|
|
if docker network create --driver bridge --subnet 10.0.1.0/24 --gateway 10.0.1.1 test-vpc-public &> /dev/null; then
|
|
print_pass "Created public network test-vpc-public with subnet 10.0.1.0/24"
|
|
docker network inspect test-vpc-public --format='Subnet: {{range .IPAM.Config}}{{.Subnet}}{{end}}'
|
|
else
|
|
print_fail "Failed to create public network with custom subnet"
|
|
exit 1
|
|
fi
|
|
|
|
# Test 3: Create private network with --internal flag
|
|
print_test "Test 3: Create private network with --internal flag (10.0.2.0/24)"
|
|
if docker network create --driver bridge --internal --subnet 10.0.2.0/24 --gateway 10.0.2.1 test-vpc-private &> /dev/null; then
|
|
print_pass "Created private network test-vpc-private with --internal flag"
|
|
docker network inspect test-vpc-private --format='Internal: {{.Internal}}'
|
|
else
|
|
print_fail "Failed to create private network with --internal flag"
|
|
exit 1
|
|
fi
|
|
|
|
# Test 4: Verify networks appear in docker network ls
|
|
print_test "Test 4: Verify networks appear in docker network ls"
|
|
public_found=$(docker network ls --format '{{.Name}}' | grep -c "^test-vpc-public$" || true)
|
|
private_found=$(docker network ls --format '{{.Name}}' | grep -c "^test-vpc-private$" || true)
|
|
|
|
if [[ $public_found -eq 1 && $private_found -eq 1 ]]; then
|
|
print_pass "Both test-vpc-public and test-vpc-private found in network list"
|
|
docker network ls --filter "name=test-vpc-" --format "table {{.Name}}\t{{.Driver}}\t{{.Scope}}"
|
|
else
|
|
print_fail "Networks not found in list. public_found=$public_found, private_found=$private_found"
|
|
fi
|
|
|
|
# Test 5: Verify network inspection shows correct subnet
|
|
print_test "Test 5: Verify network inspection shows correct subnet configuration"
|
|
public_subnet=$(docker network inspect test-vpc-public --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}' 2>/dev/null || echo "")
|
|
private_subnet=$(docker network inspect test-vpc-private --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}' 2>/dev/null || echo "")
|
|
|
|
if [[ "$public_subnet" == "10.0.1.0/24" && "$private_subnet" == "10.0.2.0/24" ]]; then
|
|
print_pass "Network subnets correctly configured"
|
|
echo " Public: $public_subnet"
|
|
echo " Private: $private_subnet"
|
|
else
|
|
print_fail "Network subnets mismatch. public=$public_subnet (expected 10.0.1.0/24), private=$private_subnet (expected 10.0.2.0/24)"
|
|
fi
|
|
|
|
# Test 6: Verify private network has internal flag set
|
|
print_test "Test 6: Verify private network has --internal flag set"
|
|
internal_flag=$(docker network inspect test-vpc-private --format '{{.Internal}}' 2>/dev/null || echo "false")
|
|
|
|
if [[ "$internal_flag" == "true" ]]; then
|
|
print_pass "Private network correctly marked as internal (no external access)"
|
|
else
|
|
print_fail "Private network internal flag not set (value: $internal_flag)"
|
|
fi
|
|
|
|
# Test 7: Verify bridge driver is used
|
|
print_test "Test 7: Verify bridge driver is used for both networks"
|
|
public_driver=$(docker network inspect test-vpc-public --format '{{.Driver}}' 2>/dev/null || echo "")
|
|
private_driver=$(docker network inspect test-vpc-private --format '{{.Driver}}' 2>/dev/null || echo "")
|
|
|
|
if [[ "$public_driver" == "bridge" && "$private_driver" == "bridge" ]]; then
|
|
print_pass "Both networks use bridge driver"
|
|
else
|
|
print_fail "Driver mismatch. public=$public_driver, private=$private_driver (expected: bridge)"
|
|
fi
|
|
|
|
# Test 8: Check if docker-compose.yml exists (optional - may not exist yet in RED phase)
|
|
print_test "Test 8: Check if lab docker-compose.yml exists"
|
|
COMPOSE_FILE="$PROJECT_ROOT/labs/lab-02-network/docker-compose.yml"
|
|
if [[ -f "$COMPOSE_FILE" ]]; then
|
|
print_pass "docker-compose.yml found at $COMPOSE_FILE"
|
|
|
|
# Test 9: Verify docker-compose config is valid
|
|
print_test "Test 9: Validate docker-compose.yml syntax"
|
|
if docker compose -f "$COMPOSE_FILE" config &> /dev/null; then
|
|
print_pass "docker-compose.yml is valid YAML"
|
|
else
|
|
print_fail "docker-compose.yml has syntax errors"
|
|
fi
|
|
else
|
|
print_skip "docker-compose.yml not found yet (expected in RED phase - will be created in GREEN phase)"
|
|
fi
|
|
|
|
# Test 10: Verify networks can be removed
|
|
print_test "Test 10: Verify test networks can be removed"
|
|
# This will be handled by cleanup trap, but we verify the command works
|
|
if docker network rm test-vpc-public test-vpc-private &> /dev/null; then
|
|
print_pass "Test networks successfully removed"
|
|
|
|
# Recreate for cleanup trap
|
|
docker network create --driver bridge --subnet 10.0.1.0/24 --gateway 10.0.1.1 test-vpc-public &> /dev/null
|
|
docker network create --driver bridge --internal --subnet 10.0.2.0/24 --gateway 10.0.2.1 test-vpc-private &> /dev/null
|
|
else
|
|
print_fail "Failed to remove test networks"
|
|
fi
|
|
|
|
# Summary
|
|
print_header "Test Summary"
|
|
echo -e "Total tests run: $((pass_count + fail_count + skip_count))"
|
|
echo -e "${GREEN}Passed: $pass_count${NC}"
|
|
if [[ $fail_count -gt 0 ]]; then
|
|
echo -e "${RED}Failed: $fail_count${NC}"
|
|
fi
|
|
if [[ $skip_count -gt 0 ]]; then
|
|
echo -e "${YELLOW}Skipped: $skip_count${NC}"
|
|
fi
|
|
|
|
# Exit with error code if any tests failed
|
|
if [[ $fail_count -gt 0 ]]; then
|
|
echo -e "\n${RED}Some tests failed. Please review the output above.${NC}"
|
|
exit 1
|
|
else
|
|
echo -e "\n${GREEN}All tests passed! Network creation is working correctly.${NC}"
|
|
exit 0
|
|
fi
|