756 lines
34 KiB
PowerShell
756 lines
34 KiB
PowerShell
# 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
|
||
}
|