exchanger/tools/soak/run-runtime-soak.ps1

101 lines
3.5 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.

[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$ExecutablePath,
[string[]]$ApplicationArguments = @(),
[ValidateRange(0.0167, 168)]
[double]$DurationHours = 24,
[ValidateRange(5, 3600)]
[int]$SampleIntervalSeconds = 60,
[ValidateRange(128, 16384)]
[int]$MaximumWorkingSetMb = 2048,
[string]$OutputDirectory = ""
)
$ErrorActionPreference = 'Stop'
$resolvedExecutable = [System.IO.Path]::GetFullPath($ExecutablePath)
if (-not (Test-Path -LiteralPath $resolvedExecutable -PathType Leaf)) {
throw 'Не найден исполняемый файл для soak-теста.'
}
$resolvedOutputDirectory = if ([string]::IsNullOrWhiteSpace($OutputDirectory)) {
Join-Path (Get-Location) 'artifacts\soak'
} else {
[System.IO.Path]::GetFullPath($OutputDirectory)
}
New-Item -ItemType Directory -Path $resolvedOutputDirectory -Force | Out-Null
$timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$csvPath = Join-Path $resolvedOutputDirectory "runtime-soak-$timestamp.csv"
$summaryPath = Join-Path $resolvedOutputDirectory "runtime-soak-$timestamp.txt"
$deadline = [DateTimeOffset]::Now.AddHours($DurationHours)
$process = $null
$peakWorkingSetMb = 0.0
$samples = 0
try {
$workingDirectory = [System.IO.Path]::GetDirectoryName($resolvedExecutable)
$process = Start-Process `
-FilePath $resolvedExecutable `
-ArgumentList $ApplicationArguments `
-WorkingDirectory $workingDirectory `
-WindowStyle Hidden `
-PassThru
'Timestamp,WorkingSetMb,PrivateMemoryMb,Responding' | Set-Content -LiteralPath $csvPath -Encoding UTF8
while ([DateTimeOffset]::Now -lt $deadline) {
Start-Sleep -Seconds $SampleIntervalSeconds
$process.Refresh()
if ($process.HasExited) {
throw "Процесс завершился до окончания soak-теста: exit_code=$($process.ExitCode)."
}
$workingSetMb = [Math]::Round($process.WorkingSet64 / 1MB, 2)
$privateMemoryMb = [Math]::Round($process.PrivateMemorySize64 / 1MB, 2)
$peakWorkingSetMb = [Math]::Max($peakWorkingSetMb, $workingSetMb)
$samples++
[string]::Format(
[Globalization.CultureInfo]::InvariantCulture,
'{0:o},{1:F2},{2:F2},{3}',
[DateTimeOffset]::Now,
$workingSetMb,
$privateMemoryMb,
$process.Responding) |
Add-Content -LiteralPath $csvPath -Encoding UTF8
if ($workingSetMb -gt $MaximumWorkingSetMb) {
throw "Working set превысил безопасный предел $MaximumWorkingSetMb МБ."
}
}
@(
'Result=Passed'
"DurationHours=$DurationHours"
"Samples=$samples"
'PeakWorkingSetMb=' + $peakWorkingSetMb.ToString('F2', [Globalization.CultureInfo]::InvariantCulture)
"ProcessId=$($process.Id)"
) | Set-Content -LiteralPath $summaryPath -Encoding UTF8
} catch {
@(
'Result=Failed'
"DurationHours=$DurationHours"
"Samples=$samples"
'PeakWorkingSetMb=' + $peakWorkingSetMb.ToString('F2', [Globalization.CultureInfo]::InvariantCulture)
"ErrorType=$($_.Exception.GetType().Name)"
) | Set-Content -LiteralPath $summaryPath -Encoding UTF8
throw
} finally {
if ($null -ne $process -and -not $process.HasExited) {
$null = $process.CloseMainWindow()
if (-not $process.WaitForExit(10000)) {
Stop-Process -Id $process.Id -Force
}
}
}
Write-Output "Soak-тест завершён. Сводка: $summaryPath"