Skip to content

Commit

Permalink
Add retries to SDK download in VerifyDotnetFolderContents test (dotne…
Browse files Browse the repository at this point in the history
  • Loading branch information
lbussell committed Mar 6, 2025
1 parent 0792a0d commit 76fc665
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 54 deletions.
95 changes: 42 additions & 53 deletions tests/Microsoft.DotNet.Docker.Tests/SdkImageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Polly;
using Polly.Retry;
using SharpCompress.Common;
using SharpCompress.Readers;
using Xunit;
using Xunit.Abstractions;

#nullable enable
namespace Microsoft.DotNet.Docker.Tests
{
[Trait("Category", "sdk")]
Expand All @@ -25,6 +28,21 @@ public class SdkImageTests : ProductImageTests
private static readonly Dictionary<string, IEnumerable<SdkContentFileInfo>> s_sdkContentsCache =
new Dictionary<string, IEnumerable<SdkContentFileInfo>>();

private static readonly RetryStrategyOptions s_sdkDownloadRetryStrategy =
new()
{
BackoffType = DelayBackoffType.Exponential,
MaxRetryAttempts = 4,
Delay = TimeSpan.FromSeconds(3),
};

private static readonly ResiliencePipeline s_sdkDownloadPipeline =
new ResiliencePipelineBuilder()
.AddRetry(s_sdkDownloadRetryStrategy)
.Build();

private static readonly HttpClient s_httpClient = CreateHttpClient();

public SdkImageTests(ITestOutputHelper outputHelper)
: base(outputHelper)
{
Expand All @@ -36,8 +54,6 @@ public static IEnumerable<object[]> GetImageData()
{
return TestData.GetImageData(DotNetImageRepo.SDK)
.Where(imageData => !imageData.IsDistroless)
// Filter the image data down to the distinct SDK OSes
.Distinct(new SdkImageDataEqualityComparer())
.Select(imageData => new object[] { imageData });
}

Expand Down Expand Up @@ -118,7 +134,7 @@ public void VerifyEnvironmentVariables(ProductImageData imageData)
[MemberData(nameof(GetImageData))]
public void VerifyPowerShellScenario_DefaultUser(ProductImageData imageData)
{
PowerShellScenario_Execute(imageData, null);
PowerShellScenario_Execute(imageData, string.Empty);
}

[DotNetTheory]
Expand Down Expand Up @@ -276,21 +292,14 @@ private async Task<IEnumerable<SdkContentFileInfo>> GetExpectedSdkContentsAsync(
string sdkUrl = GetSdkUrl(imageData);
OutputHelper.WriteLine("Downloading SDK archive: " + sdkUrl);

if (!s_sdkContentsCache.TryGetValue(sdkUrl, out IEnumerable<SdkContentFileInfo> files))
if (!s_sdkContentsCache.TryGetValue(sdkUrl, out IEnumerable<SdkContentFileInfo>? files))
{
string sdkFile = Path.GetTempFileName();

using HttpClient httpClient = new();

if (Config.IsInternal)
await s_sdkDownloadPipeline.ExecuteAsync(async cancellationToken =>
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "",
Config.InternalAccessToken))));
}

await httpClient.DownloadFileAsync(new Uri(sdkUrl), sdkFile);
await s_httpClient.DownloadFileAsync(new Uri(sdkUrl), sdkFile);
});

files = EnumerateArchiveContents(sdkFile)
.OrderBy(file => file.Path)
Expand Down Expand Up @@ -347,7 +356,7 @@ private string GetSdkUrl(ProductImageData imageData)
return url;
}

private void PowerShellScenario_Execute(ProductImageData imageData, string optionalArgs)
private void PowerShellScenario_Execute(ProductImageData imageData, string? optionalArgs = null)
{
string image = imageData.GetImage(DotNetImageRepo.SDK, DockerHelper);

Expand All @@ -368,52 +377,17 @@ private void PowerShellScenario_Execute(ProductImageData imageData, string optio
Assert.Equal(output, bool.TrueString, ignoreCase: true);
}

private class SdkImageDataEqualityComparer : IEqualityComparer<ProductImageData>
private record SdkContentFileInfo
{
public bool Equals([AllowNull] ProductImageData x, [AllowNull] ProductImageData y)
{
if (x is null && y is null)
{
return true;
}

if (x is null && !(y is null))
{
return false;
}

if (!(x is null) && y is null)
{
return false;
}

return x.VersionString == y.VersionString &&
x.SdkOS == y.SdkOS &&
x.Arch == y.Arch;
}
public string Path { get; init; }
public string Sha512 { get; init; }

public int GetHashCode([DisallowNull] ProductImageData obj)
{
return $"{obj.VersionString}-{obj.SdkOS}-{obj.Arch}".GetHashCode();
}
}

private class SdkContentFileInfo : IComparable<SdkContentFileInfo>
{
public SdkContentFileInfo(string path, string sha512)
{
Path = NormalizePath(path);
Sha512 = sha512.ToLower();
}

public string Path { get; }
public string Sha512 { get; }

public int CompareTo([AllowNull] SdkContentFileInfo other)
{
return (Path + Sha512).CompareTo(other.Path + other.Sha512);
}

private static string NormalizePath(string path)
{
return path
Expand All @@ -424,5 +398,20 @@ private static string NormalizePath(string path)
.ToLower();
}
}

private static HttpClient CreateHttpClient()
{
var client = new HttpClient();

if (Config.IsInternal)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "",
Config.InternalAccessToken))));
};

return client;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Polly;
using Polly.CircuitBreaker;
using Polly.Retry;
using Xunit.Abstractions;

Expand Down

0 comments on commit 76fc665

Please sign in to comment.