[Identity][Infrastructure] Improve test reliability (#13646)
* Catches HttpClient exceptions and retries on IdentityUI_ScriptTags_SubresourceIntegrityCheck and IdentityUI_ScriptTags_FallbackSourceContent_Matches_CDNContent
This commit is contained in:
parent
ddf987eb4e
commit
3368ea6f9c
|
|
@ -9,7 +9,6 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -26,7 +25,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||||
public IdentityUIScriptsTest(ITestOutputHelper output)
|
public IdentityUIScriptsTest(ITestOutputHelper output)
|
||||||
{
|
{
|
||||||
_output = output;
|
_output = output;
|
||||||
_httpClient = new HttpClient(new RetryHandler(new HttpClientHandler() { }));
|
_httpClient = new HttpClient(new RetryHandler(new HttpClientHandler() { }, output, TimeSpan.FromSeconds(1), 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<object[]> ScriptWithIntegrityData
|
public static IEnumerable<object[]> ScriptWithIntegrityData
|
||||||
|
|
@ -188,25 +187,5 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||||
|
|
||||||
throw new InvalidOperationException($"Solution root could not be located using application root {applicationPath}.");
|
throw new InvalidOperationException($"Solution root could not be located using application root {applicationPath}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
class RetryHandler : DelegatingHandler
|
|
||||||
{
|
|
||||||
public RetryHandler(HttpMessageHandler innerHandler) : base(innerHandler) { }
|
|
||||||
|
|
||||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
HttpResponseMessage result = null;
|
|
||||||
for (var i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
result = await base.SendAsync(request, cancellationToken);
|
|
||||||
if (result.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
await Task.Delay(1000);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Identity.Test
|
||||||
|
{
|
||||||
|
internal class RetryHandler : DelegatingHandler
|
||||||
|
{
|
||||||
|
private readonly ITestOutputHelper _output;
|
||||||
|
private readonly int _maxRetries;
|
||||||
|
private TimeSpan _waitIntervalBeforeRetry;
|
||||||
|
|
||||||
|
public RetryHandler(
|
||||||
|
HttpClientHandler httpClientHandler,
|
||||||
|
ITestOutputHelper output,
|
||||||
|
TimeSpan initialWaitTime,
|
||||||
|
int maxAttempts) : base(httpClientHandler)
|
||||||
|
{
|
||||||
|
_waitIntervalBeforeRetry = initialWaitTime;
|
||||||
|
_output = output;
|
||||||
|
_maxRetries = maxAttempts;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
HttpResponseMessage result = null;
|
||||||
|
var url = request.RequestUri;
|
||||||
|
var method = request.Method;
|
||||||
|
|
||||||
|
for (var i = 0; i < _maxRetries; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_output.WriteLine($"Sending request '{method} - {url}' {i+1} attempt.");
|
||||||
|
result = await base.SendAsync(request, cancellationToken);
|
||||||
|
if (result.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_output.WriteLine($"Request '{method} - {url}' failed with {result.StatusCode}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_output.WriteLine($"Request '{method} - {url}' failed with {e.ToString()}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
await Task.Delay(_waitIntervalBeforeRetry, cancellationToken);
|
||||||
|
_waitIntervalBeforeRetry = _waitIntervalBeforeRetry * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try one last time to show the actual error.
|
||||||
|
return await base.SendAsync(request, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue