Files
laboratori-cloud/labs/lab-02-network/tests/01-network-creation-test.sh
Luca Sacchi Ricciardi 5b2c8c37aa feat(lab-02): complete Phase 3 - Network & VPC lab
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>
2026-03-25 17:26:35 +01:00

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