Shell脚本如何配置容器测试策略

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器测试策略

  1. 基础测试脚本框架
  2. 容器生命周期测试
  3. 健康检查测试
  4. 资源限制测试
  5. 网络测试
  6. 完整测试套件
  7. 使用示例
  8. 最佳实践建议

我来介绍如何在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

最佳实践建议

  1. 测试隔离:每个测试使用独立的容器,避免相互影响
  2. 超时控制:为每个测试设置合理的超时时间
  3. 资源清理:测试结束后自动清理临时资源
  4. 日志记录:详细记录测试过程和结果
  5. 失败重试:对网络等不稳定因素实施重试机制
  6. 并行测试:使用&wait实现并行测试提高效率

这个脚本框架可以根据具体需求进行扩展和修改,适配不同的测试场景。

抱歉,评论功能暂时关闭!