diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index 2b2968ea3da..79aaf2f1033 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -2145,6 +2145,16 @@ Describe "Invoke-WebRequest tests" -Tags "Feature", "RequireAdminOnWindows" { $jsonError.error | Should -BeExactly 'Error: HTTP - 400 occurred.' } + It "Invoke-WebRequest can retry - specified number of times following Retry-After header - error 429" { + + $uri = Get-WebListenerUrl -Test 'Retry' -Query @{ sessionid = (New-Guid).Guid; failureCode = 429; failureCount = 2; retryAfter = 2 } + $verboseFile = Join-Path $TestDrive -ChildPath verbose.txt + $result = Invoke-WebRequest -Uri $uri -MaximumRetryCount 2 -RetryIntervalSec 1 -Verbose 4>>$verboseFile + + $result.StatusCode | Should -Be "200" + $verboseFile | Should -FileContentMatch "Retrying after interval of 2 seconds. Status code for previous attempt: TooManyRequests" + } + It "Invoke-WebRequest can retry with POST" { $uri = Get-WebListenerUrl -Test 'Retry' @@ -4036,6 +4046,15 @@ Describe "Invoke-RestMethod tests" -Tags "Feature", "RequireAdminOnWindows" { $result.output.sessionId | Should -BeExactly $sessionId } + It "Invoke-RestMethod can retry - specified number of times following Retry-After header - error 429" { + + $uri = Get-WebListenerUrl -Test 'Retry' -Query @{ sessionid = (New-Guid).Guid; failureCode = 429; failureCount = 2; retryAfter = 2 } + $verboseFile = Join-Path $TestDrive -ChildPath verbose.txt + $result = Invoke-RestMethod -Uri $uri -MaximumRetryCount 2 -RetryIntervalSec 1 -Verbose 4>>$verboseFile + + $verboseFile | Should -FileContentMatch "Retrying after interval of 2 seconds. Status code for previous attempt: TooManyRequests" + } + It "Invoke-RestMethod can retry with POST" { $uri = Get-WebListenerUrl -Test 'Retry' diff --git a/test/tools/WebListener/Controllers/RetryController.cs b/test/tools/WebListener/Controllers/RetryController.cs index f9f93bae4c0..bdb70ff0f12 100644 --- a/test/tools/WebListener/Controllers/RetryController.cs +++ b/test/tools/WebListener/Controllers/RetryController.cs @@ -9,6 +9,7 @@ using System.Net; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Primitives; @@ -21,10 +22,15 @@ public class RetryController : Controller // Dictionary for sessionId as key and failureCode, failureCount and failureResponsesSent as the value. private static Dictionary> retryInfo; - public JsonResult Retry(string sessionId, int failureCode, int failureCount) + public JsonResult Retry(string sessionId, int failureCode, int failureCount, int retryAfter = 0) { retryInfo ??= new Dictionary>(); + if (failureCode == 429 && retryAfter > 0) + { + Response.Headers.Append("Retry-After", $"{retryAfter}"); + } + if (retryInfo.TryGetValue(sessionId, out Tuple retry)) { // if failureResponsesSent is less than failureCount