65 lines
3.8 KiB
PowerShell
65 lines
3.8 KiB
PowerShell
[CmdletBinding()]
|
||
param([Parameter(Mandatory=$true)][string]$PythonPath, [Parameter(Mandatory=$true)][string]$TestRoot)
|
||
. (Join-Path $PSScriptRoot 'TaskHost.Common.ps1')
|
||
if (Test-Path -LiteralPath $TestRoot) { throw '请选择新的隔离测试目录,避免覆盖现有文件。' }
|
||
$root = [IO.Path]::GetFullPath($TestRoot)
|
||
$app = Join-Path $root 'backend/app'
|
||
New-Item -ItemType Directory -Path $app -Force | Out-Null
|
||
'' | Set-Content -LiteralPath (Join-Path $app '__init__.py') -Encoding UTF8
|
||
@'
|
||
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)
|
||
(stop.parent/'worker.started').write_text('ready',encoding='utf-8')
|
||
while not stop.exists():
|
||
time.sleep(0.05)
|
||
(stop.parent/'worker.stopped').write_text('stopped',encoding='utf-8')
|
||
'@ | Set-Content -LiteralPath (Join-Path $app 'cli.py') -Encoding UTF8
|
||
$connection = Join-Path $root 'dummy reader.json'
|
||
'{}' | Set-Content -LiteralPath $connection -Encoding UTF8
|
||
$runtime = Join-Path $root 'runtime with spaces'
|
||
$shell = Join-Path $env:WINDIR 'System32/WindowsPowerShell/v1.0/powershell.exe'
|
||
$launcher = Join-Path $PSScriptRoot 'Run-PayrollHost.ps1'
|
||
function Start-TestHost([string]$Role) {
|
||
$argsText = '-NoProfile -NonInteractive -File ' + (Quote-TaskArgument $launcher) + ' -Role ' + $Role +
|
||
' -ProjectRoot ' + (Quote-TaskArgument $root) + ' -PythonPath ' + (Quote-TaskArgument $PythonPath) +
|
||
' -RuntimeDirectory ' + (Quote-TaskArgument $runtime) + ' -ConnectionFile ' + (Quote-TaskArgument $connection)
|
||
$child = Start-Process -FilePath $shell -ArgumentList $argsText -WindowStyle Hidden -PassThru `
|
||
-RedirectStandardOutput (Join-Path $root "$Role-host.out.log") -RedirectStandardError (Join-Path $root "$Role-host.err.log")
|
||
$null = $child.Handle
|
||
return $child
|
||
}
|
||
$taskHostProcess = Start-TestHost 'worker'
|
||
$deadline = (Get-Date).AddSeconds(20)
|
||
while (-not (Test-Path -LiteralPath (Join-Path $runtime 'worker.started')) -and (Get-Date) -lt $deadline) {
|
||
if ($taskHostProcess.HasExited) { throw '隔离worker未能启动,请检查测试目录日志。' }
|
||
Start-Sleep -Milliseconds 100
|
||
}
|
||
if (-not (Test-Path -LiteralPath (Join-Path $runtime 'worker.started'))) { throw '等待隔离worker启动超时。' }
|
||
'stop' | Set-Content -LiteralPath (Join-Path $runtime 'stop.requested') -Encoding UTF8
|
||
if (-not $taskHostProcess.WaitForExit(15000)) { throw '停止标记未能结束隔离worker。' }
|
||
if ($taskHostProcess.ExitCode -ne 0 -or -not (Test-Path -LiteralPath (Join-Path $runtime 'worker.stopped'))) {
|
||
throw '隔离worker未正常停止。'
|
||
}
|
||
Remove-Item -LiteralPath (Join-Path $runtime 'stop.requested')
|
||
$failureProcess = Start-TestHost 'maintenance'
|
||
if (-not $failureProcess.WaitForExit(15000)) { throw '隔离失败进程未退出。' }
|
||
if ($failureProcess.ExitCode -ne 7) { throw '启动器没有保留子进程失败退出码。' }
|
||
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 隔离托管验证通过:含空格路径、隐藏子进程、停止标记、失败退出码及日志轮转;未注册计划任务或连接业务数据库。'
|