Fix infinite retry loop in SetResource.ps1 (missing $iterator increment) - #198
Fix infinite retry loop in SetResource.ps1 (missing $iterator increment)#198madanmishra1223 wants to merge 2 commits into
Conversation
UpdateLoop initializes $iterator to 1 but never increments it, so the loop guard ($iterator -le $maxIterations) stays true forever whenever Set-AzResource keeps failing. Instead of giving up after maxIterations attempts, the function retries indefinitely with a 5 second sleep between tries, hanging the pipeline task, and the "Failed to update resources" throw below the loop is unreachable. Increment $iterator in the catch block so the retry budget passed by the caller (-maxIterations 3) is honored and a persistent failure surfaces as an error instead of a hang. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
@microsoft-github-policy-service agree |
Arsh Verma (ArshVermaGit)
left a comment
There was a problem hiding this comment.
The fix looks correct and the retry counter now advances on failures as expected. Could you add a small test covering persistent Set-AzResource failure and verifying that -maxIterations is respected? That would prevent this infinite-loop regression from coming back. Otherwise the change looks good.
Review feedback: cover persistent Set-AzResource failure and assert that -maxIterations is respected, so the infinite loop cannot come back. The failing-forever case needs care: a test that simply keeps failing would hang rather than fail if the counter regressed. So the mock fails well past the retry budget and then starts succeeding. A loop that never counts its attempts still terminates, and the test fails on the assertions instead of hanging the run. Against the pre-fix script the first test fails in ~180ms with "Expected an exception ... but no exception was thrown". Az cmdlets are stubbed and Get-AzResource returns nothing, so dot-sourcing the script only imports its functions and no Azure call is ever made. Verified with Pester 6.1.0 on PowerShell 7.6.5: 3 passed with the fix, 1 failed without it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Thanks Arsh Verma (@ArshVermaGit) — test added in The tricky partA test that just fails forever is the wrong shape here: if the counter ever regressed, that test would hang the run rather than fail it — the same failure mode as the bug. So the mock fails well past the retry budget and then starts succeeding. A loop that never counts its attempts still terminates, and the test fails on the assertions instead of hanging: $script:attempts = 0
Mock Set-AzResource {
$script:attempts++
if ($script:attempts -le 20) { throw 'persistent failure' }
}
{ UpdateLoop -maxIterations 3 -resource $script:resource } |
Should -Throw 'Failed to update resources'
$script:attempts | Should -Be 3Three cases covered: gives up after No Azure is touched — the Az cmdlets are stubbed so Pester has something to mock, and Verified both waysPester 6.1.0 on PowerShell 7.6.5. With the fix: With the 181ms, not a hang — which is the point of the escape hatch above. One noteThis repo has no PowerShell test runner wired up (no GitHub Actions workflows at all, and the Install-Module Pester -Scope CurrentUser -Force
Invoke-Pester .ci/scripts/SetResource.Tests.ps1Happy to add a small workflow to run it on PRs if you'd like that, though I left it out to keep this PR scoped to the fix you reviewed. |
Problem
UpdateLoopin.ci/scripts/SetResource.ps1is meant to retry a failingSet-AzResourcecall a bounded number of times:$iteratoris initialized to1but is never incremented. WhenSet-AzResourcekeeps failing,$successstays$falseand$iteratorstays1, so the guard($iterator -le $maxIterations)is always true.Consequences:
UpdateLoop -maxIterations 3 -resource $_) is ignored.throw "Failed to update resources"below the loop is unreachable on persistent failure, so a genuine failure is reported as a hung/timed-out job instead of a clear error.Fix
Increment
$iteratorin thecatchblock, so the loop honors-maxIterationsand a persistent failure exits via the existingthrow.Write-Host($_.Exception.Message) + $iterator++ Start-Sleep -Seconds 5One line changed; no behavior change on the success path (that path still
breaks on the first successful call).