test_docker_optimization.shโข10.4 kB
#!/bin/bash
# Docker Optimization Test Script
# Tests the optimized MCP Optimizer Docker image
set -e
echo "๐ณ Testing MCP Optimizer Docker Image Optimization"
echo "=================================================="
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Image name
IMAGE_NAME="mcp-optimizer:optimized"
# Function to print colored output
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Function to check if Docker is running
check_docker() {
print_status "Checking Docker availability..."
if ! docker info > /dev/null 2>&1; then
print_error "Docker is not running or not accessible"
exit 1
fi
print_success "Docker is available"
}
# Function to build optimized image
build_image() {
print_status "Building optimized Docker image..."
# Record start time
start_time=$(date +%s)
# Build the image
if docker build -t "$IMAGE_NAME" --build-arg ENV=production .; then
end_time=$(date +%s)
build_time=$((end_time - start_time))
print_success "Image built successfully in ${build_time}s"
else
print_error "Failed to build Docker image"
exit 1
fi
}
# Function to check image size
check_image_size() {
print_status "Checking image size..."
# Get image size
size=$(docker images "$IMAGE_NAME" --format "table {{.Size}}" | tail -n 1)
size_bytes=$(docker images "$IMAGE_NAME" --format "table {{.Size}}" | tail -n 1 | sed 's/[^0-9.]//g')
echo "๐ Image size: $size"
# Check if size is reasonable (should be < 500MB for optimized image)
if [[ "$size" == *"GB"* ]]; then
print_warning "Image size is in GB range - may need further optimization"
elif [[ "$size" == *"MB"* ]]; then
size_mb=$(echo "$size" | sed 's/MB//')
if (( $(echo "$size_mb > 500" | bc -l) )); then
print_warning "Image size is > 500MB - consider further optimization"
else
print_success "Image size is optimized (< 500MB)"
fi
else
print_success "Image size is very optimized"
fi
}
# Function to test basic functionality
test_basic_functionality() {
print_status "Testing basic functionality..."
# Test Python import
if docker run --rm "$IMAGE_NAME" python -c "
import sys
print(f'Python version: {sys.version}')
print('โ
Python works')
"; then
print_success "Python runtime works"
else
print_error "Python runtime failed"
return 1
fi
}
# Function to test MCP Optimizer imports
test_mcp_imports() {
print_status "Testing MCP Optimizer imports..."
if docker run --rm "$IMAGE_NAME" python -c "
import mcp_optimizer
from mcp_optimizer.tools.linear_programming import solve_linear_program
from mcp_optimizer.tools.assignment import solve_assignment_problem
from mcp_optimizer.tools.knapsack import solve_knapsack_problem
print('โ
All MCP Optimizer imports successful')
"; then
print_success "MCP Optimizer imports work"
else
print_error "MCP Optimizer imports failed"
return 1
fi
}
# Function to test PuLP solver
test_pulp_solver() {
print_status "Testing PuLP solver..."
if docker run --rm "$IMAGE_NAME" python -c "
import pulp
print(f'PuLP version: {pulp.__version__}')
# Simple linear programming problem
prob = pulp.LpProblem('test', pulp.LpMaximize)
x = pulp.LpVariable('x', 0, None)
y = pulp.LpVariable('y', 0, None)
# Objective function
prob += 3*x + 2*y
# Constraints
prob += x + y <= 4
prob += 2*x + y <= 6
# Solve
prob.solve(pulp.PULP_CBC_CMD(msg=0))
print(f'Status: {pulp.LpStatus[prob.status]}')
print(f'Optimal value: {pulp.value(prob.objective)}')
print(f'x = {pulp.value(x)}, y = {pulp.value(y)}')
print('โ
PuLP solver works correctly')
"; then
print_success "PuLP solver works"
else
print_error "PuLP solver failed"
return 1
fi
}
# Function to test OR-Tools solver
test_ortools_solver() {
print_status "Testing OR-Tools solver..."
if docker run --rm "$IMAGE_NAME" python -c "
from ortools.linear_solver import pywraplp
print('OR-Tools version: Available')
# Create solver
solver = pywraplp.Solver.CreateSolver('SCIP')
if not solver:
solver = pywraplp.Solver.CreateSolver('GLOP')
# Variables
x = solver.NumVar(0, solver.infinity(), 'x')
y = solver.NumVar(0, solver.infinity(), 'y')
# Constraints
solver.Add(x + y <= 4)
solver.Add(2*x + y <= 6)
# Objective
solver.Maximize(3*x + 2*y)
# Solve
status = solver.Solve()
if status == pywraplp.Solver.OPTIMAL:
print(f'Optimal value: {solver.Objective().Value()}')
print(f'x = {x.solution_value()}, y = {y.solution_value()}')
print('โ
OR-Tools solver works correctly')
else:
print('โ OR-Tools solver failed to find optimal solution')
exit(1)
"; then
print_success "OR-Tools solver works"
else
print_error "OR-Tools solver failed"
return 1
fi
}
# Function to test MCP server startup
test_mcp_server() {
print_status "Testing MCP server startup..."
# Test MCP server creation and JSON-RPC communication
if echo '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0"}}}' | docker run --rm -i "$IMAGE_NAME" | grep -q '"result"'; then
print_success "MCP server responds to JSON-RPC requests"
else
print_error "MCP server failed to respond to JSON-RPC requests"
return 1
fi
# Test server creation without running
if docker run --rm "$IMAGE_NAME" python -c "
from mcp_optimizer.mcp_server import create_mcp_server
server = create_mcp_server()
print('โ
MCP server created successfully')
print(f'Server type: {type(server)}')
"; then
print_success "MCP server creation works"
else
print_error "MCP server creation failed"
return 1
fi
}
# Function to test memory usage
test_memory_usage() {
print_status "Testing memory usage..."
# Run container with memory limit and check usage
container_id=$(docker run -d --memory=512m "$IMAGE_NAME" python -c "
import time
import psutil
import mcp_optimizer
print(f'Memory usage: {psutil.virtual_memory().percent}%')
print(f'Available memory: {psutil.virtual_memory().available / 1024 / 1024:.1f} MB')
# Load some modules to test memory
from mcp_optimizer.tools.linear_programming import solve_linear_program
from mcp_optimizer.tools.assignment import solve_assignment_problem
print('โ
Memory test completed')
time.sleep(2)
")
# Wait and check
sleep 3
if docker wait "$container_id" > /dev/null 2>&1; then
print_success "Memory usage test passed"
else
print_warning "Memory usage test had issues"
fi
# Cleanup
docker rm "$container_id" > /dev/null 2>&1
}
# Function to run performance benchmark
run_performance_benchmark() {
print_status "Running performance benchmark..."
if docker run --rm "$IMAGE_NAME" python -c "
import time
import mcp_optimizer
from mcp_optimizer.tools.linear_programming import solve_linear_program
# Benchmark linear programming solver
objective = {'sense': 'maximize', 'coefficients': {'x': 3, 'y': 2}}
variables = {
'x': {'type': 'continuous', 'lower': 0},
'y': {'type': 'continuous', 'lower': 0}
}
constraints = [
{'expression': {'x': 1, 'y': 1}, 'operator': '<=', 'rhs': 4},
{'expression': {'x': 2, 'y': 1}, 'operator': '<=', 'rhs': 6}
]
# Run multiple times to get average
times = []
for i in range(10):
start = time.time()
result = solve_linear_program(objective, variables, constraints)
end = time.time()
times.append(end - start)
avg_time = sum(times) / len(times)
print(f'Average solve time: {avg_time:.4f}s')
print(f'Min time: {min(times):.4f}s')
print(f'Max time: {max(times):.4f}s')
print('โ
Performance benchmark completed')
"; then
print_success "Performance benchmark passed"
else
print_error "Performance benchmark failed"
return 1
fi
}
# Function to generate optimization report
generate_report() {
print_status "Generating optimization report..."
# Get detailed image information
image_info=$(docker inspect "$IMAGE_NAME")
size=$(docker images "$IMAGE_NAME" --format "table {{.Size}}" | tail -n 1)
created=$(docker images "$IMAGE_NAME" --format "table {{.CreatedAt}}" | tail -n 1)
# Create report
cat > docker_optimization_report.txt << EOF
๐ณ MCP Optimizer Docker Image Optimization Report
================================================
๐ Image Information:
- Name: $IMAGE_NAME
- Size: $size
- Created: $created
โ
Test Results:
- Basic functionality: PASSED
- MCP Optimizer imports: PASSED
- PuLP solver: PASSED
- OR-Tools solver: PASSED
- MCP server startup: PASSED
- Memory usage: PASSED
- Performance benchmark: PASSED
๐ฏ Optimization Achievements:
- Target size: < 500MB
- Actual size: $size
- Multi-stage build: ENABLED
- Security: Non-root user
- Python optimization: ENABLED
- Cache cleanup: ENABLED
๐ Recommendations:
1. Monitor image size when adding dependencies
2. Regular security updates for base image
3. Consider distroless for even smaller size
4. Use BuildKit for faster builds
Generated: $(date)
EOF
print_success "Report generated: docker_optimization_report.txt"
}
# Main execution
main() {
echo "Starting Docker optimization tests..."
echo
# Run all tests
check_docker
build_image
check_image_size
test_basic_functionality
test_mcp_imports
test_pulp_solver
test_ortools_solver
test_mcp_server
test_memory_usage
run_performance_benchmark
generate_report
echo
echo "๐ All tests completed successfully!"
echo "๐ Check docker_optimization_report.txt for detailed results"
echo
echo "๐ก Next steps:"
echo " - Deploy to production: docker run -p 8000:8000 $IMAGE_NAME"
echo " - Push to registry: docker tag $IMAGE_NAME your-registry/$IMAGE_NAME"
echo " - Use in docker-compose: see examples/integration/docker-compose.yml"
}
# Run main function
main "$@"