Skip to content

Commit 4423871

Browse files
committed
Add a test that makes sure all images are represented in TestData (dotnet#6207)
1 parent 03069a4 commit 4423871

File tree

7 files changed

+159
-40
lines changed

7 files changed

+159
-40
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
#nullable enable
6+
7+
using System;
8+
using System.Text.RegularExpressions;
9+
10+
namespace Microsoft.DotNet.Docker.Tests;
11+
12+
/// <summary>
13+
/// Represents information about a specific Dockerfile's location.
14+
/// </summary>
15+
/// <param name="Repo">The repository directory where the Dockerfile is located.</param>
16+
/// <param name="MajorMinor">The version directory where the Dockerfile is located.</param>
17+
/// <param name="Os">The operating system directory where the Dockerfile is located.</param>
18+
/// <param name="Architecture">The architecture directory where the Dockerfile is located.</param>
19+
public partial record DockerfileInfo(string Repo, string MajorMinor, string Os, string Architecture)
20+
{
21+
[GeneratedRegex(@"src/(?<repo>.+)/(?<major_minor>\d+\.\d+)/(?<os>.+)/(?<architecture>.+)")]
22+
private static partial Regex DockerfileRegex { get; }
23+
24+
public static DockerfileInfo Create(string dockerfilePath)
25+
{
26+
Match match = DockerfileRegex.Match(dockerfilePath);
27+
if (!match.Success)
28+
{
29+
throw new Exception($"Failed to parse dockerfile: {dockerfilePath}");
30+
}
31+
32+
return new DockerfileInfo(
33+
match.Groups["repo"].Value,
34+
match.Groups["major_minor"].Value,
35+
match.Groups["os"].Value,
36+
match.Groups["architecture"].Value);
37+
}
38+
}

tests/Microsoft.DotNet.Docker.Tests/ImageData.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,20 +136,23 @@ protected void PullImageIfNecessary(string imageName, DockerHelper dockerHelper,
136136

137137
public static string GetImageName(string tag, string repoName, string repoNameModifier = null)
138138
{
139-
string repo = $"dotnet{repoNameModifier ?? GetRepoNameModifier()}/{repoName}";
139+
string repo = GetRepoName(repoName, repoNameModifier);
140140
string registry = GetRegistryName(repo, tag);
141141

142142
return $"{registry}{repo}:{tag}";
143143
}
144144

145+
public static string GetRepoName(string repoName, string repoNameModifier = null) =>
146+
$"dotnet{repoNameModifier ?? GetRepoNameModifier()}/{repoName}";
147+
145148
protected string GetTagName(string tagPrefix, string os, string tagPostfix = null)
146149
{
147150
IEnumerable<string> tagParts = [ tagPrefix, os, tagPostfix, GetArchTagSuffix() ];
148151
tagParts = tagParts.Where(s => !string.IsNullOrEmpty(s));
149152
return string.Join('-', tagParts);
150153
}
151154

152-
protected virtual string GetArchTagSuffix() => (Arch == Arch.Amd64 && !DockerHelper.IsLinuxContainerModeEnabled)
155+
protected virtual string GetArchTagSuffix() => (Arch == Arch.Amd64 && IsWindows)
153156
? string.Empty
154157
: GetArchLabel();
155158

tests/Microsoft.DotNet.Docker.Tests/ManifestHelper.cs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ namespace Microsoft.DotNet.Docker.Tests
1414
{
1515
public static class ManifestHelper
1616
{
17-
public record DockerfileInfo(string Repo, string MajorMinor, string Os, string Architecture);
18-
1917
public static Manifest GetManifest() =>
2018
JsonConvert.DeserializeObject<Manifest>(Config.Manifest.Value.ToString()) ??
2119
throw new Exception("Failed to deserialize manifest");
@@ -29,40 +27,30 @@ public static IEnumerable<string> GetResolvedProductVersions(Repo repo) =>
2927
public static List<string> GetResolvedSharedTags(Image image) =>
3028
image.SharedTags.Keys.Select(GetVariableValue).ToList();
3129

32-
public static List<string> GetResolvedTags(Platform platform) =>
30+
public static List<string> GetResolvedTags(this Platform platform) =>
3331
platform.Tags.Keys.Select(GetVariableValue).ToList();
3432

35-
private static readonly string DockerfileRegex = @"src/(?<repo>.+)/(?<major_minor>\d+\.\d+)/(?<os>.+)/(?<architecture>.+)";
36-
3733
public static Dictionary<DockerfileInfo, List<string>> GetDockerfileTags(Repo repo)
3834
{
3935
Dictionary<DockerfileInfo, List<string>> dockerfileTags = new Dictionary<DockerfileInfo, List<string>>();
4036
foreach (Image image in repo.Images)
4137
{
4238
foreach (Platform platform in image.Platforms)
4339
{
44-
DockerfileInfo dockerfileInfo = GetDockerfileInfo(platform.Dockerfile);
45-
if (!dockerfileTags.ContainsKey(dockerfileInfo))
40+
DockerfileInfo dockerfileInfo = DockerfileInfo.Create(platform.Dockerfile);
41+
if (!dockerfileTags.TryGetValue(dockerfileInfo, out List<string>? value))
4642
{
47-
dockerfileTags[dockerfileInfo] = new List<string>();
43+
value = [];
44+
dockerfileTags[dockerfileInfo] = value;
4845
}
49-
dockerfileTags[dockerfileInfo].AddRange(GetResolvedTags(platform));
50-
dockerfileTags[dockerfileInfo].AddRange(GetResolvedSharedTags(image));
46+
47+
value.AddRange(GetResolvedTags(platform));
48+
value.AddRange(GetResolvedSharedTags(image));
5149
}
5250
}
5351
return dockerfileTags;
5452
}
5553

56-
public static DockerfileInfo GetDockerfileInfo(string dockerfile)
57-
{
58-
var match = Regex.Match(dockerfile, DockerfileRegex);
59-
if (!match.Success)
60-
{
61-
throw new Exception($"Failed to parse dockerfile: {dockerfile}");
62-
}
63-
return new DockerfileInfo(match.Groups["repo"].Value, match.Groups["major_minor"].Value, match.Groups["os"].Value, match.Groups["architecture"].Value);
64-
}
65-
6654
private static string GetVariableValue(string input)
6755
{
6856
string variablePattern = @"\$\((?<variable>.+)\)";

tests/Microsoft.DotNet.Docker.Tests/ProductImageData.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public string GetDockerfilePath(DotNetImageRepo imageRepo)
7171
IEnumerable<string> pathComponents =
7272
[
7373
"src",
74-
GetImageRepoName(imageRepo),
74+
GetDotNetImageRepoName(imageRepo),
7575
Version.ToString(),
7676
OSDir + GetVariantSuffix(),
7777
GetArchLabel()
@@ -86,7 +86,7 @@ private string GetVariantSuffix() =>
8686

8787
public override string GetIdentifier(string type) => $"{VersionString}-{base.GetIdentifier(type)}";
8888

89-
public static string GetImageRepoName(DotNetImageRepo imageRepo) =>
89+
public static string GetDotNetImageRepoName(DotNetImageRepo imageRepo) =>
9090
Enum.GetName(typeof(DotNetImageRepo), imageRepo).ToLowerInvariant().Replace('_', '-');
9191

9292
public static string GetImageVariantName(DotNetImageVariant imageVariant)
@@ -117,7 +117,7 @@ public string GetImage(DotNetImageRepo imageRepo, DockerHelper dockerHelper, boo
117117
}
118118

119119
string tag = GetTagName(imageRepo);
120-
string imageName = GetImageName(tag, GetImageRepoName(imageRepo));
120+
string imageName = GetImageName(tag, GetDotNetImageRepoName(imageRepo));
121121

122122
if (!skipPull)
123123
{

tests/Microsoft.DotNet.Docker.Tests/StaticTagTests.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public void PlatformTag_TagExists(
113113
VersionType versionType,
114114
bool checkOs,
115115
bool checkArchitecture,
116-
Func<ManifestHelper.DockerfileInfo, bool> skipDockerFileOn)
116+
Func<DockerfileInfo, bool> skipDockerFileOn)
117117
{
118118

119119
if (!checkOs && !checkArchitecture)
@@ -122,10 +122,10 @@ public void PlatformTag_TagExists(
122122
"Please use the VersionTag tests for this scenario.");
123123
}
124124

125-
Dictionary<ManifestHelper.DockerfileInfo, List<string>> dockerfileTags = ManifestHelper.GetDockerfileTags(repo);
126-
foreach (KeyValuePair<ManifestHelper.DockerfileInfo, List<string>> dockerfileTag in dockerfileTags)
125+
Dictionary<DockerfileInfo, List<string>> dockerfileTags = ManifestHelper.GetDockerfileTags(repo);
126+
foreach (KeyValuePair<DockerfileInfo, List<string>> dockerfileTag in dockerfileTags)
127127
{
128-
ManifestHelper.DockerfileInfo dockerfileInfo = dockerfileTag.Key;
128+
DockerfileInfo dockerfileInfo = dockerfileTag.Key;
129129
if (skipDockerFileOn(dockerfileInfo))
130130
{
131131
continue;
@@ -205,7 +205,7 @@ Regex GetFloatingTagRegex(DockerfileInfo info) =>
205205
public void VersionTag_SameOsAndVersion(Repo repo, VersionType versionType)
206206
{
207207
// Group tags -> dockerfiles
208-
Dictionary<string, List<ManifestHelper.DockerfileInfo>> tagsToDockerfiles = ManifestHelper.GetDockerfileTags(repo)
208+
Dictionary<string, List<DockerfileInfo>> tagsToDockerfiles = ManifestHelper.GetDockerfileTags(repo)
209209
.SelectMany(pair => pair.Value
210210
.Where(tag => IsTagOfFormat(
211211
tag,
@@ -217,10 +217,10 @@ public void VersionTag_SameOsAndVersion(Repo repo, VersionType versionType)
217217
.GroupBy(pair => pair.tag, pair => pair.Key)
218218
.ToDictionary(group => group.Key, group => group.ToList());
219219

220-
foreach (KeyValuePair<string, List<ManifestHelper.DockerfileInfo>> tagToDockerfiles in tagsToDockerfiles)
220+
foreach (KeyValuePair<string, List<DockerfileInfo>> tagToDockerfiles in tagsToDockerfiles)
221221
{
222222
string tag = tagToDockerfiles.Key;
223-
List<ManifestHelper.DockerfileInfo> dockerfiles = tagToDockerfiles.Value;
223+
List<DockerfileInfo> dockerfiles = tagToDockerfiles.Value;
224224

225225
List<string> dockerfileVersions = dockerfiles
226226
.Select(dockerfile => dockerfile.MajorMinor)
@@ -489,7 +489,7 @@ private static object[] GetTagTestInput(
489489
VersionType? versionType = null,
490490
bool? checkOs = false,
491491
bool? checkArchitecture = false,
492-
Func<ManifestHelper.DockerfileInfo, bool>? skipDockerfileOn = null)
492+
Func<DockerfileInfo, bool>? skipDockerfileOn = null)
493493
{
494494
switch (testType)
495495
{
@@ -522,18 +522,18 @@ private static object[] GetTagTestInput(
522522
}
523523
}
524524

525-
private static bool IsWindows(ManifestHelper.DockerfileInfo dockerfileInfo) =>
525+
private static bool IsWindows(DockerfileInfo dockerfileInfo) =>
526526
dockerfileInfo.Os.Contains("windowsservercore") || dockerfileInfo.Os.Contains("nanoserver");
527527

528528
// Certain versions of appliance repos use a new tag schema.
529529
// This new schema excludes the OS from all tags.
530530
// The aspire-dashboard repo uses this schema for all versions.
531531
// The monitor and monitor-base repos use this schema for versions 9 and above.
532-
private static bool IsApplianceVersionUsingOldSchema(ManifestHelper.DockerfileInfo dockerfileInfo) =>
532+
private static bool IsApplianceVersionUsingOldSchema(DockerfileInfo dockerfileInfo) =>
533533
dockerfileInfo.Repo.Contains("monitor") && GetVersion(dockerfileInfo.MajorMinor).Major <= 8;
534534

535535
// <cref="IsApplianceVersionUsingOldSchema"/>
536-
private static bool IsApplianceVersionUsingNewSchema(ManifestHelper.DockerfileInfo dockerfileInfo) =>
536+
private static bool IsApplianceVersionUsingNewSchema(DockerfileInfo dockerfileInfo) =>
537537
!IsApplianceVersionUsingOldSchema(dockerfileInfo);
538538

539539
private static bool IsExpectedMajorMinorVersion(Repo repo, string version)
@@ -602,7 +602,7 @@ private static Regex GetTagRegex(VersionType versionType, string? majorMinor, st
602602
return new Regex($"^{tagRegex}" + (os != null ? $"-{os}" : string.Empty) + (architecture != null ? $"-{architecture}" : string.Empty) + "$");
603603
}
604604

605-
private static Version GetAlpineVersion(ManifestHelper.DockerfileInfo dockerfileInfo)
605+
private static Version GetAlpineVersion(DockerfileInfo dockerfileInfo)
606606
{
607607
string parsedOs = dockerfileInfo.Os.Replace(OS.Alpine, string.Empty);
608608
parsedOs.Should().NotBeNullOrWhiteSpace(

tests/Microsoft.DotNet.Docker.Tests/TestData.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ public static class TestData
6868
ImageVariant = DotNetImageVariant.Composite, SupportedImageRepos = DotNetImageRepo.Aspnet },
6969
new ProductImageData { Version = V8_0, OS = OS.AzureLinux30Distroless, Arch = Arch.Arm64, SdkOS = OS.AzureLinux30,
7070
ImageVariant = DotNetImageVariant.Composite | DotNetImageVariant.Extra, SupportedImageRepos = DotNetImageRepo.Aspnet },
71+
new ProductImageData { Version = V8_0, OS = OS.AzureLinux30Distroless, Arch = Arch.Arm64, SdkOS = OS.AzureLinux30, SdkImageVariant = DotNetImageVariant.AOT,
72+
ImageVariant = DotNetImageVariant.AOT, SupportedImageRepos = DotNetImageRepo.Runtime_Deps },
7173
new ProductImageData { Version = V8_0, OS = OS.Mariner20, Arch = Arch.Arm64 },
7274
new ProductImageData { Version = V8_0, OS = OS.Mariner20Distroless, Arch = Arch.Arm64, SdkOS = OS.Mariner20 },
7375
new ProductImageData { Version = V8_0, OS = OS.Mariner20Distroless, Arch = Arch.Arm64, SdkOS = OS.Mariner20,
@@ -76,6 +78,8 @@ public static class TestData
7678
ImageVariant = DotNetImageVariant.Composite, SupportedImageRepos = DotNetImageRepo.Aspnet },
7779
new ProductImageData { Version = V8_0, OS = OS.Mariner20Distroless, Arch = Arch.Arm64, SdkOS = OS.Mariner20,
7880
ImageVariant = DotNetImageVariant.Composite | DotNetImageVariant.Extra, SupportedImageRepos = DotNetImageRepo.Aspnet },
81+
new ProductImageData { Version = V8_0, OS = OS.Mariner20Distroless, Arch = Arch.Arm64, SdkOS = OS.Mariner20, SdkImageVariant = DotNetImageVariant.AOT,
82+
ImageVariant = DotNetImageVariant.AOT, SupportedImageRepos = DotNetImageRepo.Runtime_Deps },
7983
new ProductImageData { Version = V8_0, OS = OS.BookwormSlim, Arch = Arch.Arm64 },
8084
new ProductImageData { Version = V8_0, OS = OS.Jammy, Arch = Arch.Arm64 },
8185
new ProductImageData { Version = V8_0, OS = OS.JammyChiseled, Arch = Arch.Arm64, SdkOS = OS.Jammy },
@@ -162,6 +166,8 @@ public static class TestData
162166
ImageVariant = DotNetImageVariant.Composite, SupportedImageRepos = DotNetImageRepo.Aspnet },
163167
new ProductImageData { Version = V9_0, OS = OS.AzureLinux30Distroless, Arch = Arch.Arm64, SdkOS = OS.AzureLinux30,
164168
ImageVariant = DotNetImageVariant.Composite | DotNetImageVariant.Extra, SupportedImageRepos = DotNetImageRepo.Aspnet },
169+
new ProductImageData { Version = V9_0, OS = OS.AzureLinux30Distroless, Arch = Arch.Arm64, SdkOS = OS.AzureLinux30, SdkImageVariant = DotNetImageVariant.AOT,
170+
ImageVariant = DotNetImageVariant.AOT, SupportedImageRepos = DotNetImageRepo.Runtime_Deps },
165171
new ProductImageData { Version = V9_0, OS = OS.BookwormSlim, Arch = Arch.Arm64 },
166172
new ProductImageData { Version = V9_0, OS = OS.Noble, Arch = Arch.Arm64 },
167173
new ProductImageData { Version = V9_0, OS = OS.NobleChiseled, Arch = Arch.Arm64, SdkOS = OS.Noble },
@@ -217,7 +223,7 @@ public static class TestData
217223
new ProductImageData { Version = V9_0, OS = OS.NanoServerLtsc2025, Arch = Arch.Amd64 },
218224
new ProductImageData { Version = V9_0, OS = OS.ServerCoreLtsc2019, Arch = Arch.Amd64 },
219225
new ProductImageData { Version = V9_0, OS = OS.ServerCoreLtsc2022, Arch = Arch.Amd64 },
220-
new ProductImageData { Version = V9_0, OS = OS.ServerCoreLtsc2025, Arch = Arch.Amd64 },
226+
new ProductImageData { Version = V9_0, OS = OS.ServerCoreLtsc2025, Arch = Arch.Amd64 }
221227
};
222228

223229
private static readonly SampleImageData[] s_linuxSampleTestData =
@@ -268,8 +274,8 @@ public static class TestData
268274
new ProductImageData { Version = V8_0, VersionFamily = V8_0, OS = OS.JammyChiseled, OSTag = OS.UbuntuChiseled, Arch = Arch.Arm64, SupportedImageRepos = DotNetImageRepo.Monitor },
269275
new ProductImageData { Version = V8_0, VersionFamily = V8_0, OS = OS.Mariner20Distroless, OSTag = OS.MarinerDistroless, Arch = Arch.Amd64, SupportedImageRepos = DotNetImageRepo.Monitor },
270276
new ProductImageData { Version = V8_0, VersionFamily = V8_0, OS = OS.Mariner20Distroless, OSTag = OS.MarinerDistroless, Arch = Arch.Arm64, SupportedImageRepos = DotNetImageRepo.Monitor },
271-
new ProductImageData { Version = V9_0, VersionFamily = V9_0, OS = OS.AzureLinux30Distroless, OSTag = OS.MarinerDistroless, Arch = Arch.Amd64, SupportedImageRepos = DotNetImageRepo.Monitor },
272-
new ProductImageData { Version = V9_0, VersionFamily = V9_0, OS = OS.AzureLinux30Distroless, OSTag = OS.MarinerDistroless, Arch = Arch.Arm64, SupportedImageRepos = DotNetImageRepo.Monitor }
277+
new ProductImageData { Version = V9_0, VersionFamily = V9_0, OS = OS.AzureLinux30Distroless, OSTag = "", Arch = Arch.Amd64, SupportedImageRepos = DotNetImageRepo.Monitor },
278+
new ProductImageData { Version = V9_0, VersionFamily = V9_0, OS = OS.AzureLinux30Distroless, OSTag = "", Arch = Arch.Arm64, SupportedImageRepos = DotNetImageRepo.Monitor }
273279
};
274280

275281
private static readonly ProductImageData[] s_windowsMonitorTestData =
@@ -298,6 +304,15 @@ public static class TestData
298304
},
299305
};
300306

307+
public static IEnumerable<ProductImageData> AllImageData =>
308+
[
309+
..s_linuxTestData,
310+
..s_windowsTestData,
311+
..s_AspireDashboardTestData,
312+
..s_linuxMonitorTestData,
313+
..s_windowsMonitorTestData
314+
];
315+
301316
public static IEnumerable<ProductImageData> GetImageData(
302317
DotNetImageRepo imageRepo,
303318
DotNetImageVariant variant = DotNetImageVariant.None)

0 commit comments

Comments
 (0)