本文目录导读:

我来介绍如何在Shell脚本中配置容器测试策略,包括测试流程、健康检查、资源限制等关键环节。
基础测试脚本框架
#!/bin/bash
# 容器测试配置
CONTAINER_NAME="test-app"
IMAGE_NAME="myapp:latest"
TEST_TIMEOUT=60
NETWORK_NAME="test-network"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志函数
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
容器生命周期测试
# 容器启动测试
test_container_startup() {
log_info "Testing container startup..."
# 清理旧容器
docker rm -f $CONTAINER_NAME 2>/dev/null || true
# 启动容器
docker run -d \
--name $CONTAINER_NAME \
--restart unless-stopped \
-p 8080:8080 \
$IMAGE_NAME
# 等待容器就绪
local retries=30
local counter=0
while [ $counter -lt $retries ]; do
if docker inspect $CONTAINER_NAME --format='{{.State.Status}}' | grep -q "running"; then
log_info "Container started successfully"
return 0
fi
sleep 1
((counter++))
done
log_error "Container failed to start within timeout"
return 1
}
# 容器停止测试
test_container_shutdown() {
log_info "Testing container shutdown..."
# 优雅停止
docker stop -t 10 $CONTAINER_NAME
if [ $? -eq 0 ]; then
log_info "Container stopped gracefully"
else
log_warn "Container had to be force stopped"
fi
# 验证容器已停止
local status=$(docker inspect $CONTAINER_NAME --format='{{.State.Status}}' 2>/dev/null)
if [ "$status" == "exited" ]; then
log_info "Container successfully exited"
fi
}
健康检查测试
# 配置健康检查
configure_health_check() {
log_info "Configuring health check..."
docker run -d \
--name ${CONTAINER_NAME}-health \
--health-cmd="curl -f http://localhost:8080/health || exit 1" \
--health-interval=5s \
--health-retries=3 \
--health-timeout=3s \
--health-start-period=10s \
$IMAGE_NAME
}
# 测试健康检查
test_health_check() {
log_info "Testing health check functionality..."
local retries=20
local counter=0
while [ $counter -lt $retries ]; do
local status=$(docker inspect ${CONTAINER_NAME}-health \
--format='{{.State.Health.Status}}' 2>/dev/null)
if [ "$status" == "healthy" ]; then
log_info "Container health check passed"
return 0
elif [ "$status" == "unhealthy" ]; then
log_error "Container health check failed"
return 1
fi
sleep 2
((counter++))
done
log_error "Health check timeout"
return 1
}
# 模拟故障测试健康检查
test_health_check_failure() {
log_info "Testing health check failure detection..."
# 模拟故障
docker exec ${CONTAINER_NAME}-health sh -c "kill 1" 2>/dev/null
sleep 15
local status=$(docker inspect ${CONTAINER_NAME}-health \
--format='{{.State.Health.Status}}')
if [ "$status" == "unhealthy" ]; then
log_info "Health check correctly detected failure"
return 0
else
log_error "Health check failed to detect failure"
return 1
fi
}
资源限制测试
# 测试资源限制
test_resource_limits() {
log_info "Testing resource limits..."
# 创建带资源限制的容器
docker run -d \
--name ${CONTAINER_NAME}-limits \
--memory="256m" \
--memory-swap="512m" \
--cpus="0.5" \
$IMAGE_NAME
# 验证资源限制
local mem_limit=$(docker inspect ${CONTAINER_NAME}-limits \
--format='{{.HostConfig.Memory}}')
local cpu_shares=$(docker inspect ${CONTAINER_NAME}-limits \
--format='{{.HostConfig.CpuShares}}')
log_info "Memory limit: $(($mem_limit / 1048576))MB"
log_info "CPU shares: $cpu_shares"
}
# 压力测试
test_container_stress() {
log_info "Running stress test..."
# 使用stress工具进行压力测试
docker exec ${CONTAINER_NAME}-limits \
stress --cpu 2 --timeout 30
# 检查容器是否仍然运行
local status=$(docker inspect ${CONTAINER_NAME}-limits \
--format='{{.State.Status}}')
if [ "$status" == "running" ]; then
log_info "Container survived stress test"
else
log_warn "Container crashed under stress"
fi
}
网络测试
# 测试网络配置
test_network() {
log_info "Testing network configuration..."
# 创建测试网络
docker network create $NETWORK_NAME
# 启动容器在测试网络中
docker run -d \
--name ${CONTAINER_NAME}-net \
--network $NETWORK_NAME \
$IMAGE_NAME
# 测试网络连通性
docker run --rm \
--network $NETWORK_NAME \
busybox ping -c 3 ${CONTAINER_NAME}-net
if [ $? -eq 0 ]; then
log_info "Network connectivity test passed"
else
log_error "Network test failed"
fi
}
# 测试端口映射
test_port_mapping() {
log_info "Testing port mapping..."
local host_port=9090
local container_port=8080
docker run -d \
--name ${CONTAINER_NAME}-port \
-p ${host_port}:${container_port} \
$IMAGE_NAME
# 测试端口可访问性
curl -s -o /dev/null -w "%{http_code}" \
http://localhost:${host_port}/health
log_info "Port mapping test completed"
}
完整测试套件
#!/bin/bash
# 主测试函数
run_full_test_suite() {
log_info "Starting full container test suite"
local failed_tests=0
# 阶段1: 基础启动测试
log_info "Phase 1: Basic startup tests"
test_container_startup || ((failed_tests++))
# 阶段2: 健康检查测试
log_info "Phase 2: Health check tests"
configure_health_check
test_health_check || ((failed_tests++))
# 阶段3: 资源限制测试
log_info "Phase 3: Resource limit tests"
test_resource_limits
test_container_stress || ((failed_tests++))
# 阶段4: 网络测试
log_info "Phase 4: Network tests"
test_network || ((failed_tests++))
test_port_mapping || ((failed_tests++))
# 阶段5: 停止和清理测试
log_info "Phase 5: Cleanup tests"
test_container_shutdown || ((failed_tests++))
# 报告结果
log_info "Test suite completed"
if [ $failed_tests -eq 0 ]; then
log_info "All tests passed! ✅"
return 0
else
log_warn "$failed_tests test(s) failed! ❌"
return 1
fi
}
# 清理函数
cleanup() {
log_info "Cleaning up test containers..."
docker rm -f $CONTAINER_NAME ${CONTAINER_NAME}-health \
${CONTAINER_NAME}-limits ${CONTAINER_NAME}-net \
${CONTAINER_NAME}-port 2>/dev/null || true
docker network rm $NETWORK_NAME 2>/dev/null || true
}
# 主执行流程
main() {
# 注册清理
trap cleanup EXIT
# 运行测试
run_full_test_suite
# 退出代码
exit $?
}
# 执行主函数
main "$@"
使用示例
# 基础用法 ./container_test.sh # 指定特定测试阶段 ./container_test.sh --phase startup # 带超时设置的测试 timeout 300 ./container_test.sh # 详细输出模式 ./container_test.sh --verbose # 跳过某些测试 ./container_test.sh --skip network
最佳实践建议
- 测试隔离:每个测试使用独立的容器,避免相互影响
- 超时控制:为每个测试设置合理的超时时间
- 资源清理:测试结束后自动清理临时资源
- 日志记录:详细记录测试过程和结果
- 失败重试:对网络等不稳定因素实施重试机制
- 并行测试:使用
&和wait实现并行测试提高效率
这个脚本框架可以根据具体需求进行扩展和修改,适配不同的测试场景。