Files
2025-06-02 11:27:10 +08:00

456 lines
20 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
}