Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions scripts/Invoke-IntegrationRunbook.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ function Invoke-PhaseLoop {
param($r,$ctx)
Write-PhaseBanner $r.name
$env:LOOP_SIMULATE = '' # ensure real
$loopFinalStatusPath = Join-Path ([System.IO.Path]::GetTempPath()) ("runbook-loop-final-status-" + [guid]::NewGuid().ToString() + ".json")
# Optional quick/override controls via env (non-breaking defaults)
try {
if (-not $PSBoundParameters.ContainsKey('LoopIterations')) {
Expand All @@ -270,9 +271,36 @@ function Invoke-PhaseLoop {
try { if ($env:RUNBOOK_LOOP_QUICK -match '^(?i:1|true|yes|on)$') { $failOn = $true } } catch {}
$env:LOOP_FAIL_ON_DIFF = ($failOn ? 'true' : 'false')
try {
& (Join-Path (Get-Location) 'scripts' 'Run-AutonomousIntegrationLoop.ps1')
& (Join-Path (Get-Location) 'scripts' 'Run-AutonomousIntegrationLoop.ps1') -FinalStatusJsonPath $loopFinalStatusPath
$code = $LASTEXITCODE
$r.details.exitCode = $code
$r.details.finalStatusPath = $loopFinalStatusPath
if (Test-Path -LiteralPath $loopFinalStatusPath -PathType Leaf) {
try {
$finalStatus = Get-Content -LiteralPath $loopFinalStatusPath -Raw | ConvertFrom-Json -ErrorAction Stop
$r.details.loopIterations = $finalStatus.iterations
if ($finalStatus.PSObject.Properties.Name -contains 'harness' -and $finalStatus.harness) {
$r.details.harness = $finalStatus.harness
$r.details.executionTopology = [ordered]@{
runtimeSurface = $finalStatus.harness.runtimeSurface
processModelClass = $finalStatus.harness.processModelClass
windowsOnly = $finalStatus.harness.windowsOnly
requestedSimultaneous = $finalStatus.harness.requestedSimultaneous
cellClass = $finalStatus.harness.cellClass
executionCellLeasePath = $finalStatus.harness.executionCellLeasePath
executionCellId = $finalStatus.harness.executionCellId
executionCellLeaseId = $finalStatus.harness.executionCellLeaseId
harnessInstanceLeasePath = $finalStatus.harness.harnessInstanceLeasePath
harnessInstanceLeaseId = $finalStatus.harness.harnessInstanceLeaseId
harnessInstanceId = $finalStatus.harness.harnessInstanceId
}
}
} catch {
$r.details.finalStatusReadError = $_.Exception.Message
}
} else {
$r.details.finalStatusMissing = $true
}
if ($code -eq 0) { $r.status='Passed' } else { $r.status='Failed' }
} catch {
$r.details.error = $_.Exception.Message
Expand Down Expand Up @@ -387,4 +415,3 @@ if ($env:GITHUB_STEP_SUMMARY) {
if ($PassThru) { return $final }

if ($overallFailed) { exit 1 } else { exit 0 }

60 changes: 60 additions & 0 deletions tests/IntegrationRunbook.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,66 @@ Describe 'IntegrationRunbook - Phase Selection & JSON' -Tag 'Unit' {
Remove-Item Env:LV_HEAD_VI -ErrorAction SilentlyContinue
}
}

It 'projects loop execution topology from the loop final status into Loop phase details' {
$tempRepo = Join-Path $TestDrive 'runbook-loop-topology'
$scriptsDir = Join-Path $tempRepo 'scripts'
New-Item -ItemType Directory -Path $scriptsDir -Force | Out-Null

$runbookCopy = Join-Path $scriptsDir 'Invoke-IntegrationRunbook.ps1'
Copy-Item -LiteralPath $runScript -Destination $runbookCopy -Force

$loopStub = @"
param([string]`$FinalStatusJsonPath)
`$payload = [ordered]@{
schema = 'loop-final-status-v1'
timestamp = '2026-03-24T12:30:00Z'
iterations = 2
diffs = 0
errors = 0
succeeded = `$true
harness = [ordered]@{
runtimeSurface = 'windows-native-teststand'
processModelClass = 'parallel-process-model'
windowsOnly = `$true
requestedSimultaneous = `$true
cellClass = 'worker'
executionCellLeasePath = 'tests/results/_agent/runtime/execution-cell-hooke-loop.json'
executionCellId = 'exec-cell-hooke-loop-01'
executionCellLeaseId = 'lease-hooke-loop-01'
harnessInstanceLeasePath = 'tests/results/_agent/runtime/harness-instance-hooke-loop.json'
harnessInstanceLeaseId = 'harness-lease-hooke-loop-01'
harnessInstanceId = 'ts-hooke-loop-01'
}
}
(`$payload | ConvertTo-Json -Depth 8) | Set-Content -LiteralPath `$FinalStatusJsonPath -Encoding UTF8
exit 0
"@
Set-Content -LiteralPath (Join-Path $scriptsDir 'Run-AutonomousIntegrationLoop.ps1') -Value $loopStub -Encoding UTF8

Set-Content -LiteralPath (Join-Path $tempRepo 'VI1.vi') -Value '' -Encoding utf8
Set-Content -LiteralPath (Join-Path $tempRepo 'VI2.vi') -Value '' -Encoding utf8

$tmp = Join-Path $tempRepo 'tmp-runbook-loop-topology.json'
Push-Location $tempRepo
try {
& $runbookCopy -Phases 'Prereqs,ViInputs,Loop' -JsonReport $tmp | Out-Null
$LASTEXITCODE | Should -Be 0
} finally {
Pop-Location
}

Test-Path $tmp | Should -BeTrue
$json = Get-Content $tmp -Raw | ConvertFrom-Json
$loopPhase = $json.phases | Where-Object name -eq 'Loop'
$loopPhase.status | Should -Be 'Passed'
$loopPhase.details.loopIterations | Should -Be 2
$loopPhase.details.executionTopology.runtimeSurface | Should -Be 'windows-native-teststand'
$loopPhase.details.executionTopology.processModelClass | Should -Be 'parallel-process-model'
$loopPhase.details.executionTopology.executionCellLeaseId | Should -Be 'lease-hooke-loop-01'
$loopPhase.details.executionTopology.harnessInstanceLeaseId | Should -Be 'harness-lease-hooke-loop-01'
$loopPhase.details.executionTopology.harnessInstanceId | Should -Be 'ts-hooke-loop-01'
}
}

Describe 'IntegrationRunbook - Schema Shape Minimal Validation' -Tag 'Unit' {
Expand Down
Loading