<#
.SYNOPSIS
コンパイル済みYAMLを実行する試験ランナー
.EXAMPLE
.\Run-Test.ps1 -YamlPath ".\compiled_tests\001_fgt_policy.yaml"
#>
param (
[Parameter(Mandatory=$true)]
[string]$YamlPath
)
# --- Init: 依存モジュールの確認とYAMLパース ---
if (-not (Get-Module -ListAvailable -Name "powershell-yaml")) {
Write-Warning "powershell-yaml モジュールが必要です。Install-Module powershell-yaml -Scope CurrentUser を実行してください。"
exit 1
}
$YamlText = Get-Content $YamlPath -Raw
$Scenario = ConvertFrom-Yaml $YamlText
# --- 共通実行関数 ---
function Invoke-TestTask {
param ($Task)
Write-Host "[Exec] $($Task.Type) - $($Task.Target) $($Task.Endpoint)" -ForegroundColor Cyan
try {
if ($Task.Type -eq "API") {
# 認証ヘッダーの簡易ルーティング (環境変数から取得)
$Headers = @{ "Content-Type" = "application/json" }
if ($Task.Target -match "FGT") { $Headers["Authorization"] = "Bearer $env:FGT_TOKEN" }
elseif ($Task.Target -match "PA") { $Headers["X-PAN-KEY"] = $env:PA_TOKEN }
# API送信
$res = Invoke-RestMethod -Uri $Task.Endpoint -Method $Task.Method -Headers $Headers -Body $Task.Payload -SkipCertificateCheck
# 簡易アサート
if ($Task.Assert -and $Task.Assert.ResponseContains) {
$resStr = $res | ConvertTo-Json -Depth 10
if ($resStr -notmatch $Task.Assert.ResponseContains) {
throw "Assert Failed: レスポンスに $($Task.Assert.ResponseContains) が含まれていません。"
}
}
}
elseif ($Task.Type -eq "Command") {
# 外部コマンド実行
& $Task.Command $Task.Arguments
if ($LASTEXITCODE -ne 0) { throw "Command Failed with ExitCode $LASTEXITCODE" }
}
elseif ($Task.Type -eq "Wait") {
Start-Sleep -Milliseconds $Task.WaitAfterMs
}
}
catch {
Write-Error "[Error] Task Failed: $_"
throw $_ # フェイルファスト(即時停止)
}
}
# --- メイン実行ライフサイクル ---
try {
# 1. Setup (基本設定)
if ($Scenario.Setup) {
Write-Host "=== 1. Setup ===" -ForegroundColor Yellow
foreach ($task in $Scenario.Setup) { Invoke-TestTask -Task $task }
}
# 2. BaseSteps (基本試験)
if ($Scenario.BaseSteps) {
Write-Host "=== 2. BaseSteps ===" -ForegroundColor Yellow
foreach ($task in $Scenario.BaseSteps) { Invoke-TestTask -Task $task }
}
# 3. LoopBlock (部分設定ループ配列)
if ($Scenario.LoopBlock) {
Write-Host "=== 3. LoopBlock ===" -ForegroundColor Yellow
$loop = $Scenario.LoopBlock
foreach ($config in $loop.Configs) {
Write-Host ">>> Loop Config 適用: $config" -ForegroundColor Green
# 設定変更タスクを動的生成して実行
$configTask = [PSCustomObject]@{
Type = "API"
Target = $loop.Target
Method = $loop.Method
Endpoint = $loop.Endpoint
Payload = $config
}
Invoke-TestTask -Task $configTask
# ループ内試験の実行
foreach ($step in $loop.LoopSteps) { Invoke-TestTask -Task $step }
}
}
}
finally {
# 4. Teardown (後片付け:必ず逆順で実行し依存関係エラーを回避)
if ($Scenario.Teardown) {
Write-Host "=== 4. Teardown (Reverse) ===" -ForegroundColor Yellow
for ($i = $Scenario.Teardown.Count - 1; $i -ge 0; $i--) {
try { Invoke-TestTask -Task $Scenario.Teardown[$i] }
catch { Write-Host "[Teardown Warn] $_" -ForegroundColor DarkGray }
}
}
}