v0.0.3 published
This commit is contained in:
94
test/v0.0.2/start.sh
Normal file
94
test/v0.0.2/start.sh
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Enhanced startup script with improved logging, error handling, and dynamic permissions
|
||||
# Version: 0.0.2 - Test version for development
|
||||
|
||||
# Color definitions for logging
|
||||
RED="\033[0;31m"
|
||||
GREEN="\033[0;32m"
|
||||
YELLOW="\033[1;33m"
|
||||
BLUE="\033[0;34m"
|
||||
NC="\033[0m"
|
||||
|
||||
# Configuration
|
||||
LOG_DIR="/var/log/container"
|
||||
LOG_FILE="$LOG_DIR/services.log"
|
||||
MAX_LOG_SIZE=10485760 # 10MB
|
||||
|
||||
# Logging functions
|
||||
_log() {
|
||||
local level_color=$1
|
||||
local level_name=$2
|
||||
shift 2
|
||||
echo -e "${level_color}[${level_name}]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $*"
|
||||
}
|
||||
|
||||
log_info() { _log "$BLUE" "INFO" "$@"; }
|
||||
log_success() { _log "$GREEN" "SUCCESS" "$@"; }
|
||||
log_warning() { _log "$YELLOW" "WARNING" "$@"; }
|
||||
log_error() { _log "$RED" "ERROR" "$@"; }
|
||||
|
||||
# Setup logging with rotation
|
||||
setup_logging() {
|
||||
mkdir -p "$LOG_DIR"
|
||||
touch "$LOG_FILE"
|
||||
|
||||
# Rotate log if it's too large
|
||||
if [ -f "$LOG_FILE" ] && [ $(stat -c%s "$LOG_FILE" 2>/dev/null || echo 0) -gt $MAX_LOG_SIZE ]; then
|
||||
log_info "Log file size exceeded ${MAX_LOG_SIZE} bytes, rotating..."
|
||||
mv "$LOG_FILE" "${LOG_FILE}.old"
|
||||
touch "$LOG_FILE"
|
||||
log_info "Log rotation completed"
|
||||
fi
|
||||
|
||||
log_info "Logging to console and $LOG_FILE"
|
||||
exec > >(tee -a "$LOG_FILE") 2> >(tee -a "$LOG_FILE" >&2)
|
||||
}
|
||||
|
||||
# Apply dynamic PUID/PGID if different from defaults
|
||||
apply_dynamic_permissions() {
|
||||
local current_uid=$(id -u hexo)
|
||||
local current_gid=$(id -g hexo)
|
||||
local target_uid=${PUID:-1000}
|
||||
local target_gid=${PGID:-1000}
|
||||
|
||||
if [ "$current_uid" != "$target_uid" ] || [ "$current_gid" != "$target_gid" ]; then
|
||||
log_info "Applying dynamic user/group mapping: $current_uid:$current_gid -> $target_uid:$target_gid"
|
||||
|
||||
# Update group if needed
|
||||
if [ "$current_gid" != "$target_gid" ]; then
|
||||
groupmod -g "$target_gid" hexo
|
||||
log_info "Updated hexo group ID to $target_gid"
|
||||
fi
|
||||
|
||||
# Update user if needed
|
||||
if [ "$current_uid" != "$target_uid" ]; then
|
||||
usermod -u "$target_uid" hexo
|
||||
log_info "Updated hexo user ID to $target_uid"
|
||||
fi
|
||||
|
||||
# Update ownership of important directories
|
||||
log_info "Updating ownership of critical directories..."
|
||||
chown -R hexo:hexo /home/hexo /home/www/hexo 2>/dev/null || true
|
||||
log_success "Dynamic permissions applied successfully"
|
||||
else
|
||||
log_info "User/group IDs already match target values ($target_uid:$target_gid)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution function
|
||||
main() {
|
||||
setup_logging
|
||||
|
||||
log_info "===== Hexo Container Starting (v0.0.2) ====="
|
||||
log_info "Timestamp: $(date)"
|
||||
log_info "This is a test version of the enhanced startup script"
|
||||
|
||||
# Test dynamic permissions function
|
||||
apply_dynamic_permissions
|
||||
|
||||
log_success "===== Test completed successfully ====="
|
||||
}
|
||||
|
||||
# Start main execution
|
||||
main
|
||||
121
test/v0.0.3/linux/PORT_MAPPING_UPDATE_REPORT.md
Normal file
121
test/v0.0.3/linux/PORT_MAPPING_UPDATE_REPORT.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Linux 测试套件端口映射修改报告
|
||||
|
||||
## 📋 修改概述
|
||||
|
||||
**任务**: 将 Linux 测试套件中的 HTTP 端口映射从 8888 改为 8080
|
||||
**完成日期**: 2025年6月1日
|
||||
**状态**: ✅ **完成** - 所有测试通过
|
||||
|
||||
## 🔧 修改的文件
|
||||
|
||||
### 1. `/home/bhk/Desktop/dockerfiledir/test/v0.0.3/linux/run_test.sh`
|
||||
```bash
|
||||
# 修改前
|
||||
HTTP_PORT=${3:-8888}
|
||||
|
||||
# 修改后
|
||||
HTTP_PORT=${3:-8080}
|
||||
```
|
||||
|
||||
### 2. `/home/bhk/Desktop/dockerfiledir/test/v0.0.3/linux/functional_test.sh`
|
||||
```bash
|
||||
# 修改前
|
||||
HTTP_PORT=${2:-8888}
|
||||
|
||||
# 修改后
|
||||
HTTP_PORT=${2:-8080}
|
||||
```
|
||||
|
||||
### 3. `/home/bhk/Desktop/dockerfiledir/test/v0.0.3/linux/test_paths.sh`
|
||||
```bash
|
||||
# 修改前
|
||||
DEFAULT_PORTS=(8888 2222)
|
||||
|
||||
# 修改后
|
||||
DEFAULT_PORTS=(8080 2222)
|
||||
```
|
||||
|
||||
## ✅ 验证结果
|
||||
|
||||
### 端口映射验证
|
||||
- ✅ Docker 容器正确绑定到 `8080:80` 端口
|
||||
- ✅ HTTP 服务可通过 http://localhost:8080 访问
|
||||
- ✅ 健康检查端点 http://localhost:8080/health 正常工作
|
||||
- ✅ SSH 端口 2222 保持不变
|
||||
|
||||
### 完整测试套件结果
|
||||
```
|
||||
测试时间: 2025年6月1日 01:50:37
|
||||
总测试数: 5
|
||||
通过测试: 5/5
|
||||
失败测试: 0/5
|
||||
成功率: 100%
|
||||
总耗时: 145s
|
||||
```
|
||||
|
||||
### 各模块测试结果
|
||||
- ✅ **构建测试** (build_test.sh) - 通过
|
||||
- ✅ **运行测试** (run_test.sh) - 通过 (使用8080端口)
|
||||
- ✅ **功能测试** (functional_test.sh) - 通过 (验证8080端口HTTP服务)
|
||||
- ✅ **日志轮转测试** (log_rotation_test.sh) - 通过
|
||||
- ✅ **清理测试** (cleanup_test.sh) - 通过
|
||||
|
||||
## 🔍 技术细节
|
||||
|
||||
### Docker 运行命令示例
|
||||
```bash
|
||||
docker run -d \
|
||||
--name hexo-test-v003 \
|
||||
-p 8080:80 \ # 新的端口映射
|
||||
-p 2222:22 \ # SSH端口保持不变
|
||||
-e PUID=1000 \
|
||||
-e PGID=1000 \
|
||||
-e TZ=Asia/Shanghai \
|
||||
hexo-test:v0.0.3
|
||||
```
|
||||
|
||||
### 访问地址更新
|
||||
- **HTTP 访问**: http://localhost:8080 (原 8888)
|
||||
- **健康检查**: http://localhost:8080/health (原 8888)
|
||||
- **SSH 连接**: ssh -p 2222 hexo@localhost (保持不变)
|
||||
|
||||
## 📊 影响范围
|
||||
|
||||
### 自动处理的部分
|
||||
- ✅ 所有使用 `$HTTP_PORT` 变量的地方都自动更新
|
||||
- ✅ 容器端口映射自动更新到8080
|
||||
- ✅ HTTP连接测试自动使用新端口
|
||||
- ✅ 健康检查端点自动使用新端口
|
||||
|
||||
### 无需额外修改的部分
|
||||
- ✅ 容器内部服务仍然运行在80端口
|
||||
- ✅ SSH服务端口(2222)保持不变
|
||||
- ✅ 日志轮转功能不受影响
|
||||
- ✅ 测试脚本逻辑保持不变
|
||||
|
||||
## 🎯 验证步骤
|
||||
|
||||
1. **端口占用检查**: 确认8080端口可用
|
||||
2. **容器启动**: 验证容器使用8080端口启动
|
||||
3. **HTTP服务**: 测试HTTP服务通过8080端口访问
|
||||
4. **功能测试**: 所有功能测试使用新端口
|
||||
5. **完整套件**: 运行完整测试套件验证兼容性
|
||||
|
||||
## 📝 注意事项
|
||||
|
||||
- **向后兼容**: 可通过参数指定其他端口 `./run_test.sh hexo-test <port>`
|
||||
- **环境隔离**: 修改只影响Linux测试套件,Windows测试套件保持独立
|
||||
- **文档更新**: 相关文档和README需要更新端口信息
|
||||
|
||||
## 🚀 后续建议
|
||||
|
||||
1. **文档更新**: 更新测试指南中的端口信息
|
||||
2. **端口标准化**: 考虑在所有环境中统一使用8080端口
|
||||
3. **配置管理**: 考虑将端口配置集中管理
|
||||
|
||||
---
|
||||
|
||||
**修改完成**: ✅ 所有测试通过
|
||||
**端口映射**: 8888 → 8080
|
||||
**测试验证**: 100% 成功率
|
||||
**兼容性**: 完全兼容现有功能
|
||||
318
test/v0.0.3/linux/README.md
Normal file
318
test/v0.0.3/linux/README.md
Normal file
@@ -0,0 +1,318 @@
|
||||
# Hexo Container v0.0.3 测试脚本使用说明 (Linux)
|
||||
|
||||
## 路径修正说明
|
||||
|
||||
本次更新修正了 `test/v0.0.3/linux` 目录下所有测试脚本的路径问题,确保脚本能够:
|
||||
|
||||
1. **正确调用对应文件** - 无论从哪个目录执行脚本
|
||||
2. **正确生成文件** - 所有生成的文件都保存在测试目录及其子目录中
|
||||
3. **使用相对路径** - 提高脚本的可移植性
|
||||
|
||||
## 修正的关键问题
|
||||
|
||||
### 1. 脚本工作目录统一
|
||||
- 所有脚本现在都会自动切换到脚本所在目录作为工作目录
|
||||
- 使用 `SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"` 获取脚本目录
|
||||
- 使用 `cd "$SCRIPT_DIR"` 设置工作目录
|
||||
|
||||
### 2. 路径引用修正
|
||||
- **Dockerfile 路径**: `../../../Dockerfile_v0.0.3` (相对于测试脚本目录)
|
||||
- **日志目录**: `$SCRIPT_DIR/logs` (在测试脚本目录下)
|
||||
- **测试数据**: `$SCRIPT_DIR/test_data` (在测试脚本目录下)
|
||||
- **SSH 密钥**: `$SCRIPT_DIR/test_data/ssh_keys/test_key`
|
||||
|
||||
### 3. Docker 卷挂载路径修正
|
||||
- 使用 `$SCRIPT_DIR` 构建绝对路径进行卷挂载
|
||||
- 确保容器能正确访问主机文件
|
||||
|
||||
### 4. 端口配置更新
|
||||
- 默认 HTTP 端口从 8888 更新为 8080
|
||||
- 避免与常见服务的端口冲突
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
test/v0.0.3/linux/
|
||||
├── build_test.sh # 构建测试脚本
|
||||
├── run_test.sh # 运行测试脚本
|
||||
├── functional_test.sh # 功能测试脚本
|
||||
├── log_rotation_test.sh # 日志轮转测试脚本 (v0.0.3新功能)
|
||||
├── test_log_size_reset.sh # 🆕 日志大小重置专项测试脚本 (容器重启修复验证)
|
||||
├── cleanup_test.sh # 清理测试脚本
|
||||
├── start.sh # 一键测试套件
|
||||
├── test_paths.sh # 路径验证脚本 (新增)
|
||||
├── README.md # 使用说明文档 (新增)
|
||||
├── logs/ # 测试日志目录 (自动创建)
|
||||
└── test_data/ # 测试数据目录 (自动创建)
|
||||
├── hexo_site/ # 测试站点文件
|
||||
└── ssh_keys/ # SSH 密钥文件
|
||||
```
|
||||
|
||||
## 使用方式
|
||||
|
||||
### 方式1: 从测试目录运行 (推荐)
|
||||
```bash
|
||||
cd "/path/to/dockerfiledir/test/v0.0.3/linux"
|
||||
./start.sh
|
||||
```
|
||||
|
||||
### 方式2: 从任意目录运行
|
||||
```bash
|
||||
/path/to/dockerfiledir/test/v0.0.3/linux/start.sh
|
||||
```
|
||||
|
||||
### 方式3: 单独运行各个测试
|
||||
```bash
|
||||
cd "/path/to/dockerfiledir/test/v0.0.3/linux"
|
||||
./build_test.sh # 构建镜像
|
||||
./run_test.sh # 启动容器
|
||||
./functional_test.sh # 功能测试
|
||||
./log_rotation_test.sh # 日志轮转测试
|
||||
./test_log_size_reset.sh # 🆕 日志大小重置测试 (容器重启修复验证)
|
||||
./cleanup_test.sh # 清理环境
|
||||
```
|
||||
|
||||
## 测试参数
|
||||
|
||||
### start.sh 参数
|
||||
- `--clean-start`: 清理后重新开始测试
|
||||
- `--help`: 显示帮助信息
|
||||
|
||||
### 各脚本参数
|
||||
|
||||
#### build_test.sh
|
||||
```bash
|
||||
./build_test.sh [TAG] [PLATFORM]
|
||||
# TAG: 镜像标签 (默认: hexo-test:v0.0.3)
|
||||
# PLATFORM: 平台架构 (默认: linux/amd64)
|
||||
```
|
||||
|
||||
#### run_test.sh
|
||||
```bash
|
||||
./run_test.sh [TAG] [CONTAINER_NAME] [HTTP_PORT] [SSH_PORT] [PUID] [PGID] [TIMEZONE]
|
||||
# TAG: 镜像标签 (默认: hexo-test:v0.0.3)
|
||||
# CONTAINER_NAME: 容器名称 (默认: hexo-test-v003)
|
||||
# HTTP_PORT: HTTP端口 (默认: 8080)
|
||||
# SSH_PORT: SSH端口 (默认: 2222)
|
||||
# PUID: 用户ID (默认: 1000)
|
||||
# PGID: 组ID (默认: 1000)
|
||||
# TIMEZONE: 时区 (默认: Asia/Shanghai)
|
||||
```
|
||||
|
||||
#### functional_test.sh
|
||||
```bash
|
||||
./functional_test.sh [CONTAINER_NAME] [HTTP_PORT] [SSH_PORT]
|
||||
# CONTAINER_NAME: 容器名称 (默认: hexo-test-v003)
|
||||
# HTTP_PORT: HTTP端口 (默认: 8080)
|
||||
# SSH_PORT: SSH端口 (默认: 2222)
|
||||
```
|
||||
|
||||
#### log_rotation_test.sh
|
||||
```bash
|
||||
./log_rotation_test.sh [CONTAINER_NAME] [HTTP_PORT] [SSH_PORT] [OPTIONS]
|
||||
# CONTAINER_NAME: 容器名称 (默认: hexo-test-v003)
|
||||
# HTTP_PORT: HTTP端口 (默认: 8080)
|
||||
# SSH_PORT: SSH端口 (默认: 2222)
|
||||
# OPTIONS: --fast-test, --quick-gen, --log-threshold-mb N
|
||||
```
|
||||
|
||||
#### test_log_size_reset.sh (🆕 容器重启修复验证)
|
||||
```bash
|
||||
./test_log_size_reset.sh [OPTIONS]
|
||||
# --container-name NAME 容器名称 (默认: hexo-test-v003)
|
||||
# --ssh-port PORT SSH端口 (默认: 2222)
|
||||
# --target-size-kb SIZE 目标日志大小KB (默认: 25)
|
||||
# --verbose 详细输出模式
|
||||
# --help 显示帮助信息
|
||||
```
|
||||
|
||||
此脚本专门验证容器重启时的日志监控修复功能,确保:
|
||||
- 容器重启后不会重复输出旧的Git部署信息
|
||||
- 日志位置跟踪文件正确工作
|
||||
- 部署日志监控在重启后正常恢复
|
||||
|
||||
#### cleanup_test.sh
|
||||
```bash
|
||||
./cleanup_test.sh [CONTAINER_NAME] [IMAGE_TAG] [OPTIONS]
|
||||
# CONTAINER_NAME: 容器名称 (默认: hexo-test-v003)
|
||||
# IMAGE_TAG: 镜像标签 (默认: hexo-test:v0.0.3)
|
||||
# OPTIONS: --remove-image, --remove-test-data, --remove-logs
|
||||
```
|
||||
|
||||
### 使用示例
|
||||
```bash
|
||||
# 完整测试 (清理模式)
|
||||
./start.sh --clean-start
|
||||
|
||||
# 自定义端口运行
|
||||
./run_test.sh "hexo-test:v0.0.3" "my-hexo-test" 9999 3333
|
||||
|
||||
# 🆕 容器重启修复验证测试
|
||||
./test_log_size_reset.sh
|
||||
|
||||
# 详细模式运行重启修复测试
|
||||
./test_log_size_reset.sh --verbose
|
||||
|
||||
# 自定义目标大小测试
|
||||
./test_log_size_reset.sh --target-size-kb 30
|
||||
|
||||
# 日志轮转快速测试
|
||||
./log_rotation_test.sh --fast-test
|
||||
|
||||
# 彻底清理环境
|
||||
./cleanup_test.sh --remove-image --remove-test-data --remove-logs
|
||||
```
|
||||
|
||||
## 验证路径配置
|
||||
|
||||
运行路径验证脚本检查配置:
|
||||
```bash
|
||||
./test_paths.sh
|
||||
```
|
||||
|
||||
此脚本会检查所有关键路径是否正确,并自动创建必需的目录。
|
||||
|
||||
## 系统要求
|
||||
|
||||
### 基本要求
|
||||
- **操作系统**: Linux (Ubuntu 18.04+, Debian 10+, CentOS 7+)
|
||||
- **Docker**: Docker Engine 20.10+
|
||||
- **Shell**: Bash 4.0+
|
||||
- **内存**: 至少 2GB 可用内存
|
||||
- **磁盘**: 至少 5GB 可用磁盘空间
|
||||
|
||||
### 必需的系统工具
|
||||
- `docker` - Docker 容器引擎
|
||||
- `curl` - HTTP 客户端工具
|
||||
- `ssh` - SSH 客户端
|
||||
- `ssh-keygen` - SSH 密钥生成工具
|
||||
- `netstat` - 网络状态查看工具
|
||||
|
||||
### 安装依赖 (Ubuntu/Debian)
|
||||
```bash
|
||||
# 更新包管理器
|
||||
sudo apt-get update
|
||||
|
||||
# 安装 Docker
|
||||
sudo apt-get install docker.io
|
||||
|
||||
# 安装其他工具
|
||||
sudo apt-get install curl openssh-client net-tools
|
||||
|
||||
# 将用户添加到 docker 组
|
||||
sudo usermod -aG docker $USER
|
||||
newgrp docker
|
||||
```
|
||||
|
||||
### 安装依赖 (CentOS/RHEL)
|
||||
```bash
|
||||
# 安装 Docker
|
||||
sudo yum install docker
|
||||
|
||||
# 安装其他工具
|
||||
sudo yum install curl openssh-clients net-tools
|
||||
|
||||
# 启动 Docker 服务
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
|
||||
# 将用户添加到 docker 组
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **权限要求**: 确保有 Docker 使用权限(用户在 docker 组中)
|
||||
2. **端口冲突**: 确保指定的端口未被占用
|
||||
3. **SSH 密钥**: 测试脚本会自动生成 SSH 密钥对
|
||||
4. **Docker 环境**: 确保 Docker 服务正在运行
|
||||
5. **脚本权限**: 确保所有 .sh 文件有执行权限
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 权限错误
|
||||
```bash
|
||||
# 设置脚本执行权限
|
||||
chmod +x *.sh
|
||||
|
||||
# 检查 Docker 权限
|
||||
docker version
|
||||
```
|
||||
|
||||
### 路径不存在错误
|
||||
```bash
|
||||
# 运行路径验证
|
||||
./test_paths.sh
|
||||
```
|
||||
|
||||
### Docker 连接错误
|
||||
```bash
|
||||
# 检查 Docker 状态
|
||||
sudo systemctl status docker
|
||||
|
||||
# 启动 Docker 服务
|
||||
sudo systemctl start docker
|
||||
```
|
||||
|
||||
### 端口占用错误
|
||||
```bash
|
||||
# 查看端口占用
|
||||
netstat -tlnp | grep :8080
|
||||
netstat -tlnp | grep :2222
|
||||
|
||||
# 杀死占用进程
|
||||
sudo kill -9 <PID>
|
||||
```
|
||||
|
||||
### 日志查看
|
||||
```bash
|
||||
# 查看最新测试日志
|
||||
ls -la logs/ | tail -5
|
||||
|
||||
# 查看特定日志
|
||||
tail -f logs/test_suite_*.log
|
||||
|
||||
# 搜索错误信息
|
||||
grep -i error logs/*.log
|
||||
```
|
||||
|
||||
## 高级用法
|
||||
|
||||
### 自定义配置
|
||||
```bash
|
||||
# 使用自定义镜像标签
|
||||
export HEXO_IMAGE_TAG="my-hexo:custom"
|
||||
./start.sh
|
||||
|
||||
# 使用自定义容器名称
|
||||
export HEXO_CONTAINER_NAME="my-hexo-container"
|
||||
./start.sh
|
||||
```
|
||||
|
||||
### 批量测试
|
||||
```bash
|
||||
# 测试多个端口配置
|
||||
for port in 8080 8081 8082; do
|
||||
./run_test.sh "hexo-test:v0.0.3" "hexo-test-$port" $port $((port+1000))
|
||||
./functional_test.sh "hexo-test-$port" $port $((port+1000))
|
||||
./cleanup_test.sh "hexo-test-$port"
|
||||
done
|
||||
```
|
||||
|
||||
### 调试模式
|
||||
```bash
|
||||
# 启用详细输出
|
||||
set -x
|
||||
./start.sh
|
||||
set +x
|
||||
```
|
||||
|
||||
## 版本历史
|
||||
|
||||
### v0.0.3-linux-update (2025年5月30日)
|
||||
- ✅ 修正了所有测试脚本的路径处理
|
||||
- ✅ 统一了工作目录管理
|
||||
- ✅ 更新了默认端口配置 (8888 → 8080)
|
||||
- ✅ 添加了路径验证工具 `test_paths.sh`
|
||||
- ✅ 改进了错误处理和日志记录
|
||||
- ✅ 增强了脚本的可移植性和稳定性
|
||||
118
test/v0.0.3/linux/build_test.sh
Normal file
118
test/v0.0.3/linux/build_test.sh
Normal file
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash
|
||||
# Hexo Container v0.0.3 构建测试脚本 (Linux)
|
||||
# build_test.sh
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# 参数设置
|
||||
TAG=${1:-"hexo-test:v0.0.3"}
|
||||
PLATFORM=${2:-"linux/amd64"}
|
||||
|
||||
echo "=== Hexo Container v0.0.3 构建测试 ==="
|
||||
echo "镜像标签: $TAG"
|
||||
echo "平台架构: $PLATFORM"
|
||||
echo "工作目录: $SCRIPT_DIR"
|
||||
|
||||
# Dockerfile 路径 (相对于测试脚本目录)
|
||||
DOCKERFILE_PATH="../../../Dockerfile_v0.0.3"
|
||||
|
||||
# 检查 Dockerfile 是否存在
|
||||
if [ ! -f "$DOCKERFILE_PATH" ]; then
|
||||
echo "❌ 错误: Dockerfile 不存在: $DOCKERFILE_PATH"
|
||||
echo "完整路径: $(realpath "$DOCKERFILE_PATH" 2>/dev/null || echo "路径无法解析")"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 创建日志目录 (在测试脚本目录下)
|
||||
LOG_DIR="./logs"
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# 记录开始时间
|
||||
START_TIME=$(LC_ALL=C date)
|
||||
LOG_FILE="$LOG_DIR/build_$(date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
echo "构建开始时间: $START_TIME"
|
||||
echo "日志文件: $LOG_FILE"
|
||||
|
||||
# 执行构建
|
||||
echo ""
|
||||
echo "开始构建镜像..."
|
||||
|
||||
# 获取 Dockerfile 所在目录的绝对路径
|
||||
DOCKERFILE_DIR="$(cd "$(dirname "$DOCKERFILE_PATH")" && pwd)"
|
||||
DOCKERFILE_NAME=$(basename "$DOCKERFILE_PATH")
|
||||
|
||||
echo "Dockerfile 目录: $DOCKERFILE_DIR"
|
||||
echo "Dockerfile 文件: $DOCKERFILE_NAME"
|
||||
|
||||
# 切换到 Dockerfile 所在目录进行构建
|
||||
cd "$DOCKERFILE_DIR" || exit 1
|
||||
|
||||
BUILD_CMD="docker build -f $DOCKERFILE_NAME -t $TAG --platform $PLATFORM ."
|
||||
echo "执行命令: $BUILD_CMD"
|
||||
|
||||
# 执行构建并记录日志
|
||||
if $BUILD_CMD 2>&1 | tee "$SCRIPT_DIR/$LOG_FILE"; then
|
||||
END_TIME=$(LC_ALL=C date)
|
||||
|
||||
# 计算构建时间
|
||||
START_TIMESTAMP=$(date -d "$START_TIME" +%s)
|
||||
END_TIMESTAMP=$(date -d "$END_TIME" +%s)
|
||||
DURATION=$((END_TIMESTAMP - START_TIMESTAMP))
|
||||
DURATION_MIN=$(echo "scale=2; $DURATION / 60" | bc 2>/dev/null || echo "$(($DURATION / 60))")
|
||||
|
||||
echo ""
|
||||
echo "=== 构建成功 ==="
|
||||
echo "构建结束时间: $END_TIME"
|
||||
echo "构建耗时: ${DURATION_MIN} 分钟"
|
||||
|
||||
# 显示镜像信息
|
||||
echo ""
|
||||
echo "=== 镜像信息 ==="
|
||||
docker images "$TAG"
|
||||
|
||||
# 显示镜像详细信息
|
||||
echo ""
|
||||
echo "=== 镜像详细信息 ==="
|
||||
if command -v jq > /dev/null 2>&1; then
|
||||
IMAGE_SIZE=$(docker inspect "$TAG" | jq -r '.[0].Size')
|
||||
IMAGE_SIZE_MB=$(echo "scale=2; $IMAGE_SIZE / 1024 / 1024" | bc 2>/dev/null || echo "$(($IMAGE_SIZE / 1024 / 1024))")
|
||||
IMAGE_CREATED=$(docker inspect "$TAG" | jq -r '.[0].Created')
|
||||
IMAGE_ARCH=$(docker inspect "$TAG" | jq -r '.[0].Architecture')
|
||||
|
||||
echo "镜像大小: ${IMAGE_SIZE_MB} MB"
|
||||
echo "创建时间: $IMAGE_CREATED"
|
||||
echo "架构: $IMAGE_ARCH"
|
||||
else
|
||||
echo "镜像大小: $(docker inspect "$TAG" --format='{{.Size}}' | awk '{print int($1/1024/1024) " MB"}')"
|
||||
echo "创建时间: $(docker inspect "$TAG" --format='{{.Created}}')"
|
||||
echo "架构: $(docker inspect "$TAG" --format='{{.Architecture}}')"
|
||||
fi
|
||||
|
||||
# 输出构建统计
|
||||
echo ""
|
||||
echo "=== 构建统计 ==="
|
||||
LAYER_COUNT=$(grep -c "^Step [0-9]*/" "$SCRIPT_DIR/$LOG_FILE" 2>/dev/null || echo "未知")
|
||||
echo "构建步骤数: $LAYER_COUNT"
|
||||
|
||||
cd "$SCRIPT_DIR"
|
||||
exit 0
|
||||
else
|
||||
echo ""
|
||||
echo "=== 构建失败 ==="
|
||||
echo "详细日志请查看: $LOG_FILE"
|
||||
|
||||
# 显示最后几行日志
|
||||
echo ""
|
||||
echo "=== 最后10行构建日志 ==="
|
||||
tail -10 "$SCRIPT_DIR/$LOG_FILE"
|
||||
|
||||
cd "$SCRIPT_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "构建测试完成。"
|
||||
echo "详细日志保存在: $LOG_FILE"
|
||||
357
test/v0.0.3/linux/cleanup_test.sh
Normal file
357
test/v0.0.3/linux/cleanup_test.sh
Normal file
@@ -0,0 +1,357 @@
|
||||
#!/bin/bash
|
||||
# Hexo Container v0.0.3 清理测试脚本 (Linux)
|
||||
# cleanup_test.sh
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# 参数设置
|
||||
CONTAINER_NAME=${1:-"hexo-test-v003"}
|
||||
IMAGE_TAG=${2:-"hexo-test:v0.0.3"}
|
||||
REMOVE_IMAGE=${3:-false}
|
||||
REMOVE_TEST_DATA=${4:-false}
|
||||
KEEP_LOGS=${5:-true}
|
||||
|
||||
echo "=== Hexo Container v0.0.3 清理测试 ==="
|
||||
echo "工作目录: $SCRIPT_DIR"
|
||||
|
||||
# 解析命令行参数
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--remove-image)
|
||||
REMOVE_IMAGE=true
|
||||
shift
|
||||
;;
|
||||
--remove-test-data)
|
||||
REMOVE_TEST_DATA=true
|
||||
shift
|
||||
;;
|
||||
--remove-logs)
|
||||
KEEP_LOGS=false
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
echo "用法: $0 [选项]"
|
||||
echo "选项:"
|
||||
echo " --remove-image 删除测试镜像"
|
||||
echo " --remove-test-data 删除测试数据"
|
||||
echo " --remove-logs 删除测试日志"
|
||||
echo " -h, --help 显示此帮助信息"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "=== Hexo Container v0.0.3 测试环境清理 ==="
|
||||
|
||||
CLEANUP_RESULTS=()
|
||||
|
||||
# 函数:记录清理结果
|
||||
add_cleanup_result() {
|
||||
local action="$1"
|
||||
local status="$2"
|
||||
local message="$3"
|
||||
CLEANUP_RESULTS+=("$action:$status:$message:$(date)")
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "=== 步骤 1: 停止并删除容器 ==="
|
||||
|
||||
# 检查容器是否存在并运行
|
||||
if docker ps -a --filter "name=$CONTAINER_NAME" --format "{{.Names}}" | grep -q "$CONTAINER_NAME"; then
|
||||
echo "发现容器: $CONTAINER_NAME"
|
||||
|
||||
# 停止容器
|
||||
echo "停止容器..."
|
||||
if docker stop "$CONTAINER_NAME" 2>/dev/null; then
|
||||
echo "✅ 容器已停止"
|
||||
add_cleanup_result "停止容器" "SUCCESS" ""
|
||||
else
|
||||
echo "⚠️ 容器停止失败或容器已停止"
|
||||
add_cleanup_result "停止容器" "WARNING" "容器可能已停止"
|
||||
fi
|
||||
|
||||
# 删除容器
|
||||
echo "删除容器..."
|
||||
if docker rm "$CONTAINER_NAME" 2>/dev/null; then
|
||||
echo "✅ 容器已删除"
|
||||
add_cleanup_result "删除容器" "SUCCESS" ""
|
||||
else
|
||||
echo "❌ 容器删除失败"
|
||||
add_cleanup_result "删除容器" "ERROR" "删除命令执行失败"
|
||||
fi
|
||||
else
|
||||
echo "✅ 容器不存在,无需删除"
|
||||
add_cleanup_result "删除容器" "SKIPPED" "容器不存在"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== 步骤 2: 清理 Docker 镜像 ==="
|
||||
|
||||
if [ "$REMOVE_IMAGE" = true ]; then
|
||||
# 检查镜像是否存在
|
||||
if docker images --filter "reference=$IMAGE_TAG" --format "{{.Repository}}:{{.Tag}}" | grep -q "$IMAGE_TAG"; then
|
||||
echo "删除测试镜像: $IMAGE_TAG"
|
||||
if docker rmi "$IMAGE_TAG" 2>/dev/null; then
|
||||
echo "✅ 测试镜像已删除"
|
||||
add_cleanup_result "删除测试镜像" "SUCCESS" ""
|
||||
else
|
||||
echo "❌ 测试镜像删除失败"
|
||||
add_cleanup_result "删除测试镜像" "ERROR" "镜像可能被其他容器使用"
|
||||
fi
|
||||
else
|
||||
echo "✅ 测试镜像不存在,无需删除"
|
||||
add_cleanup_result "删除测试镜像" "SKIPPED" "镜像不存在"
|
||||
fi
|
||||
|
||||
# 清理悬挂镜像
|
||||
echo "清理悬挂镜像..."
|
||||
if docker image prune -f >/dev/null 2>&1; then
|
||||
echo "✅ 悬挂镜像已清理"
|
||||
add_cleanup_result "清理悬挂镜像" "SUCCESS" ""
|
||||
else
|
||||
echo "⚠️ 清理悬挂镜像失败"
|
||||
add_cleanup_result "清理悬挂镜像" "WARNING" "清理命令执行失败"
|
||||
fi
|
||||
else
|
||||
echo "⏭️ 跳过镜像删除 (使用 --remove-image 参数强制删除)"
|
||||
add_cleanup_result "删除测试镜像" "SKIPPED" "用户选择保留"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== 步骤 3: 清理测试数据 ==="
|
||||
|
||||
if [ "$REMOVE_TEST_DATA" = true ]; then
|
||||
TEST_DATA_DIR="./test_data"
|
||||
if [ -d "$TEST_DATA_DIR" ]; then
|
||||
echo "删除测试数据目录: $TEST_DATA_DIR"
|
||||
if rm -rf "$TEST_DATA_DIR"; then
|
||||
echo "✅ 测试数据已删除"
|
||||
add_cleanup_result "删除测试数据" "SUCCESS" ""
|
||||
else
|
||||
echo "❌ 删除测试数据失败"
|
||||
add_cleanup_result "删除测试数据" "ERROR" "权限不足或目录被占用"
|
||||
fi
|
||||
else
|
||||
echo "✅ 测试数据目录不存在"
|
||||
add_cleanup_result "删除测试数据" "SKIPPED" "目录不存在"
|
||||
fi
|
||||
else
|
||||
echo "⏭️ 保留测试数据 (使用 --remove-test-data 参数强制删除)"
|
||||
add_cleanup_result "删除测试数据" "SKIPPED" "用户选择保留"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== 步骤 4: 清理测试日志 ==="
|
||||
|
||||
if [ "$KEEP_LOGS" = false ]; then
|
||||
LOGS_DIR="./logs"
|
||||
if [ -d "$LOGS_DIR" ]; then
|
||||
echo "删除测试日志目录: $LOGS_DIR"
|
||||
if rm -rf "$LOGS_DIR"; then
|
||||
echo "✅ 测试日志已删除"
|
||||
add_cleanup_result "删除测试日志" "SUCCESS" ""
|
||||
else
|
||||
echo "❌ 删除测试日志失败"
|
||||
add_cleanup_result "删除测试日志" "ERROR" "权限不足或目录被占用"
|
||||
fi
|
||||
else
|
||||
echo "✅ 测试日志目录不存在"
|
||||
add_cleanup_result "删除测试日志" "SKIPPED" "目录不存在"
|
||||
fi
|
||||
else
|
||||
echo "⏭️ 保留测试日志 (日志文件保存在 ./logs 目录)"
|
||||
add_cleanup_result "删除测试日志" "SKIPPED" "用户选择保留"
|
||||
|
||||
# 显示保留的日志文件
|
||||
LOGS_DIR="./logs"
|
||||
if [ -d "$LOGS_DIR" ]; then
|
||||
LOG_FILES=$(find "$LOGS_DIR" -type f -name "*.log" -o -name "*.txt" | sort -t_ -k2 -r)
|
||||
if [ -n "$LOG_FILES" ]; then
|
||||
echo ""
|
||||
echo "保留的日志文件:"
|
||||
echo "$LOG_FILES" | while read -r file; do
|
||||
size=$(du -h "$file" | cut -f1)
|
||||
modified=$(stat -c %y "$file" 2>/dev/null || date -r "$file" 2>/dev/null || echo "未知时间")
|
||||
echo " $(basename "$file") ($size) - $modified"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== 步骤 5: 清理 Docker 系统资源 ==="
|
||||
|
||||
# 清理未使用的网络
|
||||
echo "清理未使用的 Docker 网络..."
|
||||
if docker network prune -f >/dev/null 2>&1; then
|
||||
echo "✅ 未使用的网络已清理"
|
||||
add_cleanup_result "清理网络" "SUCCESS" ""
|
||||
else
|
||||
echo "⚠️ 网络清理失败"
|
||||
add_cleanup_result "清理网络" "WARNING" "清理命令执行失败"
|
||||
fi
|
||||
|
||||
# 清理未使用的卷
|
||||
echo "清理未使用的 Docker 卷..."
|
||||
if docker volume prune -f >/dev/null 2>&1; then
|
||||
echo "✅ 未使用的卷已清理"
|
||||
add_cleanup_result "清理卷" "SUCCESS" ""
|
||||
else
|
||||
echo "⚠️ 卷清理失败"
|
||||
add_cleanup_result "清理卷" "WARNING" "清理命令执行失败"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== 步骤 6: 验证清理结果 ==="
|
||||
|
||||
# 检查容器是否已完全删除
|
||||
if ! docker ps -a --filter "name=$CONTAINER_NAME" --format "{{.Names}}" | grep -q "$CONTAINER_NAME"; then
|
||||
echo "✅ 容器清理验证通过"
|
||||
else
|
||||
REMAINING=$(docker ps -a --filter "name=$CONTAINER_NAME" --format "{{.Names}}")
|
||||
echo "❌ 仍有容器残留: $REMAINING"
|
||||
fi
|
||||
|
||||
# 检查镜像清理情况
|
||||
if [ "$REMOVE_IMAGE" = true ]; then
|
||||
if ! docker images --filter "reference=$IMAGE_TAG" --format "{{.Repository}}:{{.Tag}}" | grep -q "$IMAGE_TAG"; then
|
||||
echo "✅ 镜像清理验证通过"
|
||||
else
|
||||
REMAINING=$(docker images --filter "reference=$IMAGE_TAG" --format "{{.Repository}}:{{.Tag}}")
|
||||
echo "❌ 仍有镜像残留: $REMAINING"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 显示当前 Docker 资源使用情况
|
||||
echo ""
|
||||
echo "=== Docker 资源使用情况 ==="
|
||||
|
||||
echo "容器数量:"
|
||||
CONTAINER_COUNT=$(docker ps -a --format "table {{.Names}}\t{{.Status}}" | wc -l)
|
||||
if [ $CONTAINER_COUNT -gt 1 ]; then
|
||||
docker ps -a --format "table {{.Names}}\t{{.Status}}" | head -10
|
||||
echo " 总计: $((CONTAINER_COUNT - 1)) 个容器"
|
||||
else
|
||||
echo " 无容器运行"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "镜像数量:"
|
||||
IMAGE_COUNT=$(docker images --format "{{.Repository}}" | wc -l)
|
||||
echo " 总计: $IMAGE_COUNT 个镜像"
|
||||
|
||||
echo ""
|
||||
echo "磁盘使用:"
|
||||
if command -v docker >/dev/null 2>&1; then
|
||||
docker system df 2>/dev/null || echo " 无法获取磁盘使用信息"
|
||||
fi
|
||||
|
||||
# 生成清理报告
|
||||
echo ""
|
||||
echo "=== 清理报告 ==="
|
||||
|
||||
SUCCESS_COUNT=0
|
||||
WARNING_COUNT=0
|
||||
ERROR_COUNT=0
|
||||
SKIPPED_COUNT=0
|
||||
TOTAL_ACTIONS=0
|
||||
|
||||
for result in "${CLEANUP_RESULTS[@]}"; do
|
||||
TOTAL_ACTIONS=$((TOTAL_ACTIONS + 1))
|
||||
status=$(echo "$result" | cut -d: -f2)
|
||||
case $status in
|
||||
SUCCESS) SUCCESS_COUNT=$((SUCCESS_COUNT + 1)) ;;
|
||||
WARNING) WARNING_COUNT=$((WARNING_COUNT + 1)) ;;
|
||||
ERROR) ERROR_COUNT=$((ERROR_COUNT + 1)) ;;
|
||||
SKIPPED) SKIPPED_COUNT=$((SKIPPED_COUNT + 1)) ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "清理操作统计:"
|
||||
echo " 成功: $SUCCESS_COUNT"
|
||||
echo " 警告: $WARNING_COUNT"
|
||||
echo " 错误: $ERROR_COUNT"
|
||||
echo " 跳过: $SKIPPED_COUNT"
|
||||
echo " 总计: $TOTAL_ACTIONS"
|
||||
|
||||
# 详细清理结果
|
||||
echo ""
|
||||
echo "详细清理结果:"
|
||||
for result in "${CLEANUP_RESULTS[@]}"; do
|
||||
IFS=':' read -r action status message timestamp <<< "$result"
|
||||
case $status in
|
||||
SUCCESS) color="✅" ;;
|
||||
WARNING) color="⚠️" ;;
|
||||
ERROR) color="❌" ;;
|
||||
SKIPPED) color="⏭️" ;;
|
||||
*) color="ℹ️" ;;
|
||||
esac
|
||||
|
||||
if [ -n "$message" ]; then
|
||||
echo " $color $action: $status - $message"
|
||||
else
|
||||
echo " $color $action: $status"
|
||||
fi
|
||||
done
|
||||
|
||||
# 保存清理报告
|
||||
if [ "$KEEP_LOGS" = true ] && [ -d "./logs" ]; then
|
||||
REPORT_CONTENT="=== Hexo Container v0.0.3 测试环境清理报告 ===
|
||||
清理时间: $(date)
|
||||
容器名称: $CONTAINER_NAME
|
||||
镜像标签: $IMAGE_TAG
|
||||
|
||||
=== 清理参数 ===
|
||||
删除镜像: $REMOVE_IMAGE
|
||||
删除测试数据: $REMOVE_TEST_DATA
|
||||
保留日志: $KEEP_LOGS
|
||||
|
||||
=== 清理统计 ===
|
||||
成功: $SUCCESS_COUNT
|
||||
警告: $WARNING_COUNT
|
||||
错误: $ERROR_COUNT
|
||||
跳过: $SKIPPED_COUNT
|
||||
总计: $TOTAL_ACTIONS
|
||||
|
||||
=== 详细结果 ==="
|
||||
|
||||
for result in "${CLEANUP_RESULTS[@]}"; do
|
||||
IFS=':' read -r action status message timestamp <<< "$result"
|
||||
REPORT_CONTENT="$REPORT_CONTENT
|
||||
$timestamp - $action: $status $message"
|
||||
done
|
||||
|
||||
REPORT_FILE="./logs/cleanup_report_$(date +%Y%m%d_%H%M%S).txt"
|
||||
echo "$REPORT_CONTENT" > "$REPORT_FILE"
|
||||
echo ""
|
||||
echo "清理报告已保存: $REPORT_FILE"
|
||||
fi
|
||||
|
||||
# 使用建议
|
||||
echo ""
|
||||
echo "=== 使用建议 ==="
|
||||
echo "重新开始测试请运行:"
|
||||
echo " ./build_test.sh # 重新构建镜像"
|
||||
echo " ./run_test.sh # 重新运行容器"
|
||||
echo " ./functional_test.sh # 执行功能测试"
|
||||
|
||||
echo ""
|
||||
echo "完全清理 (包括镜像和数据) 请运行:"
|
||||
echo " ./cleanup_test.sh --remove-image --remove-test-data"
|
||||
|
||||
echo ""
|
||||
echo "=== 清理完成 ==="
|
||||
|
||||
# 根据清理结果设置退出代码
|
||||
if [ $ERROR_COUNT -eq 0 ]; then
|
||||
echo "🎉 清理操作成功完成!"
|
||||
exit 0
|
||||
else
|
||||
echo "⚠️ 清理过程中出现错误,请检查详细报告。"
|
||||
exit 1
|
||||
fi
|
||||
242
test/v0.0.3/linux/functional_test.sh
Normal file
242
test/v0.0.3/linux/functional_test.sh
Normal file
@@ -0,0 +1,242 @@
|
||||
#!/bin/bash
|
||||
# Hexo Container v0.0.3 功能测试脚本 (Linux)
|
||||
# functional_test.sh
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# 参数设置
|
||||
CONTAINER_NAME=${1:-"hexo-test-v003"}
|
||||
HTTP_PORT=${2:-8080}
|
||||
SSH_PORT=${3:-2222}
|
||||
SSH_KEY_PATH="$SCRIPT_DIR/test_data/ssh_keys/test_key"
|
||||
|
||||
echo "=== Hexo Container v0.0.3 功能测试 ==="
|
||||
echo "工作目录: $SCRIPT_DIR"
|
||||
|
||||
# 创建日志文件 (在测试脚本目录下)
|
||||
LOG_DIR="./logs"
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
TEST_LOG="$LOG_DIR/functional_test_$(date +%Y%m%d_%H%M%S).log"
|
||||
TEST_RESULTS=()
|
||||
|
||||
# 测试函数
|
||||
run_test() {
|
||||
local test_name="$1"
|
||||
local description="$2"
|
||||
local test_command="$3"
|
||||
|
||||
echo ""
|
||||
echo "=== $test_name ==="
|
||||
echo "$description"
|
||||
|
||||
local start_time=$(date +%s)
|
||||
local status
|
||||
local message=""
|
||||
|
||||
if eval "$test_command"; then
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
echo "✅ $test_name 通过 (${duration}s)"
|
||||
status="PASS"
|
||||
else
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
echo "❌ $test_name 失败 (${duration}s)"
|
||||
status="FAIL"
|
||||
fi
|
||||
|
||||
TEST_RESULTS+=("$test_name:$status:$duration")
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $test_name - $status (${duration}s)" >> "$TEST_LOG"
|
||||
}
|
||||
|
||||
# 检查容器是否运行
|
||||
echo "检查容器状态..."
|
||||
if ! docker ps --filter "name=$CONTAINER_NAME" --format "{{.Names}}" | grep -q "$CONTAINER_NAME"; then
|
||||
echo "❌ 容器 $CONTAINER_NAME 未运行,请先运行 run_test.sh"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ 容器正在运行"
|
||||
|
||||
# 测试 1: HTTP 服务基础测试
|
||||
run_test "HTTP服务基础测试" "测试主页是否可以正常访问" \
|
||||
"curl -f http://localhost:$HTTP_PORT --max-time 10 >/dev/null 2>&1"
|
||||
|
||||
# 测试 2: 健康检查端点测试
|
||||
run_test "健康检查端点测试" "测试 /health 端点是否返回正确响应" \
|
||||
"curl -f http://localhost:$HTTP_PORT/health --max-time 5 2>/dev/null | grep -q '^healthy$'"
|
||||
|
||||
# 测试 3: SSH 服务连接测试
|
||||
run_test "SSH服务连接测试" "测试 SSH 服务是否可以正常连接" \
|
||||
'if [ -f "$SSH_KEY_PATH" ]; then
|
||||
docker exec "$CONTAINER_NAME" bash -c "mkdir -p /home/hexo/.ssh && cp /home/hexo/.ssh/test_key.pub /home/hexo/.ssh/authorized_keys && chown -R hexo:hexo /home/hexo/.ssh && chmod 600 /home/hexo/.ssh/authorized_keys" 2>/dev/null &&
|
||||
ssh -p "$SSH_PORT" -i "$SSH_KEY_PATH" -o ConnectTimeout=10 -o StrictHostKeyChecking=no hexo@localhost "echo SSH连接成功" 2>/dev/null | grep -q "SSH连接成功"
|
||||
else
|
||||
echo "SSH 密钥不存在: $SSH_KEY_PATH" >&2
|
||||
false
|
||||
fi'
|
||||
|
||||
# 测试 4: Git 仓库初始化测试
|
||||
run_test "Git仓库初始化测试" "检查 Git 裸仓库是否正确初始化" \
|
||||
'docker exec "$CONTAINER_NAME" bash -c "test -d /home/hexo/hexo.git" 2>/dev/null'
|
||||
|
||||
# 测试 5: 部署钩子测试
|
||||
run_test "部署钩子测试" "检查 Git post-receive 钩子是否正确配置" \
|
||||
'docker exec "$CONTAINER_NAME" bash -c "test -f /home/hexo/hexo.git/hooks/post-receive && test -x /home/hexo/hexo.git/hooks/post-receive" 2>/dev/null'
|
||||
|
||||
# 测试 6: 文件权限测试
|
||||
run_test "文件权限测试" "检查用户权限和目录访问权限" \
|
||||
'docker exec "$CONTAINER_NAME" bash -c "su - hexo -s /bin/bash -c \"whoami && test -w /home/www/hexo\" 2>/dev/null | grep -q hexo"'
|
||||
|
||||
# 测试 7: 日志文件权限测试 (v0.0.3 新功能)
|
||||
run_test "日志文件权限测试" "测试 hexo 用户对部署日志文件的写入权限 (v0.0.3 新功能)" \
|
||||
'docker exec "$CONTAINER_NAME" bash -c "if [ ! -f /var/log/container/deployment.log ]; then touch /var/log/container/deployment.log && chown hexo:hexo /var/log/container/deployment.log; fi && ls -la /var/log/container/ | grep deployment.log | awk '\''{print \$3}'\'' | grep -q hexo && su - hexo -s /bin/bash -c '\''echo 测试写入 >> /var/log/container/deployment.log && echo 写入成功'\'' 2>/dev/null | grep -q \"写入成功\""'
|
||||
|
||||
# 测试 8: 模拟 Git 部署测试
|
||||
run_test "模拟Git部署测试" "模拟 Git 推送部署并检查日志生成" \
|
||||
'current_dir_before_git_ops_test8="$(pwd)";
|
||||
TMP_REPO_PATH_TEST8="/tmp/test8_repo_$$";
|
||||
rm -rf "$TMP_REPO_PATH_TEST8";
|
||||
mkdir -p "$TMP_REPO_PATH_TEST8";
|
||||
cd "$TMP_REPO_PATH_TEST8";
|
||||
git init -q -b master;
|
||||
git config user.email "test@example.com";
|
||||
git config user.name "Test User";
|
||||
echo "Test content for Test 8 on $(date)" > test_file.html;
|
||||
git add test_file.html;
|
||||
git commit -q -m "Commit for Test 8";
|
||||
# Ensure authorized_keys is set up in the container for hexo user
|
||||
docker exec "'"$CONTAINER_NAME"'" bash -c "mkdir -p /home/hexo/.ssh && echo '\''$(cat "'"$SSH_KEY_PATH.pub"'")'\'' > /home/hexo/.ssh/authorized_keys && chown -R hexo:hexo /home/hexo/.ssh && chmod 600 /home/hexo/.ssh/authorized_keys" >/dev/null 2>&1;
|
||||
# Perform the git push
|
||||
GIT_SSH_COMMAND="ssh -p '"$SSH_PORT"' -i '\''"'"$SSH_KEY_PATH"'"'\'' -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" git push -q ssh://hexo@localhost/home/hexo/hexo.git master -f;
|
||||
PUSH_EC=$?;
|
||||
if [ $PUSH_EC -eq 0 ]; then
|
||||
echo "Git push for Test 8 successful, waiting 3s for hook...";
|
||||
sleep 3;
|
||||
# Verify deployment log and deployed file content
|
||||
docker exec "'"$CONTAINER_NAME"'" bash -c "grep -q '\''=== Git Push Deployment Started ==='\'' /var/log/container/deployment.log && grep -q '\''Files checked out successfully'\'' /var/log/container/deployment.log && test -f /home/www/hexo/test_file.html && grep -q '\''Test content for Test 8 on'\'' /home/www/hexo/test_file.html";
|
||||
VERIFY_EC=$?;
|
||||
cd "$current_dir_before_git_ops_test8";
|
||||
rm -rf "$TMP_REPO_PATH_TEST8";
|
||||
exit $VERIFY_EC;
|
||||
else
|
||||
echo "Git push failed in Test 8 (EC: $PUSH_EC)";
|
||||
# For debugging, show verbose SSH output if push fails
|
||||
GIT_SSH_COMMAND="ssh -vvv -p '"$SSH_PORT"' -i '\''"'"$SSH_KEY_PATH"'"'\'' -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" git push ssh://hexo@localhost/home/hexo/hexo.git master -f;
|
||||
cd "$current_dir_before_git_ops_test8";
|
||||
rm -rf "$TMP_REPO_PATH_TEST8";
|
||||
exit 1;
|
||||
fi'
|
||||
|
||||
# 测试 9: 日志轮转功能测试 (v0.0.3 新功能)
|
||||
run_test "日志轮转功能测试" "检查日志轮转功能是否正确配置 (v0.0.3 新功能)" \
|
||||
'docker exec "$CONTAINER_NAME" bash -c "grep -q \\\\"rotate_log\\\\" /root/start.sh && grep -q \\\\"check_and_rotate_logs\\\\" /root/start.sh" 2>/dev/null'
|
||||
|
||||
# 测试 10: 容器资源使用测试
|
||||
run_test "容器资源使用测试" "检查容器的 CPU 和内存限制设置" \
|
||||
'docker exec "'"$CONTAINER_NAME"'" bash -c "if [ -f /sys/fs/cgroup/cpu/cpu.cfs_quota_us ] && [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then cpu_quota=\\\\\$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us); memory_limit=\\\\\$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes); [ \\\\\\"\\\\\\\$cpu_quota\\\\\\" -ne 0 ] && [ \\\\\\"\\\\\\\$memory_limit\\\\\\" -ne 0 ]; else false; fi"'
|
||||
|
||||
# 生成测试报告
|
||||
echo ""
|
||||
echo "=== 测试总结报告 ==="
|
||||
|
||||
PASSED_TESTS=0
|
||||
FAILED_TESTS=0
|
||||
TOTAL_TESTS=0
|
||||
|
||||
for result in "${TEST_RESULTS[@]}"; do
|
||||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||||
if echo "$result" | grep -q ":PASS:"; then
|
||||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||||
else
|
||||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
SUCCESS_RATE=$(echo "scale=1; $PASSED_TESTS * 100 / $TOTAL_TESTS" | bc 2>/dev/null || echo "0.0")
|
||||
|
||||
echo "总测试数: $TOTAL_TESTS"
|
||||
echo "通过: $PASSED_TESTS"
|
||||
echo "失败: $FAILED_TESTS"
|
||||
echo "成功率: $SUCCESS_RATE%"
|
||||
|
||||
# 详细测试结果表格
|
||||
echo ""
|
||||
echo "=== 详细测试结果 ==="
|
||||
printf "%-25s %-8s %-10s\n" "测试名称" "状态" "耗时(s)"
|
||||
printf "%-25s %-8s %-10s\n" "------------------------" "--------" "----------"
|
||||
|
||||
for result in "${TEST_RESULTS[@]}"; do
|
||||
IFS=':' read -r test_name status duration <<< "$result"
|
||||
printf "%-25s %-8s %-10s\n" "$test_name" "$status" "$duration"
|
||||
done
|
||||
|
||||
# 失败的测试详情
|
||||
FAILED_TESTS_LIST=()
|
||||
for result in "${TEST_RESULTS[@]}"; do
|
||||
if echo "$result" | grep -q ":FAIL:"; then
|
||||
test_name=$(echo "$result" | cut -d: -f1)
|
||||
FAILED_TESTS_LIST+=("$test_name")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#FAILED_TESTS_LIST[@]} -gt 0 ]; then
|
||||
echo ""
|
||||
echo "=== 失败的测试 ==="
|
||||
for failed_test in "${FAILED_TESTS_LIST[@]}"; do
|
||||
echo "❌ $failed_test"
|
||||
done
|
||||
fi
|
||||
|
||||
# 保存详细报告到文件
|
||||
REPORT_CONTENT="=== Hexo Container v0.0.3 功能测试报告 ===
|
||||
测试时间: $(date)
|
||||
容器名称: $CONTAINER_NAME
|
||||
HTTP 端口: $HTTP_PORT
|
||||
SSH 端口: $SSH_PORT
|
||||
|
||||
=== 测试统计 ===
|
||||
总测试数: $TOTAL_TESTS
|
||||
通过: $PASSED_TESTS
|
||||
失败: $FAILED_TESTS
|
||||
成功率: $SUCCESS_RATE%
|
||||
|
||||
=== 详细结果 ===
|
||||
$(for result in "${TEST_RESULTS[@]}"; do
|
||||
IFS=':' read -r test_name status duration <<< "$result"
|
||||
echo "$test_name: $status (${duration}s)"
|
||||
done)
|
||||
|
||||
=== v0.0.3 新功能测试状态 ==="
|
||||
|
||||
# 查找新功能测试状态
|
||||
for result in "${TEST_RESULTS[@]}"; do
|
||||
if echo "$result" | grep -q "日志文件权限测试"; then
|
||||
status=$(echo "$result" | cut -d: -f2)
|
||||
echo "日志文件权限测试: $status"
|
||||
fi
|
||||
if echo "$result" | grep -q "日志轮转功能测试"; then
|
||||
status=$(echo "$result" | cut -d: -f2)
|
||||
echo "日志轮转功能测试: $status"
|
||||
fi
|
||||
done
|
||||
|
||||
REPORT_FILE="$LOG_DIR/functional_test_report_$(date +%Y%m%d_%H%M%S).txt"
|
||||
echo "$REPORT_CONTENT" > "$REPORT_FILE"
|
||||
|
||||
echo ""
|
||||
echo "详细测试日志: $TEST_LOG"
|
||||
echo "测试报告: $REPORT_FILE"
|
||||
|
||||
# 根据测试结果设置退出代码
|
||||
if [ $FAILED_TESTS -eq 0 ]; then
|
||||
echo ""
|
||||
echo "🎉 所有测试通过!"
|
||||
exit 0
|
||||
else
|
||||
echo ""
|
||||
echo "⚠️ 部分测试失败,请检查详细日志。"
|
||||
exit 1
|
||||
fi
|
||||
397
test/v0.0.3/linux/log_rotation_test.sh
Normal file
397
test/v0.0.3/linux/log_rotation_test.sh
Normal file
@@ -0,0 +1,397 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Hexo Static Blog v0.0.3 - Linux Log Rotation Test Script
|
||||
# 用于测试 v0.0.3 版本的日志轮转功能
|
||||
|
||||
set -e
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 配置参数
|
||||
CONTAINER_NAME=${1:-"hexo-test-v003"}
|
||||
IMAGE_NAME="hexo-test"
|
||||
IMAGE_TAG="v0.0.3"
|
||||
SSH_KEY_PATH="$SCRIPT_DIR/test_data/ssh_keys/test_key"
|
||||
LOG_DIR="$SCRIPT_DIR/logs"
|
||||
TEST_DIR="$SCRIPT_DIR/test_data/log_rotation"
|
||||
LOG_FILE="$LOG_DIR/log_rotation_test_$(date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
# 创建日志目录
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
echo "=== Hexo Container v0.0.3 日志轮转测试 ==="
|
||||
echo "工作目录: $SCRIPT_DIR"
|
||||
|
||||
# 函数:记录日志
|
||||
log() {
|
||||
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] ✓${NC} $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ✗${NC} $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] ⚠${NC} $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# 函数:清理资源
|
||||
cleanup() {
|
||||
log "清理测试资源..."
|
||||
docker stop "$CONTAINER_NAME" 2>/dev/null || true
|
||||
docker rm "$CONTAINER_NAME" 2>/dev/null || true
|
||||
sudo rm -rf "$TEST_DIR" 2>/dev/null || true
|
||||
log_success "清理完成"
|
||||
}
|
||||
|
||||
# 函数:清理现有容器
|
||||
cleanup_existing_container() {
|
||||
if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
|
||||
log "发现现有容器 $CONTAINER_NAME,正在清理..."
|
||||
docker stop "$CONTAINER_NAME" 2>/dev/null || true
|
||||
docker rm "$CONTAINER_NAME" 2>/dev/null || true
|
||||
log "现有容器已清理"
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:检查前置条件
|
||||
check_prerequisites() {
|
||||
log "检查前置条件..."
|
||||
|
||||
# 检查 Docker
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log_error "Docker 未安装或不在 PATH 中"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查 Docker 服务
|
||||
if ! docker info &> /dev/null; then
|
||||
log_error "Docker 服务未运行"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查镜像
|
||||
if ! docker image inspect "${IMAGE_NAME}:${IMAGE_TAG}" &> /dev/null; then
|
||||
log_error "Docker 镜像 ${IMAGE_NAME}:${IMAGE_TAG} 不存在"
|
||||
log "请先运行 build_test.sh 构建镜像"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "前置条件检查通过"
|
||||
}
|
||||
|
||||
# 函数:准备测试环境
|
||||
prepare_test_environment() {
|
||||
log "准备测试环境..."
|
||||
|
||||
# 创建测试目录
|
||||
mkdir -p "$TEST_DIR"
|
||||
mkdir -p "$TEST_DIR/logs"
|
||||
mkdir -p "$TEST_DIR/hexo-blog"
|
||||
|
||||
# 创建初始日志文件以便测试
|
||||
echo "Initial log entry" > "$TEST_DIR/logs/container.log"
|
||||
echo "Initial ssh log entry" > "$TEST_DIR/logs/ssh.log"
|
||||
|
||||
log_success "测试环境准备完成"
|
||||
}
|
||||
|
||||
# 函数:启动容器
|
||||
start_container() {
|
||||
log "启动测试容器..."
|
||||
|
||||
# 清理可能存在的同名容器
|
||||
cleanup_existing_container
|
||||
|
||||
docker run -d \
|
||||
--name "$CONTAINER_NAME" \
|
||||
-p 4000:4000 \
|
||||
-p 2222:22 \
|
||||
-e PUID=1000 \
|
||||
-e PGID=1000 \
|
||||
-e LOG_ROTATION_ENABLED=true \
|
||||
-e LOG_MAX_SIZE=1M \
|
||||
-e LOG_BACKUP_COUNT=5 \
|
||||
-v "$TEST_DIR/hexo-blog:/app/hexo-blog" \
|
||||
-v "$TEST_DIR/logs:/var/log/container" \
|
||||
"${IMAGE_NAME}:${IMAGE_TAG}"
|
||||
|
||||
# 等待容器启动
|
||||
log "等待容器完全启动..."
|
||||
sleep 10
|
||||
|
||||
# 检查容器状态
|
||||
if ! docker ps | grep -q "$CONTAINER_NAME"; then
|
||||
log_error "容器启动失败"
|
||||
docker logs "$CONTAINER_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "容器启动成功"
|
||||
}
|
||||
|
||||
# 函数:测试基本日志轮转功能
|
||||
test_basic_log_rotation() {
|
||||
log "测试基本日志轮转功能..."
|
||||
|
||||
# 生成大量日志以触发轮转
|
||||
for i in {1..1000}; do
|
||||
echo "Test log entry $i - $(date) - This is a test message to fill up the log file for rotation testing" >> "$TEST_DIR/logs/container.log"
|
||||
if [ $((i % 100)) -eq 0 ]; then
|
||||
log "已写入 $i 条日志记录..."
|
||||
fi
|
||||
done
|
||||
|
||||
# 检查日志文件大小
|
||||
log_size=$(stat -f%z "$TEST_DIR/logs/container.log" 2>/dev/null || stat -c%s "$TEST_DIR/logs/container.log" 2>/dev/null)
|
||||
log "当前日志文件大小: $log_size 字节"
|
||||
|
||||
# 触发手动轮转测试
|
||||
docker exec "$CONTAINER_NAME" bash -c "
|
||||
if [ -f /usr/local/bin/rotate_log ]; then
|
||||
/usr/local/bin/rotate_log /var/log/container/container.log
|
||||
else
|
||||
echo 'rotate_log function not found'
|
||||
fi
|
||||
"
|
||||
|
||||
sleep 5
|
||||
|
||||
# 检查轮转后的文件
|
||||
if [ -f "$TEST_DIR/logs/container.log.1" ]; then
|
||||
log_success "基本日志轮转功能正常 - 找到备份文件"
|
||||
else
|
||||
log_warning "未找到备份文件,可能日志未达到轮转阈值"
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:测试定期日志轮转
|
||||
test_periodic_log_rotation() {
|
||||
log "测试定期日志轮转功能..."
|
||||
|
||||
# 检查容器中的日志轮转配置
|
||||
docker exec "$CONTAINER_NAME" bash -c "
|
||||
echo '=== 检查日志轮转配置 ==='
|
||||
env | grep LOG_
|
||||
echo
|
||||
echo '=== 检查监控进程 ==='
|
||||
ps aux | grep -E '(monitor|check.*log)' | grep -v grep
|
||||
echo
|
||||
echo '=== 检查日志目录 ==='
|
||||
ls -la /var/log/container/
|
||||
"
|
||||
|
||||
# 模拟长时间运行,观察定期轮转
|
||||
log "模拟30分钟周期的定期检查..."
|
||||
|
||||
# 生成持续的日志流
|
||||
docker exec -d "$CONTAINER_NAME" bash -c "
|
||||
while true; do
|
||||
echo '$(date): Continuous log entry for rotation testing' >> /var/log/container/container.log
|
||||
sleep 1
|
||||
done
|
||||
"
|
||||
|
||||
# 等待一段时间观察轮转
|
||||
log "等待60秒观察日志轮转行为..."
|
||||
sleep 60
|
||||
|
||||
# 检查轮转结果
|
||||
rotation_files=$(ls "$TEST_DIR/logs/"*.log.* 2>/dev/null | wc -l)
|
||||
if [ "$rotation_files" -gt 0 ]; then
|
||||
log_success "找到 $rotation_files 个轮转后的日志文件"
|
||||
ls -la "$TEST_DIR/logs/"
|
||||
else
|
||||
log_warning "未检测到轮转文件,可能需要更长时间或更多日志"
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:测试日志权限
|
||||
test_log_permissions() {
|
||||
log "测试日志文件权限..."
|
||||
|
||||
# 检查容器内的日志文件权限
|
||||
docker exec "$CONTAINER_NAME" bash -c "
|
||||
echo '=== 日志目录权限 ==='
|
||||
ls -la /var/log/container/
|
||||
echo
|
||||
echo '=== 检查 hexo 用户权限 ==='
|
||||
su - hexo -c 'echo \"Test write permission\" >> /var/log/container/test_permission.log'
|
||||
if [ \$? -eq 0 ]; then
|
||||
echo 'hexo 用户可以写入日志目录'
|
||||
else
|
||||
echo 'hexo 用户无法写入日志目录'
|
||||
fi
|
||||
echo
|
||||
echo '=== 检查日志文件所有权 ==='
|
||||
stat /var/log/container/*.log 2>/dev/null | grep -E '(Uid|Gid)'
|
||||
"
|
||||
|
||||
# 测试 Git Hook 日志写入
|
||||
if docker exec "$CONTAINER_NAME" test -f "/app/hexo-blog/.git/hooks/post-receive"; then
|
||||
log "测试 Git Hook 日志写入权限..."
|
||||
docker exec "$CONTAINER_NAME" bash -c "
|
||||
su - hexo -c 'echo \"Test deployment log\" >> /var/log/container/deployment.log'
|
||||
if [ \$? -eq 0 ]; then
|
||||
echo 'Git Hook 日志写入权限正常'
|
||||
else
|
||||
echo 'Git Hook 日志写入权限有问题'
|
||||
fi
|
||||
"
|
||||
fi
|
||||
|
||||
log_success "日志权限测试完成"
|
||||
}
|
||||
|
||||
# 函数:测试日志备份和清理
|
||||
test_log_backup_cleanup() {
|
||||
log "测试日志备份和清理功能..."
|
||||
|
||||
# 创建多个旧的备份文件进行清理测试
|
||||
for i in {1..10}; do
|
||||
echo "Old backup log $i" > "$TEST_DIR/logs/container.log.$i"
|
||||
# 设置不同的时间戳
|
||||
touch -t "$(date -d "-$i days" +%Y%m%d%H%M)" "$TEST_DIR/logs/container.log.$i" 2>/dev/null || \
|
||||
touch -d "-$i days" "$TEST_DIR/logs/container.log.$i" 2>/dev/null
|
||||
done
|
||||
|
||||
log "创建了10个模拟备份文件"
|
||||
|
||||
# 执行清理
|
||||
docker exec "$CONTAINER_NAME" bash -c "
|
||||
if [ -f /usr/local/bin/cleanup_old_logs ]; then
|
||||
/usr/local/bin/cleanup_old_logs /var/log/container/
|
||||
else
|
||||
echo 'cleanup_old_logs function not found'
|
||||
fi
|
||||
"
|
||||
|
||||
sleep 5
|
||||
|
||||
# 检查清理结果
|
||||
remaining_backups=$(ls "$TEST_DIR/logs/"*.log.* 2>/dev/null | wc -l)
|
||||
log "清理后剩余备份文件数量: $remaining_backups"
|
||||
|
||||
if [ "$remaining_backups" -le 5 ]; then
|
||||
log_success "日志清理功能正常 - 保留了合理数量的备份"
|
||||
else
|
||||
log_warning "日志清理可能未按预期工作"
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:生成测试报告
|
||||
generate_test_report() {
|
||||
log "生成日志轮转测试报告..."
|
||||
|
||||
local report_file="$TEST_DIR/log_rotation_test_report.txt"
|
||||
|
||||
cat > "$report_file" << EOF
|
||||
Docker Hexo Static Blog v0.0.3 - 日志轮转测试报告
|
||||
======================================================
|
||||
|
||||
测试时间: $(date)
|
||||
测试环境: Linux ($(uname -r))
|
||||
镜像版本: ${IMAGE_NAME}:${IMAGE_TAG}
|
||||
|
||||
测试结果概要:
|
||||
EOF
|
||||
|
||||
# 检查各项测试结果
|
||||
echo "1. 容器运行状态:" >> "$report_file"
|
||||
if docker ps | grep -q "$CONTAINER_NAME"; then
|
||||
echo " ✓ 容器正常运行" >> "$report_file"
|
||||
else
|
||||
echo " ✗ 容器未运行" >> "$report_file"
|
||||
fi
|
||||
|
||||
echo "2. 日志文件检查:" >> "$report_file"
|
||||
if [ -f "$TEST_DIR/logs/container.log" ]; then
|
||||
log_size=$(stat -c%s "$TEST_DIR/logs/container.log" 2>/dev/null)
|
||||
echo " ✓ 主日志文件存在 (大小: $log_size 字节)" >> "$report_file"
|
||||
else
|
||||
echo " ✗ 主日志文件不存在" >> "$report_file"
|
||||
fi
|
||||
|
||||
echo "3. 日志轮转文件:" >> "$report_file"
|
||||
rotation_count=$(ls "$TEST_DIR/logs/"*.log.* 2>/dev/null | wc -l)
|
||||
if [ "$rotation_count" -gt 0 ]; then
|
||||
echo " ✓ 找到 $rotation_count 个轮转文件" >> "$report_file"
|
||||
ls -la "$TEST_DIR/logs/"*.log.* >> "$report_file" 2>/dev/null
|
||||
else
|
||||
echo " - 未找到轮转文件(可能正常,取决于日志大小)" >> "$report_file"
|
||||
fi
|
||||
|
||||
echo "4. 容器资源使用:" >> "$report_file"
|
||||
docker stats "$CONTAINER_NAME" --no-stream >> "$report_file" 2>/dev/null || echo " 无法获取资源使用情况" >> "$report_file"
|
||||
|
||||
echo "5. 容器日志(最后20行):" >> "$report_file"
|
||||
docker logs --tail 20 "$CONTAINER_NAME" >> "$report_file" 2>&1
|
||||
|
||||
log_success "测试报告已生成: $report_file"
|
||||
cat "$report_file"
|
||||
}
|
||||
|
||||
# 主测试流程
|
||||
main() {
|
||||
log "开始 Docker Hexo Static Blog v0.0.3 日志轮转测试"
|
||||
log "=============================================="
|
||||
|
||||
# 设置错误处理
|
||||
trap cleanup EXIT
|
||||
|
||||
# 执行测试步骤
|
||||
check_prerequisites
|
||||
prepare_test_environment
|
||||
start_container
|
||||
test_basic_log_rotation
|
||||
test_periodic_log_rotation
|
||||
test_log_permissions
|
||||
test_log_backup_cleanup
|
||||
generate_test_report
|
||||
|
||||
log_success "日志轮转测试完成!"
|
||||
log "测试结果和日志保存在: $TEST_DIR"
|
||||
}
|
||||
|
||||
# 脚本参数处理
|
||||
case "${1:-}" in
|
||||
--help|-h)
|
||||
echo "Docker Hexo Static Blog v0.0.3 - Linux 日志轮转测试脚本"
|
||||
echo ""
|
||||
echo "用法: $0 [选项]"
|
||||
echo ""
|
||||
echo "选项:"
|
||||
echo " --help, -h 显示此帮助信息"
|
||||
echo " --cleanup 仅执行清理操作"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " $0 # 运行完整的日志轮转测试"
|
||||
echo " $0 --cleanup # 清理测试资源"
|
||||
exit 0
|
||||
;;
|
||||
--cleanup)
|
||||
cleanup
|
||||
exit 0
|
||||
;;
|
||||
"")
|
||||
main
|
||||
;;
|
||||
*)
|
||||
log_error "未知参数: $1"
|
||||
echo "使用 --help 查看使用说明"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
199
test/v0.0.3/linux/run_test.sh
Normal file
199
test/v0.0.3/linux/run_test.sh
Normal file
@@ -0,0 +1,199 @@
|
||||
#!/bin/bash
|
||||
# Hexo Container v0.0.3 运行测试脚本 (Linux)
|
||||
# run_test.sh
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# 参数设置
|
||||
TAG=${1:-"hexo-test:v0.0.3"}
|
||||
CONTAINER_NAME=${2:-"hexo-test-v003"}
|
||||
HTTP_PORT=${3:-8080}
|
||||
SSH_PORT=${4:-2222}
|
||||
PUID=${5:-1000}
|
||||
PGID=${6:-1000}
|
||||
TIMEZONE=${7:-"Asia/Shanghai"}
|
||||
|
||||
echo "=== Hexo Container v0.0.3 运行测试 ==="
|
||||
echo "工作目录: $SCRIPT_DIR"
|
||||
|
||||
# 创建日志目录 (在测试脚本目录下)
|
||||
LOG_DIR="./logs"
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# 创建测试数据目录 (在测试脚本目录下)
|
||||
TEST_DATA_DIR="./test_data"
|
||||
HEXO_SITE_DIR="$TEST_DATA_DIR/hexo_site"
|
||||
SSH_KEYS_DIR="$TEST_DATA_DIR/ssh_keys"
|
||||
|
||||
echo "创建测试数据目录..."
|
||||
mkdir -p "$HEXO_SITE_DIR"
|
||||
mkdir -p "$SSH_KEYS_DIR"
|
||||
|
||||
# 创建测试用的 HTML 文件
|
||||
echo "创建测试网站文件..."
|
||||
cat > "$HEXO_SITE_DIR/index.html" << 'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hexo v0.0.3 Test Site</title>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 40px; background: #f5f5f5; }
|
||||
.container { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
|
||||
h1 { color: #333; border-bottom: 2px solid #007acc; padding-bottom: 10px; }
|
||||
.info { background: #e7f3ff; padding: 15px; border-radius: 4px; margin: 15px 0; }
|
||||
.status { display: inline-block; padding: 4px 8px; border-radius: 3px; color: white; background: #28a745; }
|
||||
ul { list-style-type: none; padding: 0; }
|
||||
li { padding: 8px; margin: 5px 0; background: #f8f9fa; border-left: 4px solid #007acc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Hexo Container v0.0.3 测试站点</h1>
|
||||
<div class="info">
|
||||
<p><strong>测试时间:</strong> <span id="time"></span></p>
|
||||
<p><strong>版本:</strong> <span class="status">v0.0.3</span></p>
|
||||
<p><strong>状态:</strong> <span class="status">运行中</span></p>
|
||||
</div>
|
||||
|
||||
<h2>v0.0.3 新功能测试</h2>
|
||||
<ul>
|
||||
<li>定期日志轮转 (每30分钟检查)</li>
|
||||
<li>Git Hook 日志权限修复</li>
|
||||
<li>增强的部署日志管理</li>
|
||||
<li>智能日志文件大小控制</li>
|
||||
<li>自动旧日志清理</li>
|
||||
<li>时间戳备份文件生成</li>
|
||||
</ul>
|
||||
|
||||
<h2>测试链接</h2>
|
||||
<ul>
|
||||
<li><a href="/health">健康检查端点</a></li>
|
||||
<li>SSH 连接: ssh -p 2222 hexo@localhost</li>
|
||||
</ul>
|
||||
</div>
|
||||
<script>
|
||||
document.getElementById('time').textContent = new Date().toLocaleString('zh-CN');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
# 生成 SSH 密钥对 (如果不存在)
|
||||
SSH_KEY_PATH="$SSH_KEYS_DIR/test_key"
|
||||
if [ ! -f "$SSH_KEY_PATH" ]; then
|
||||
echo "生成 SSH 密钥对..."
|
||||
if ssh-keygen -t rsa -b 4096 -f "$SSH_KEY_PATH" -N "" -q; then
|
||||
echo "[SUCCESS] SSH 密钥生成成功"
|
||||
else
|
||||
echo "[FAIL] SSH 密钥生成失败"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 停止并删除已存在的容器
|
||||
echo "清理旧容器..."
|
||||
docker stop "$CONTAINER_NAME" 2>/dev/null || true
|
||||
docker rm "$CONTAINER_NAME" 2>/dev/null || true
|
||||
|
||||
# 检查端口是否被占用
|
||||
if netstat -tlnp 2>/dev/null | grep -q ":$HTTP_PORT "; then
|
||||
echo "[WARNING] 警告: 端口 $HTTP_PORT 已被占用"
|
||||
fi
|
||||
if netstat -tlnp 2>/dev/null | grep -q ":$SSH_PORT "; then
|
||||
echo "[WARNING] 警告: 端口 $SSH_PORT 已被占用"
|
||||
fi
|
||||
|
||||
# 构建 Docker 运行命令
|
||||
echo ""
|
||||
echo "启动容器..."
|
||||
|
||||
DOCKER_CMD="docker run -d \
|
||||
--name $CONTAINER_NAME \
|
||||
-p $HTTP_PORT:80 \
|
||||
-p $SSH_PORT:22 \
|
||||
-e PUID=$PUID \
|
||||
-e PGID=$PGID \
|
||||
-e TZ=$TIMEZONE \
|
||||
-e HTTP_PORT=80 \
|
||||
-e SSH_PORT=22 \
|
||||
-v $SCRIPT_DIR/test_data/hexo_site:/home/www/hexo \
|
||||
-v $SCRIPT_DIR/test_data/ssh_keys:/home/hexo/.ssh \
|
||||
-v $SCRIPT_DIR/logs:/var/log/container \
|
||||
$TAG"
|
||||
|
||||
echo "执行命令:"
|
||||
echo "$DOCKER_CMD"
|
||||
|
||||
# 执行 Docker 运行命令
|
||||
if CONTAINER_ID=$($DOCKER_CMD); then
|
||||
echo ""
|
||||
echo "=== 容器启动成功 ==="
|
||||
echo "容器 ID: $CONTAINER_ID"
|
||||
echo "容器名称: $CONTAINER_NAME"
|
||||
|
||||
# 等待容器启动
|
||||
echo ""
|
||||
echo "等待容器完全启动 (增加等待时间)..."
|
||||
sleep 30 # MODIFIED: Increased sleep time to 30 seconds
|
||||
|
||||
# 检查容器状态
|
||||
echo ""
|
||||
echo "=== 容器状态 ==="
|
||||
docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||
|
||||
# 显示访问信息
|
||||
echo ""
|
||||
echo "=== 访问信息 ==="
|
||||
LOCAL_IP=$(hostname -I | awk '{print $1}')
|
||||
echo "HTTP 访问地址: http://$LOCAL_IP:$HTTP_PORT"
|
||||
echo "健康检查地址: http://$LOCAL_IP:$HTTP_PORT/health"
|
||||
echo "SSH 连接命令: ssh -p $SSH_PORT -i test_data/ssh_keys/test_key hexo@$LOCAL_IP"
|
||||
|
||||
# 显示容器日志
|
||||
echo ""
|
||||
echo "=== 容器启动日志 (最后20行) ==="
|
||||
docker logs "$CONTAINER_NAME" --tail 20
|
||||
|
||||
# 基础健康检查
|
||||
echo ""
|
||||
echo "=== 基础健康检查 ==="
|
||||
sleep 5
|
||||
|
||||
# 健康检查
|
||||
if curl -f "http://localhost:$HTTP_PORT/health" --max-time 10 >/dev/null 2>&1; then
|
||||
echo "[SUCCESS] 健康检查通过"
|
||||
else
|
||||
echo "[FAIL] 健康检查失败"
|
||||
fi
|
||||
|
||||
# HTTP 服务检查
|
||||
if curl -f "http://localhost:$HTTP_PORT" --max-time 10 >/dev/null 2>&1; then
|
||||
echo "[SUCCESS] HTTP 服务正常"
|
||||
else
|
||||
echo "[FAIL] HTTP 服务异常"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== 运行测试完成 ==="
|
||||
echo "容器已成功启动并运行。使用以下命令进行进一步测试:"
|
||||
echo " ./functional_test.sh # 功能测试"
|
||||
echo " ./log_rotation_test.sh # 日志轮转测试"
|
||||
echo " ./cleanup_test.sh # 清理测试环境"
|
||||
|
||||
exit 0
|
||||
else
|
||||
echo ""
|
||||
echo "=== 容器启动失败 ==="
|
||||
echo "[ERROR] Docker 容器启动失败"
|
||||
|
||||
# 尝试显示错误日志
|
||||
if docker logs "$CONTAINER_NAME" 2>/dev/null; then
|
||||
echo ""
|
||||
echo "=== 容器错误日志 ==="
|
||||
docker logs "$CONTAINER_NAME"
|
||||
fi
|
||||
|
||||
exit 1
|
||||
fi
|
||||
556
test/v0.0.3/linux/start.sh
Normal file
556
test/v0.0.3/linux/start.sh
Normal file
@@ -0,0 +1,556 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Hexo Static Blog v0.0.3 - Linux Complete Test Suite Startup Script
|
||||
# 完整测试套件启动脚本
|
||||
|
||||
# set -e # Re-enabled for production use
|
||||
|
||||
# 颜色定义 (Corrected for echo -e and printf)
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 配置参数
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
DOCKERFILE_DIR="$(cd "$SCRIPT_DIR/../../../" && pwd)"
|
||||
LOG_DIR="$SCRIPT_DIR/logs"
|
||||
# SUITE_LOG is defined in main after mkdir -p LOG_DIR
|
||||
|
||||
# 测试脚本数组
|
||||
TESTS=(
|
||||
"build_test.sh:构建测试"
|
||||
"run_test.sh:运行测试"
|
||||
"functional_test.sh:功能测试"
|
||||
"log_rotation_test.sh:日志轮转测试"
|
||||
"cleanup_test.sh:清理测试"
|
||||
)
|
||||
|
||||
# 函数:显示横幅
|
||||
show_banner() {
|
||||
echo -e "${CYAN}"
|
||||
echo " ╔══════════════════════════════════════════════════════════════╗"
|
||||
echo " ║ Docker Hexo Static Blog v0.0.3 ║"
|
||||
echo " ║ 完整测试套件 (Linux) ║"
|
||||
echo " ║ ║"
|
||||
echo " ║ • 自动化构建和部署测试 ║"
|
||||
echo " ║ • 功能完整性验证 ║"
|
||||
echo " ║ • 日志轮转和权限测试 ║"
|
||||
echo " ║ • 安全配置验证 ║"
|
||||
echo " ║ • 性能监控 ║"
|
||||
echo " ╚══════════════════════════════════════════════════════════════╝"
|
||||
echo -e "${NC}"
|
||||
}
|
||||
|
||||
# 函数:记录日志
|
||||
log() {
|
||||
echo -e "${BLUE}[$(LC_ALL=C date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$SUITE_LOG"
|
||||
local tee_status=${PIPESTATUS[1]}
|
||||
if [ $tee_status -ne 0 ]; then
|
||||
echo -e "${RED}CRITICAL: tee in log failed (status $tee_status) writing to $SUITE_LOG${NC}" >&2
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[$(LC_ALL=C date '+%Y-%m-%d %H:%M:%S')] ✓${NC} $1" | tee -a "$SUITE_LOG"
|
||||
local tee_status=${PIPESTATUS[1]}
|
||||
if [ $tee_status -ne 0 ]; then
|
||||
echo -e "${RED}CRITICAL: tee in log_success failed (status $tee_status) writing to $SUITE_LOG${NC}" >&2
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[$(LC_ALL=C date '+%Y-%m-%d %H:%M:%S')] ✗${NC} $1" | tee -a "$SUITE_LOG"
|
||||
local tee_status=${PIPESTATUS[1]}
|
||||
if [ $tee_status -ne 0 ]; then
|
||||
# Avoid using log_error here to prevent recursion if SUITE_LOG is the problem
|
||||
echo -e "${RED}CRITICAL: tee in log_error failed (status $tee_status) writing to $SUITE_LOG${NC}" >&2
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[$(LC_ALL=C date '+%Y-%m-%d %H:%M:%S')] ⚠${NC} $1" | tee -a "$SUITE_LOG"
|
||||
local tee_status=${PIPESTATUS[1]}
|
||||
if [ $tee_status -ne 0 ]; then
|
||||
echo -e "${RED}CRITICAL: tee in log_warning failed (status $tee_status) writing to $SUITE_LOG${NC}" >&2
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
log_step() {
|
||||
echo -e "${CYAN}[$(LC_ALL=C date '+%Y-%m-%d %H:%M:%S')] ▶${NC} $1" | tee -a "$SUITE_LOG"
|
||||
local tee_status=${PIPESTATUS[1]}
|
||||
if [ $tee_status -ne 0 ]; then
|
||||
echo -e "${RED}CRITICAL: tee in log_step failed (status $tee_status) writing to $SUITE_LOG${NC}" >&2
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# 函数:显示进度条
|
||||
show_progress() {
|
||||
local current=$1
|
||||
local total=$2
|
||||
local width=50
|
||||
local percentage=$((current * 100 / total))
|
||||
local filled=$((current * width / total))
|
||||
local empty=$((width - filled))
|
||||
|
||||
printf "\r${CYAN}进度: [${NC}" # Corrected format string
|
||||
printf "%*s" "$filled" | tr ' ' '=' # Corrected tr command and quoted variable
|
||||
printf "%*s" "$empty" | tr ' ' ' ' # Corrected tr command and quoted variable
|
||||
printf "${CYAN}] %d%% (%d/%d)${NC}" "$percentage" "$current" "$total" # Quoted variables
|
||||
}
|
||||
|
||||
# 函数:检查前置条件
|
||||
check_prerequisites() {
|
||||
log_step "检查测试前置条件..."
|
||||
|
||||
local errors=0
|
||||
|
||||
# 检查 Docker
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log_error "Docker 未安装或不在 PATH 中"
|
||||
((errors++))
|
||||
fi
|
||||
|
||||
# 检查 Docker 服务
|
||||
if ! docker info &> /dev/null; then
|
||||
log_error "Docker 服务未运行"
|
||||
((errors++))
|
||||
fi
|
||||
|
||||
# 检查 Dockerfile
|
||||
if [ ! -f "$DOCKERFILE_DIR/Dockerfile_v0.0.3" ]; then
|
||||
log_error "Dockerfile_v0.0.3 不存在于 $DOCKERFILE_DIR"
|
||||
((errors++))
|
||||
fi
|
||||
|
||||
# 检查测试脚本
|
||||
for test_info in "${TESTS[@]}"; do
|
||||
script_name="${test_info%%:*}"
|
||||
if [ ! -f "$SCRIPT_DIR/$script_name" ]; then
|
||||
log_error "测试脚本不存在: $script_name"
|
||||
((errors++))
|
||||
elif [ ! -x "$SCRIPT_DIR/$script_name" ]; then
|
||||
log_warning "测试脚本没有执行权限: $script_name (将自动修复)"
|
||||
chmod +x "$SCRIPT_DIR/$script_name"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $errors -gt 0 ]; then
|
||||
log_error "发现 $errors 个前置条件问题,无法继续测试"
|
||||
exit 1 # Exit if prerequisites fail
|
||||
fi
|
||||
|
||||
log_success "前置条件检查通过"
|
||||
}
|
||||
|
||||
# 函数:准备测试环境
|
||||
prepare_test_environment() {
|
||||
log_step "准备测试环境..."
|
||||
|
||||
# 创建日志目录 (already created in main, but ensure it)
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# 清理旧的测试资源(可选)
|
||||
if [ "${CLEAN_START:-false}" = "true" ]; then
|
||||
log "清理旧的测试资源..."
|
||||
# Allow these commands to fail without exiting the script immediately
|
||||
docker stop hexo-blog-test 2>/dev/null || true
|
||||
docker rm hexo-blog-test 2>/dev/null || true
|
||||
docker rmi hexo-test:v0.0.3 2>/dev/null || true # Ensure correct image name used elsewhere
|
||||
fi
|
||||
|
||||
# 设置测试脚本权限
|
||||
chmod +x "$SCRIPT_DIR"/*.sh
|
||||
|
||||
log_success "测试环境准备完成"
|
||||
}
|
||||
|
||||
# 函数:运行单个测试
|
||||
run_test() {
|
||||
local test_info="$1"
|
||||
local script_name="${test_info%%:*}"
|
||||
local test_description="${test_info##*:}"
|
||||
|
||||
log_step "执行测试: $test_description ($script_name)"
|
||||
|
||||
local test_log="$LOG_DIR/${script_name%.sh}.log"
|
||||
local start_time
|
||||
start_time=$(LC_ALL=C date +%s)
|
||||
|
||||
# 执行测试脚本
|
||||
# The actual script ($script_name) should handle its own set -e behavior.
|
||||
# If it fails, its non-zero exit code will be caught here.
|
||||
if LC_ALL=C bash "$SCRIPT_DIR/$script_name" > "$test_log" 2>&1; then
|
||||
local end_time
|
||||
end_time=$(LC_ALL=C date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
log_success "$test_description 测试通过 (耗时: ${duration}s)"
|
||||
return 0 # Test script succeeded
|
||||
else
|
||||
local exit_code=$? # Capture exit code of the failing script
|
||||
local end_time
|
||||
end_time=$(LC_ALL=C date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
log_error "$test_description 测试失败 (退出码: $exit_code, 耗时: ${duration}s)"
|
||||
log_error "详细日志: $test_log"
|
||||
|
||||
# 显示失败的最后几行
|
||||
echo -e "${RED}错误详情 (最后10行):${NC}"
|
||||
tail -10 "$test_log" | sed \'s/^/ /\' # Ensure sed doesn\'t cause issues
|
||||
|
||||
return 1 # Test script failed
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:运行所有测试
|
||||
run_all_tests() {
|
||||
log_step "开始执行完整测试套件..."
|
||||
|
||||
local total_tests=${#TESTS[@]}
|
||||
local passed_tests=0
|
||||
local failed_tests=0
|
||||
local suite_start_time
|
||||
suite_start_time=$(LC_ALL=C date +%s)
|
||||
|
||||
echo "" # Newline before progress
|
||||
|
||||
for i in "${!TESTS[@]}"; do
|
||||
local current=$((i + 1))
|
||||
show_progress $current $total_tests
|
||||
echo "" # Newline after progress bar, before test execution logs
|
||||
|
||||
if run_test "${TESTS[$i]}"; then
|
||||
((passed_tests++))
|
||||
else
|
||||
((failed_tests++))
|
||||
if [ "${CONTINUE_ON_FAILURE:-true}" = "true" ]; then # Default to true
|
||||
log_warning "测试失败,但继续执行剩余测试..."
|
||||
else
|
||||
log_error "测试失败,停止执行"
|
||||
break # Exit loop
|
||||
fi
|
||||
fi
|
||||
echo "" # Newline after test result
|
||||
done
|
||||
|
||||
local suite_end_time
|
||||
suite_end_time=$(LC_ALL=C date +%s)
|
||||
local total_duration=$((suite_end_time - suite_start_time))
|
||||
|
||||
# Final progress update to 100% if all tests run
|
||||
if [ $failed_tests -eq 0 ] || [ "${CONTINUE_ON_FAILURE:-true}" = "true" ]; then
|
||||
show_progress $total_tests $total_tests
|
||||
echo "" # Newline after final progress
|
||||
fi
|
||||
|
||||
echo ""
|
||||
log_step "测试套件执行完成"
|
||||
log "总耗时: ${total_duration}s"
|
||||
log "通过测试: $passed_tests/$total_tests"
|
||||
log "失败测试: $failed_tests/$total_tests"
|
||||
|
||||
# 生成测试报告
|
||||
generate_test_report $passed_tests $failed_tests $total_duration
|
||||
|
||||
if [ $failed_tests -eq 0 ]; then
|
||||
log_success "所有测试都通过了!🎉"
|
||||
return 0 # Overall success
|
||||
else
|
||||
log_error "有 $failed_tests 个测试失败"
|
||||
return 1 # Overall failure
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:生成测试报告
|
||||
generate_test_report() {
|
||||
local passed=$1
|
||||
local failed=$2
|
||||
local duration=$3
|
||||
local total=$((passed + failed))
|
||||
local success_rate=0
|
||||
if [ $total -gt 0 ]; then
|
||||
success_rate=$(( passed * 100 / total ))
|
||||
fi
|
||||
|
||||
local report_file="$LOG_DIR/test_suite_report.txt"
|
||||
|
||||
log_step "生成测试报告..."
|
||||
|
||||
# Use cat with explicit EOF marker
|
||||
cat > "$report_file" <<-EOF
|
||||
Docker Hexo Static Blog v0.0.3 - 完整测试套件报告 (Linux)
|
||||
========================================================
|
||||
|
||||
测试时间: $(LC_ALL=C date)
|
||||
测试环境: Linux ($(uname -r))
|
||||
Docker 版本: $(docker --version)
|
||||
测试位置: $SCRIPT_DIR
|
||||
|
||||
测试结果概要:
|
||||
- 总测试数: $total
|
||||
- 通过测试: $passed
|
||||
- 失败测试: $failed
|
||||
- 成功率: $success_rate%
|
||||
- 总耗时: ${duration}s
|
||||
|
||||
详细测试结果:
|
||||
EOF
|
||||
|
||||
for test_info in "${TESTS[@]}"; do
|
||||
local script_name="${test_info%%:*}"
|
||||
local test_description="${test_info##*:}"
|
||||
local test_log_file="$LOG_DIR/${script_name%.sh}.log" # Renamed to avoid conflict
|
||||
|
||||
echo "- $test_description:" >> "$report_file"
|
||||
if [ -f "$test_log_file" ]; then
|
||||
# Check for success markers more robustly
|
||||
# Assuming test scripts output specific success strings or exit 0
|
||||
# For now, rely on the run_test logic that populates passed/failed counts
|
||||
# This report section can be enhanced if tests output specific markers
|
||||
if grep -q -E "SUCCESS|成功|✓|测试通过" "$test_log_file" 2>/dev/null || \
|
||||
( [ -s "$test_log_file" ] && ! grep -q -E "FAIL|失败|✗|测试失败" "$test_log_file" 2>/dev/null && \
|
||||
grep -q "构建成功" "$test_log_file" 2>/dev/null ) ; then # Example for build_test
|
||||
echo " 状态: ✓ 通过" >> "$report_file"
|
||||
elif grep -q -E "FAIL|失败|✗|测试失败" "$test_log_file" 2>/dev/null; then
|
||||
echo " 状态: ✗ 失败" >> "$report_file"
|
||||
else
|
||||
# If log exists but no clear pass/fail, mark as indeterminate or check exit code if stored
|
||||
echo " 状态: ? 结果未知 (检查日志)" >> "$report_file"
|
||||
fi
|
||||
echo " 日志: $test_log_file" >> "$report_file"
|
||||
else
|
||||
echo " 状态: ? 未执行或日志丢失" >> "$report_file"
|
||||
fi
|
||||
echo "" >> "$report_file"
|
||||
done
|
||||
|
||||
# 添加系统信息
|
||||
echo "系统信息:" >> "$report_file"
|
||||
echo "- 操作系统: $(uname -s)" >> "$report_file"
|
||||
echo "- 内核版本: $(uname -r)" >> "$report_file"
|
||||
echo "- 架构: $(uname -m)" >> "$report_file"
|
||||
# Ensure free and df commands don't fail due to locale
|
||||
echo "- 可用内存: $(LC_ALL=C free -h | grep '^Mem:' | awk '{print $7}')" >> "$report_file"
|
||||
echo "- 磁盘空间: $(LC_ALL=C df -h . | tail -1 | awk '{print $4}')" >> "$report_file"
|
||||
|
||||
log_success "测试报告已生成: $report_file"
|
||||
}
|
||||
|
||||
# 函数:显示帮助信息
|
||||
show_help() {
|
||||
cat <<-EOF
|
||||
Docker Hexo Static Blog v0.0.3 - Linux 完整测试套件
|
||||
|
||||
用法: $0 [选项]
|
||||
|
||||
选项:
|
||||
--help, -h 显示此帮助信息
|
||||
--clean-start 清理旧资源后开始测试 (设置 CLEAN_START=true)
|
||||
--stop-on-failure 第一个测试失败时停止 (设置 CONTINUE_ON_FAILURE=false)
|
||||
--list 列出所有可用的测试
|
||||
--test <script_name> 只运行指定的测试脚本 (例如: build_test.sh)
|
||||
--report-only 只生成报告,不运行测试 (需要现有日志)
|
||||
|
||||
环境变量:
|
||||
CLEAN_START=true 等同于 --clean-start
|
||||
CONTINUE_ON_FAILURE=false 等同于 --stop-on-failure
|
||||
|
||||
示例:
|
||||
$0 # 运行完整测试套件
|
||||
$0 --clean-start # 清理后运行测试
|
||||
$0 --test build_test.sh # 只运行构建测试
|
||||
|
||||
测试脚本:
|
||||
EOF
|
||||
|
||||
for test_info in "${TESTS[@]}"; do
|
||||
local script_name="${test_info%%:*}"
|
||||
local test_description="${test_info##*:}"
|
||||
printf " %-25s %s\\n" "$script_name" "$test_description"
|
||||
done
|
||||
}
|
||||
|
||||
# 函数:列出测试
|
||||
list_tests() {
|
||||
echo "可用的测试脚本:"
|
||||
echo ""
|
||||
for i in "${!TESTS[@]}"; do
|
||||
local test_info="${TESTS[$i]}"
|
||||
local script_name="${test_info%%:*}"
|
||||
local test_description="${test_info##*:}"
|
||||
printf "%d. %-25s - %s\\n" $((i + 1)) "$script_name" "$test_description"
|
||||
done
|
||||
}
|
||||
|
||||
# 函数:运行单个指定测试
|
||||
run_single_test() {
|
||||
local target_script="$1"
|
||||
|
||||
# Find the test_info for the target_script
|
||||
local found_test_info=""
|
||||
for test_info_item in "${TESTS[@]}"; do
|
||||
local script_name_item="${test_info_item%%:*}"
|
||||
if [ "$script_name_item" = "$target_script" ]; then
|
||||
found_test_info="$test_info_item"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$found_test_info" ]; then
|
||||
log_error "未找到测试脚本: $target_script"
|
||||
echo "可用的测试脚本:"
|
||||
list_tests # Call list_tests function
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Prepare environment for single test run
|
||||
# Note: SUITE_LOG might not be set if main() isn't fully run.
|
||||
# For simplicity, single test runs will log to their own file and console.
|
||||
# More robust single test logging would require initializing SUITE_LOG.
|
||||
mkdir -p "$LOG_DIR" # Ensure log dir exists
|
||||
export SUITE_LOG="$LOG_DIR/single_test_run_$(date +%Y%m%d_%H%M%S).log" # Temporary suite log for this run
|
||||
echo "Running single test: $target_script. Main log: $SUITE_LOG" > "$SUITE_LOG"
|
||||
|
||||
|
||||
log_step "运行单个测试: $target_script"
|
||||
# check_prerequisites # Optional: run for single test
|
||||
prepare_test_environment # Run prepare, it handles CLEAN_START
|
||||
|
||||
run_test "$found_test_info"
|
||||
local test_exit_code=$?
|
||||
|
||||
if [ $test_exit_code -eq 0 ]; then
|
||||
log_success "$target_script 测试通过"
|
||||
else
|
||||
log_error "$target_script 测试失败"
|
||||
fi
|
||||
return $test_exit_code
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
# Ensure LOG_DIR exists before SUITE_LOG is defined
|
||||
mkdir -p "$LOG_DIR"
|
||||
# Define SUITE_LOG here so all log functions can use it
|
||||
# This was previously in the parameter parsing block for main call
|
||||
export SUITE_LOG="$LOG_DIR/test_suite_$(LC_ALL=C date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
show_banner
|
||||
|
||||
log "Docker Hexo Static Blog v0.0.3 完整测试套件启动"
|
||||
log "================================================"
|
||||
log "脚本位置: $SCRIPT_DIR"
|
||||
log "Dockerfile 位置: $DOCKERFILE_DIR"
|
||||
log "日志位置: $LOG_DIR (主套件日志: $SUITE_LOG)"
|
||||
|
||||
check_prerequisites
|
||||
prepare_test_environment # Handles CLEAN_START logic
|
||||
run_all_tests
|
||||
# run_all_tests returns 0 for all pass, 1 for any failure
|
||||
return $? # Propagate the exit status of run_all_tests
|
||||
}
|
||||
|
||||
# --- Main script execution starts here ---
|
||||
|
||||
# Default behavior: continue on failure
|
||||
export CONTINUE_ON_FAILURE="${CONTINUE_ON_FAILURE:-true}"
|
||||
# Default behavior: don't clean start unless specified
|
||||
export CLEAN_START="${CLEAN_START:-false}"
|
||||
|
||||
|
||||
# Argument parsing
|
||||
if [ $# -eq 0 ]; then
|
||||
main
|
||||
exit $? # Exit with main's status
|
||||
fi
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--help|-h)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
--list)
|
||||
list_tests
|
||||
exit 0
|
||||
;;
|
||||
--clean-start)
|
||||
export CLEAN_START=true
|
||||
# If it's the only arg, run main. If others follow, they'll be processed.
|
||||
shift
|
||||
if [ $# -eq 0 ]; then main; exit $?; fi
|
||||
;;
|
||||
--stop-on-failure)
|
||||
export CONTINUE_ON_FAILURE=false
|
||||
shift
|
||||
if [ $# -eq 0 ]; then main; exit $?; fi
|
||||
;;
|
||||
--test)
|
||||
if [ -z "$2" ]; then
|
||||
# Temporarily set SUITE_LOG for this error message if not already set
|
||||
export SUITE_LOG="${SUITE_LOG:-$LOG_DIR/error_$(date +%Y%m%d_%H%M%S).log}"
|
||||
mkdir -p "$(dirname "$SUITE_LOG")"
|
||||
log_error "请指定要运行的测试脚本名称 (例如: build_test.sh)"
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
run_single_test "$2"
|
||||
exit $? # Exit with single test's status
|
||||
;;
|
||||
--report-only)
|
||||
# Ensure SUITE_LOG is defined for logging within generate_test_report
|
||||
export SUITE_LOG="${SUITE_LOG:-$LOG_DIR/report_only_$(date +%Y%m%d_%H%M%S).log}"
|
||||
mkdir -p "$(dirname "$SUITE_LOG")"
|
||||
if [ -d "$LOG_DIR" ] && [ "$(find "$LOG_DIR" -name \'*.log\' -print -quit)" ]; then
|
||||
# Dummy values for passed/failed/duration as we are only generating report from existing logs
|
||||
generate_test_report 0 0 0
|
||||
exit $?
|
||||
else
|
||||
log_error "没有找到测试日志目录 $LOG_DIR 或日志文件以生成报告。"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# If main hasn't run yet due to options, run it now.
|
||||
# This handles the case where options like --clean-start are given,
|
||||
# and then the script is expected to run the full suite.
|
||||
if ! ps -p $$ -o comm= | grep -q "start.sh"; then # Basic check if main was already invoked
|
||||
main
|
||||
exit $?
|
||||
else
|
||||
# If options were processed and we still have an unknown one, it's an error.
|
||||
export SUITE_LOG="${SUITE_LOG:-$LOG_DIR/error_$(date +%Y%m%d_%H%M%S).log}"
|
||||
mkdir -p "$(dirname "$SUITE_LOG")"
|
||||
log_error "未知参数: $1"
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
# shift # Shift only if argument was consumed and not an exit/main call
|
||||
done
|
||||
|
||||
# If loop finishes and main hasn't been called (e.g. only options like --clean-start were set)
|
||||
# This logic might be complex depending on desired option interactions.
|
||||
# A common pattern is to set flags and have one call to main() at the end.
|
||||
# The current structure calls main or exits within the case statement for most paths.
|
||||
# If we reach here, it implies options were processed that set flags, and now main should run.
|
||||
if [ "${#BASH_SOURCE[@]}" -eq 1 ] && [ -z "${_MAIN_CALLED_VIA_OPTIONS:-}" ]; then
|
||||
# Check if main was called by an option that then shifted out all args
|
||||
# This is a fallback if options like --clean-start are given,
|
||||
# and the parameter parsing was modified to call main if --clean-start is the only arg.
|
||||
# So this path might not be strictly needed anymore.
|
||||
: # Do nothing, main should have been called or script exited.
|
||||
fi
|
||||
|
||||
# Final exit status should be from main or specific option handlers.
|
||||
# Bash scripts exit with the status of the last command if not specified.
|
||||
# The explicit `exit $?` after main calls ensures this.
|
||||
88
test/v0.0.3/linux/start_simple.sh
Normal file
88
test/v0.0.3/linux/start_simple.sh
Normal file
@@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Hexo Static Blog v0.0.3 - Linux Complete Test Suite Startup Script (Simplified)
|
||||
# 完整测试套件启动脚本 (简化版)
|
||||
|
||||
# 配置参数
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
DOCKERFILE_DIR="$(cd "$SCRIPT_DIR/../../../" && pwd)"
|
||||
LOG_DIR="$SCRIPT_DIR/logs"
|
||||
|
||||
# 测试脚本数组
|
||||
TESTS=(
|
||||
"build_test.sh"
|
||||
"run_test.sh"
|
||||
"functional_test.sh"
|
||||
"log_rotation_test.sh"
|
||||
"cleanup_test.sh"
|
||||
)
|
||||
|
||||
# 创建日志目录
|
||||
mkdir -p "$LOG_DIR"
|
||||
SUITE_LOG="$LOG_DIR/test_suite_$(date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
echo "=== Docker Hexo Static Blog v0.0.3 - Linux 完整测试套件 ===" | tee "$SUITE_LOG"
|
||||
echo "开始时间: $(date)" | tee -a "$SUITE_LOG"
|
||||
echo "脚本位置: $SCRIPT_DIR" | tee -a "$SUITE_LOG"
|
||||
echo "Dockerfile 位置: $DOCKERFILE_DIR" | tee -a "$SUITE_LOG"
|
||||
echo "日志位置: $LOG_DIR" | tee -a "$SUITE_LOG"
|
||||
echo "" | tee -a "$SUITE_LOG"
|
||||
|
||||
# 清理旧资源(如果指定)
|
||||
if [ "${1:-}" = "--clean-start" ]; then
|
||||
echo "清理旧的测试资源..." | tee -a "$SUITE_LOG"
|
||||
docker stop hexo-test-v003 2>/dev/null || true
|
||||
docker rm hexo-test-v003 2>/dev/null || true
|
||||
docker rmi hexo-test:v0.0.3 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# 设置测试脚本权限
|
||||
chmod +x "$SCRIPT_DIR"/*.sh
|
||||
|
||||
# 运行测试
|
||||
passed_tests=0
|
||||
failed_tests=0
|
||||
total_tests=${#TESTS[@]}
|
||||
|
||||
for i in "${!TESTS[@]}"; do
|
||||
current=$((i + 1))
|
||||
script_name="${TESTS[$i]}"
|
||||
|
||||
echo "[$current/$total_tests] 运行测试: $script_name" | tee -a "$SUITE_LOG"
|
||||
|
||||
test_log="$LOG_DIR/${script_name%.sh}_$(date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
# 运行测试脚本
|
||||
if bash "$SCRIPT_DIR/$script_name" > "$test_log" 2>&1; then
|
||||
echo "✓ $script_name 测试通过" | tee -a "$SUITE_LOG"
|
||||
((passed_tests++))
|
||||
else
|
||||
echo "✗ $script_name 测试失败" | tee -a "$SUITE_LOG"
|
||||
echo " 详细日志: $test_log" | tee -a "$SUITE_LOG"
|
||||
echo " 最后10行错误:" | tee -a "$SUITE_LOG"
|
||||
tail -10 "$test_log" | sed 's/^/ /' | tee -a "$SUITE_LOG"
|
||||
((failed_tests++))
|
||||
|
||||
# 默认继续执行其他测试
|
||||
if [ "${CONTINUE_ON_FAILURE:-true}" != "true" ]; then
|
||||
echo "测试失败,停止执行" | tee -a "$SUITE_LOG"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
echo "" | tee -a "$SUITE_LOG"
|
||||
done
|
||||
|
||||
# 生成最终报告
|
||||
echo "=== 测试套件执行完成 ===" | tee -a "$SUITE_LOG"
|
||||
echo "结束时间: $(date)" | tee -a "$SUITE_LOG"
|
||||
echo "通过测试: $passed_tests/$total_tests" | tee -a "$SUITE_LOG"
|
||||
echo "失败测试: $failed_tests/$total_tests" | tee -a "$SUITE_LOG"
|
||||
|
||||
if [ $failed_tests -eq 0 ]; then
|
||||
echo "🎉 所有测试都通过了!" | tee -a "$SUITE_LOG"
|
||||
exit 0
|
||||
else
|
||||
echo "❌ 有 $failed_tests 个测试失败" | tee -a "$SUITE_LOG"
|
||||
exit 1
|
||||
fi
|
||||
277
test/v0.0.3/linux/test_paths.sh
Normal file
277
test/v0.0.3/linux/test_paths.sh
Normal file
@@ -0,0 +1,277 @@
|
||||
#!/bin/bash
|
||||
# Hexo Container v0.0.3 路径验证脚本 (Linux)
|
||||
# test_paths.sh - 验证测试环境的路径配置
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${CYAN}=== Hexo Container v0.0.3 路径验证工具 (Linux) ===${NC}"
|
||||
echo -e "${BLUE}工作目录: $SCRIPT_DIR${NC}"
|
||||
echo ""
|
||||
|
||||
# 验证结果数组
|
||||
declare -a RESULTS=()
|
||||
|
||||
# 验证函数
|
||||
check_path() {
|
||||
local description="$1"
|
||||
local path="$2"
|
||||
local should_exist="$3" # true/false
|
||||
local create_if_missing="$4" # true/false
|
||||
|
||||
echo -n "检查 $description... "
|
||||
|
||||
if [ "$should_exist" = "true" ]; then
|
||||
if [ -e "$path" ]; then
|
||||
echo -e "${GREEN}✓ 存在${NC}"
|
||||
RESULTS+=("PASS: $description")
|
||||
return 0
|
||||
else
|
||||
if [ "$create_if_missing" = "true" ]; then
|
||||
mkdir -p "$path" 2>/dev/null
|
||||
if [ -d "$path" ]; then
|
||||
echo -e "${YELLOW}✓ 已创建${NC}"
|
||||
RESULTS+=("CREATED: $description")
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}✗ 创建失败${NC}"
|
||||
RESULTS+=("FAIL: $description - 创建失败")
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}✗ 不存在${NC}"
|
||||
RESULTS+=("FAIL: $description - 路径不存在: $path")
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [ -e "$path" ]; then
|
||||
echo -e "${YELLOW}! 存在 (不应该存在)${NC}"
|
||||
RESULTS+=("WARN: $description - 意外存在")
|
||||
return 0
|
||||
else
|
||||
echo -e "${GREEN}✓ 不存在 (正确)${NC}"
|
||||
RESULTS+=("PASS: $description")
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
echo -e "${YELLOW}=== 关键路径验证 ===${NC}"
|
||||
|
||||
# 1. 验证 Dockerfile
|
||||
check_path "Dockerfile_v0.0.3" "../../../Dockerfile_v0.0.3" true false
|
||||
|
||||
# 2. 验证和创建测试目录结构
|
||||
echo ""
|
||||
echo -e "${YELLOW}=== 测试目录结构验证 ===${NC}"
|
||||
|
||||
check_path "日志目录" "./logs" false true
|
||||
check_path "测试数据目录" "./test_data" false true
|
||||
check_path "Hexo 站点目录" "./test_data/hexo_site" false true
|
||||
check_path "SSH 密钥目录" "./test_data/ssh_keys" false true
|
||||
|
||||
# 3. 验证测试脚本
|
||||
echo ""
|
||||
echo -e "${YELLOW}=== 测试脚本验证 ===${NC}"
|
||||
|
||||
SCRIPTS=(
|
||||
"start.sh"
|
||||
"build_test.sh"
|
||||
"run_test.sh"
|
||||
"functional_test.sh"
|
||||
"log_rotation_test.sh"
|
||||
"cleanup_test.sh"
|
||||
)
|
||||
|
||||
for script in "${SCRIPTS[@]}"; do
|
||||
check_path "测试脚本: $script" "./$script" true false
|
||||
if [ -f "./$script" ]; then
|
||||
if [ -x "./$script" ]; then
|
||||
echo -e " ${GREEN}✓ 可执行权限${NC}"
|
||||
else
|
||||
echo -e " ${YELLOW}! 设置可执行权限${NC}"
|
||||
chmod +x "./$script"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# 4. 验证系统依赖
|
||||
echo ""
|
||||
echo -e "${YELLOW}=== 系统依赖验证 ===${NC}"
|
||||
|
||||
COMMANDS=(
|
||||
"docker:Docker"
|
||||
"curl:HTTP 客户端"
|
||||
"ssh:SSH 客户端"
|
||||
"ssh-keygen:SSH 密钥生成"
|
||||
)
|
||||
|
||||
for cmd_info in "${COMMANDS[@]}"; do
|
||||
cmd=$(echo "$cmd_info" | cut -d':' -f1)
|
||||
desc=$(echo "$cmd_info" | cut -d':' -f2)
|
||||
|
||||
echo -n "检查 $desc ($cmd)... "
|
||||
if command -v "$cmd" > /dev/null 2>&1; then
|
||||
version=$(${cmd} --version 2>&1 | head -n1 || echo "版本未知")
|
||||
echo -e "${GREEN}✓ 可用${NC} ($version)"
|
||||
RESULTS+=("PASS: $desc")
|
||||
else
|
||||
echo -e "${RED}✗ 未找到${NC}"
|
||||
RESULTS+=("FAIL: $desc - 命令未找到")
|
||||
fi
|
||||
done
|
||||
|
||||
# 5. 验证网络端口
|
||||
echo ""
|
||||
echo -e "${YELLOW}=== 网络端口验证 ===${NC}"
|
||||
|
||||
DEFAULT_PORTS=(8080 2222)
|
||||
|
||||
for port in "${DEFAULT_PORTS[@]}"; do
|
||||
echo -n "检查端口 $port... "
|
||||
if netstat -tlnp 2>/dev/null | grep -q ":$port "; then
|
||||
echo -e "${YELLOW}! 已被占用${NC}"
|
||||
RESULTS+=("WARN: 端口 $port 已被占用")
|
||||
else
|
||||
echo -e "${GREEN}✓ 可用${NC}"
|
||||
RESULTS+=("PASS: 端口 $port")
|
||||
fi
|
||||
done
|
||||
|
||||
# 6. 创建基本测试文件
|
||||
echo ""
|
||||
echo -e "${YELLOW}=== 创建基本测试文件 ===${NC}"
|
||||
|
||||
# 创建测试网站首页
|
||||
TEST_INDEX="./test_data/hexo_site/index.html"
|
||||
if [ ! -f "$TEST_INDEX" ]; then
|
||||
echo -n "创建测试网站首页... "
|
||||
cat > "$TEST_INDEX" << 'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hexo v0.0.3 Test Site - Linux</title>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 40px; background: #f5f5f5; }
|
||||
.container { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
|
||||
h1 { color: #333; border-bottom: 2px solid #007acc; padding-bottom: 10px; }
|
||||
.info { background: #e7f3ff; padding: 15px; border-radius: 4px; margin: 15px 0; }
|
||||
.status { display: inline-block; padding: 4px 8px; border-radius: 3px; color: white; background: #28a745; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Hexo Container v0.0.3 测试站点 (Linux)</h1>
|
||||
<div class="info">
|
||||
<p><span class="status">运行中</span> 测试环境已就绪</p>
|
||||
<p><strong>平台:</strong> Linux</p>
|
||||
<p><strong>版本:</strong> v0.0.3</p>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('Hexo v0.0.3 测试页面加载完成');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
echo -e "${GREEN}✓ 完成${NC}"
|
||||
RESULTS+=("CREATED: 测试网站首页")
|
||||
else
|
||||
echo -e "测试网站首页... ${GREEN}✓ 已存在${NC}"
|
||||
RESULTS+=("PASS: 测试网站首页")
|
||||
fi
|
||||
|
||||
# 生成 SSH 密钥对
|
||||
SSH_KEY_PATH="./test_data/ssh_keys/test_key"
|
||||
if [ ! -f "$SSH_KEY_PATH" ]; then
|
||||
echo -n "生成 SSH 密钥对... "
|
||||
if ssh-keygen -t rsa -b 4096 -f "$SSH_KEY_PATH" -N "" -q 2>/dev/null; then
|
||||
echo -e "${GREEN}✓ 完成${NC}"
|
||||
RESULTS+=("CREATED: SSH 密钥对")
|
||||
else
|
||||
echo -e "${RED}✗ 失败${NC}"
|
||||
RESULTS+=("FAIL: SSH 密钥对生成失败")
|
||||
fi
|
||||
else
|
||||
echo -e "SSH 密钥对... ${GREEN}✓ 已存在${NC}"
|
||||
RESULTS+=("PASS: SSH 密钥对")
|
||||
fi
|
||||
|
||||
# 显示结果汇总
|
||||
echo ""
|
||||
echo -e "${CYAN}=== 验证结果汇总 ===${NC}"
|
||||
|
||||
PASS_COUNT=0
|
||||
FAIL_COUNT=0
|
||||
WARN_COUNT=0
|
||||
CREATED_COUNT=0
|
||||
|
||||
for result in "${RESULTS[@]}"; do
|
||||
case "$result" in
|
||||
PASS:*)
|
||||
echo -e "${GREEN}✓${NC} ${result#PASS: }"
|
||||
((PASS_COUNT++))
|
||||
;;
|
||||
FAIL:*)
|
||||
echo -e "${RED}✗${NC} ${result#FAIL: }"
|
||||
((FAIL_COUNT++))
|
||||
;;
|
||||
WARN:*)
|
||||
echo -e "${YELLOW}!${NC} ${result#WARN: }"
|
||||
((WARN_COUNT++))
|
||||
;;
|
||||
CREATED:*)
|
||||
echo -e "${BLUE}+${NC} ${result#CREATED: }"
|
||||
((CREATED_COUNT++))
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}=== 统计信息 ===${NC}"
|
||||
echo -e "通过: ${GREEN}$PASS_COUNT${NC}"
|
||||
echo -e "创建: ${BLUE}$CREATED_COUNT${NC}"
|
||||
echo -e "警告: ${YELLOW}$WARN_COUNT${NC}"
|
||||
echo -e "失败: ${RED}$FAIL_COUNT${NC}"
|
||||
|
||||
# 提供建议
|
||||
echo ""
|
||||
echo -e "${CYAN}=== 建议 ===${NC}"
|
||||
|
||||
if [ $FAIL_COUNT -gt 0 ]; then
|
||||
echo -e "${RED}存在失败项,请检查并修复后再运行测试。${NC}"
|
||||
echo ""
|
||||
echo "常见解决方案:"
|
||||
echo "1. 安装 Docker: sudo apt-get install docker.io"
|
||||
echo "2. 安装 curl: sudo apt-get install curl"
|
||||
echo "3. 安装 ssh: sudo apt-get install openssh-client"
|
||||
echo "4. 设置脚本权限: chmod +x *.sh"
|
||||
exit 1
|
||||
elif [ $WARN_COUNT -gt 0 ]; then
|
||||
echo -e "${YELLOW}存在警告项,建议检查但不影响测试运行。${NC}"
|
||||
echo ""
|
||||
echo "如果端口被占用,可以在运行测试时指定其他端口。"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${GREEN}所有检查都通过了!测试环境已就绪。${NC}"
|
||||
echo ""
|
||||
echo "你现在可以运行:"
|
||||
echo " ./start.sh # 完整测试套件"
|
||||
echo " ./build_test.sh # 仅构建测试"
|
||||
echo " ./run_test.sh # 仅运行测试"
|
||||
echo " ./functional_test.sh # 仅功能测试"
|
||||
exit 0
|
||||
fi
|
||||
209
test/v0.0.3/windows/README.md
Normal file
209
test/v0.0.3/windows/README.md
Normal file
@@ -0,0 +1,209 @@
|
||||
# Hexo Container v0.0.3 测试脚本使用说明 (含日志轮转功能)
|
||||
|
||||
本指南详细说明了如何使用针对 Hexo Container v0.0.3 (已验证稳定版) 的 PowerShell 测试脚本套件。
|
||||
|
||||
## v0.0.3 版本核心特性与测试说明
|
||||
|
||||
### 🚀 日志轮转功能 (Log Rotation)
|
||||
v0.0.3 版本新增了自动日志轮转功能,包括:
|
||||
- **智能大小检测** - 当 `deployment.log` 文件达到 1MB 时自动轮转
|
||||
- **自动备份** - 保留最近 5 个轮转文件 (例如 `deployment.log.1.gz`, `deployment.log.2.gz` 等)
|
||||
- **压缩存储** - 自动压缩旧日志文件 (如 `.gz` 格式) 节省空间
|
||||
- **权限管理** - 确保 hexo 用户可正常写入日志及轮转操作
|
||||
- **测试优化** - 相关测试脚本经过优化,可快速验证此功能
|
||||
|
||||
### 📊 测试脚本优化成果 (针对 v0.0.3 测试流程)
|
||||
- **成功率提升** - 测试脚本的整体执行成功率得到提升
|
||||
- **测试速度** - 日志轮转等测试的验证速度加快
|
||||
- **阈值优化** - 日志轮转阈值在测试中调整为 1MB,以加速验证过程
|
||||
- **快速验证** - `log_rotation_test.ps1` 脚本提供快速测试模式,生成少量日志即可验证核心轮转机制
|
||||
|
||||
## 路径修正说明
|
||||
|
||||
本次更新修正了 `test/v0.0.3/windows` 目录下所有测试脚本的路径问题,确保脚本能够:
|
||||
|
||||
1. **正确调用对应文件** - 无论从哪个目录执行脚本
|
||||
2. **正确生成文件** - 所有生成的文件都保存在测试目录及其子目录中
|
||||
3. **使用相对路径** - 提高脚本的可移植性
|
||||
|
||||
## 修正的关键问题
|
||||
|
||||
### 1. 脚本工作目录统一
|
||||
- 所有脚本现在都会自动切换到脚本所在目录作为工作目录
|
||||
- 使用 `$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path` 获取脚本目录
|
||||
- 使用 `Set-Location $ScriptDir` 设置工作目录
|
||||
|
||||
### 2. PowerShell param 块位置修正
|
||||
- 将 `param()` 块移动到脚本最开始
|
||||
- 确保脚本可以正确接收参数
|
||||
|
||||
### 3. 路径引用修正
|
||||
- **Dockerfile 路径**: `../../../Dockerfile_v0.0.3` (相对于测试脚本目录)
|
||||
- **日志目录**: `./logs` (在测试脚本目录下)
|
||||
- **测试数据**: `./test_data` (在测试脚本目录下)
|
||||
- **SSH 密钥**: `./test_data/ssh_keys/test_key`
|
||||
|
||||
### 4. Docker 卷挂载路径修正
|
||||
- 使用 `$ScriptDir` 构建绝对路径进行卷挂载
|
||||
- 确保容器能正确访问主机文件
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
test/v0.0.3/windows/
|
||||
├── build_test.ps1 # 构建测试脚本
|
||||
├── run_test.ps1 # 运行测试脚本
|
||||
├── functional_test.ps1 # 功能测试脚本
|
||||
├── log_rotation_test.ps1 # 🆕 日志轮转测试脚本 (v0.0.3核心新功能)
|
||||
├── test_log_size_reset.ps1 # 🆕 日志大小重置专项测试脚本 (容器重启修复验证)
|
||||
├── cleanup_test.ps1 # 清理测试脚本
|
||||
├── start.ps1 # 一键测试套件
|
||||
├── test_paths.ps1 # 路径验证脚本
|
||||
├── logs/ # 测试日志目录 (自动创建)
|
||||
└── test_data/ # 测试数据目录 (自动创建)
|
||||
├── hexo_site/ # 测试站点文件
|
||||
└── ssh_keys/ # SSH 密钥文件
|
||||
```
|
||||
|
||||
## 🆕 日志轮转测试详解
|
||||
|
||||
### log_rotation_test.ps1 参数
|
||||
- `-FastRotationTest`: 快速轮转测试 (3批次×50条日志,约3KB)
|
||||
- `-QuickLogGen`: 快速日志生成 (5批次×100条日志,约100KB)
|
||||
- `-LogSizeThresholdMB`: 日志大小阈值(MB) (默认: 1)
|
||||
- `-ContainerName`: 容器名称 (默认: hexo-test-v003)
|
||||
|
||||
### test_log_size_reset.ps1 参数 (🆕 容器重启修复验证)
|
||||
- `-ContainerName`: 容器名称 (默认: hexo-test-v003)
|
||||
- `-SshPort`: SSH端口 (默认: 2222)
|
||||
- `-TargetSizeKB`: 目标日志大小(KB) (默认: 25KB,超过20KB阈值)
|
||||
- `-Verbose`: 详细输出模式
|
||||
|
||||
此脚本专门验证容器重启时的日志监控修复功能,确保:
|
||||
- 容器重启后不会重复输出旧的Git部署信息
|
||||
- 日志位置跟踪文件正确工作
|
||||
- 部署日志监控在重启后正常恢复
|
||||
|
||||
### 测试模式说明
|
||||
1. **FastRotationTest** - 验证轮转机制,生成少量日志快速验证
|
||||
2. **QuickLogGen** - 测试日志写入和权限,生成中等量日志
|
||||
3. **默认模式** - 完整测试,生成足够日志触发实际轮转
|
||||
|
||||
### 使用示例
|
||||
```powershell
|
||||
# 快速验证日志轮转机制 (推荐,仅需2分钟)
|
||||
.\log_rotation_test.ps1 -FastRotationTest
|
||||
|
||||
# 测试日志写入功能
|
||||
.\log_rotation_test.ps1 -QuickLogGen
|
||||
|
||||
# 完整日志轮转测试
|
||||
.\log_rotation_test.ps1
|
||||
|
||||
# 自定义日志大小阈值
|
||||
.\log_rotation_test.ps1 -LogSizeThresholdMB 2
|
||||
|
||||
# 🆕 容器重启修复验证测试
|
||||
.\test_log_size_reset.ps1
|
||||
|
||||
# 详细模式运行重启修复测试
|
||||
.\test_log_size_reset.ps1 -Verbose
|
||||
|
||||
# 自定义目标大小测试
|
||||
.\test_log_size_reset.ps1 -TargetSizeKB 30
|
||||
```
|
||||
|
||||
### 测试报告
|
||||
每次测试都会生成详细报告:
|
||||
- **执行日志**: `./logs/log_rotation_test_YYYYMMDD_HHMMSS.log`
|
||||
- **测试报告**: `./logs/log_rotation_test_report_YYYYMMDD_HHMMSS.txt`
|
||||
|
||||
## 使用方式
|
||||
|
||||
### 方式1: 从测试目录运行 (推荐)
|
||||
```powershell
|
||||
cd "c:\Users\Unbal\Desktop\dockerfiledir\test\v0.0.3\windows"
|
||||
.\start.ps1
|
||||
```
|
||||
|
||||
### 方式2: 从任意目录运行
|
||||
```powershell
|
||||
& "c:\Users\Unbal\Desktop\dockerfiledir\test\v0.0.3\windows\start.ps1"
|
||||
```
|
||||
|
||||
### 方式3: 单独运行各个测试
|
||||
```powershell
|
||||
cd "c:\Users\Unbal\Desktop\dockerfiledir\test\v0.0.3\windows"
|
||||
.\build_test.ps1 # 构建镜像
|
||||
.\run_test.ps1 # 启动容器
|
||||
.\functional_test.ps1 # 功能测试
|
||||
.\log_rotation_test.ps1 # 日志轮转测试
|
||||
.\cleanup_test.ps1 # 清理环境
|
||||
```
|
||||
|
||||
## 测试参数
|
||||
|
||||
### start.ps1 参数
|
||||
- `-SkipBuild`: 跳过构建阶段
|
||||
- `-SkipFunctional`: 跳过功能测试
|
||||
- `-SkipLogRotation`: 跳过日志轮转测试
|
||||
- `-CleanupAfter`: 测试后自动清理
|
||||
- `-Tag`: 镜像标签 (默认: hexo-test:v0.0.3)
|
||||
- `-ContainerName`: 容器名称 (默认: hexo-test-v003)
|
||||
- `-HttpPort`: HTTP端口 (默认: 8080)
|
||||
- `-SshPort`: SSH端口 (默认: 2222)
|
||||
|
||||
### 使用示例
|
||||
```powershell
|
||||
# 完整测试 (包含构建和清理)
|
||||
.\start.ps1 -CleanupAfter
|
||||
|
||||
# 跳过构建,只测试功能
|
||||
.\start.ps1 -SkipBuild
|
||||
|
||||
# 自定义端口
|
||||
.\start.ps1 -HttpPort 9999 -SshPort 3333
|
||||
```
|
||||
|
||||
## 验证路径配置
|
||||
|
||||
运行路径验证脚本检查配置:
|
||||
```powershell
|
||||
.\test_paths.ps1
|
||||
```
|
||||
|
||||
此脚本会检查所有关键路径是否正确,并自动创建必需的目录。
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **权限要求**: 需要管理员权限运行 Docker 命令
|
||||
2. **端口冲突**: 确保指定的端口 (如 8080, 2222) 未被占用
|
||||
3. **SSH 密钥**: 测试脚本 (`run_test.ps1`) 会优先尝试从用户 `~/.ssh/` 目录或测试子目录 `test_data/ssh_keys/` 中使用现有的 `test_key` (或 `id_rsa`)。如果找不到这些密钥,脚本会自动生成新的密钥对用于测试,并存放于 `test_data/ssh_keys/`。
|
||||
4. **Docker 环境**: 确保 Docker Desktop 正在运行
|
||||
5. **日志清理**: `cleanup_test.ps1` 或 `start.ps1 -CleanupAfter` 会清理测试容器和镜像。测试脚本自身产生的日志默认保留在 `logs` 目录下。
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 权限错误
|
||||
```powershell
|
||||
# 以管理员身份运行 PowerShell
|
||||
Start-Process powershell -Verb RunAs
|
||||
```
|
||||
|
||||
### 路径不存在错误
|
||||
```powershell
|
||||
# 运行路径验证
|
||||
.\test_paths.ps1
|
||||
```
|
||||
|
||||
### Docker 连接错误
|
||||
```powershell
|
||||
# 检查 Docker 状态
|
||||
docker version
|
||||
```
|
||||
|
||||
### 端口占用错误
|
||||
```powershell
|
||||
# 查看端口占用
|
||||
netstat -ano | findstr :8080
|
||||
```
|
||||
125
test/v0.0.3/windows/build_test.ps1
Normal file
125
test/v0.0.3/windows/build_test.ps1
Normal file
@@ -0,0 +1,125 @@
|
||||
# Hexo Container v0.0.3 构建测试脚本 (Windows)
|
||||
# build_test.ps1
|
||||
|
||||
param(
|
||||
[string]$Tag = "hexo-test:v0.0.3",
|
||||
[string]$Platform = "linux/amd64",
|
||||
[string]$DockerfilePath = "..\..\..\Dockerfile_v0.0.3"
|
||||
)
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
Set-Location $ScriptDir
|
||||
|
||||
Write-Host "=== Hexo Container v0.0.3 构建测试 ===" -ForegroundColor Cyan
|
||||
Write-Host "镜像标签: $Tag" -ForegroundColor Green
|
||||
Write-Host "平台架构: $Platform" -ForegroundColor Green
|
||||
Write-Host "Dockerfile: $DockerfilePath" -ForegroundColor Green
|
||||
|
||||
# 检查 Dockerfile 是否存在
|
||||
if (-not (Test-Path $DockerfilePath)) {
|
||||
Write-Host "错误: Dockerfile 不存在: $DockerfilePath" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 创建日志目录
|
||||
$LogDir = ".\logs"
|
||||
if (-not (Test-Path $LogDir)) {
|
||||
New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# 如果这是独立运行的构建测试,清理旧的构建测试文件
|
||||
if ($MyInvocation.ScriptName -eq $PSCommandPath) {
|
||||
Write-Host "=== 清理旧的构建测试文件 ===" -ForegroundColor Cyan
|
||||
$OldLogsDir = "$LogDir\old"
|
||||
if (-not (Test-Path $OldLogsDir)) {
|
||||
New-Item -ItemType Directory -Path $OldLogsDir -Force | Out-Null
|
||||
Write-Host "创建旧日志归档目录: $OldLogsDir" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# 移动旧的构建测试文件到 old 文件夹
|
||||
$OldBuildFiles = Get-ChildItem $LogDir -File | Where-Object {
|
||||
$_.Name -match "build_.*\.log$"
|
||||
}
|
||||
|
||||
if ($OldBuildFiles.Count -gt 0) {
|
||||
Write-Host "归档 $($OldBuildFiles.Count) 个旧构建测试文件到 old 文件夹..." -ForegroundColor Gray
|
||||
foreach ($file in $OldBuildFiles) {
|
||||
$destPath = Join-Path $OldLogsDir $file.Name
|
||||
Move-Item $file.FullName $destPath -Force
|
||||
Write-Host " 移动: $($file.Name)" -ForegroundColor Gray
|
||||
}
|
||||
} else {
|
||||
Write-Host "没有旧的构建测试文件需要归档" -ForegroundColor Gray
|
||||
}
|
||||
}
|
||||
|
||||
# 记录开始时间
|
||||
$StartTime = Get-Date
|
||||
$LogFile = "$LogDir\build_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
|
||||
|
||||
Write-Host "构建开始时间: $StartTime" -ForegroundColor Yellow
|
||||
Write-Host "日志文件: $LogFile" -ForegroundColor Yellow
|
||||
|
||||
# 执行构建
|
||||
Write-Host "`n开始构建镜像..." -ForegroundColor Yellow
|
||||
|
||||
try {
|
||||
# 获取 Dockerfile 的绝对路径
|
||||
$DockerfileAbsPath = Join-Path $ScriptDir $DockerfilePath
|
||||
$DockerContext = Split-Path $DockerfileAbsPath -Parent
|
||||
|
||||
$BuildCmd = "docker build -f `"$DockerfileAbsPath`" -t $Tag --platform $Platform `"$DockerContext`""
|
||||
Write-Host "执行命令: $BuildCmd" -ForegroundColor Gray
|
||||
|
||||
# 执行构建并捕获输出
|
||||
$BuildOutput = Invoke-Expression $BuildCmd 2>&1
|
||||
$BuildOutput | Out-File -FilePath $LogFile -Encoding UTF8
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
$EndTime = Get-Date
|
||||
$Duration = $EndTime - $StartTime
|
||||
|
||||
Write-Host "`n=== 构建成功 ===" -ForegroundColor Green
|
||||
Write-Host "构建结束时间: $EndTime" -ForegroundColor Green
|
||||
Write-Host "构建耗时: $($Duration.TotalMinutes.ToString('F2')) 分钟" -ForegroundColor Green
|
||||
|
||||
# 显示镜像信息
|
||||
Write-Host "`n=== 镜像信息 ===" -ForegroundColor Cyan
|
||||
docker images $Tag
|
||||
|
||||
# 显示镜像详细信息
|
||||
Write-Host "`n=== 镜像详细信息 ===" -ForegroundColor Cyan
|
||||
$ImageInfo = docker inspect $Tag | ConvertFrom-Json
|
||||
$ImageSize = [math]::Round($ImageInfo[0].Size / 1MB, 2)
|
||||
Write-Host "镜像大小: $ImageSize MB" -ForegroundColor Green
|
||||
Write-Host "创建时间: $($ImageInfo[0].Created)" -ForegroundColor Green
|
||||
Write-Host "架构: $($ImageInfo[0].Architecture)" -ForegroundColor Green
|
||||
|
||||
# 输出构建统计
|
||||
Write-Host "`n=== 构建统计 ===" -ForegroundColor Cyan
|
||||
$LayerCount = ($BuildOutput | Select-String "^Step \d+/\d+").Count
|
||||
Write-Host "构建步骤数: $LayerCount" -ForegroundColor Green
|
||||
|
||||
return $true
|
||||
} else {
|
||||
throw "Docker build 命令执行失败"
|
||||
}
|
||||
} catch {
|
||||
Write-Host "`n=== 构建失败 ===" -ForegroundColor Red
|
||||
Write-Host "错误信息: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Write-Host "详细日志请查看: $LogFile" -ForegroundColor Red
|
||||
|
||||
# 显示最后几行日志
|
||||
if (Test-Path $LogFile) {
|
||||
Write-Host "`n=== 最后10行构建日志 ===" -ForegroundColor Yellow
|
||||
Get-Content $LogFile | Select-Object -Last 10 | ForEach-Object {
|
||||
Write-Host $_ -ForegroundColor Gray
|
||||
}
|
||||
}
|
||||
|
||||
return $false
|
||||
}
|
||||
|
||||
Write-Host "`n构建测试完成。" -ForegroundColor Cyan
|
||||
Write-Host "详细日志保存在: $LogFile" -ForegroundColor Gray
|
||||
308
test/v0.0.3/windows/cleanup_test.ps1
Normal file
308
test/v0.0.3/windows/cleanup_test.ps1
Normal file
@@ -0,0 +1,308 @@
|
||||
# Hexo Container v0.0.3 清理脚本
|
||||
# cleanup_test.ps1 - 清理测试环境和资源
|
||||
|
||||
param(
|
||||
[switch]$Force = $false,
|
||||
[switch]$KeepImages = $false,
|
||||
[switch]$KeepLogs = $false,
|
||||
[switch]$DeepClean = $false,
|
||||
[string]$ContainerName = "hexo-test-v003*",
|
||||
[string]$ImageTag = "hexo*",
|
||||
[switch]$Interactive = $true
|
||||
)
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
Set-Location $ScriptDir
|
||||
|
||||
Write-Host "=== Hexo Container v0.0.3 清理脚本 ===" -ForegroundColor Cyan
|
||||
Write-Host "此脚本将清理测试环境中的容器、镜像和日志文件" -ForegroundColor Gray
|
||||
|
||||
# 获取时间戳用于备份
|
||||
$TimeStamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||||
|
||||
# 创建清理日志
|
||||
$LogDir = ".\logs"
|
||||
if (-not (Test-Path $LogDir)) {
|
||||
New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
|
||||
}
|
||||
$CleanupLog = "$LogDir\cleanup_$TimeStamp.log"
|
||||
|
||||
# 记录清理开始
|
||||
"=== 清理操作开始 $(Get-Date) ===" | Add-Content $CleanupLog
|
||||
|
||||
# 函数:安全确认
|
||||
function Confirm-Action {
|
||||
param([string]$Message, [switch]$Force)
|
||||
|
||||
if ($Force) {
|
||||
Write-Host "FORCE 模式: $Message" -ForegroundColor Yellow
|
||||
return $true
|
||||
}
|
||||
|
||||
if (-not $Interactive) {
|
||||
return $true
|
||||
}
|
||||
|
||||
Write-Host "$Message" -ForegroundColor Yellow
|
||||
$response = Read-Host "继续吗? (y/N)"
|
||||
return ($response -eq "y" -or $response -eq "Y" -or $response -eq "yes")
|
||||
}
|
||||
|
||||
# 函数:停止并删除容器
|
||||
function Remove-TestContainers {
|
||||
param([string]$Pattern, [bool]$Force)
|
||||
|
||||
Write-Host "`n=== 清理容器 ===" -ForegroundColor Cyan
|
||||
|
||||
# 获取匹配的容器
|
||||
$Containers = docker ps -a --filter "name=$Pattern" --format "{{.Names}}" 2>$null
|
||||
|
||||
if (-not $Containers) {
|
||||
Write-Host "未找到匹配的容器: $Pattern" -ForegroundColor Green
|
||||
"未找到匹配的容器: $Pattern" | Add-Content $CleanupLog
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "找到以下容器:" -ForegroundColor Gray
|
||||
$Containers | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
|
||||
if (Confirm-Action "删除这些容器?" -Force:$Force) {
|
||||
foreach ($container in $Containers) {
|
||||
Write-Host "停止容器: $container" -ForegroundColor Yellow
|
||||
docker stop $container 2>$null | Out-Null
|
||||
|
||||
Write-Host "删除容器: $container" -ForegroundColor Yellow
|
||||
docker rm $container 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "SUCCESS: 容器 $container 已删除" -ForegroundColor Green
|
||||
"SUCCESS: 容器 $container 已删除" | Add-Content $CleanupLog
|
||||
} else {
|
||||
Write-Host "ERROR: 删除容器 $container 失败" -ForegroundColor Red
|
||||
"ERROR: 删除容器 $container 失败" | Add-Content $CleanupLog
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Host "用户取消了容器清理操作" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
# 函数:删除镜像
|
||||
function Remove-TestImages {
|
||||
param([string]$Pattern, [bool]$Force)
|
||||
|
||||
Write-Host "`n=== 清理镜像 ===" -ForegroundColor Cyan
|
||||
|
||||
# 获取匹配的镜像
|
||||
$Images = docker images --filter "reference=$Pattern" --format "{{.Repository}}:{{.Tag}}" 2>$null
|
||||
|
||||
if (-not $Images) {
|
||||
Write-Host "未找到匹配的镜像: $Pattern" -ForegroundColor Green
|
||||
"未找到匹配的镜像: $Pattern" | Add-Content $CleanupLog
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "找到以下镜像:" -ForegroundColor Gray
|
||||
$Images | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
|
||||
if (Confirm-Action "删除这些镜像?" -Force:$Force) {
|
||||
foreach ($image in $Images) {
|
||||
Write-Host "删除镜像: $image" -ForegroundColor Yellow
|
||||
docker rmi $image 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "SUCCESS: 镜像 $image 已删除" -ForegroundColor Green
|
||||
"SUCCESS: 镜像 $image 已删除" | Add-Content $CleanupLog
|
||||
} else {
|
||||
Write-Host "WARNING: 删除镜像 $image 失败(可能被其他容器使用)" -ForegroundColor Yellow
|
||||
"WARNING: 删除镜像 $image 失败" | Add-Content $CleanupLog
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Host "用户取消了镜像清理操作" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
# 函数:清理日志文件
|
||||
function Remove-TestLogs {
|
||||
param([bool]$Force, [bool]$DeepClean)
|
||||
|
||||
Write-Host "`n=== 清理日志文件 ===" -ForegroundColor Cyan
|
||||
|
||||
# 检查日志目录
|
||||
if (-not (Test-Path $LogDir)) {
|
||||
Write-Host "日志目录不存在: $LogDir" -ForegroundColor Green
|
||||
return
|
||||
}
|
||||
|
||||
# 获取日志文件
|
||||
$LogFiles = Get-ChildItem $LogDir -File -Recurse | Where-Object {
|
||||
$_.Extension -eq ".log" -or $_.Extension -eq ".txt"
|
||||
}
|
||||
|
||||
if (-not $LogFiles) {
|
||||
Write-Host "未找到日志文件" -ForegroundColor Green
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "找到 $($LogFiles.Count) 个日志文件" -ForegroundColor Gray
|
||||
|
||||
if ($DeepClean) {
|
||||
# 深度清理:删除所有日志文件
|
||||
if (Confirm-Action "深度清理:删除所有日志文件?" -Force:$Force) {
|
||||
$LogFiles | ForEach-Object {
|
||||
Write-Host "删除: $($_.Name)" -ForegroundColor Gray
|
||||
Remove-Item $_.FullName -Force
|
||||
}
|
||||
Write-Host "SUCCESS: 所有日志文件已删除" -ForegroundColor Green
|
||||
"SUCCESS: 深度清理完成,删除了 $($LogFiles.Count) 个日志文件" | Add-Content $CleanupLog
|
||||
}
|
||||
} else {
|
||||
# 普通清理:归档旧日志文件
|
||||
$OldLogsDir = "$LogDir\old_$TimeStamp"
|
||||
|
||||
if (Confirm-Action "将日志文件归档到 old_$TimeStamp 文件夹?" -Force:$Force) {
|
||||
New-Item -ItemType Directory -Path $OldLogsDir -Force | Out-Null
|
||||
|
||||
$LogFiles | ForEach-Object {
|
||||
if ($_.Name -ne "cleanup_$TimeStamp.log") { # 保留当前清理日志
|
||||
Write-Host "归档: $($_.Name)" -ForegroundColor Gray
|
||||
Move-Item $_.FullName $OldLogsDir -Force
|
||||
}
|
||||
}
|
||||
Write-Host "SUCCESS: 日志文件已归档到 $OldLogsDir" -ForegroundColor Green
|
||||
"SUCCESS: 日志文件已归档到 $OldLogsDir" | Add-Content $CleanupLog
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 函数:清理SSH密钥
|
||||
function Remove-TestSSHKeys {
|
||||
param([bool]$Force)
|
||||
|
||||
Write-Host "`n=== 清理SSH密钥 ===" -ForegroundColor Cyan
|
||||
|
||||
$SshKeyDir = ".\test_data\ssh_keys"
|
||||
if (-not (Test-Path $SshKeyDir)) {
|
||||
Write-Host "SSH密钥目录不存在: $SshKeyDir" -ForegroundColor Green
|
||||
return
|
||||
}
|
||||
|
||||
# 查找临时生成的密钥文件
|
||||
$TempKeys = Get-ChildItem $SshKeyDir -File | Where-Object {
|
||||
$_.Name -match "temp_" -or $_.Name -match "test_key" -or $_.Name -match "container_key"
|
||||
}
|
||||
|
||||
if (-not $TempKeys) {
|
||||
Write-Host "未找到临时SSH密钥文件" -ForegroundColor Green
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "找到以下临时SSH密钥:" -ForegroundColor Gray
|
||||
$TempKeys | ForEach-Object { Write-Host " $($_.Name)" -ForegroundColor Gray }
|
||||
|
||||
if (Confirm-Action "删除这些临时SSH密钥?" -Force:$Force) {
|
||||
$TempKeys | ForEach-Object {
|
||||
Write-Host "删除: $($_.Name)" -ForegroundColor Gray
|
||||
Remove-Item $_.FullName -Force
|
||||
}
|
||||
Write-Host "SUCCESS: 临时SSH密钥已删除" -ForegroundColor Green
|
||||
"SUCCESS: 删除了 $($TempKeys.Count) 个临时SSH密钥" | Add-Content $CleanupLog
|
||||
}
|
||||
}
|
||||
|
||||
# 函数:Docker系统清理
|
||||
function Invoke-DockerSystemClean {
|
||||
param([bool]$Force)
|
||||
|
||||
Write-Host "`n=== Docker系统清理 ===" -ForegroundColor Cyan
|
||||
|
||||
if (Confirm-Action "执行 docker system prune 清理未使用的资源?" -Force:$Force) {
|
||||
Write-Host "执行 docker system prune..." -ForegroundColor Yellow
|
||||
docker system prune -f 2>$null
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "SUCCESS: Docker系统清理完成" -ForegroundColor Green
|
||||
"SUCCESS: Docker系统清理完成" | Add-Content $CleanupLog
|
||||
} else {
|
||||
Write-Host "WARNING: Docker系统清理失败" -ForegroundColor Yellow
|
||||
"WARNING: Docker系统清理失败" | Add-Content $CleanupLog
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 主清理流程
|
||||
Write-Host "`n开始清理操作..." -ForegroundColor Yellow
|
||||
|
||||
# 1. 清理容器
|
||||
Remove-TestContainers -Pattern $ContainerName -Force $Force
|
||||
|
||||
# 2. 清理镜像(如果不保留)
|
||||
if (-not $KeepImages) {
|
||||
Remove-TestImages -Pattern $ImageTag -Force $Force
|
||||
}
|
||||
|
||||
# 3. 清理日志文件(如果不保留)
|
||||
if (-not $KeepLogs) {
|
||||
Remove-TestLogs -Force $Force -DeepClean $DeepClean
|
||||
}
|
||||
|
||||
# 4. 清理SSH密钥
|
||||
Remove-TestSSHKeys -Force $Force
|
||||
|
||||
# 5. Docker系统清理(如果深度清理)
|
||||
if ($DeepClean) {
|
||||
Invoke-DockerSystemClean -Force $Force
|
||||
}
|
||||
|
||||
# 显示清理结果
|
||||
Write-Host "`n=== 清理完成 ===" -ForegroundColor Cyan
|
||||
|
||||
# 检查剩余资源
|
||||
Write-Host "`n剩余资源状态:" -ForegroundColor Gray
|
||||
|
||||
Write-Host " 容器:" -ForegroundColor Gray
|
||||
$RemainingContainers = docker ps -a --filter "name=hexo*" --format "{{.Names}}" 2>$null
|
||||
if ($RemainingContainers) {
|
||||
$RemainingContainers | ForEach-Object { Write-Host " $_" -ForegroundColor Yellow }
|
||||
} else {
|
||||
Write-Host " 无相关容器" -ForegroundColor Green
|
||||
}
|
||||
|
||||
Write-Host " 镜像:" -ForegroundColor Gray
|
||||
$RemainingImages = docker images --filter "reference=hexo*" --format "{{.Repository}}:{{.Tag}}" 2>$null
|
||||
if ($RemainingImages) {
|
||||
$RemainingImages | ForEach-Object { Write-Host " $_" -ForegroundColor Yellow }
|
||||
} else {
|
||||
Write-Host " 无相关镜像" -ForegroundColor Green
|
||||
}
|
||||
|
||||
Write-Host " 日志文件:" -ForegroundColor Gray
|
||||
if (Test-Path $LogDir) {
|
||||
$RemainingLogs = Get-ChildItem $LogDir -File -Recurse | Where-Object {
|
||||
$_.Extension -eq ".log" -or $_.Extension -eq ".txt"
|
||||
}
|
||||
if ($RemainingLogs) {
|
||||
Write-Host " $($RemainingLogs.Count) 个文件" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host " 无日志文件" -ForegroundColor Green
|
||||
}
|
||||
} else {
|
||||
Write-Host " 无日志目录" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# 记录清理完成
|
||||
"=== 清理操作完成 $(Get-Date) ===" | Add-Content $CleanupLog
|
||||
|
||||
Write-Host "`n清理日志: $CleanupLog" -ForegroundColor Gray
|
||||
Write-Host "清理操作完成!" -ForegroundColor Green
|
||||
|
||||
# 用法提示
|
||||
Write-Host "`n用法示例:" -ForegroundColor Cyan
|
||||
Write-Host " .\cleanup_test.ps1 # 交互式清理" -ForegroundColor Gray
|
||||
Write-Host " .\cleanup_test.ps1 -Force # 强制清理,无确认" -ForegroundColor Gray
|
||||
Write-Host " .\cleanup_test.ps1 -KeepImages # 保留镜像" -ForegroundColor Gray
|
||||
Write-Host " .\cleanup_test.ps1 -KeepLogs # 保留日志" -ForegroundColor Gray
|
||||
Write-Host " .\cleanup_test.ps1 -DeepClean # 深度清理" -ForegroundColor Gray
|
||||
Write-Host " .\cleanup_test.ps1 -Force -DeepClean # 强制深度清理" -ForegroundColor Gray
|
||||
438
test/v0.0.3/windows/functional_test.ps1
Normal file
438
test/v0.0.3/windows/functional_test.ps1
Normal file
@@ -0,0 +1,438 @@
|
||||
# Hexo Container v0.0.3 功能测试脚本 (Windows)
|
||||
# functional_test.ps1
|
||||
|
||||
param(
|
||||
[string]$ContainerName = "hexo-test-v003",
|
||||
[int]$HttpPort = 8080, # Corrected port back to 8080 to match run_test.ps1
|
||||
[int]$SshPort = 2222,
|
||||
[string]$SshKeyPath = ".\\test_data\\ssh_keys\\test_key",
|
||||
[boolean]$SshDebug = $false # 新增 SshDebug 参数,默认为 false
|
||||
)
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
Set-Location $ScriptDir
|
||||
|
||||
# 确保 SSH 密钥路径为绝对路径
|
||||
$SshKeyPath = Join-Path $ScriptDir "test_data\ssh_keys\test_key"
|
||||
|
||||
Write-Host "=== Hexo Container v0.0.3 功能测试 ===" -ForegroundColor Cyan
|
||||
|
||||
# 创建日志文件
|
||||
$LogDir = ".\logs"
|
||||
if (-not (Test-Path $LogDir)) {
|
||||
New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# 如果这是独立运行的功能测试,清理旧的功能测试文件
|
||||
if ($MyInvocation.ScriptName -eq $PSCommandPath) {
|
||||
Write-Host "=== 清理旧的功能测试文件 ===" -ForegroundColor Cyan
|
||||
$OldLogsDir = "$LogDir\old"
|
||||
if (-not (Test-Path $OldLogsDir)) {
|
||||
New-Item -ItemType Directory -Path $OldLogsDir -Force | Out-Null
|
||||
Write-Host "创建旧日志归档目录: $OldLogsDir" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# 移动旧的功能测试文件到 old 文件夹
|
||||
$OldFunctionalFiles = Get-ChildItem $LogDir -File | Where-Object {
|
||||
$_.Name -match "functional_test_.*\.(log|txt)$"
|
||||
}
|
||||
|
||||
if ($OldFunctionalFiles.Count -gt 0) {
|
||||
Write-Host "归档 $($OldFunctionalFiles.Count) 个旧功能测试文件到 old 文件夹..." -ForegroundColor Gray
|
||||
foreach ($file in $OldFunctionalFiles) {
|
||||
$destPath = Join-Path $OldLogsDir $file.Name
|
||||
Move-Item $file.FullName $destPath -Force
|
||||
Write-Host " 移动: $($file.Name)" -ForegroundColor Gray
|
||||
}
|
||||
} else {
|
||||
Write-Host "没有旧的功能测试文件需要归档" -ForegroundColor Gray
|
||||
}
|
||||
}
|
||||
|
||||
$TestLog = "$LogDir\functional_test_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
|
||||
$TestResults = @()
|
||||
|
||||
# 测试函数
|
||||
function Test-Function {
|
||||
param(
|
||||
[string]$TestName,
|
||||
[scriptblock]$TestScript,
|
||||
[string]$Description
|
||||
)
|
||||
|
||||
Write-Host "`n=== $TestName ===" -ForegroundColor Yellow
|
||||
Write-Host "$Description" -ForegroundColor Gray
|
||||
|
||||
$StartTime = Get-Date
|
||||
try {
|
||||
$Result = & $TestScript
|
||||
Write-Host "Debug: Test '$TestName', ScriptBlock returned: '$Result' (Type: $($Result.GetType().FullName))" -ForegroundColor Magenta # DEBUG LINE
|
||||
$EndTime = Get-Date
|
||||
$Duration = ($EndTime - $StartTime).TotalSeconds
|
||||
|
||||
if ($Result) {
|
||||
Write-Host "✅ $TestName 通过 ($($Duration.ToString('F2'))s)" -ForegroundColor Green
|
||||
$Status = "PASS"
|
||||
} else {
|
||||
Write-Host "❌ $TestName 失败 ($($Duration.ToString('F2'))s)" -ForegroundColor Red
|
||||
$Status = "FAIL"
|
||||
}
|
||||
} catch {
|
||||
$EndTime = Get-Date
|
||||
$Duration = ($EndTime - $StartTime).TotalSeconds
|
||||
Write-Host "❌ $TestName 异常: $($_.Exception.Message) ($($Duration.ToString('F2'))s)" -ForegroundColor Red
|
||||
$Status = "ERROR" }
|
||||
$Script:TestResults += [PSCustomObject]@{
|
||||
TestName = $TestName
|
||||
Status = $Status
|
||||
Duration = $Duration
|
||||
Timestamp = $StartTime
|
||||
}
|
||||
|
||||
# 记录到日志文件
|
||||
"[$($StartTime.ToString('yyyy-MM-dd HH:mm:ss'))] $TestName - $Status ($($Duration.ToString('F2'))s)" | Add-Content $TestLog
|
||||
}
|
||||
|
||||
# 检查容器是否运行
|
||||
Write-Host "检查容器状态..." -ForegroundColor Yellow
|
||||
$ContainerRunning = docker ps --filter "name=$ContainerName" --format "{{.Names}}" | Select-String $ContainerName
|
||||
if (-not $ContainerRunning) {
|
||||
Write-Host "❌ 容器 $ContainerName 未运行,请先运行 run_test.ps1" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
Write-Host "✅ 容器正在运行" -ForegroundColor Green
|
||||
|
||||
# 测试 1: HTTP 服务基础测试
|
||||
Test-Function "HTTP服务基础测试" {
|
||||
try {
|
||||
$Response = Invoke-WebRequest -Uri "http://localhost:$HttpPort" -TimeoutSec 10
|
||||
return $Response.StatusCode -eq 200
|
||||
} catch {
|
||||
Write-Host "HTTP 请求失败: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
} "测试主页是否可以正常访问"
|
||||
|
||||
# 测试 2: 健康检查端点测试
|
||||
Test-Function "健康检查端点测试" {
|
||||
try {
|
||||
$Response = Invoke-WebRequest -Uri "http://localhost:$HttpPort/health" -TimeoutSec 5
|
||||
# 修复: 正确处理响应内容
|
||||
$Content = if ($Response.Content -is [byte[]]) {
|
||||
[System.Text.Encoding]::UTF8.GetString($Response.Content).Trim()
|
||||
} else {
|
||||
$Response.Content.ToString().Trim()
|
||||
}
|
||||
return $Response.StatusCode -eq 200 -and ($Content -eq "healthy" -or $Content -eq "OK")
|
||||
} catch {
|
||||
Write-Host "健康检查请求失败: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
} "测试 /health 端点是否返回正确响应"
|
||||
|
||||
# 测试 3: SSH 服务连接测试
|
||||
Test-Function "SSH服务连接测试" {
|
||||
if (-not (Test-Path $SshKeyPath)) {
|
||||
Write-Host "SSH 密钥不存在: $SshKeyPath" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
|
||||
try {
|
||||
Write-Host "Attempting to remove [localhost]:$SshPort from known_hosts" -ForegroundColor DarkGray
|
||||
ssh-keygen -R "[localhost]:$SshPort" | Out-Null # Suppress normal output, errors will still show
|
||||
|
||||
$SshRemoteCommand = "`"echo \'SSH_SUCCESS\'`""
|
||||
$SshVerbosityArgs = ""
|
||||
|
||||
if ($SshDebug) {
|
||||
$SshVerbosityArgs = "-vvv"
|
||||
Write-Host "SshDebug is ON, using verbose SSH output for connection test." -ForegroundColor DarkGray
|
||||
} else {
|
||||
$SshVerbosityArgs = "-q -o LogLevel=ERROR"
|
||||
}
|
||||
|
||||
$SshCommand = "ssh $SshVerbosityArgs -p $SshPort -i `"$SshKeyPath`" -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null hexo@localhost $SshRemoteCommand"
|
||||
|
||||
if ($SshDebug) { # Print command if debug is on
|
||||
Write-Host "Executing SSH command (Connection Test): $SshCommand" -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
$SshOutput = Invoke-Expression $SshCommand 2>&1
|
||||
$CurrentExitCode = $LASTEXITCODE
|
||||
|
||||
if ($SshDebug) {
|
||||
Write-Host "SSH command (Connection Test) executed. Exit code: $CurrentExitCode" -ForegroundColor DarkGray
|
||||
Write-Host "SSH output (raw):`n--BEGIN SSH OUTPUT--`n$SshOutput`n--END SSH OUTPUT--`n" -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
if ($CurrentExitCode -ne 0) {
|
||||
Write-Host "SSH command failed with non-zero exit code: $CurrentExitCode." -ForegroundColor Red
|
||||
if (-not $SshDebug -and $SshOutput) { # 如果不是调试模式且有输出,则显示输出
|
||||
Write-Host "SSH output (Error):`n$SshOutput" -ForegroundColor DarkGray
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
if ($SshOutput -match "SSH_SUCCESS") {
|
||||
Write-Host "SSH command successful (exit code 0) and output matched \'SSH_SUCCESS\'." -ForegroundColor Green
|
||||
return $true
|
||||
} else {
|
||||
Write-Host "SSH command succeeded (exit code 0), but output did not contain \'SSH_SUCCESS\'." -ForegroundColor Red
|
||||
if (-not $SshDebug -and $SshOutput) { # 如果不是调试模式且有输出,则显示输出
|
||||
Write-Host "SSH output (Unexpected):`n$SshOutput" -ForegroundColor DarkGray
|
||||
}
|
||||
return $false
|
||||
}
|
||||
} catch {
|
||||
Write-Host "SSH 连接测试中发生异常: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
} "测试 SSH 服务是否可以正常连接"
|
||||
|
||||
# 测试 4: Git 仓库初始化测试
|
||||
Test-Function "Git仓库初始化测试" {
|
||||
try {
|
||||
$GitCommandRaw = "test -d /home/hexo/hexo.git && echo 'GIT_REPO_EXISTS'"
|
||||
$GitCommand = $GitCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$GitOutput = docker exec $ContainerName bash -c $GitCommand 2>$null
|
||||
|
||||
return ($GitOutput -match "GIT_REPO_EXISTS") # Changed to -match
|
||||
} catch {
|
||||
Write-Host "Git 仓库检查失败: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
} "检查 Git 裸仓库是否正确初始化"
|
||||
|
||||
# 测试 5: 部署钩子测试
|
||||
Test-Function "部署钩子测试" {
|
||||
try {
|
||||
$HookCommandRaw = "test -f /home/hexo/hexo.git/hooks/post-receive && echo 'HOOK_EXISTS'"
|
||||
$HookCommand = $HookCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$HookOutput = docker exec $ContainerName bash -c $HookCommand 2>$null
|
||||
if ($HookOutput -match "HOOK_EXISTS") { # Changed to -match
|
||||
# 检查钩子是否可执行
|
||||
$HookExecCommandRaw = "test -x /home/hexo/hexo.git/hooks/post-receive && echo 'HOOK_EXECUTABLE'"
|
||||
$HookExecCommand = $HookExecCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$HookExecOutput = docker exec $ContainerName bash -c $HookExecCommand 2>$null
|
||||
return ($HookExecOutput -match "HOOK_EXECUTABLE") # Changed to -match
|
||||
}
|
||||
return $false
|
||||
} catch {
|
||||
Write-Host "部署钩子检查失败: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
} "检查 Git post-receive 钩子是否正确配置"
|
||||
|
||||
# 测试 6: 文件权限测试
|
||||
Test-Function "文件权限测试" {
|
||||
try {
|
||||
# 检查 hexo 用户权限
|
||||
$PermCommandRaw = "su - hexo -c 'whoami'"
|
||||
$PermCommand = $PermCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$PermOutput = docker exec $ContainerName bash -c $PermCommand 2>$null
|
||||
if ($PermOutput -match "hexo") { # Changed to -match
|
||||
# 检查网站目录权限
|
||||
$WebDirCommandRaw = "su - hexo -c 'test -w /home/www/hexo && echo WRITABLE'"
|
||||
$WebDirCommand = $WebDirCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$WebDirOutput = docker exec $ContainerName bash -c $WebDirCommand 2>$null
|
||||
return ($WebDirOutput -match "WRITABLE") # Changed to -match
|
||||
}
|
||||
return $false
|
||||
} catch {
|
||||
Write-Host "权限检查失败: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
} "检查用户权限和目录访问权限"
|
||||
|
||||
# 测试 7: 日志文件权限测试 (v0.0.3 新功能)
|
||||
Test-Function "日志文件权限测试" {
|
||||
try {
|
||||
# 检查日志文件是否存在且属于 hexo 用户
|
||||
$LogFileCheckCommandRaw = "LANG=C ls -la /var/log/container/deployment.log"
|
||||
$LogFileCheckCommand = $LogFileCheckCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$LogFileCheck = docker exec $ContainerName bash -c $LogFileCheckCommand 2>$null
|
||||
if ($LogFileCheck -match "hexo.*hexo") {
|
||||
# 测试 hexo 用户是否可以写入日志
|
||||
$WriteTestCommandRaw = "su - hexo -c 'echo TEST_WRITE >> /var/log/container/deployment.log && echo WRITE_SUCCESS'"
|
||||
$WriteTestCommand = $WriteTestCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$WriteTest = docker exec $ContainerName bash -c $WriteTestCommand 2>$null
|
||||
return ($WriteTest -match "WRITE_SUCCESS") # Changed to -match
|
||||
}
|
||||
Write-Host "日志文件权限检查失败: 文件不属于 hexo 用户" -ForegroundColor Red
|
||||
return $false
|
||||
} catch {
|
||||
Write-Host "日志权限检查失败: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
} "测试 hexo 用户对部署日志文件的写入权限 (v0.0.3 新功能)"
|
||||
|
||||
# 测试 8: 模拟 Git 部署测试
|
||||
Test-Function "模拟Git部署测试" {
|
||||
if (-not (Test-Path $SshKeyPath)) {
|
||||
Write-Host "SSH 密钥不存在,跳过部署测试" -ForegroundColor Yellow
|
||||
return $false # Return false to indicate test did not pass
|
||||
}
|
||||
|
||||
try {
|
||||
Write-Host "Attempting to remove [localhost]:$SshPort from known_hosts for Git test" -ForegroundColor DarkGray
|
||||
ssh-keygen -R "[localhost]:$SshPort" | Out-Null # Suppress normal output, errors will still show
|
||||
|
||||
$GitDeployRemoteCommand = "`"cd /home/hexo/hexo.git && git --git-dir=. --work-tree=/home/www/hexo status && echo \'GIT_DEPLOY_SUCCESS\'`""
|
||||
$SshVerbosityArgsGit = ""
|
||||
|
||||
if ($SshDebug) {
|
||||
$SshVerbosityArgsGit = "-vvv"
|
||||
Write-Host "SshDebug is ON, using verbose SSH output for Git deploy test." -ForegroundColor DarkGray
|
||||
} else {
|
||||
$SshVerbosityArgsGit = "-q -o LogLevel=ERROR"
|
||||
}
|
||||
|
||||
$GitDeployCommand = "ssh $SshVerbosityArgsGit -p $SshPort -i `"$SshKeyPath`" -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null hexo@localhost $GitDeployRemoteCommand"
|
||||
|
||||
if ($SshDebug) { # Print command if debug is on
|
||||
Write-Host "Executing SSH (Git Deploy) command (Debug): $GitDeployCommand" -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
$GitDeployOutput = Invoke-Expression $GitDeployCommand 2>&1
|
||||
$CurrentExitCode = $LASTEXITCODE
|
||||
|
||||
if ($SshDebug) {
|
||||
Write-Host "SSH (Git Deploy) command executed. Exit code: $CurrentExitCode" -ForegroundColor DarkGray
|
||||
Write-Host "SSH (Git Deploy) output (raw):`n--BEGIN GIT DEPLOY SSH OUTPUT--`n$GitDeployOutput`n--END GIT DEPLOY SSH OUTPUT--`n" -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
if ($CurrentExitCode -ne 0) {
|
||||
Write-Host "SSH (Git Deploy) command failed with non-zero exit code: $CurrentExitCode." -ForegroundColor Red
|
||||
if (-not $SshDebug -and $GitDeployOutput) {
|
||||
Write-Host "SSH (Git Deploy) output (Error):`n$GitDeployOutput" -ForegroundColor DarkGray
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
if (-not ($GitDeployOutput -match "GIT_DEPLOY_SUCCESS")) {
|
||||
Write-Host "SSH (Git Deploy) command succeeded (exit code 0), but did not output \'GIT_DEPLOY_SUCCESS\'." -ForegroundColor Red
|
||||
if (-not $SshDebug -and $GitDeployOutput) {
|
||||
Write-Host "SSH (Git Deploy) output (Unexpected):`n$GitDeployOutput" -ForegroundColor DarkGray
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
Start-Sleep -Seconds 2 # Give time for log to be written if deployment was triggered
|
||||
$LogCheckCommandRaw = "test -f /var/log/container/deployment.log && echo \'LOG_EXISTS\'"
|
||||
$LogCheckCommand = $LogCheckCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$LogOutput = docker exec $ContainerName bash -c $LogCheckCommand 2>$null
|
||||
|
||||
if ($LogOutput -match "LOG_EXISTS") {
|
||||
Write-Host "SSH (Git Deploy) successful and deployment log found." -ForegroundColor Green
|
||||
return $true
|
||||
} else {
|
||||
Write-Host "SSH (Git Deploy) successful, but deployment log \'/var/log/container/deployment.log\' not found." -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
} catch {
|
||||
Write-Host "模拟 Git 部署测试中发生异常: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
} "模拟 Git 推送部署并检查日志生成"
|
||||
|
||||
# 测试 9: 日志轮转功能测试 (v0.0.3 新功能)
|
||||
Test-Function "日志轮转功能测试" {
|
||||
try {
|
||||
# 检查日志轮转函数是否存在
|
||||
$RotateOutputCommandRaw = "grep -q 'setup_log_rotation' /root/start.sh && echo 'SCRIPT_EXISTS'"
|
||||
$RotateOutputCommand = $RotateOutputCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$RotateOutput = docker exec $ContainerName bash -c $RotateOutputCommand 2>$null
|
||||
if ($RotateOutput -match "SCRIPT_EXISTS") { # Changed to -match
|
||||
# 检查 logrotate 配置文件是否存在
|
||||
$LogrotateOutputCommandRaw = "test -f /etc/logrotate.d/deployment && echo 'LOGROTATE_CONFIG_EXISTS'"
|
||||
$LogrotateOutputCommand = $LogrotateOutputCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$LogrotateOutput = docker exec $ContainerName bash -c $LogrotateOutputCommand 2>$null
|
||||
return ($LogrotateOutput -match "LOGROTATE_CONFIG_EXISTS") # Changed to -match
|
||||
}
|
||||
return $false
|
||||
} catch {
|
||||
Write-Host "日志轮转检查失败: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
} "检查日志轮转功能是否正确配置 (v0.0.3 新功能)"
|
||||
|
||||
# 测试 10: 容器资源使用测试
|
||||
Test-Function "容器资源使用测试" {
|
||||
try {
|
||||
$Stats = docker stats $ContainerName --no-stream --format "table {{.MemUsage}}\t{{.CPUPerc}}" | Select-Object -Skip 1
|
||||
if ($Stats) {
|
||||
Write-Host "资源使用情况: $Stats" -ForegroundColor Gray
|
||||
# 简单检查:如果能获取到统计信息就认为通过
|
||||
return $true
|
||||
}
|
||||
return $false
|
||||
} catch {
|
||||
Write-Host "资源统计获取失败: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
} "检查容器资源使用情况"
|
||||
|
||||
# 生成测试报告
|
||||
Write-Host "`n=== 测试总结报告 ===" -ForegroundColor Cyan
|
||||
|
||||
$PassedTests = ($TestResults | Where-Object { $_.Status -eq "PASS" }).Count
|
||||
$FailedTests = ($TestResults | Where-Object { $_.Status -eq "FAIL" }).Count
|
||||
$ErrorTests = ($TestResults | Where-Object { $_.Status -eq "ERROR" }).Count
|
||||
$TotalTests = $TestResults.Count
|
||||
|
||||
Write-Host "总测试数: $TotalTests" -ForegroundColor White
|
||||
Write-Host "通过: $PassedTests" -ForegroundColor Green
|
||||
Write-Host "失败: $FailedTests" -ForegroundColor Red
|
||||
Write-Host "错误: $ErrorTests" -ForegroundColor Yellow
|
||||
|
||||
$SuccessRate = if ($TotalTests -gt 0) { ($PassedTests / $TotalTests * 100).ToString("F1") } else { "0.0" }
|
||||
Write-Host "成功率: $SuccessRate%" -ForegroundColor $(if ($PassedTests -eq $TotalTests) { "Green" } else { "Yellow" })
|
||||
|
||||
# 详细测试结果表格
|
||||
Write-Host "`n=== 详细测试结果 ===" -ForegroundColor Cyan
|
||||
$TestResults | Format-Table -Property TestName, Status, Duration, Timestamp -AutoSize
|
||||
|
||||
# 失败的测试详情
|
||||
$FailedTestList = $TestResults | Where-Object { $_.Status -ne "PASS" }
|
||||
if ($FailedTestList) {
|
||||
Write-Host "`n=== 失败的测试 ===" -ForegroundColor Red
|
||||
$FailedTestList | ForEach-Object {
|
||||
Write-Host "❌ $($_.TestName) - $($_.Status)" -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
|
||||
# 保存详细报告到文件
|
||||
$ReportContent = @"
|
||||
=== Hexo Container v0.0.3 功能测试报告 ===
|
||||
测试时间: $(Get-Date)
|
||||
容器名称: $ContainerName
|
||||
HTTP 端口: $HttpPort
|
||||
SSH 端口: $SshPort
|
||||
|
||||
=== 测试统计 ===
|
||||
总测试数: $TotalTests
|
||||
通过: $PassedTests
|
||||
失败: $FailedTests
|
||||
错误: $ErrorTests
|
||||
成功率: $SuccessRate%
|
||||
|
||||
=== 详细结果 ===
|
||||
$($TestResults | ForEach-Object { "$($_.TestName): $($_.Status) ($($_.Duration.ToString('F2'))s)" } | Out-String)
|
||||
|
||||
=== v0.0.3 新功能测试状态 ===
|
||||
日志文件权限测试: $($TestResults | Where-Object { $_.TestName -eq "日志文件权限测试" } | Select-Object -ExpandProperty Status)
|
||||
日志轮转功能测试: $($TestResults | Where-Object { $_.TestName -eq "日志轮转功能测试" } | Select-Object -ExpandProperty Status)
|
||||
"@
|
||||
|
||||
$ReportFile = "$LogDir\\functional_test_report_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt" # Corrected date format and added .txt extension
|
||||
|
||||
# 如果测试是从 run_test.ps1 调用的,则退出状态码将由 run_test.ps1 处理
|
||||
# 如果是独立运行,则根据测试结果设置退出代码
|
||||
if ($MyInvocation.ScriptName -eq $PSCommandPath) {
|
||||
if ($FailedTests -gt 0 -or $ErrorTests -gt 0) {
|
||||
exit 1
|
||||
} else {
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
755
test/v0.0.3/windows/log_rotation_test.ps1
Normal file
755
test/v0.0.3/windows/log_rotation_test.ps1
Normal file
@@ -0,0 +1,755 @@
|
||||
# Hexo Container v0.0.3 日志轮转测试脚本 (Windows)
|
||||
# log_rotation_test.ps1
|
||||
|
||||
param(
|
||||
[string]$ContainerName = "hexo-test-v003",
|
||||
[int]$HttpPort = 8080,
|
||||
[int]$SshPort = 2222,
|
||||
[string]$SshKeyPath = ".\test_data\ssh_keys\test_key",
|
||||
[int]$TestDeployments = 20,
|
||||
[int]$LogSizeThresholdMB = 1,
|
||||
[int]$TotalBatches = 10, # 添加可配置的批次数参数
|
||||
[switch]$SkipLogGeneration = $false,
|
||||
[switch]$QuickLogGen = $false,
|
||||
[switch]$FastRotationTest = $false,
|
||||
[switch]$CalledFromTestSuite = $false, # 新增参数,用于指示是否从主测试套件调用
|
||||
[switch]$SshDebug = $false # 新增 SshDebug 参数,控制SSH命令的详细程度
|
||||
)
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
Set-Location $ScriptDir
|
||||
|
||||
# 确保 SSH 密钥路径为绝对路径
|
||||
$SshKeyPath = Join-Path $ScriptDir "test_data\ssh_keys\test_key"
|
||||
|
||||
Write-Host "=== Hexo Container v0.0.3 日志轮转测试 ===" -ForegroundColor Cyan
|
||||
Write-Host "这个测试将验证 v0.0.3 版本的新日志轮转功能" -ForegroundColor Gray
|
||||
|
||||
# 创建日志目录
|
||||
$LogDir = ".\logs"
|
||||
if (-not (Test-Path $LogDir)) {
|
||||
New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# 函数:清理重复的deployment.log文件
|
||||
function Clear-DuplicateDeploymentLogs {
|
||||
param([string]$ContainerName)
|
||||
|
||||
Write-Host "清理重复的deployment.log文件..." -ForegroundColor Yellow
|
||||
$bashCommandRaw = @'
|
||||
cd /var/log/container
|
||||
LOG_FILE="deployment.log"
|
||||
# Check if the log file exists and who owns it
|
||||
if [ -f "$LOG_FILE" ]; then
|
||||
OWNER=$(stat -c '%U' "$LOG_FILE")
|
||||
echo "Found existing $LOG_FILE, owner is $OWNER"
|
||||
if [ "$OWNER" = "root" ]; then
|
||||
echo "File is owned by root, removing and recreating as hexo user..."
|
||||
rm -f "$LOG_FILE"
|
||||
su - hexo -c "touch /var/log/container/$LOG_FILE && chmod 664 /var/log/container/$LOG_FILE"
|
||||
echo "$LOG_FILE recreated by hexo user."
|
||||
elif [ "$OWNER" != "hexo" ]; then
|
||||
echo "File owner is not hexo ($OWNER), attempting to chown to hexo..."
|
||||
chown hexo:hexo "$LOG_FILE"
|
||||
chmod 664 "$LOG_FILE"
|
||||
echo "Permissions corrected for $LOG_FILE."
|
||||
else
|
||||
echo "$LOG_FILE is already owned by hexo. Ensuring correct permissions."
|
||||
chmod 664 "$LOG_FILE"
|
||||
fi
|
||||
else
|
||||
echo "$LOG_FILE not found, creating one as hexo user..."
|
||||
su - hexo -c "touch /var/log/container/$LOG_FILE && chmod 664 /var/log/container/$LOG_FILE"
|
||||
echo "$LOG_FILE created by hexo user."
|
||||
fi
|
||||
# Verify final state
|
||||
echo "Final state of $LOG_FILE:"
|
||||
ls -la "$LOG_FILE"
|
||||
'@
|
||||
$bashCommand = $bashCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
docker exec $ContainerName bash -c $bashCommand
|
||||
}
|
||||
|
||||
# 如果这是独立运行的日志轮转测试,清理旧的日志文件
|
||||
# 判断逻辑:当脚本不是从主测试套件调用时
|
||||
$IsStandaloneExecution = -not $CalledFromTestSuite
|
||||
|
||||
Write-Host "执行模式检测:" -ForegroundColor Magenta
|
||||
Write-Host " CalledFromTestSuite: $CalledFromTestSuite" -ForegroundColor Gray
|
||||
Write-Host " IsStandaloneExecution: $IsStandaloneExecution" -ForegroundColor Gray
|
||||
|
||||
if ($IsStandaloneExecution) {
|
||||
Write-Host "=== 检测到独立执行或未指定调用来源,将清理旧的相关日志文件 ===" -ForegroundColor Cyan
|
||||
$OldLogsDir = "$LogDir\old"
|
||||
if (-not (Test-Path $OldLogsDir)) {
|
||||
New-Item -ItemType Directory -Path $OldLogsDir -Force | Out-Null
|
||||
Write-Host "创建旧日志归档目录: $OldLogsDir" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# 检查 deployment.log 是否需要处理
|
||||
function Test-DeploymentLogCompatibility {
|
||||
param([string]$DeploymentLogPath)
|
||||
|
||||
if (-not (Test-Path $DeploymentLogPath)) {
|
||||
return $false
|
||||
}
|
||||
|
||||
try {
|
||||
$fileSize = (Get-Item $DeploymentLogPath).Length
|
||||
$fileSizeKB = [math]::Round($fileSize / 1024, 2)
|
||||
Write-Host "检测到现有 deployment.log,大小: $fileSizeKB KB" -ForegroundColor Gray
|
||||
|
||||
# 根据当前测试模式判断是否保留
|
||||
if ($SkipLogGeneration) {
|
||||
Write-Host "跳过日志生成模式:保留现有 deployment.log" -ForegroundColor Green
|
||||
return $true
|
||||
} elseif ($FastRotationTest) {
|
||||
if ($fileSizeKB -ge 2 -and $fileSizeKB -le 10) {
|
||||
Write-Host "检测到快速轮转测试模式的现有文件,保留使用" -ForegroundColor Green
|
||||
return $true
|
||||
}
|
||||
} elseif ($QuickLogGen) {
|
||||
if ($fileSizeKB -ge 10 -and $fileSizeKB -le 100) {
|
||||
Write-Host "检测到快速日志生成模式的现有文件,保留使用" -ForegroundColor Green
|
||||
return $true
|
||||
}
|
||||
} else {
|
||||
if ($fileSizeKB -ge 300) {
|
||||
Write-Host "检测到正常模式的现有文件,保留使用" -ForegroundColor Green
|
||||
return $true
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "现有文件不符合当前测试模式要求,需要重新生成" -ForegroundColor Yellow
|
||||
return $false
|
||||
} catch {
|
||||
Write-Host "检查 deployment.log 兼容性时出错: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
# 检查 deployment.log 是否需要处理
|
||||
$DeploymentLogPath = "$LogDir\\deployment.log"
|
||||
# $KeepDeploymentLog = Test-DeploymentLogCompatibility -DeploymentLogPath $DeploymentLogPath # 这部分逻辑由 start.ps1 处理,独立运行时通常不保留
|
||||
|
||||
# 移动旧的日志文件到 old 文件夹 (仅处理 log_rotation_test 相关日志和 deployment.log)
|
||||
$OldLogFiles = Get-ChildItem $LogDir -File | Where-Object {
|
||||
($_.Name -like "log_rotation_test_*.log" -or $_.Name -like "log_rotation_test_report_*.txt" -or $_.Name -eq "deployment.log")
|
||||
}
|
||||
|
||||
if ($OldLogFiles.Count -gt 0) {
|
||||
Write-Host "归档 $($OldLogFiles.Count) 个旧日志文件到 old 文件夹..." -ForegroundColor Gray
|
||||
foreach ($file in $OldLogFiles) {
|
||||
$destPath = Join-Path $OldLogsDir $file.Name
|
||||
Move-Item $file.FullName $destPath -Force
|
||||
Write-Host " 移动: $($file.Name)" -ForegroundColor Gray
|
||||
}
|
||||
} else {
|
||||
Write-Host "没有旧日志文件需要归档" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# 处理容器内的 deployment.log
|
||||
Write-Host "处理容器内的 deployment.log (独立执行模式)..." -ForegroundColor Gray
|
||||
try {
|
||||
$ContainerStatus = docker ps -f "name=$ContainerName" --format "{{.Names}}" 2>$null | Select-String $ContainerName
|
||||
if ($ContainerStatus) {
|
||||
# 在独立执行时,通常我们希望从一个干净的 deployment.log 开始测试轮转
|
||||
Write-Host "发现运行中的容器,清空容器内的 deployment.log..." -ForegroundColor Gray
|
||||
$cleanupCommandRaw = "echo '' > /var/log/container/deployment.log && chown hexo:hexo /var/log/container/deployment.log && chmod 664 /var/log/container/deployment.log"
|
||||
$cleanupCommand = $cleanupCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
docker exec $ContainerName sh -c $cleanupCommand 2>$null
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "容器内 deployment.log 已清空并设置权限" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "清空容器内 deployment.log 失败" -ForegroundColor Yellow
|
||||
}
|
||||
} else {
|
||||
Write-Host "容器未运行,无法处理容器内的 deployment.log" -ForegroundColor Yellow
|
||||
}
|
||||
} catch {
|
||||
Write-Host "处理容器内 deployment.log 时出错: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
}
|
||||
} else {
|
||||
Write-Host "=== 检测到通过测试套件调用,跳过旧文件清理和容器内 deployment.log 的预处理 ===" -ForegroundColor Yellow
|
||||
Write-Host "注意: 日志文件清理和容器内 deployment.log 的初始状态将由主控脚本 start.ps1 负责" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
$TimeStamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||||
$TestLog = "$LogDir\log_rotation_test_$TimeStamp.log"
|
||||
|
||||
# 检查容器是否运行
|
||||
Write-Host "`n检查容器状态..." -ForegroundColor Yellow
|
||||
$ContainerRunning = docker ps --filter "name=$ContainerName" --format "{{.Names}}" | Select-String $ContainerName
|
||||
if (-not $ContainerRunning) {
|
||||
Write-Host "ERROR: 容器 $ContainerName 未运行,请先运行 run_test.ps1" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
Write-Host "SUCCESS: 容器正在运行" -ForegroundColor Green
|
||||
|
||||
# 修复日志文件权限(在测试开始前)
|
||||
Write-Host "`n修复日志文件权限..." -ForegroundColor Yellow
|
||||
try {
|
||||
# 确保日志目录存在且权限正确
|
||||
$bashCommandMkdirRaw = @'
|
||||
mkdir -p /var/log/container && chown hexo:hexo /var/log/container && chmod 755 /var/log/container
|
||||
'@
|
||||
$bashCommandMkdir = $bashCommandMkdirRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
docker exec $ContainerName bash -c $bashCommandMkdir
|
||||
|
||||
# 清理重复的deployment.log文件
|
||||
Clear-DuplicateDeploymentLogs -ContainerName $ContainerName
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "SUCCESS: 日志文件权限已修复" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "WARNING: 权限修复可能失败,但继续测试" -ForegroundColor Yellow
|
||||
}
|
||||
} catch {
|
||||
Write-Host "WARNING: 权限修复时出错: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# 检查 SSH 密钥
|
||||
if (-not (Test-Path $SshKeyPath)) {
|
||||
Write-Host "ERROR: SSH 密钥不存在: $SshKeyPath" -ForegroundColor Red
|
||||
Write-Host "请先运行 run_test.ps1 生成 SSH 密钥" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 额外的权限验证和修复
|
||||
Write-Host "`n进行额外的权限验证和修复..." -ForegroundColor Yellow
|
||||
try {
|
||||
# 验证当前权限状态 - 使用LANG=C避免中文编码问题
|
||||
$bashCommandLsRaw = @'
|
||||
LANG=C ls -la /var/log/container/deployment.log 2>/dev/null || echo 'FILE_NOT_FOUND'
|
||||
'@
|
||||
$bashCommandLs = $bashCommandLsRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$currentPermissions = docker exec $ContainerName bash -c $bashCommandLs 2>$null
|
||||
Write-Host "当前文件权限: $currentPermissions" -ForegroundColor Gray
|
||||
# 静默修复权限(减少错误输出)
|
||||
Write-Host "验证和修复权限..." -ForegroundColor Gray
|
||||
$bashCommandFixRaw = @'
|
||||
# 确保目录存在(静默执行)
|
||||
mkdir -p /var/log/container >/dev/null 2>&1
|
||||
chown hexo:hexo /var/log/container >/dev/null 2>&1
|
||||
chmod 755 /var/log/container >/dev/null 2>&1
|
||||
|
||||
LOG_FILE="/var/log/container/deployment.log"
|
||||
|
||||
# 如果文件存在且是root拥有的,则删除
|
||||
if [ -f "$LOG_FILE" ]; then
|
||||
OWNER=$(stat -c '%U' "$LOG_FILE" 2>/dev/null || echo "unknown")
|
||||
if [ "$OWNER" = "root" ]; then
|
||||
rm -f "$LOG_FILE" >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 创建文件如果不存在 (确保以hexo用户创建)
|
||||
if [ ! -f "$LOG_FILE" ]; then
|
||||
su - hexo -c "touch $LOG_FILE" >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
# 设置正确的所有者和权限
|
||||
chown hexo:hexo "$LOG_FILE" >/dev/null 2>&1
|
||||
chmod 664 "$LOG_FILE" >/dev/null 2>&1
|
||||
|
||||
# 验证修复结果
|
||||
if [ -f "$LOG_FILE" ]; then
|
||||
echo "SUCCESS"
|
||||
else
|
||||
echo "FAILED"
|
||||
fi
|
||||
'@
|
||||
$bashCommandFix = $bashCommandFixRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$permissionResult = docker exec $ContainerName bash -c $bashCommandFix 2>$null
|
||||
|
||||
if ($permissionResult -eq "SUCCESS") {
|
||||
Write-Host "SUCCESS: 权限验证和修复完成" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "FAILED: 权限修复失败,但测试将继续进行" -ForegroundColor Yellow
|
||||
}
|
||||
# 测试hexo用户的写入权限
|
||||
Write-Host "测试hexo用户写入权限..." -ForegroundColor Gray
|
||||
$bashCommandWriteTestRaw = @'
|
||||
su - hexo -c 'echo "PERMISSION_TEST_$(date)" >> /var/log/container/deployment.log 2>/dev/null' && echo 'SUCCESS' || echo 'FAILED'
|
||||
'@
|
||||
$bashCommandWriteTest = $bashCommandWriteTestRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$testResult = docker exec $ContainerName bash -c $bashCommandWriteTest 2>$null
|
||||
|
||||
if ($testResult -eq "SUCCESS") {
|
||||
Write-Host "SUCCESS: hexo用户可以正常写入日志文件" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "FAILED: hexo用户无法写入日志文件,这会影响测试结果" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# 静默检查SSH配置(减少输出)
|
||||
Write-Host "验证hexo用户SSH配置..." -ForegroundColor Gray
|
||||
$bashCommandSshCheckRaw = @'
|
||||
# 静默设置SSH权限
|
||||
su - hexo -c "mkdir -p /home/hexo/.ssh && chmod 700 /home/hexo/.ssh" >/dev/null 2>&1
|
||||
su - hexo -c "touch /home/hexo/.ssh/authorized_keys && chmod 600 /home/hexo/.ssh/authorized_keys" >/dev/null 2>&1
|
||||
|
||||
# 验证SSH配置是否正确
|
||||
if [ -d "/home/hexo/.ssh" ] && [ -f "/home/hexo/.ssh/authorized_keys" ]; then
|
||||
echo "SUCCESS"
|
||||
else
|
||||
echo "FAILED"
|
||||
fi
|
||||
'@
|
||||
$bashCommandSshCheck = $bashCommandSshCheckRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$sshResult = docker exec $ContainerName bash -c $bashCommandSshCheck 2>$null
|
||||
|
||||
if ($sshResult -eq "SUCCESS") {
|
||||
Write-Host "SUCCESS: SSH配置验证完成" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "FAILED: SSH配置验证失败" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
} catch {
|
||||
Write-Host "WARNING: 额外权限修复时出错: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# 函数:获取日志文件大小
|
||||
function Get-LogFileSize {
|
||||
param([string]$LogPath)
|
||||
try {
|
||||
$bashCommandStatRaw = "stat -c%s $LogPath 2>/dev/null; if [ `$? -ne 0 ]; then echo 0; fi"
|
||||
$bashCommandStat = $bashCommandStatRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$SizeBytes = docker exec $ContainerName bash -c $bashCommandStat
|
||||
if ($null -eq $SizeBytes -or $SizeBytes -eq "") {
|
||||
return 0
|
||||
}
|
||||
return [int]$SizeBytes
|
||||
} catch {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
# 函数:获取日志文件列表
|
||||
function Get-LogFileList {
|
||||
try {
|
||||
# 使用 LANG=C 强制英文输出,避免中文编码问题
|
||||
# 修复:更精确的文件过滤,避免重复行和非预期匹配
|
||||
$bashCommandLsLogsRaw = 'LANG=C ls -la /var/log/container/*.log* 2>/dev/null | sort -u || echo "No log files found"'
|
||||
$bashCommandLsLogs = $bashCommandLsLogsRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$Files = docker exec $ContainerName bash -c $bashCommandLsLogs
|
||||
return $Files
|
||||
} catch {
|
||||
return @()
|
||||
}
|
||||
}
|
||||
|
||||
# 函数:生成测试日志内容
|
||||
function New-LogContent {
|
||||
param([int]$Count)
|
||||
Write-Host "生成 $Count 条测试日志..." -ForegroundColor Yellow
|
||||
|
||||
for ($i = 1; $i -le $Count; $i++) {
|
||||
$CurrentTime = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
|
||||
|
||||
try {
|
||||
$SshVerbosityArgs = ""
|
||||
if ($SshDebug) {
|
||||
$SshVerbosityArgs = "-vvv"
|
||||
Write-Host "SshDebug is ON, using verbose SSH output." -ForegroundColor DarkGray
|
||||
} else {
|
||||
$SshVerbosityArgs = "-q -o LogLevel=ERROR"
|
||||
}
|
||||
|
||||
# Construct the remote command part - use simpler approach
|
||||
$LogEntry = "TEST_LOG_ENTRY_$i : $CurrentTime - Entry $i of $Count"
|
||||
|
||||
# Use Start-Process for better control over command execution
|
||||
$ProcessArgs = @(
|
||||
$SshVerbosityArgs -split ' '
|
||||
"-p", $SshPort
|
||||
"-i", $SshKeyPath
|
||||
"-o", "ConnectTimeout=10"
|
||||
"-o", "StrictHostKeyChecking=no"
|
||||
"-o", "UserKnownHostsFile=/dev/null"
|
||||
"hexo@localhost"
|
||||
"echo '$LogEntry' >> /var/log/container/deployment.log"
|
||||
) | Where-Object { $_ -ne "" }
|
||||
|
||||
if ($SshDebug) {
|
||||
Write-Host "Executing SSH command: ssh $($ProcessArgs -join ' ')" -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
$process = Start-Process -FilePath "ssh" -ArgumentList $ProcessArgs -Wait -PassThru -NoNewWindow -RedirectStandardOutput "stdout.tmp" -RedirectStandardError "stderr.tmp"
|
||||
|
||||
if ($process.ExitCode -ne 0) {
|
||||
$sshError = if (Test-Path "stderr.tmp") { Get-Content "stderr.tmp" -Raw } else { "No error output" }
|
||||
Write-Host "SSH command failed. Exit code: $($process.ExitCode)" -ForegroundColor Red
|
||||
Write-Host "SSH output: $sshError" -ForegroundColor Red
|
||||
} else {
|
||||
if ($SshDebug) {
|
||||
$sshOutput = if (Test-Path "stdout.tmp") { Get-Content "stdout.tmp" -Raw } else { "" }
|
||||
if ($sshOutput) {
|
||||
Write-Host "SSH output: $sshOutput" -ForegroundColor DarkGray
|
||||
}
|
||||
}
|
||||
}
|
||||
# Clean up temp files
|
||||
Remove-Item "stdout.tmp", "stderr.tmp" -ErrorAction SilentlyContinue
|
||||
|
||||
if ($i % 10 -eq 0) {
|
||||
Write-Host "已生成 $i/$Count 条日志" -ForegroundColor Gray
|
||||
}
|
||||
Start-Sleep -Milliseconds 10
|
||||
} catch {
|
||||
Write-Host "生成日志失败: $($_.Exception.Message)" -ForegroundColor Red
|
||||
# Optionally, log the command that failed if SshDebug is on
|
||||
if ($SshDebug) {
|
||||
Write-Host "Failed SSH command with args: $($ProcessArgs -join ' ')" -ForegroundColor DarkGray
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 开始测试
|
||||
"=== 日志轮转测试开始 $(Get-Date) ===" | Add-Content $TestLog
|
||||
|
||||
Write-Host "`n=== 步骤 1: 检查初始日志状态 ===" -ForegroundColor Cyan
|
||||
$InitialLogFiles = Get-LogFileList
|
||||
Write-Host "初始日志文件:" -ForegroundColor Gray
|
||||
$InitialLogFiles | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
|
||||
$InitialLogSize = Get-LogFileSize "/var/log/container/deployment.log"
|
||||
Write-Host "部署日志初始大小: $($InitialLogSize / 1024) KB" -ForegroundColor Gray
|
||||
|
||||
"初始日志大小: $InitialLogSize bytes" | Add-Content $TestLog
|
||||
|
||||
Write-Host "`n=== 步骤 2: 检查日志轮转配置 ===" -ForegroundColor Cyan
|
||||
|
||||
# 检查日志轮转函数是否存在
|
||||
$RotateFunctionCheckCommand = 'grep -q setup_log_rotation /root/start.sh; if [ $? -eq 0 ]; then echo FUNCTION_EXISTS; else echo FUNCTION_NOT_FOUND; fi'
|
||||
$CleanRotateFunctionCheckCommand = $RotateFunctionCheckCommand.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$RotateFunctionCheck = docker exec $ContainerName bash -c $CleanRotateFunctionCheckCommand
|
||||
if ($RotateFunctionCheck -eq "FUNCTION_EXISTS") {
|
||||
Write-Host "SUCCESS: 日志轮转函数存在" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "FAIL: 日志轮转函数不存在" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# 检查定期检查功能
|
||||
$PeriodicCheckCommand = 'grep -q setup_log_rotation /root/start.sh; if [ $? -eq 0 ]; then echo PERIODIC_EXISTS; else echo PERIODIC_NOT_FOUND; fi'
|
||||
$CleanPeriodicCheckCommand = $PeriodicCheckCommand.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$PeriodicCheck = docker exec $ContainerName bash -c $CleanPeriodicCheckCommand
|
||||
if ($PeriodicCheck -eq "PERIODIC_EXISTS") {
|
||||
Write-Host "SUCCESS: 定期日志检查功能存在" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "FAIL: 定期日志检查功能不存在" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# 检查日志轮转配置文件
|
||||
$LogrotateConfigCheckCommand = 'test -f /etc/logrotate.d/deployment; if [ $? -eq 0 ]; then echo CONFIG_EXISTS; else echo CONFIG_NOT_FOUND; fi'
|
||||
$CleanLogrotateConfigCheckCommand = $LogrotateConfigCheckCommand.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$LogrotateConfigCheck = docker exec $ContainerName bash -c $CleanLogrotateConfigCheckCommand
|
||||
if ($LogrotateConfigCheck -eq "CONFIG_EXISTS") {
|
||||
Write-Host "SUCCESS: 日志轮转配置文件存在" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "FAIL: 日志轮转配置文件不存在" -ForegroundColor Red
|
||||
}
|
||||
|
||||
Write-Host "`n=== 步骤 3: 生成测试日志 ===" -ForegroundColor Cyan
|
||||
|
||||
# 调试信息:显示参数传递情况
|
||||
Write-Host "参数调试信息:" -ForegroundColor Magenta
|
||||
Write-Host " TotalBatches = $TotalBatches (来自参数)" -ForegroundColor Magenta
|
||||
Write-Host " FastRotationTest = $FastRotationTest" -ForegroundColor Magenta
|
||||
Write-Host " QuickLogGen = $QuickLogGen" -ForegroundColor Magenta
|
||||
Write-Host " PSBoundParameters.ContainsKey('TotalBatches') = $($PSBoundParameters.ContainsKey('TotalBatches'))" -ForegroundColor Magenta
|
||||
|
||||
if ($FastRotationTest) {
|
||||
Write-Host "快速轮转测试模式: 生成少量日志以快速验证轮转机制" -ForegroundColor Yellow
|
||||
Write-Host "注意: 快速模式主要验证轮转机制,而非大文件轮转" -ForegroundColor Gray
|
||||
|
||||
# 快速轮转测试模式:生成更少的日志
|
||||
$FastBatchSize = 50
|
||||
# 只有在用户没有明确指定TotalBatches时才使用默认值
|
||||
if ($PSBoundParameters.ContainsKey('TotalBatches') -eq $false) {
|
||||
$TotalBatches = 3
|
||||
Write-Host " 未指定TotalBatches,使用快速模式默认值: $TotalBatches" -ForegroundColor Magenta
|
||||
} else {
|
||||
Write-Host " 使用用户指定的TotalBatches: $TotalBatches" -ForegroundColor Magenta
|
||||
}
|
||||
|
||||
Write-Host "快速轮转测试: 将生成 $TotalBatches 批次,每批次 $FastBatchSize 条日志 (总计约$(($TotalBatches * $FastBatchSize * 211) / 1024)KB)" -ForegroundColor Gray
|
||||
} elseif ($QuickLogGen) {
|
||||
Write-Host "快速日志生成模式: 生成少量日志数据以验证日志轮转机制" -ForegroundColor Yellow
|
||||
Write-Host "注意: 快速模式不会触发大文件轮转,但会验证日志写入和权限" -ForegroundColor Gray
|
||||
|
||||
# 快速日志生成模式:如果没有指定TotalBatches参数,则使用默认值5
|
||||
if ($PSBoundParameters.ContainsKey('TotalBatches') -eq $false) {
|
||||
$TotalBatches = 5
|
||||
Write-Host " 未指定TotalBatches,使用快速日志生成默认值: $TotalBatches" -ForegroundColor Magenta
|
||||
} else {
|
||||
Write-Host " 使用用户指定的TotalBatches: $TotalBatches" -ForegroundColor Magenta
|
||||
}
|
||||
$BatchSize = 100
|
||||
|
||||
Write-Host "快速日志生成: 将生成 $TotalBatches 批次,每批次 $BatchSize 条日志" -ForegroundColor Gray
|
||||
} else {
|
||||
Write-Host "目标: 生成超过 ${LogSizeThresholdMB}MB 的日志数据以触发轮转" -ForegroundColor Gray
|
||||
Write-Host "注意: 针对测试环境,日志轮转阈值已设置为 20KB" -ForegroundColor Yellow
|
||||
|
||||
# 计算需要生成的日志条数(实际测量每条约211字节,20KB需要约95条日志)
|
||||
$LogEntrySize = 211 # 基于实际测量结果更新
|
||||
$TargetBytes = 20 * 1024 # 20KB 固定目标,确保能触发轮转
|
||||
$RequiredEntries = [Math]::Ceiling($TargetBytes / $LogEntrySize)
|
||||
|
||||
Write-Host "预计需要生成 $RequiredEntries 条日志以触发 20KB 轮转 (基于实际测量的 $LogEntrySize 字节/条)" -ForegroundColor Gray
|
||||
|
||||
# 分批生成日志 - 使用传入的TotalBatches参数,默认为10个批次
|
||||
$BatchSize = 100
|
||||
# $TotalBatches 使用参数传入的值,不再重新赋值
|
||||
|
||||
Write-Host "将生成 $TotalBatches 个批次,每批次 $BatchSize 条日志" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# 开始日志生成和轮转测试
|
||||
if (-not $SkipLogGeneration) {
|
||||
$TotalLogsGenerated = 0
|
||||
|
||||
for ($batch = 1; $batch -le $TotalBatches; $batch++) {
|
||||
if ($FastRotationTest) {
|
||||
$CurrentBatchSize = $FastBatchSize
|
||||
} elseif ($QuickLogGen) {
|
||||
$CurrentBatchSize = $BatchSize
|
||||
} else {
|
||||
# 固定每个批次大小为 100 条日志
|
||||
$CurrentBatchSize = $BatchSize
|
||||
}
|
||||
|
||||
Write-Host "批次 $batch/$TotalBatches : 生成 $CurrentBatchSize 条日志..." -ForegroundColor Yellow
|
||||
|
||||
# 记录批次开始前的日志行数
|
||||
$bashCommandWcBeforeRaw = "LANG=C wc -l < /var/log/container/deployment.log 2>/dev/null || echo 0"
|
||||
$bashCommandWcBefore = $bashCommandWcBeforeRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$LogCountBefore = docker exec $ContainerName bash -c $bashCommandWcBefore
|
||||
|
||||
New-LogContent -Count $CurrentBatchSize
|
||||
|
||||
# 记录批次结束后的日志行数
|
||||
$bashCommandWcAfterRaw = "LANG=C wc -l < /var/log/container/deployment.log 2>/dev/null || echo 0"
|
||||
$bashCommandWcAfter = $bashCommandWcAfterRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$LogCountAfter = docker exec $ContainerName bash -c $bashCommandWcAfter
|
||||
$ActualLogsAdded = [int]$LogCountAfter - [int]$LogCountBefore
|
||||
$TotalLogsGenerated += $ActualLogsAdded
|
||||
|
||||
Write-Host "实际添加日志: $ActualLogsAdded 条 (总计: $TotalLogsGenerated 条)" -ForegroundColor Gray
|
||||
# 检查当前日志大小
|
||||
$CurrentLogSize = Get-LogFileSize "/var/log/container/deployment.log"
|
||||
Write-Host "当前日志大小: $($CurrentLogSize / 1024) KB" -ForegroundColor Gray
|
||||
|
||||
"批次 $batch 完成,当前日志大小: $CurrentLogSize bytes" | Add-Content $TestLog
|
||||
# 检查是否需要触发日志轮转(如果超过20KB)
|
||||
$ThresholdBytes = 20 * 1024 # 20KB
|
||||
if ($CurrentLogSize -gt $ThresholdBytes) {
|
||||
Write-Host "日志大小超过 20KB 阈值,尝试触发日志轮转..." -ForegroundColor Yellow
|
||||
$bashCommandLogrotateRaw = "LANG=C logrotate -f /etc/logrotate.d/deployment"
|
||||
$bashCommandLogrotate = $bashCommandLogrotateRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
docker exec $ContainerName bash -c $bashCommandLogrotate | Out-Null
|
||||
Start-Sleep -Seconds 1
|
||||
|
||||
# 重新检查文件大小
|
||||
$NewLogSize = Get-LogFileSize "/var/log/container/deployment.log"
|
||||
Write-Host "轮转后日志大小: $($NewLogSize / 1024) KB" -ForegroundColor Gray
|
||||
} # 检查是否触发了日志轮转(排除.lock文件)
|
||||
$bashCommandLsBackupRaw = "LANG=C ls -la /var/log/container/ | grep 'deployment\.log\.' | grep -v '\.lock' | grep -v '^-.*deployment\.log$'"
|
||||
$bashCommandLsBackup = $bashCommandLsBackupRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$BackupFiles = docker exec $ContainerName bash -c $bashCommandLsBackup 2>$null
|
||||
if ($BackupFiles) {
|
||||
Write-Host "检测到备份文件,日志轮转已触发:" -ForegroundColor Green
|
||||
$BackupFiles | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
}
|
||||
|
||||
# 为快速轮转测试在每个批次后短暂暂停
|
||||
if ($FastRotationTest) {
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Host "跳过日志生成步骤 (-SkipLogGeneration 已设置)" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
Write-Host "`n=== 步骤 4: 验证日志轮转结果 ===" -ForegroundColor Cyan
|
||||
|
||||
# 检查最终日志状态
|
||||
$FinalLogFiles = Get-LogFileList
|
||||
Write-Host "最终日志文件:" -ForegroundColor Gray
|
||||
$FinalLogFiles | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
|
||||
$CurrentLogSize = Get-LogFileSize "/var/log/container/deployment.log"
|
||||
Write-Host "最终日志大小: $($CurrentLogSize / 1024) KB" -ForegroundColor Gray
|
||||
|
||||
# 检查备份文件(排除.lock文件)
|
||||
$BackupFileCommandRaw = "LANG=C ls -la /var/log/container/ | grep 'deployment\.log\.' | grep -v '\.lock' | grep -v '^-.*deployment\.log$' | wc -l"
|
||||
$BackupFileCommand = $BackupFileCommandRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$BackupFileCount = docker exec $ContainerName bash -c $BackupFileCommand 2>$null
|
||||
|
||||
Write-Host "备份文件数量: $BackupFileCount" -ForegroundColor Gray
|
||||
|
||||
# 详细分析日志轮转效果
|
||||
Write-Host "`n=== 日志轮转分析报告 ===" -ForegroundColor Cyan
|
||||
if (-not $SkipLogGeneration) {
|
||||
Write-Host "总共生成日志条数: $TotalLogsGenerated 条" -ForegroundColor Gray
|
||||
$EstimatedTotalSize = $TotalLogsGenerated * 211 # 基于实际测量的字节数
|
||||
Write-Host "预估总数据量: $($EstimatedTotalSize / 1024) KB" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# 获取所有日志文件的详细信息
|
||||
# $bashCommandLsAll = ("LANG=C ls -la /var/log/container/deployment.log*" -replace "\\\\r\\\\n", "\\\\n") # Fix CRLF
|
||||
$bashCommandLsAllRaw = "LANG=C ls -la /var/log/container/deployment.log*"
|
||||
$bashCommandLsAll = $bashCommandLsAllRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$AllLogFiles = docker exec $ContainerName bash -c $bashCommandLsAll 2>$null
|
||||
if ($AllLogFiles) {
|
||||
Write-Host "所有相关日志文件:" -ForegroundColor Gray
|
||||
$AllLogFiles | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
|
||||
# 计算总的日志文件大小
|
||||
$TotalLogSize = 0
|
||||
$AllLogFiles | ForEach-Object {
|
||||
if ($_ -match '\s+(\d+)\s+.*deployment\.log') {
|
||||
$TotalLogSize += [int]$matches[1]
|
||||
}
|
||||
}
|
||||
Write-Host "所有日志文件总大小: $($TotalLogSize / 1024) KB" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# 测试评估
|
||||
$TestResults = @()
|
||||
|
||||
# 测试1: 检查日志轮转函数
|
||||
if ($RotateFunctionCheck -eq "FUNCTION_EXISTS") {
|
||||
$TestResults += "日志轮转函数: PASS"
|
||||
} else {
|
||||
$TestResults += "日志轮转函数: FAIL"
|
||||
}
|
||||
|
||||
# 测试2: 检查定期检查功能
|
||||
if ($PeriodicCheck -eq "PERIODIC_EXISTS") {
|
||||
$TestResults += "定期检查函数: PASS"
|
||||
} else {
|
||||
$TestResults += "定期检查函数: FAIL"
|
||||
}
|
||||
|
||||
# 测试3: 检查配置文件
|
||||
if ($LogrotateConfigCheck -eq "CONFIG_EXISTS") {
|
||||
$TestResults += "轮转配置文件: PASS"
|
||||
} else {
|
||||
$TestResults += "轮转配置文件: FAIL"
|
||||
}
|
||||
|
||||
# 测试4: 检查日志权限
|
||||
$bashCommandPermCheckRaw = "LANG=C ls -la /var/log/container/deployment.log | awk '{print `$1, `$3, `$4}'"
|
||||
$bashCommandPermCheck = $bashCommandPermCheckRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$LogPermissionCheck = docker exec $ContainerName bash -c $bashCommandPermCheck
|
||||
Write-Host "日志文件权限: $LogPermissionCheck" -ForegroundColor Gray
|
||||
if ($LogPermissionCheck -match "hexo.*hexo") {
|
||||
$TestResults += "日志权限: PASS"
|
||||
} else {
|
||||
$TestResults += "日志权限: FAIL"
|
||||
}
|
||||
|
||||
# 测试5: 检查备份文件命名(排除.lock文件)
|
||||
$bashCommandBackupNameRaw = "LANG=C ls /var/log/container/ | grep 'deployment\.log\.[0-9]' | grep -v '\.lock' | head -1"
|
||||
$bashCommandBackupName = $bashCommandBackupNameRaw.Replace("`r`n", "`n").Replace("`r", "`n")
|
||||
$BackupNamingCheck = docker exec $ContainerName bash -c $bashCommandBackupName 2>$null
|
||||
if ($BackupNamingCheck) {
|
||||
$TestResults += "备份文件命名: PASS"
|
||||
} else {
|
||||
$TestResults += "备份文件命名: FAIL - 没有找到正确命名的备份文件"
|
||||
}
|
||||
|
||||
if (-not $FastRotationTest -and -not $QuickLogGen) {
|
||||
# 测试6: 检查日志大小重置(仅在完整测试中)
|
||||
if ($CurrentLogSize -lt $InitialLogSize -or $BackupFileCount -gt 0) {
|
||||
$TestResults += "日志大小重置: PASS"
|
||||
} else {
|
||||
$TestResults += "日志大小重置: FAIL - 日志未被轮转"
|
||||
}
|
||||
} else {
|
||||
$TestResults += "日志大小重置: SKIP - 快速测试模式"
|
||||
}
|
||||
|
||||
# 计算成功率
|
||||
$TotalTests = $TestResults.Count
|
||||
$PassedTests = ($TestResults | Where-Object { $_ -match "PASS" }).Count
|
||||
$SkippedTests = ($TestResults | Where-Object { $_ -match "SKIP" }).Count
|
||||
$FailedTests = $TotalTests - $PassedTests - $SkippedTests
|
||||
$SuccessRate = [Math]::Round(($PassedTests / $TotalTests) * 100, 2)
|
||||
|
||||
Write-Host "`n=== 测试结果汇总 ===" -ForegroundColor Cyan
|
||||
Write-Host "总测试项: $TotalTests" -ForegroundColor Gray
|
||||
Write-Host "通过: $PassedTests" -ForegroundColor Green
|
||||
Write-Host "跳过: $SkippedTests" -ForegroundColor Yellow
|
||||
Write-Host "失败: $FailedTests" -ForegroundColor Red
|
||||
Write-Host "成功率: $SuccessRate%" -ForegroundColor Gray
|
||||
|
||||
Write-Host "`n详细结果:" -ForegroundColor Gray
|
||||
$TestResults | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
|
||||
# 保存测试报告
|
||||
$TestMode = if ($FastRotationTest) { "快速轮转测试" } elseif ($QuickLogGen) { "快速日志生成" } else { "完整轮转测试" }
|
||||
$PeriodicCheckResult = if ($TestResults | Where-Object { $_ -match "定期检查函数: PASS" }) { "通过" } else { "失败" }
|
||||
$PermissionCheckResult = if ($TestResults | Where-Object { $_ -match "日志权限: PASS" }) { "通过" } else { "失败" }
|
||||
$SizeControlCheckResult = if ($TestResults | Where-Object { $_ -match "日志大小重置: PASS" }) {
|
||||
"通过"
|
||||
} elseif ($TestResults | Where-Object { $_ -match "日志大小重置: SKIP" }) {
|
||||
"跳过(快速测试模式)"
|
||||
} else {
|
||||
"失败"
|
||||
}
|
||||
$BackupNamingCheckResult = if ($TestResults | Where-Object { $_ -match "备份文件命名: PASS" }) { "通过" } else { "失败" }
|
||||
$DetailedResults = $TestResults | ForEach-Object { $_ } | Out-String
|
||||
|
||||
$ReportContent = @"
|
||||
=== Hexo Container v0.0.3 日志轮转测试报告 ===
|
||||
测试时间: $(Get-Date)
|
||||
容器名称: $ContainerName
|
||||
日志大小阈值: ${LogSizeThresholdMB}MB
|
||||
测试模式: $TestMode
|
||||
|
||||
=== 测试统计 ===
|
||||
总测试项: $TotalTests
|
||||
通过: $PassedTests
|
||||
跳过: $SkippedTests
|
||||
失败: $FailedTests
|
||||
成功率: $SuccessRate%
|
||||
|
||||
=== 详细结果 ===
|
||||
$DetailedResults
|
||||
|
||||
=== 日志文件状态 ===
|
||||
初始大小: $($InitialLogSize / 1024) KB
|
||||
最终大小: $($CurrentLogSize / 1024) KB
|
||||
备份文件数: $BackupFileCount
|
||||
|
||||
=== v0.0.3 新功能验证 ===
|
||||
- 定期日志轮转检查: $PeriodicCheckResult
|
||||
- Git Hook 日志权限: $PermissionCheckResult
|
||||
- 智能日志大小控制: $SizeControlCheckResult
|
||||
- 时间戳备份文件: $BackupNamingCheckResult
|
||||
"@
|
||||
|
||||
$ReportFile = "$LogDir\log_rotation_test_report_$TimeStamp.txt"
|
||||
$ReportContent | Out-File -FilePath $ReportFile -Encoding UTF8
|
||||
|
||||
Write-Host "`n详细测试日志: $TestLog" -ForegroundColor Gray
|
||||
Write-Host "测试报告: $ReportFile" -ForegroundColor Gray
|
||||
|
||||
# 清理提示
|
||||
Write-Host "`n=== 测试完成 ===" -ForegroundColor Cyan
|
||||
Write-Host "日志轮转功能测试已完成。如需清理测试环境,请运行:" -ForegroundColor Gray
|
||||
Write-Host " .\cleanup_test.ps1" -ForegroundColor Gray
|
||||
|
||||
# 根据测试结果设置退出代码
|
||||
if ($FailedTests -eq 0) {
|
||||
Write-Host "SUCCESS: 所有日志轮转测试通过!" -ForegroundColor Green
|
||||
exit 0
|
||||
} else {
|
||||
Write-Host "WARNING: 部分日志轮转测试失败,请检查详细报告。" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
310
test/v0.0.3/windows/run_test.ps1
Normal file
310
test/v0.0.3/windows/run_test.ps1
Normal file
@@ -0,0 +1,310 @@
|
||||
# Hexo Container v0.0.3 运行测试脚本 (Windows)
|
||||
# run_test.ps1
|
||||
|
||||
param(
|
||||
[string]$Tag = "hexo-test:v0.0.3",
|
||||
[string]$ContainerName = "hexo-test-v003",
|
||||
[int]$HttpPort = 8080,
|
||||
[int]$SshPort = 2222,
|
||||
[int]$Puid = 1000,
|
||||
[int]$Pgid = 1000,
|
||||
[string]$TimeZone = "Asia/Shanghai"
|
||||
)
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
Set-Location $ScriptDir
|
||||
|
||||
Write-Host "=== Hexo Container v0.0.3 运行测试 ===" -ForegroundColor Cyan
|
||||
|
||||
# 创建日志目录
|
||||
$LogDir = ".\logs"
|
||||
if (-not (Test-Path $LogDir)) {
|
||||
New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# 创建测试数据目录
|
||||
$TestDataDir = ".\test_data"
|
||||
$HexoSiteDir = "$TestDataDir\hexo_site"
|
||||
$SshKeysDir = "$TestDataDir\ssh_keys"
|
||||
|
||||
Write-Host "创建测试数据目录..." -ForegroundColor Yellow
|
||||
New-Item -ItemType Directory -Path $HexoSiteDir -Force | Out-Null
|
||||
New-Item -ItemType Directory -Path $SshKeysDir -Force | Out-Null
|
||||
|
||||
# SSH 密钥文件路径定义
|
||||
$UserSshDir = Join-Path $env:USERPROFILE ".ssh"
|
||||
$DefaultPrivateKeyName = "id_rsa"
|
||||
$DefaultPublicKeyName = "id_rsa.pub"
|
||||
|
||||
$SourceUserPrivateKeyPath = Join-Path $UserSshDir $DefaultPrivateKeyName
|
||||
$SourceUserPublicKeyPath = Join-Path $UserSshDir $DefaultPublicKeyName
|
||||
|
||||
# $SshKeysDir is already defined as ".\\test_data\\ssh_keys" relative to script dir if Set-Location $ScriptDir is effective.
|
||||
# For robustness, use absolute paths for targets. $ScriptDir is defined at the start of the script.
|
||||
$TargetSshKeysDir = Join-Path $ScriptDir "test_data\\ssh_keys"
|
||||
|
||||
# Ensure $TargetSshKeysDir (which is $SshKeysDir) is created. The script does this above.
|
||||
# New-Item -ItemType Directory -Path $TargetSshKeysDir -Force | Out-Null # Redundant if $SshKeysDir creation is confirmed above
|
||||
|
||||
$TargetPrivateKeyPath = Join-Path $TargetSshKeysDir "test_key"
|
||||
$TargetPublicKeyPath = Join-Path $TargetSshKeysDir "test_key.pub"
|
||||
$TargetAuthorizedKeysPath = Join-Path $TargetSshKeysDir "authorized_keys"
|
||||
|
||||
Write-Host "检查 SSH 密钥文件..." -ForegroundColor Yellow
|
||||
|
||||
# 优先: 尝试从用户默认 SSH 目录复制
|
||||
if ((Test-Path $SourceUserPrivateKeyPath) -and (Test-Path $SourceUserPublicKeyPath)) {
|
||||
Write-Host "在用户默认 SSH 目录 ($UserSshDir) 中找到密钥 ($DefaultPrivateKeyName, $DefaultPublicKeyName)。" -ForegroundColor Green
|
||||
Write-Host "正在复制 '$DefaultPrivateKeyName' 到 '$TargetPrivateKeyPath'..." -ForegroundColor Gray
|
||||
try {
|
||||
Copy-Item -Path $SourceUserPrivateKeyPath -Destination $TargetPrivateKeyPath -Force -ErrorAction Stop
|
||||
Write-Host " 成功复制私钥。" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Host " 警告: 复制私钥 '$SourceUserPrivateKeyPath' 到 '$TargetPrivateKeyPath' 失败: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
Write-Host " 请检查源文件权限或目标目录权限。" -ForegroundColor Yellow
|
||||
}
|
||||
Write-Host "正在复制 '$DefaultPublicKeyName' 到 '$TargetPublicKeyPath'..." -ForegroundColor Gray
|
||||
try {
|
||||
Copy-Item -Path $SourceUserPublicKeyPath -Destination $TargetPublicKeyPath -Force -ErrorAction Stop
|
||||
Write-Host " 成功复制公钥。" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Host " 警告: 复制公钥 '$SourceUserPublicKeyPath' 到 '$TargetPublicKeyPath' 失败: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
Write-Host " 请检查源文件权限或目标目录权限。" -ForegroundColor Yellow
|
||||
}
|
||||
} else {
|
||||
Write-Host "未在用户默认 SSH 目录 ($UserSshDir) 中找到 '$DefaultPrivateKeyName' 和 '$DefaultPublicKeyName'。" -ForegroundColor Yellow
|
||||
Write-Host "将检查 '$TargetSshKeysDir' 目录中是否已存在 'test_key' 和 'test_key.pub'。" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# 次选/验证: 检查测试数据目录中是否已存在 'test_key' 和 'test_key.pub'
|
||||
if (-not (Test-Path $TargetPrivateKeyPath) -or -not (Test-Path $TargetPublicKeyPath)) {
|
||||
Write-Host "错误: 最终未能获取 SSH 密钥。" -ForegroundColor Red
|
||||
Write-Host " '$($TargetPrivateKeyPath.Split('\\')[-1])' 或 '$($TargetPublicKeyPath.Split('\\')[-1])' 未在 '$TargetSshKeysDir' 目录中找到," -ForegroundColor Red
|
||||
Write-Host " 并且无法从用户默认 SSH 目录 ($UserSshDir) 自动复制。" -ForegroundColor Red
|
||||
Write-Host "请执行以下操作之一:" -ForegroundColor Red
|
||||
Write-Host " 1. 确保您的默认 SSH 密钥 ($SourceUserPrivateKeyPath 和 $SourceUserPublicKeyPath) 存在且可访问,脚本将尝试自动复制它们。" -ForegroundColor Red
|
||||
Write-Host " 2. 或者,手动将您的SSH私钥文件复制到 '$TargetSshKeysDir' 目录,并将其重命名为 'test_key'。" -ForegroundColor Red
|
||||
Write-Host " 3. 以及,手动将您对应的SSH公钥文件复制到 '$TargetSshKeysDir' 目录,并将其重命名为 'test_key.pub'。" -ForegroundColor Red
|
||||
Write-Host "如果您没有现成的密钥对,请先使用 ssh-keygen 等工具生成它们,并确保它们位于您的默认 SSH 目录或手动复制到测试目录。" -ForegroundColor Red
|
||||
exit 1
|
||||
} else {
|
||||
Write-Host "成功确认 'test_key' 和 'test_key.pub' 已存在于 '$TargetSshKeysDir'。" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# 至此, $TargetPrivateKeyPath 和 $TargetPublicKeyPath 应该已存在
|
||||
Write-Host "处理 SSH 密钥文件并设置权限..." -ForegroundColor Yellow
|
||||
try {
|
||||
# 从 test_key.pub 创建/覆盖 authorized_keys
|
||||
Copy-Item -Path $TargetPublicKeyPath -Destination $TargetAuthorizedKeysPath -Force
|
||||
Write-Host "已使用 '$TargetPublicKeyPath' 的内容创建/覆盖 '$TargetAuthorizedKeysPath'。" -ForegroundColor Green
|
||||
|
||||
# 在Windows上为三个文件设置基本权限
|
||||
Write-Host "尝试为 SSH 密钥文件设置本地权限..." -ForegroundColor Gray
|
||||
|
||||
$filesToSecure = @($TargetPrivateKeyPath, $TargetPublicKeyPath, $TargetAuthorizedKeysPath)
|
||||
foreach ($file in $filesToSecure) {
|
||||
icacls $file /inheritance:r /grant:r "$($env:USERNAME):F" /T 2>$null | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host " 警告: 设置 '$file' 权限可能失败。请检查文件是否存在以及您是否有权修改权限。" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host " 成功为 '$file' 设置权限。" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Host "错误: 处理 SSH 密钥文件或设置权限时发生错误: $($_.Exception.Message)" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 创建测试用的 HTML 文件
|
||||
$TestHtml = @"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hexo v0.0.3 Test Site</title>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 40px; background: #f5f5f5; }
|
||||
.container { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
|
||||
h1 { color: #333; border-bottom: 2px solid #007acc; padding-bottom: 10px; }
|
||||
.info { background: #e7f3ff; padding: 15px; border-radius: 4px; margin: 15px 0; }
|
||||
.status { display: inline-block; padding: 4px 8px; border-radius: 3px; color: white; background: #28a745; }
|
||||
ul { list-style-type: none; padding: 0; }
|
||||
li { padding: 8px; margin: 5px 0; background: #f8f9fa; border-left: 4px solid #007acc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Hexo Container v0.0.3 测试站点</h1>
|
||||
<div class="info">
|
||||
<p><strong>测试时间:</strong> <span id="time"></span></p>
|
||||
<p><strong>版本:</strong> <span class="status">v0.0.3</span></p>
|
||||
<p><strong>状态:</strong> <span class="status">运行中</span></p>
|
||||
</div>
|
||||
<h2>v0.0.3 新功能测试</h2>
|
||||
<ul>
|
||||
<li>定期日志轮转 (每30分钟检查)</li>
|
||||
<li>Git Hook 日志权限修复</li>
|
||||
<li>增强的部署日志管理</li>
|
||||
<li>智能日志文件大小控制</li>
|
||||
<li>自动旧日志清理</li>
|
||||
<li>时间戳备份文件生成</li>
|
||||
</ul>
|
||||
|
||||
<h2>测试链接</h2>
|
||||
<ul>
|
||||
<li><a href="/health">健康检查端点</a></li>
|
||||
<li>SSH 连接: ssh -p $SshPort hexo@localhost</li>
|
||||
</ul>
|
||||
</div>
|
||||
<script>
|
||||
document.getElementById('time').textContent = new Date().toLocaleString('zh-CN');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
"@
|
||||
|
||||
Write-Host "创建测试网站文件..." -ForegroundColor Yellow
|
||||
$TestHtml | Out-File -FilePath "$HexoSiteDir\index.html" -Encoding UTF8
|
||||
|
||||
# 停止并删除已存在的容器
|
||||
Write-Host "清理旧容器..." -ForegroundColor Yellow
|
||||
docker stop $ContainerName 2>$null | Out-Null
|
||||
docker rm $ContainerName 2>$null | Out-Null
|
||||
|
||||
# 检查端口是否被占用
|
||||
$HttpPortInUse = Get-NetTCPConnection -LocalPort $HttpPort -ErrorAction SilentlyContinue
|
||||
$SshPortInUse = Get-NetTCPConnection -LocalPort $SshPort -ErrorAction SilentlyContinue
|
||||
|
||||
if ($HttpPortInUse) {
|
||||
Write-Host "警告: 端口 $HttpPort 已被占用" -ForegroundColor Yellow
|
||||
}
|
||||
if ($SshPortInUse) {
|
||||
Write-Host "警告: 端口 $SshPort 已被占用" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# 构建 Docker 运行命令
|
||||
$DockerCmd = @"
|
||||
docker run -d ``
|
||||
--name $ContainerName ``
|
||||
-p $($HttpPort):80 ``
|
||||
-p $($SshPort):22 ``
|
||||
-e PUID=$Puid ``
|
||||
-e PGID=$Pgid ``
|
||||
-e TZ=$TimeZone ``
|
||||
-e HTTP_PORT=80 ``
|
||||
-e SSH_PORT=22 `` -v "$ScriptDir\test_data\hexo_site:/home/www/hexo" ``
|
||||
-v "$ScriptDir\test_data\ssh_keys:/home/hexo/.ssh" ``
|
||||
$Tag
|
||||
"@
|
||||
|
||||
Write-Host "`n启动容器..." -ForegroundColor Yellow
|
||||
Write-Host "执行命令:" -ForegroundColor Gray
|
||||
Write-Host $DockerCmd -ForegroundColor Gray
|
||||
|
||||
# 执行 Docker 运行命令
|
||||
try {
|
||||
$ContainerId = Invoke-Expression $DockerCmd
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "`n=== 容器启动成功 ===" -ForegroundColor Green
|
||||
Write-Host "容器 ID: $ContainerId" -ForegroundColor Green
|
||||
Write-Host "容器名称: $ContainerName" -ForegroundColor Green
|
||||
|
||||
# 等待容器启动
|
||||
Write-Host "`n等待容器完全启动..." -ForegroundColor Yellow
|
||||
Start-Sleep -Seconds 15
|
||||
|
||||
# 检查容器状态
|
||||
$ContainerStatus = docker ps --filter "name=$ContainerName" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||
|
||||
Write-Host "`n=== 容器状态 ===" -ForegroundColor Cyan
|
||||
Write-Host $ContainerStatus -ForegroundColor Green
|
||||
|
||||
# 在容器内修复 authorized_keys 权限
|
||||
Write-Host "\\n=== 修复容器内 SSH authorized_keys 权限 ===" -ForegroundColor Cyan
|
||||
try {
|
||||
Write-Host "在容器内执行: chmod 600 /home/hexo/.ssh/authorized_keys" -ForegroundColor Gray
|
||||
docker exec $ContainerName chmod 600 /home/hexo/.ssh/authorized_keys
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "[警告] chmod 600 /home/hexo/.ssh/authorized_keys 失败。" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host "[成功] chmod 600 /home/hexo/.ssh/authorized_keys 执行完毕。" -ForegroundColor Green
|
||||
}
|
||||
|
||||
Write-Host "在容器内执行: chown hexo:hexo /home/hexo/.ssh/authorized_keys" -ForegroundColor Gray
|
||||
docker exec $ContainerName chown hexo:hexo /home/hexo/.ssh/authorized_keys
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "[警告] chown hexo:hexo /home/hexo/.ssh/authorized_keys 失败。" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host "[成功] chown hexo:hexo /home/hexo/.ssh/authorized_keys 执行完毕。" -ForegroundColor Green
|
||||
}
|
||||
} catch {
|
||||
Write-Host "[错误] 修复 SSH authorized_keys 权限时发生错误: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# 显示访问信息
|
||||
Write-Host "\\n=== 访问信息 ===" -ForegroundColor Cyan
|
||||
Write-Host "HTTP 访问地址: http://localhost:$HttpPort" -ForegroundColor Green
|
||||
Write-Host "健康检查地址: http://localhost:$HttpPort/health" -ForegroundColor Green
|
||||
Write-Host "SSH 连接命令: ssh -p $SshPort -i .\test_data\ssh_keys\test_key hexo@localhost" -ForegroundColor Green
|
||||
|
||||
# 显示容器日志
|
||||
Write-Host "`n=== 容器启动日志 (最后20行) ===" -ForegroundColor Cyan
|
||||
docker logs $ContainerName --tail 20
|
||||
# 基础健康检查
|
||||
Write-Host "`n=== 基础健康检查 ===" -ForegroundColor Cyan
|
||||
Start-Sleep -Seconds 5
|
||||
|
||||
try {
|
||||
$HealthResponse = Invoke-WebRequest -Uri "http://localhost:$HttpPort/health" -TimeoutSec 10
|
||||
# 修复: 正确处理响应内容
|
||||
$Content = if ($HealthResponse.Content -is [byte[]]) {
|
||||
[System.Text.Encoding]::UTF8.GetString($HealthResponse.Content).Trim()
|
||||
} else {
|
||||
$HealthResponse.Content.ToString().Trim()
|
||||
}
|
||||
if ($HealthResponse.StatusCode -eq 200 -and ($Content -eq "healthy" -or $Content -eq "OK")) {
|
||||
Write-Host "[SUCCESS] 健康检查通过" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] 健康检查失败: $Content" -ForegroundColor Red
|
||||
}
|
||||
} catch {
|
||||
Write-Host "[ERROR] 健康检查失败: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
try {
|
||||
$HttpResponse = Invoke-WebRequest -Uri "http://localhost:$HttpPort" -TimeoutSec 10
|
||||
if ($HttpResponse.StatusCode -eq 200) {
|
||||
Write-Host "[SUCCESS] HTTP 服务正常" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[FAIL] HTTP 服务异常: 状态码 $($HttpResponse.StatusCode)" -ForegroundColor Red
|
||||
}
|
||||
} catch {
|
||||
Write-Host "[ERROR] HTTP 服务异常: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
|
||||
Write-Host "`n=== 运行测试完成 ===" -ForegroundColor Cyan
|
||||
Write-Host "容器已成功启动并运行。使用以下命令进行进一步测试:" -ForegroundColor Gray
|
||||
Write-Host " .\functional_test.ps1 # 功能测试" -ForegroundColor Gray
|
||||
Write-Host " .\log_rotation_test.ps1 # 日志轮转测试" -ForegroundColor Gray
|
||||
Write-Host " .\cleanup_test.ps1 # 清理测试环境" -ForegroundColor Gray
|
||||
|
||||
return $true
|
||||
|
||||
} else {
|
||||
throw "Docker 容器启动失败"
|
||||
}
|
||||
} catch {
|
||||
Write-Host "`n=== 容器启动失败 ===" -ForegroundColor Red
|
||||
Write-Host "错误信息: $($_.Exception.Message)" -ForegroundColor Red
|
||||
|
||||
# 尝试显示错误日志
|
||||
try {
|
||||
Write-Host "`n=== 容器错误日志 ===" -ForegroundColor Yellow
|
||||
docker logs $ContainerName
|
||||
} catch {
|
||||
Write-Host "无法获取容器日志" -ForegroundColor Red
|
||||
}
|
||||
|
||||
return $false
|
||||
}
|
||||
455
test/v0.0.3/windows/start.ps1
Normal file
455
test/v0.0.3/windows/start.ps1
Normal file
@@ -0,0 +1,455 @@
|
||||
# Hexo Container v0.0.3 完整测试套件 (Windows)
|
||||
# start.ps1 - 一键启动所有测试
|
||||
|
||||
param(
|
||||
[switch]$SkipBuild = $false,
|
||||
[switch]$SkipFunctional = $false,
|
||||
[switch]$SkipLogRotation = $false,
|
||||
[switch]$SkipLogGeneration = $false,
|
||||
[switch]$QuickLogGen = $false,
|
||||
[switch]$FastRotationTest = $false,
|
||||
[switch]$CleanupAfter = $false,
|
||||
[switch]$SshDebug = $false, # 新增: 控制SSH详细输出
|
||||
[string]$Tag = "hexo-container:v0.0.3",
|
||||
[string]$ContainerName = "hexo-test-v003",
|
||||
[int]$HttpPort = 8080,
|
||||
[int]$SshPort = 2222
|
||||
)
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
Set-Location $ScriptDir
|
||||
|
||||
Write-Host "=== Hexo Container v0.0.3 完整测试套件 ===" -ForegroundColor Cyan
|
||||
Write-Host "这个脚本将执行完整的 v0.0.3 测试流程" -ForegroundColor Gray
|
||||
|
||||
# 创建日志目录
|
||||
$LogDir = ".\logs"
|
||||
if (-not (Test-Path $LogDir)) {
|
||||
New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# 智能清理和归档旧日志文件
|
||||
Write-Host "=== 智能清理和归档旧日志文件 ===" -ForegroundColor Cyan
|
||||
$OldLogsDir = "$LogDir\old"
|
||||
if (-not (Test-Path $OldLogsDir)) {
|
||||
New-Item -ItemType Directory -Path $OldLogsDir -Force | Out-Null
|
||||
Write-Host "创建旧日志归档目录: $OldLogsDir" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# 检查 deployment.log 文件的智能管理
|
||||
function Test-DeploymentLogCompatibility {
|
||||
param(
|
||||
[string]$DeploymentLogPath,
|
||||
[bool]$QuickLogGen,
|
||||
[bool]$SkipLogGeneration,
|
||||
[bool]$FastRotationTest
|
||||
)
|
||||
|
||||
if (-not (Test-Path $DeploymentLogPath)) {
|
||||
return $false
|
||||
}
|
||||
|
||||
try {
|
||||
# 检查文件大小来判断日志类型
|
||||
$fileSize = (Get-Item $DeploymentLogPath).Length
|
||||
$fileSizeKB = [math]::Round($fileSize / 1024, 2)
|
||||
|
||||
Write-Host "检测到现有 deployment.log,大小: $fileSizeKB KB" -ForegroundColor Gray
|
||||
|
||||
# 根据文件大小判断日志类型
|
||||
# 快速轮转测试: 通常 2-5KB (3批次 * 15条 = 45条日志)
|
||||
# 快速模式: 通常 10-100KB (5批次 * 100条 = 500条日志)
|
||||
# 正常模式: 通常 > 500KB (525批次 * 100条 = 52500条日志)
|
||||
# 跳过模式: 通常很小 < 10KB (只有系统日志)
|
||||
|
||||
if ($SkipLogGeneration) {
|
||||
# 跳过日志生成模式,任何现有文件都可以保留
|
||||
Write-Host "跳过日志生成模式:保留现有 deployment.log" -ForegroundColor Green
|
||||
return $true
|
||||
} elseif ($FastRotationTest) {
|
||||
# 快速轮转测试模式,检查是否已经是轮转测试的结果
|
||||
if ($fileSizeKB -ge 2 -and $fileSizeKB -le 10) {
|
||||
Write-Host "检测到快速轮转测试模式的现有文件,保留使用" -ForegroundColor Green
|
||||
return $true
|
||||
} else {
|
||||
Write-Host "现有文件不符合快速轮转测试模式要求,需要重新生成" -ForegroundColor Yellow
|
||||
return $false
|
||||
}
|
||||
} elseif ($QuickLogGen) {
|
||||
# 快速日志生成模式,检查是否已经是快速模式的结果
|
||||
if ($fileSizeKB -ge 10 -and $fileSizeKB -le 100) {
|
||||
Write-Host "检测到快速日志生成模式的现有文件,保留使用" -ForegroundColor Green
|
||||
return $true
|
||||
} else {
|
||||
Write-Host "现有文件不符合快速日志生成模式要求,需要重新生成" -ForegroundColor Yellow
|
||||
return $false
|
||||
}
|
||||
} else {
|
||||
# 正常模式,检查是否已经是正常模式的结果
|
||||
if ($fileSizeKB -ge 300) {
|
||||
Write-Host "检测到正常模式的现有文件,保留使用" -ForegroundColor Green
|
||||
return $true
|
||||
} else {
|
||||
Write-Host "现有文件不符合正常模式要求,需要重新生成" -ForegroundColor Yellow
|
||||
return $false
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Host "检查 deployment.log 兼容性时出错: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
# 检查 deployment.log 是否需要处理
|
||||
$DeploymentLogPath = "$LogDir\deployment.log"
|
||||
$KeepDeploymentLog = Test-DeploymentLogCompatibility -DeploymentLogPath $DeploymentLogPath -QuickLogGen $QuickLogGen -SkipLogGeneration $SkipLogGeneration -FastRotationTest $FastRotationTest
|
||||
|
||||
# 移动旧的日志和报告文件到 old 文件夹 (排除符合条件的 deployment.log)
|
||||
$OldLogFiles = Get-ChildItem $LogDir -File | Where-Object {
|
||||
($_.Extension -eq ".log" -or $_.Extension -eq ".txt") -and
|
||||
-not ($_.Name -eq "deployment.log" -and $KeepDeploymentLog)
|
||||
}
|
||||
|
||||
if ($OldLogFiles.Count -gt 0) {
|
||||
Write-Host "归档 $($OldLogFiles.Count) 个旧日志文件到 old 文件夹..." -ForegroundColor Gray
|
||||
foreach ($file in $OldLogFiles) {
|
||||
$destPath = Join-Path $OldLogsDir $file.Name
|
||||
Move-Item $file.FullName $destPath -Force
|
||||
Write-Host " 移动: $($file.Name)" -ForegroundColor Gray
|
||||
}
|
||||
} else {
|
||||
Write-Host "没有旧日志文件需要归档" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# 智能处理容器内的 deployment.log
|
||||
Write-Host "智能处理容器内的 deployment.log..." -ForegroundColor Gray
|
||||
try {
|
||||
# 检查容器是否存在并运行
|
||||
$ContainerStatus = docker ps -f "name=$ContainerName" --format "table {{.Names}}\t{{.Status}}" 2>$null
|
||||
if ($ContainerStatus -match $ContainerName) {
|
||||
if (-not $KeepDeploymentLog) {
|
||||
Write-Host "发现运行中的容器,清空 deployment.log..." -ForegroundColor Gray
|
||||
docker exec $ContainerName sh -c "echo '' > /var/log/container/deployment.log" 2>$null
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "deployment.log 已清空,将重新生成" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "清空 deployment.log 失败,容器可能没有运行" -ForegroundColor Yellow
|
||||
}
|
||||
} else {
|
||||
Write-Host "保留现有的 deployment.log,跳过清空操作" -ForegroundColor Green
|
||||
}
|
||||
} else {
|
||||
Write-Host "容器未运行,将在容器启动时处理 deployment.log" -ForegroundColor Yellow
|
||||
}
|
||||
} catch {
|
||||
Write-Host "处理 deployment.log 时出错: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
$TestSuiteLog = "$LogDir\test_suite_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
|
||||
$TestResults = @()
|
||||
|
||||
# 记录测试结果的函数
|
||||
function Add-TestResult {
|
||||
param($Phase, $Status, $Duration, $Message = "")
|
||||
$script:TestResults += [PSCustomObject]@{
|
||||
Phase = $Phase
|
||||
Status = $Status
|
||||
Duration = $Duration
|
||||
Message = $Message
|
||||
Timestamp = Get-Date
|
||||
}
|
||||
$LogEntry = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $Phase : $Status ($($Duration.ToString('F2'))s) $Message"
|
||||
Write-Host $LogEntry -ForegroundColor Gray
|
||||
$LogEntry | Add-Content $TestSuiteLog -Encoding UTF8
|
||||
}
|
||||
|
||||
Write-Host "`n测试配置:" -ForegroundColor Yellow
|
||||
Write-Host "镜像标签: $Tag" -ForegroundColor Gray
|
||||
Write-Host "容器名称: $ContainerName" -ForegroundColor Gray
|
||||
Write-Host "HTTP 端口: $HttpPort" -ForegroundColor Gray
|
||||
Write-Host "SSH 端口: $SshPort" -ForegroundColor Gray
|
||||
Write-Host "跳过构建: $SkipBuild" -ForegroundColor Gray
|
||||
Write-Host "跳过功能测试: $SkipFunctional" -ForegroundColor Gray
|
||||
Write-Host "跳过日志轮转测试: $SkipLogRotation" -ForegroundColor Gray
|
||||
Write-Host "跳过日志数据生成: $SkipLogGeneration" -ForegroundColor Gray
|
||||
Write-Host "快速日志生成模式: $QuickLogGen" -ForegroundColor Gray
|
||||
Write-Host "快速轮转测试模式: $FastRotationTest" -ForegroundColor Gray
|
||||
Write-Host "测试后清理: $CleanupAfter" -ForegroundColor Gray
|
||||
Write-Host "SSH 详细输出: $SshDebug" -ForegroundColor Gray # 新增: 显示SSH Debug状态
|
||||
|
||||
# 阶段 1: 构建测试
|
||||
if (-not $SkipBuild) {
|
||||
Write-Host "`n=== 阶段 1: 构建镜像 ===" -ForegroundColor Cyan
|
||||
$BuildStart = Get-Date
|
||||
|
||||
try {
|
||||
$BuildResult = & ".\build_test.ps1" -Tag $Tag
|
||||
$BuildEnd = Get-Date
|
||||
$BuildDuration = ($BuildEnd - $BuildStart).TotalSeconds
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "[SUCCESS] 构建阶段完成" -ForegroundColor Green
|
||||
Add-TestResult "构建镜像" "SUCCESS" $BuildDuration
|
||||
} else {
|
||||
Write-Host "[FAIL] 构建阶段失败" -ForegroundColor Red
|
||||
Add-TestResult "构建镜像" "FAIL" $BuildDuration
|
||||
Write-Host "测试中止:构建失败" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
} catch {
|
||||
$BuildEnd = Get-Date
|
||||
$BuildDuration = ($BuildEnd - $BuildStart).TotalSeconds
|
||||
Write-Host "[ERROR] 构建阶段异常: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Add-TestResult "构建镜像" "ERROR" $BuildDuration $_.Exception.Message
|
||||
exit 1
|
||||
}
|
||||
} else {
|
||||
Write-Host "[SKIP] 跳过构建阶段" -ForegroundColor Yellow
|
||||
Add-TestResult "构建镜像" "SKIPPED" 0
|
||||
}
|
||||
|
||||
# 阶段 2: 启动容器
|
||||
Write-Host "`n=== 阶段 2: 启动容器 ===" -ForegroundColor Cyan
|
||||
$RunStart = Get-Date
|
||||
|
||||
try {
|
||||
$RunResult = & ".\run_test.ps1" -Tag $Tag -ContainerName $ContainerName -HttpPort $HttpPort -SshPort $SshPort
|
||||
$RunEnd = Get-Date
|
||||
$RunDuration = ($RunEnd - $RunStart).TotalSeconds
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "[SUCCESS] 容器启动完成" -ForegroundColor Green
|
||||
Add-TestResult "启动容器" "SUCCESS" $RunDuration
|
||||
} else {
|
||||
Write-Host "[FAIL] 容器启动失败" -ForegroundColor Red
|
||||
Add-TestResult "启动容器" "FAIL" $RunDuration
|
||||
Write-Host "测试中止:容器启动失败" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
} catch {
|
||||
$RunEnd = Get-Date
|
||||
$RunDuration = ($RunEnd - $RunStart).TotalSeconds
|
||||
Write-Host "[ERROR] 容器启动异常: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Add-TestResult "启动容器" "ERROR" $RunDuration $_.Exception.Message
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 等待容器完全就绪
|
||||
Write-Host "`n等待容器服务就绪..." -ForegroundColor Yellow
|
||||
Start-Sleep -Seconds 20
|
||||
|
||||
# 阶段 3: 功能测试
|
||||
if (-not $SkipFunctional) {
|
||||
Write-Host "`n=== 阶段 3: 功能测试 ===" -ForegroundColor Cyan
|
||||
$FuncStart = Get-Date
|
||||
|
||||
try {
|
||||
$FuncResult = & ".\\functional_test.ps1" -ContainerName $ContainerName -HttpPort $HttpPort -SshPort $SshPort -SshDebug:$SshDebug # 修改: 传递 $SshDebug
|
||||
$FuncEnd = Get-Date
|
||||
$FuncDuration = ($FuncEnd - $FuncStart).TotalSeconds
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "[SUCCESS] 功能测试完成" -ForegroundColor Green
|
||||
Add-TestResult "功能测试" "SUCCESS" $FuncDuration
|
||||
} else {
|
||||
Write-Host "[FAIL] 功能测试失败" -ForegroundColor Red
|
||||
Add-TestResult "功能测试" "FAIL" $FuncDuration
|
||||
}
|
||||
} catch {
|
||||
$FuncEnd = Get-Date
|
||||
$FuncDuration = ($FuncEnd - $FuncStart).TotalSeconds
|
||||
Write-Host "[ERROR] 功能测试异常: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Add-TestResult "功能测试" "ERROR" $FuncDuration $_.Exception.Message
|
||||
}
|
||||
} else {
|
||||
Write-Host "[SKIP] 跳过功能测试阶段" -ForegroundColor Yellow
|
||||
Add-TestResult "功能测试" "SKIPPED" 0
|
||||
}
|
||||
|
||||
# 阶段 4: 日志轮转测试 (v0.0.3 新功能)
|
||||
if (-not $SkipLogRotation) {
|
||||
Write-Host "`n=== 阶段 4: 日志轮转测试 (v0.0.3 新功能) ===" -ForegroundColor Cyan
|
||||
$LogStart = Get-Date
|
||||
try {
|
||||
# 调用日志轮转测试脚本,并传递 -CalledFromTestSuite 参数
|
||||
$LogResult = & ".\\log_rotation_test.ps1" -ContainerName $ContainerName -HttpPort $HttpPort -SshPort $SshPort -FastRotationTest:$FastRotationTest -QuickLogGen:$QuickLogGen -SkipLogGeneration:$SkipLogGeneration -CalledFromTestSuite:$true -SshDebug:$SshDebug # 修改: 传递 $SshDebug
|
||||
$LogEnd = Get-Date
|
||||
$LogDuration = ($LogEnd - $LogStart).TotalSeconds
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "[SUCCESS] 日志轮转测试完成" -ForegroundColor Green
|
||||
Add-TestResult "日志轮转测试" "SUCCESS" $LogDuration
|
||||
} else {
|
||||
Write-Host "[FAIL] 日志轮转测试失败" -ForegroundColor Red
|
||||
Add-TestResult "日志轮转测试" "FAIL" $LogDuration
|
||||
}
|
||||
} catch {
|
||||
$LogEnd = Get-Date
|
||||
$LogDuration = ($LogEnd - $LogStart).TotalSeconds
|
||||
Write-Host "[ERROR] 日志轮转测试异常: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Add-TestResult "日志轮转测试" "ERROR" $LogDuration $_.Exception.Message
|
||||
}
|
||||
} else {
|
||||
Write-Host "[SKIP] 跳过日志轮转测试阶段" -ForegroundColor Yellow
|
||||
Add-TestResult "日志轮转测试" "SKIPPED" 0
|
||||
}
|
||||
|
||||
# 阶段 5: 清理 (可选)
|
||||
if ($CleanupAfter) {
|
||||
Write-Host "`n=== 阶段 5: 测试后清理 ===" -ForegroundColor Cyan
|
||||
$CleanStart = Get-Date
|
||||
try {
|
||||
$CleanResult = & ".\cleanup_test.ps1" -ContainerName $ContainerName -ImageTag $Tag -Force -Interactive:$false
|
||||
$CleanEnd = Get-Date
|
||||
$CleanDuration = ($CleanEnd - $CleanStart).TotalSeconds
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "[SUCCESS] 清理完成" -ForegroundColor Green
|
||||
Add-TestResult "测试后清理" "SUCCESS" $CleanDuration
|
||||
} else {
|
||||
Write-Host "[FAIL] 清理失败" -ForegroundColor Red
|
||||
Add-TestResult "测试后清理" "FAIL" $CleanDuration
|
||||
}
|
||||
} catch {
|
||||
$CleanEnd = Get-Date
|
||||
$CleanDuration = ($CleanEnd - $CleanStart).TotalSeconds
|
||||
Write-Host "[ERROR] 清理异常: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Add-TestResult "测试后清理" "ERROR" $CleanDuration $_.Exception.Message
|
||||
}
|
||||
} else {
|
||||
Write-Host "[SKIP] 跳过清理阶段 (容器保持运行)" -ForegroundColor Yellow
|
||||
Add-TestResult "测试后清理" "SKIPPED" 0
|
||||
}
|
||||
|
||||
# 生成完整测试报告
|
||||
Write-Host "`n=== Hexo Container v0.0.3 完整测试报告 ===" -ForegroundColor Cyan
|
||||
|
||||
$SuccessCount = ($TestResults | Where-Object { $_.Status -eq "SUCCESS" }).Count
|
||||
$FailCount = ($TestResults | Where-Object { $_.Status -eq "FAIL" }).Count
|
||||
$ErrorCount = ($TestResults | Where-Object { $_.Status -eq "ERROR" }).Count
|
||||
$SkippedCount = ($TestResults | Where-Object { $_.Status -eq "SKIPPED" }).Count
|
||||
$TotalPhases = $TestResults.Count
|
||||
|
||||
$TotalDuration = ($TestResults | Where-Object { $_.Status -ne "SKIPPED" } | Measure-Object -Property Duration -Sum).Sum
|
||||
|
||||
Write-Host "`n=== 测试统计 ===" -ForegroundColor White
|
||||
Write-Host "总阶段数: $TotalPhases" -ForegroundColor White
|
||||
Write-Host "成功: $SuccessCount" -ForegroundColor Green
|
||||
Write-Host "失败: $FailCount" -ForegroundColor Red
|
||||
Write-Host "错误: $ErrorCount" -ForegroundColor Yellow
|
||||
Write-Host "跳过: $SkippedCount" -ForegroundColor Gray
|
||||
|
||||
$SuccessRate = if (($TotalPhases - $SkippedCount) -gt 0) {
|
||||
($SuccessCount / ($TotalPhases - $SkippedCount) * 100).ToString("F1")
|
||||
} else {
|
||||
"0.0"
|
||||
}
|
||||
Write-Host "成功率: $SuccessRate%" -ForegroundColor $(if ($FailCount -eq 0 -and $ErrorCount -eq 0) { "Green" } else { "Yellow" })
|
||||
Write-Host "总耗时: $($TotalDuration.ToString('F2')) 秒" -ForegroundColor Gray
|
||||
|
||||
# 详细阶段结果
|
||||
Write-Host "`n=== 详细阶段结果 ===" -ForegroundColor White
|
||||
$TestResults | Format-Table -Property Phase, Status, @{Name="Duration(s)"; Expression={$_.Duration.ToString("F2")}}, Timestamp -AutoSize
|
||||
|
||||
# v0.0.3 新功能测试摘要
|
||||
Write-Host "`n=== v0.0.3 新功能测试摘要 ===" -ForegroundColor Cyan
|
||||
$LogRotationResult = $TestResults | Where-Object { $_.Phase -eq "日志轮转测试" }
|
||||
if ($LogRotationResult) {
|
||||
$Status = $LogRotationResult.Status
|
||||
$StatusColor = switch ($Status) {
|
||||
"SUCCESS" { "Green" }
|
||||
"FAIL" { "Red" }
|
||||
"ERROR" { "Yellow" }
|
||||
"SKIPPED" { "Gray" }
|
||||
}
|
||||
Write-Host "日志轮转功能: $Status" -ForegroundColor $StatusColor
|
||||
} else {
|
||||
Write-Host "日志轮转功能: 未测试" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# 失败阶段详情
|
||||
$FailedPhases = $TestResults | Where-Object { $_.Status -eq "FAIL" -or $_.Status -eq "ERROR" }
|
||||
if ($FailedPhases) {
|
||||
Write-Host "`n=== 失败阶段详情 ===" -ForegroundColor Red
|
||||
$FailedPhases | ForEach-Object {
|
||||
Write-Host "[FAIL] $($_.Phase): $($_.Status)" -ForegroundColor Red
|
||||
if ($_.Message) {
|
||||
Write-Host " 错误信息: $($_.Message)" -ForegroundColor Gray
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 保存完整报告
|
||||
$ReportContent = @"
|
||||
=== Hexo Container v0.0.3 完整测试套件报告 ===
|
||||
测试时间: $(Get-Date)
|
||||
测试配置:
|
||||
镜像标签: $Tag
|
||||
容器名称: $ContainerName
|
||||
HTTP 端口: $HttpPort
|
||||
SSH 端口: $SshPort
|
||||
SSH 详细输出: $SshDebug # 新增
|
||||
|
||||
=== 测试统计 ===
|
||||
总阶段数: $TotalPhases
|
||||
成功: $SuccessCount
|
||||
失败: $FailCount
|
||||
错误: $ErrorCount
|
||||
跳过: $SkippedCount
|
||||
成功率: $SuccessRate%
|
||||
总耗时: $($TotalDuration.ToString('F2')) 秒
|
||||
|
||||
=== 详细结果 ===
|
||||
$($TestResults | ForEach-Object { "$($_.Timestamp.ToString('HH:mm:ss')) - $($_.Phase): $($_.Status) ($($_.Duration.ToString('F2'))s) $($_.Message)" } | Out-String)
|
||||
|
||||
=== v0.0.3 新功能验证 ===
|
||||
日志轮转测试: $(if ($LogRotationResult) { $LogRotationResult.Status } else { "未执行" })
|
||||
|
||||
=== 建议 ===
|
||||
$(if ($FailCount -eq 0 -and $ErrorCount -eq 0) {
|
||||
"[SUCCESS] 所有测试阶段成功完成!Hexo Container v0.0.3 可以投入使用。"
|
||||
} else {
|
||||
"[WARNING] 部分测试阶段失败,建议检查详细日志并修复问题后重新测试。"
|
||||
})
|
||||
|
||||
测试完成。如需重新测试,请运行相应的测试脚本。
|
||||
"@
|
||||
|
||||
$FinalReportFile = "$LogDir\test_suite_report_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt"
|
||||
$ReportContent | Out-File -FilePath $FinalReportFile -Encoding UTF8
|
||||
|
||||
Write-Host "`n完整测试日志: $TestSuiteLog" -ForegroundColor Gray
|
||||
Write-Host "完整测试报告: $FinalReportFile" -ForegroundColor Gray
|
||||
|
||||
# 后续建议
|
||||
Write-Host "`n=== 后续操作建议 ===" -ForegroundColor Cyan
|
||||
if (-not $CleanupAfter) {
|
||||
Write-Host "容器当前正在运行,可以通过以下方式访问:" -ForegroundColor Gray
|
||||
Write-Host " 浏览器访问: http://localhost:$HttpPort" -ForegroundColor Gray
|
||||
Write-Host " 健康检查: http://localhost:$HttpPort/health" -ForegroundColor Gray
|
||||
Write-Host " SSH 连接: ssh -p $SshPort -i test_data\ssh_keys\test_key hexo@localhost" -ForegroundColor Gray
|
||||
Write-Host "`n清理测试环境: .\cleanup_test.ps1" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host "`n重新运行特定测试:" -ForegroundColor Gray
|
||||
Write-Host " .\functional_test.ps1 # 仅功能测试" -ForegroundColor Gray
|
||||
Write-Host " .\log_rotation_test.ps1 # 仅日志轮转测试" -ForegroundColor Gray
|
||||
Write-Host " .\log_rotation_test.ps1 -FastRotationTest # 快速轮转测试(含备份验证)" -ForegroundColor Gray
|
||||
Write-Host " .\log_rotation_test.ps1 -SkipLogGeneration # 跳过大量日志生成的轮转测试" -ForegroundColor Gray
|
||||
|
||||
Write-Host "`n启动选项说明:" -ForegroundColor Gray
|
||||
Write-Host " -FastRotationTest # 快速轮转测试模式(降低阈值,验证完整轮转功能)" -ForegroundColor Gray
|
||||
Write-Host " -QuickLogGen # 快速日志生成模式(不触发轮转,仅验证日志写入)" -ForegroundColor Gray
|
||||
Write-Host " -SkipLogGeneration # 跳过大量日志数据生成(加快测试速度)" -ForegroundColor Gray
|
||||
Write-Host " -SkipBuild # 跳过Docker镜像构建" -ForegroundColor Gray
|
||||
Write-Host " -SkipFunctional # 跳过功能测试" -ForegroundColor Gray
|
||||
Write-Host " -SkipLogRotation # 跳过日志轮转测试" -ForegroundColor Gray
|
||||
Write-Host " -CleanupAfter # 测试完成后自动清理" -ForegroundColor Gray
|
||||
Write-Host " -SshDebug # 启用SSH详细输出模式" -ForegroundColor Gray # 新增
|
||||
|
||||
Write-Host "`n=== 测试套件完成 ===" -ForegroundColor Cyan
|
||||
|
||||
# 根据结果设置退出代码
|
||||
if ($FailCount -eq 0 -and $ErrorCount -eq 0) {
|
||||
Write-Host "[SUCCESS] 完整测试套件成功完成!" -ForegroundColor Green
|
||||
exit 0
|
||||
} else {
|
||||
Write-Host "[WARNING] 测试套件中有失败项目,请检查详细报告。" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
341
test/v0.0.3/windows/test_log_size_reset.ps1
Normal file
341
test/v0.0.3/windows/test_log_size_reset.ps1
Normal file
@@ -0,0 +1,341 @@
|
||||
# 专用于测试日志大小重置功能的脚本
|
||||
# test_log_size_reset_fixed.ps1
|
||||
|
||||
param(
|
||||
[string]$ContainerName = "hexo-test-v003",
|
||||
[int]$SshPort = 2222,
|
||||
[string]$SshKeyPath = ".\test_data\ssh_keys\test_key",
|
||||
[int]$TargetSizeKB = 25, # 目标大小,超过20KB阈值
|
||||
[switch]$Verbose = $false
|
||||
)
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
Set-Location $ScriptDir
|
||||
|
||||
# 确保 SSH 密钥路径为绝对路径
|
||||
$SshKeyPath = Join-Path $ScriptDir "test_data\ssh_keys\test_key"
|
||||
|
||||
Write-Host "=== 日志大小重置功能专项测试 ===" -ForegroundColor Cyan
|
||||
Write-Host "目标: 验证日志文件超过 20KB 时能否正确重置" -ForegroundColor Gray
|
||||
|
||||
# 创建日志目录
|
||||
$LogDir = ".\logs"
|
||||
if (-not (Test-Path $LogDir)) {
|
||||
New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
|
||||
}
|
||||
|
||||
$TimeStamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||||
$TestLog = "$LogDir\log_size_reset_test_$TimeStamp.log"
|
||||
|
||||
# 检查容器是否运行
|
||||
Write-Host "`n检查容器状态..." -ForegroundColor Yellow
|
||||
$ContainerRunning = docker ps --filter "name=$ContainerName" --format "{{.Names}}" | Select-String $ContainerName
|
||||
if (-not $ContainerRunning) {
|
||||
Write-Host "ERROR: 容器 $ContainerName 未运行" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
Write-Host "SUCCESS: 容器正在运行" -ForegroundColor Green
|
||||
|
||||
# 检查 SSH 密钥
|
||||
if (-not (Test-Path $SshKeyPath)) {
|
||||
Write-Host "ERROR: SSH 密钥不存在: $SshKeyPath" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 函数:清理重复的deployment.log文件
|
||||
function Clear-DuplicateDeploymentLogs {
|
||||
param([string]$ContainerName)
|
||||
|
||||
$bashScript = @'
|
||||
cd /var/log/container
|
||||
# Check if there are duplicate deployment.log files
|
||||
LOG_COUNT=$(ls -1 deployment.log 2>/dev/null | wc -l)
|
||||
if [ $LOG_COUNT -gt 1 ]; then
|
||||
echo 'Found duplicate deployment.log files, cleaning up...'
|
||||
# Remove all deployment.log files and recreate one
|
||||
rm -f deployment.log
|
||||
touch deployment.log
|
||||
chown hexo:hexo deployment.log
|
||||
chmod 664 deployment.log
|
||||
echo 'Duplicate files cleaned'
|
||||
elif [ $LOG_COUNT -eq 0 ]; then
|
||||
touch deployment.log
|
||||
chown hexo:hexo deployment.log
|
||||
chmod 664 deployment.log
|
||||
else
|
||||
chown hexo:hexo deployment.log
|
||||
chmod 664 deployment.log
|
||||
fi
|
||||
'@
|
||||
|
||||
docker exec $ContainerName bash -c $bashScript
|
||||
}
|
||||
|
||||
# 修复权限
|
||||
Write-Host "`n修复日志文件权限..." -ForegroundColor Yellow
|
||||
$bashScript = 'cd /var/log/container && UNIQUE_FILES=$(find . -name "deployment.log" -type f -exec ls -li {} \; 2>/dev/null | awk "{print \$1}" | sort -u | wc -l 2>/dev/null || echo 0) && if [ "$UNIQUE_FILES" -gt 1 ]; then echo "Found $UNIQUE_FILES unique deployment.log files, removing all duplicates..." && find . -name "deployment.log" -type f -delete 2>/dev/null || true; fi && mkdir -p /var/log/container && if [ ! -f /var/log/container/deployment.log ]; then touch /var/log/container/deployment.log; fi && chown hexo:hexo /var/log/container/deployment.log && chmod 664 /var/log/container/deployment.log && echo "Single deployment.log file ensured with correct permissions"'
|
||||
|
||||
docker exec $ContainerName bash -c $bashScript
|
||||
|
||||
# 清理重复的deployment.log文件
|
||||
Clear-DuplicateDeploymentLogs -ContainerName $ContainerName
|
||||
|
||||
# 函数:获取日志文件大小
|
||||
function Get-LogFileSize {
|
||||
param([string]$LogPath)
|
||||
try {
|
||||
$bashScript = 'stat -c%s ' + $LogPath + ' 2>/dev/null || echo 0'
|
||||
$SizeBytes = docker exec $ContainerName bash -c $bashScript
|
||||
if ($null -eq $SizeBytes -or $SizeBytes -eq "") {
|
||||
return 0
|
||||
}
|
||||
return [int]$SizeBytes
|
||||
} catch {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
# 函数:获取备份文件数量
|
||||
function Get-BackupFileCount {
|
||||
try {
|
||||
$bashScript = 'LANG=C ls -la /var/log/container/ | grep "deployment\.log\.[0-9]" | wc -l'
|
||||
$BackupCount = docker exec $ContainerName bash -c $bashScript
|
||||
return [int]$BackupCount
|
||||
} catch {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
# 函数:获取唯一的文件列表(去重)
|
||||
function Get-UniqueFileList {
|
||||
param([string]$Pattern)
|
||||
try {
|
||||
# 使用find命令更精确地查找文件,避免重复
|
||||
$bashScript = 'LANG=C find /var/log/container/ -name "deployment.log*" -type f | sort | xargs ls -la'
|
||||
$FileList = docker exec $ContainerName bash -c $bashScript
|
||||
|
||||
# 去重处理
|
||||
if ($FileList) {
|
||||
$UniqueFiles = $FileList | Sort-Object | Get-Unique
|
||||
return $UniqueFiles
|
||||
} else {
|
||||
return @()
|
||||
}
|
||||
} catch {
|
||||
return @()
|
||||
}
|
||||
}
|
||||
|
||||
# 函数:生成指定大小的日志
|
||||
function Generate-LogToSize {
|
||||
param([int]$TargetSizeKB)
|
||||
|
||||
$TargetBytes = $TargetSizeKB * 1024
|
||||
$LogEntrySize = 150 # 估算单条日志大小
|
||||
$RequiredEntries = [Math]::Ceiling($TargetBytes / $LogEntrySize)
|
||||
|
||||
Write-Host "目标大小: $TargetSizeKB KB ($TargetBytes bytes)" -ForegroundColor Yellow
|
||||
Write-Host "预计需要生成: $RequiredEntries 条日志" -ForegroundColor Yellow
|
||||
|
||||
$BatchSize = 50
|
||||
$BatchCount = [Math]::Ceiling($RequiredEntries / $BatchSize)
|
||||
|
||||
for ($batch = 1; $batch -le $BatchCount; $batch++) {
|
||||
$EntriesInBatch = if ($batch -eq $BatchCount) {
|
||||
$RequiredEntries - (($batch - 1) * $BatchSize)
|
||||
} else {
|
||||
$BatchSize
|
||||
}
|
||||
|
||||
Write-Host "批次 $batch/$BatchCount : 生成 $EntriesInBatch 条日志..." -ForegroundColor Gray
|
||||
|
||||
for ($i = 1; $i -le $EntriesInBatch; $i++) {
|
||||
$CurrentTime = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' $LogMessage = "SIZE_TEST_ENTRY_${batch}_${i} : $CurrentTime - 这是用于测试日志大小重置功能的测试条目。此条目包含足够的内容以达到预期的文件大小。批次${batch},条目${i}。"
|
||||
try {
|
||||
ssh -p $SshPort -i $SshKeyPath -o ConnectTimeout=10 -o StrictHostKeyChecking=no hexo@localhost "echo '$LogMessage' >> /var/log/container/deployment.log"
|
||||
|
||||
if ($Verbose -and ($i % 10 -eq 0)) {
|
||||
$CurrentSize = Get-LogFileSize "/var/log/container/deployment.log"
|
||||
Write-Host " 已生成 $i/$EntriesInBatch 条,当前大小: $([math]::Round($CurrentSize / 1024, 2)) KB" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Start-Sleep -Milliseconds 5
|
||||
} catch {
|
||||
Write-Host "生成日志失败: $($_.Exception.Message)" -ForegroundColor Red
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
# 检查当前大小
|
||||
$CurrentSize = Get-LogFileSize "/var/log/container/deployment.log"
|
||||
Write-Host "批次 $batch 完成,当前大小: $([math]::Round($CurrentSize / 1024, 2)) KB" -ForegroundColor Green
|
||||
|
||||
# 如果已经达到目标大小,提前退出
|
||||
if ($CurrentSize -ge $TargetBytes) {
|
||||
Write-Host "已达到目标大小,停止生成" -ForegroundColor Green
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 开始测试
|
||||
"=== 日志大小重置测试开始 $(Get-Date) ===" | Add-Content $TestLog
|
||||
|
||||
Write-Host "`n=== 步骤 1: 检查初始状态 ===" -ForegroundColor Cyan
|
||||
$InitialSize = Get-LogFileSize "/var/log/container/deployment.log"
|
||||
$InitialBackupCount = Get-BackupFileCount
|
||||
|
||||
Write-Host "初始日志大小: $([math]::Round($InitialSize / 1024, 2)) KB" -ForegroundColor Gray
|
||||
Write-Host "初始备份文件数: $InitialBackupCount" -ForegroundColor Gray
|
||||
|
||||
"初始状态 - 大小: $InitialSize bytes, 备份文件: $InitialBackupCount" | Add-Content $TestLog
|
||||
|
||||
Write-Host "`n=== 步骤 2: 生成日志至目标大小 ===" -ForegroundColor Cyan
|
||||
Generate-LogToSize -TargetSizeKB $TargetSizeKB
|
||||
|
||||
Write-Host "`n=== 步骤 3: 检查轮转前状态 ===" -ForegroundColor Cyan
|
||||
$PreRotationSize = Get-LogFileSize "/var/log/container/deployment.log"
|
||||
$PreRotationBackupCount = Get-BackupFileCount
|
||||
|
||||
Write-Host "轮转前日志大小: $([math]::Round($PreRotationSize / 1024, 2)) KB" -ForegroundColor Gray
|
||||
Write-Host "轮转前备份文件数: $PreRotationBackupCount" -ForegroundColor Gray
|
||||
|
||||
# 显示详细的文件列表
|
||||
$FileList = Get-UniqueFileList "deployment.log*"
|
||||
Write-Host "轮转前文件列表:" -ForegroundColor Gray
|
||||
if ($FileList -and $FileList.Count -gt 0) {
|
||||
$FileList | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
} else {
|
||||
Write-Host " 未找到相关文件" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host "`n=== 步骤 4: 手动触发日志轮转 ===" -ForegroundColor Cyan
|
||||
if ($PreRotationSize -gt (20 * 1024)) {
|
||||
Write-Host "日志大小超过 20KB 阈值,触发轮转..." -ForegroundColor Yellow
|
||||
# 手动强制执行 logrotate
|
||||
$bashScript = 'logrotate -f /etc/logrotate.d/deployment && echo "ROTATE_SUCCESS"'
|
||||
$RotateResult = docker exec $ContainerName bash -c $bashScript
|
||||
|
||||
if ($RotateResult -eq "ROTATE_SUCCESS") {
|
||||
Write-Host "SUCCESS: logrotate 执行成功" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "WARNING: logrotate 执行可能失败" -ForegroundColor Yellow
|
||||
Write-Host "返回结果: $RotateResult" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# 等待一下确保轮转完成
|
||||
Start-Sleep -Seconds 2
|
||||
} else {
|
||||
Write-Host "WARNING: 日志大小未超过 20KB 阈值,无法测试轮转" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
Write-Host "`n=== 步骤 5: 检查轮转后状态 ===" -ForegroundColor Cyan
|
||||
$PostRotationSize = Get-LogFileSize "/var/log/container/deployment.log"
|
||||
$PostRotationBackupCount = Get-BackupFileCount
|
||||
|
||||
Write-Host "轮转后日志大小: $([math]::Round($PostRotationSize / 1024, 2)) KB" -ForegroundColor Gray
|
||||
Write-Host "轮转后备份文件数: $PostRotationBackupCount" -ForegroundColor Gray
|
||||
|
||||
# 显示轮转后的文件列表
|
||||
$PostFileList = Get-UniqueFileList "deployment.log*"
|
||||
Write-Host "轮转后文件列表:" -ForegroundColor Gray
|
||||
if ($PostFileList -and $PostFileList.Count -gt 0) {
|
||||
$PostFileList | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
} else {
|
||||
Write-Host " 未找到相关文件" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host "`n=== 步骤 6: 分析轮转效果 ===" -ForegroundColor Cyan
|
||||
|
||||
# 分析结果
|
||||
$TestResults = @()
|
||||
|
||||
# 测试1: 检查是否生成了足够大的日志
|
||||
if ($PreRotationSize -gt (20 * 1024)) {
|
||||
$TestResults += "日志大小达标: PASS - 达到 $([math]::Round($PreRotationSize / 1024, 2)) KB"
|
||||
} else {
|
||||
$TestResults += "日志大小达标: FAIL - 仅达到 $([math]::Round($PreRotationSize / 1024, 2)) KB,未超过 20KB"
|
||||
}
|
||||
|
||||
# 测试2: 检查日志大小是否被重置
|
||||
if ($PostRotationSize -lt $PreRotationSize) {
|
||||
$TestResults += "日志大小重置: PASS - 从 $([math]::Round($PreRotationSize / 1024, 2)) KB 重置为 $([math]::Round($PostRotationSize / 1024, 2)) KB"
|
||||
} else {
|
||||
$TestResults += "日志大小重置: FAIL - 大小未发生变化"
|
||||
}
|
||||
|
||||
# 测试3: 检查是否创建了备份文件
|
||||
if ($PostRotationBackupCount -gt $PreRotationBackupCount) {
|
||||
$TestResults += "备份文件创建: PASS - 备份文件从 $PreRotationBackupCount 增加到 $PostRotationBackupCount"
|
||||
} else {
|
||||
$TestResults += "备份文件创建: FAIL - 未创建新的备份文件"
|
||||
}
|
||||
|
||||
# 测试4: 检查权限是否正确
|
||||
$bashScript = 'LANG=C ls -la /var/log/container/deployment.log | awk "{print \$3, \$4}"'
|
||||
$LogPermission = docker exec $ContainerName bash -c $bashScript
|
||||
if ($LogPermission -match "hexo hexo") {
|
||||
$TestResults += "权限检查: PASS - 权限为 hexo:hexo"
|
||||
} else {
|
||||
$TestResults += "权限检查: FAIL - 权限为 '$LogPermission'"
|
||||
}
|
||||
|
||||
# 计算成功率
|
||||
$TotalTests = $TestResults.Count
|
||||
$PassedTests = ($TestResults | Where-Object { $_ -match "PASS" }).Count
|
||||
$FailedTests = $TotalTests - $PassedTests
|
||||
$SuccessRate = [Math]::Round(($PassedTests / $TotalTests) * 100, 2)
|
||||
|
||||
Write-Host "`n=== 测试结果汇总 ===" -ForegroundColor Cyan
|
||||
Write-Host "总测试项: $TotalTests" -ForegroundColor Gray
|
||||
Write-Host "通过: $PassedTests" -ForegroundColor Green
|
||||
Write-Host "失败: $FailedTests" -ForegroundColor Red
|
||||
Write-Host "成功率: $SuccessRate%" -ForegroundColor Gray
|
||||
|
||||
Write-Host "`n详细结果:" -ForegroundColor Gray
|
||||
$TestResults | ForEach-Object {
|
||||
if ($_ -match "PASS") {
|
||||
Write-Host " $_" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " $_" -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
|
||||
# 保存测试日志
|
||||
$LogContent = @"
|
||||
=== 日志大小重置测试结果 ===
|
||||
测试时间: $(Get-Date)
|
||||
容器名称: $ContainerName
|
||||
目标大小: $TargetSizeKB KB
|
||||
|
||||
=== 测试过程 ===
|
||||
初始大小: $([math]::Round($InitialSize / 1024, 2)) KB
|
||||
生成后大小: $([math]::Round($PreRotationSize / 1024, 2)) KB
|
||||
轮转后大小: $([math]::Round($PostRotationSize / 1024, 2)) KB
|
||||
|
||||
初始备份文件: $InitialBackupCount
|
||||
轮转后备份文件: $PostRotationBackupCount
|
||||
|
||||
=== 测试结果 ===
|
||||
总测试项: $TotalTests
|
||||
通过: $PassedTests
|
||||
失败: $FailedTests
|
||||
成功率: $SuccessRate%
|
||||
|
||||
详细结果:
|
||||
$($TestResults | ForEach-Object { " $_" } | Out-String)
|
||||
"@
|
||||
|
||||
$LogContent | Out-File -FilePath $TestLog -Encoding UTF8
|
||||
|
||||
Write-Host "`n详细测试日志: $TestLog" -ForegroundColor Gray
|
||||
|
||||
# 根据结果设置退出代码
|
||||
if ($FailedTests -eq 0) {
|
||||
Write-Host "`nSUCCESS: 日志大小重置功能测试通过!" -ForegroundColor Green
|
||||
exit 0
|
||||
} else {
|
||||
Write-Host "`nWARNING: 部分测试失败,请检查配置。" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
98
test/v0.0.3/windows/test_paths.ps1
Normal file
98
test/v0.0.3/windows/test_paths.ps1
Normal file
@@ -0,0 +1,98 @@
|
||||
# 路径测试脚本 - 验证所有测试脚本的路径配置是否正确
|
||||
# test_paths.ps1
|
||||
|
||||
param()
|
||||
|
||||
# 确保脚本在正确的目录下执行
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
Set-Location $ScriptDir
|
||||
|
||||
Write-Host "=== 测试脚本路径验证 ===" -ForegroundColor Cyan
|
||||
Write-Host "当前脚本目录: $ScriptDir" -ForegroundColor Green
|
||||
Write-Host "当前工作目录: $(Get-Location)" -ForegroundColor Green
|
||||
|
||||
# 检查关键文件和目录
|
||||
$PathsToCheck = @{
|
||||
"Dockerfile_v0.0.3" = "..\..\..\Dockerfile_v0.0.3"
|
||||
"logs目录" = ".\logs"
|
||||
"test_data目录" = ".\test_data"
|
||||
"test_data\hexo_site目录" = ".\test_data\hexo_site"
|
||||
"test_data\ssh_keys目录" = ".\test_data\ssh_keys"
|
||||
"build_test.ps1" = ".\build_test.ps1"
|
||||
"run_test.ps1" = ".\run_test.ps1"
|
||||
"functional_test.ps1" = ".\functional_test.ps1"
|
||||
"log_rotation_test.ps1" = ".\log_rotation_test.ps1"
|
||||
"cleanup_test.ps1" = ".\cleanup_test.ps1"
|
||||
"start.ps1" = ".\start.ps1"
|
||||
}
|
||||
|
||||
Write-Host "`n=== 路径检查结果 ===" -ForegroundColor Cyan
|
||||
|
||||
foreach ($Description in $PathsToCheck.Keys) {
|
||||
$Path = $PathsToCheck[$Description]
|
||||
$AbsolutePath = Join-Path $ScriptDir $Path
|
||||
|
||||
if (Test-Path $AbsolutePath) {
|
||||
Write-Host "[✓] $Description`: $Path" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[✗] $Description`: $Path (不存在)" -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
|
||||
# 检查必需的目录,不存在则创建
|
||||
Write-Host "`n=== 创建必需目录 ===" -ForegroundColor Cyan
|
||||
|
||||
$RequiredDirs = @(".\logs", ".\test_data", ".\test_data\hexo_site", ".\test_data\ssh_keys")
|
||||
|
||||
foreach ($Dir in $RequiredDirs) {
|
||||
if (-not (Test-Path $Dir)) {
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $Dir -Force | Out-Null
|
||||
Write-Host "[CREATE] 已创建目录: $Dir" -ForegroundColor Yellow
|
||||
} catch {
|
||||
Write-Host "[ERROR] 无法创建目录 $Dir`: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
} else {
|
||||
Write-Host "[EXISTS] 目录已存在: $Dir" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
|
||||
# 测试 Docker 命令路径构建
|
||||
Write-Host "`n=== Docker 命令路径测试 ===" -ForegroundColor Cyan
|
||||
|
||||
$DockerfilePath = "..\..\..\Dockerfile_v0.0.3"
|
||||
$DockerfileAbsPath = Join-Path $ScriptDir $DockerfilePath
|
||||
$DockerContext = Split-Path $DockerfileAbsPath -Parent
|
||||
|
||||
Write-Host "Dockerfile 相对路径: $DockerfilePath" -ForegroundColor Gray
|
||||
Write-Host "Dockerfile 绝对路径: $DockerfileAbsPath" -ForegroundColor Gray
|
||||
Write-Host "Docker 构建上下文: $DockerContext" -ForegroundColor Gray
|
||||
|
||||
if (Test-Path $DockerfileAbsPath) {
|
||||
Write-Host "[✓] Dockerfile 路径正确" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[✗] Dockerfile 路径错误" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# 测试卷挂载路径
|
||||
Write-Host "`n=== 卷挂载路径测试 ===" -ForegroundColor Cyan
|
||||
|
||||
$VolumePaths = @{
|
||||
"hexo_site" = "$ScriptDir\test_data\hexo_site"
|
||||
"ssh_keys" = "$ScriptDir\test_data\ssh_keys"
|
||||
"logs" = "$ScriptDir\logs"
|
||||
}
|
||||
|
||||
foreach ($VolumeName in $VolumePaths.Keys) {
|
||||
$Path = $VolumePaths[$VolumeName]
|
||||
Write-Host "卷 $VolumeName`: $Path" -ForegroundColor Gray
|
||||
|
||||
if (Test-Path $Path) {
|
||||
Write-Host "[✓] 路径存在" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[✗] 路径不存在" -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`n=== 路径验证完成 ===" -ForegroundColor Cyan
|
||||
Write-Host "如果所有路径都正确,可以开始运行测试脚本。" -ForegroundColor Gray
|
||||
Reference in New Issue
Block a user