diff --git a/scripts/windows/Run-PayrollHost.ps1 b/scripts/windows/Run-PayrollHost.ps1 index c149044..8bfcdf1 100644 --- a/scripts/windows/Run-PayrollHost.ps1 +++ b/scripts/windows/Run-PayrollHost.ps1 @@ -16,15 +16,29 @@ $env:T_PLUS_ENABLED = 'true' $env:T_PLUS_CONNECTION_FILE = $plan.ConnectionFile $logs = Join-Path $plan.RuntimeDirectory 'logs' New-Item -ItemType Directory -Path $logs -Force | Out-Null -$stamp = (Get-Date -Format 'yyyyMMdd-HHmmss') + '-' + [guid]::NewGuid().ToString('N').Substring(0,8) + +function Limit-PayrollLog([string]$Path) { + # current 供本次运行写入,previous 保留上一次;每分钟任务不再生成无限文件。 + $previous = [IO.Path]::ChangeExtension($Path, '.prev.log') + if (Test-Path -LiteralPath $Path) { + # .NET Framework 的 File.Replace 不接受 PowerShell 5 转换出的空备份路径。 + Move-Item -LiteralPath $Path -Destination $previous -Force + } +} + +$stdoutLog = Join-Path $logs "$Role.out.log" +$stderrLog = Join-Path $logs "$Role.err.log" +Limit-PayrollLog $stdoutLog +Limit-PayrollLog $stderrLog + $arguments = switch ($Role) { 'backend' { '-m uvicorn app.main:app --host 127.0.0.1 --port ' + $ApiPort } 'worker' { '-m app.cli tplus-worker --watch --connection-file ' + (Quote-TaskArgument $plan.ConnectionFile) + ' --stop-file ' + (Quote-TaskArgument $plan.StopFile) } 'maintenance' { '-m app.cli tplus-maintain --once --connection-file ' + (Quote-TaskArgument $plan.ConnectionFile) + ' --stop-file ' + (Quote-TaskArgument $plan.StopFile) } } $process = Start-Process -FilePath $plan.PythonPath -ArgumentList $arguments -WorkingDirectory (Join-Path $plan.ProjectRoot 'backend') ` - -WindowStyle Hidden -PassThru -RedirectStandardOutput (Join-Path $logs "$Role-$stamp.out.log") ` - -RedirectStandardError (Join-Path $logs "$Role-$stamp.err.log") + -WindowStyle Hidden -PassThru -RedirectStandardOutput $stdoutLog ` + -RedirectStandardError $stderrLog $processHandle = $process.Handle while (-not $process.HasExited) { if ($Role -eq 'backend' -and (Test-Path -LiteralPath $plan.StopFile)) { Stop-Process -Id $process.Id -ErrorAction Stop } diff --git a/scripts/windows/Test-PayrollHostRuntime.ps1 b/scripts/windows/Test-PayrollHostRuntime.ps1 index fab499e..6effdc6 100644 --- a/scripts/windows/Test-PayrollHostRuntime.ps1 +++ b/scripts/windows/Test-PayrollHostRuntime.ps1 @@ -10,6 +10,8 @@ New-Item -ItemType Directory -Path $app -Force | Out-Null import os,sys,time from pathlib import Path if 'tplus-maintain' in sys.argv: + print('maintenance result') + print('maintenance error', file=sys.stderr) raise SystemExit(7) stop=Path(os.environ['T_PLUS_STOP_FILE']) stop.parent.mkdir(parents=True,exist_ok=True) @@ -48,4 +50,15 @@ Remove-Item -LiteralPath (Join-Path $runtime 'stop.requested') $failureProcess = Start-TestHost 'maintenance' if (-not $failureProcess.WaitForExit(15000)) { throw '隔离失败进程未退出。' } if ($failureProcess.ExitCode -ne 7) { throw '启动器没有保留子进程失败退出码。' } -Write-Output 'Windows PowerShell5 隔离托管验证通过:路径含空格、隐藏子进程启动、停止标记退出、失败退出码传递;未注册计划任务或连接业务数据库。' +for ($attempt = 0; $attempt -lt 2; $attempt++) { + $failureProcess = Start-TestHost 'maintenance' + if (-not $failureProcess.WaitForExit(15000) -or $failureProcess.ExitCode -ne 7) { + throw '日志轮转后启动器没有保留子进程失败退出码。' + } +} +$maintenanceLogs = @(Get-ChildItem -LiteralPath (Join-Path $runtime 'logs') -Filter 'maintenance*.log') +if ($maintenanceLogs.Count -ne 4) { throw '维护任务日志没有限定为当前和上一次的四个文件。' } +foreach ($file in $maintenanceLogs) { + if ($file.Length -eq 0) { throw '轮转后日志内容丢失。' } +} +Write-Output 'Windows PowerShell5 隔离托管验证通过:含空格路径、隐藏子进程、停止标记、失败退出码及日志轮转;未注册计划任务或连接业务数据库。'