Latest Tag Static Validation Tests (#5852)
This commit is contained in:
Родитель
3d5dc2f970
Коммит
d5d1e30181
|
@ -13,9 +13,9 @@ namespace Microsoft.DotNet.Docker.Tests
|
|||
{
|
||||
private const string VariableGroupName = "variable";
|
||||
private const string VariablePattern = $"\\$\\((?<{VariableGroupName}>[\\w:\\-.|]+)\\)";
|
||||
private static Lazy<JObject> Manifest { get; } = new Lazy<JObject>(() => LoadManifest("manifest.json"));
|
||||
private static Lazy<JObject> ManifestVersions { get; } = new Lazy<JObject>(() => LoadManifest("manifest.versions.json"));
|
||||
|
||||
public static Lazy<JObject> Manifest { get; } = new Lazy<JObject>(() => LoadManifest("manifest.json"));
|
||||
public static string SourceRepoRoot { get; } = Environment.GetEnvironmentVariable("SOURCE_REPO_ROOT") ?? string.Empty;
|
||||
public static bool IsHttpVerificationDisabled { get; } =
|
||||
Environment.GetEnvironmentVariable("DISABLE_HTTP_VERIFICATION") != null;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.DotNet.Docker.Tests
|
||||
{
|
||||
// Simplified version of the ImageBuilder manifest model
|
||||
// See https://github.com/dotnet/docker-tools/tree/main/src/Microsoft.DotNet.ImageBuilder/src/Models/Manifest
|
||||
public class Manifest
|
||||
{
|
||||
public List<Repo> Repos { get; set; } = new List<Repo>();
|
||||
}
|
||||
|
||||
public class Repo
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public List<Image> Images { get; set; } = new List<Image>();
|
||||
}
|
||||
|
||||
public class Image
|
||||
{
|
||||
public Dictionary<string, object> SharedTags { get; set; } = new Dictionary<string, object>();
|
||||
public string ProductVersion { get; set; } = string.Empty;
|
||||
public List<Platform> Platforms { get; set; } = new List<Platform>();
|
||||
}
|
||||
|
||||
public class Platform
|
||||
{
|
||||
public string Dockerfile { get; set; } = string.Empty;
|
||||
public Dictionary<string, object> Tags { get; set; } = new Dictionary<string, object>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.DotNet.Docker.Tests
|
||||
{
|
||||
public static class ManifestHelper
|
||||
{
|
||||
public static Manifest GetManifest() =>
|
||||
JsonConvert.DeserializeObject<Manifest>(Config.Manifest.Value.ToString()) ??
|
||||
throw new Exception("Failed to deserialize manifest");
|
||||
|
||||
public static string GetResolvedProductVersion(Image image) =>
|
||||
GetVariableValue(image.ProductVersion);
|
||||
|
||||
public static List<string> GetResolvedSharedTags(Image image) =>
|
||||
image.SharedTags.Keys.Select(GetVariableValue).ToList();
|
||||
|
||||
public static List<string> GetResolvedTags(Platform platform) =>
|
||||
platform.Tags.Keys.Select(GetVariableValue).ToList();
|
||||
|
||||
private static string GetVariableValue(string input)
|
||||
{
|
||||
string variablePattern = @"\$\((?<variable>.+)\)";
|
||||
foreach (Match match in Regex.Matches(input, variablePattern))
|
||||
{
|
||||
string variableName = Config.GetVariableValue(match.Groups["variable"].Value);
|
||||
input = input.Replace(match.Value, variableName);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Xunit;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Microsoft.DotNet.Docker.Tests
|
||||
{
|
||||
[Trait("Category", "pre-build")]
|
||||
public class StaticTagTests
|
||||
{
|
||||
private const string LatestTagValue = "latest";
|
||||
|
||||
public static IEnumerable<object[]> GetRepoObjects() =>
|
||||
ManifestHelper.GetManifest().Repos.Select(repo => new object[] { repo }).ToArray();
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(GetRepoObjects))]
|
||||
private void LatestTag_OnePerRepo(Repo repo)
|
||||
{
|
||||
IEnumerable<Image> latestTagImages = repo.Images
|
||||
.Where(image => ManifestHelper.GetResolvedSharedTags(image).Contains(LatestTagValue));
|
||||
|
||||
Assert.Single(latestTagImages);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(GetRepoObjects))]
|
||||
private void LatestTag_IsNotPlatformSpecific(Repo repo)
|
||||
{
|
||||
foreach (Image image in repo.Images)
|
||||
{
|
||||
IEnumerable<Platform> latestTagPlatforms = image.Platforms
|
||||
.Where(platform => ManifestHelper.GetResolvedTags(platform).Contains(LatestTagValue));
|
||||
|
||||
Assert.Empty(latestTagPlatforms);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(GetRepoObjects))]
|
||||
private void LatestTag_OnCorrectMajorVersion(Repo repo)
|
||||
{
|
||||
Image latestImage = repo.Images
|
||||
.Where(image => ManifestHelper.GetResolvedSharedTags(image).Contains(LatestTagValue))
|
||||
.First();
|
||||
|
||||
int expectedMajorVersion = GetExpectedMajorVersion(repo);
|
||||
int actualMajorVersion = GetMajorVersion(ManifestHelper.GetResolvedProductVersion(latestImage));
|
||||
|
||||
Assert.Equal(expectedMajorVersion, actualMajorVersion);
|
||||
}
|
||||
|
||||
private static int GetExpectedMajorVersion(Repo repo)
|
||||
{
|
||||
List<string> productVersions = repo.Images
|
||||
.Select(ManifestHelper.GetResolvedProductVersion)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
Assert.NotEmpty(productVersions);
|
||||
|
||||
if (productVersions.Count == 1)
|
||||
{
|
||||
// Use the first product version if there is only one
|
||||
return GetMajorVersion(productVersions[0]);
|
||||
}
|
||||
|
||||
if (Config.IsNightlyRepo)
|
||||
{
|
||||
// Use the latest major version on the nightly branch
|
||||
List<int> majorVersions = productVersions
|
||||
.Select(GetMajorVersion)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
return majorVersions.Max();
|
||||
}
|
||||
|
||||
// Use the latest GA major version on the main branch
|
||||
// Assumes that non-GA versions have a hyphen in them
|
||||
// e.g. non GA: 5.0.0-preview.1, GA: 5.0.0
|
||||
List<int> gaVersions = productVersions
|
||||
.Where(version => !version.Contains('-'))
|
||||
.Select(GetMajorVersion)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
return gaVersions.Max();
|
||||
}
|
||||
|
||||
private static int GetMajorVersion(string version) =>
|
||||
int.Parse(version.Split('.')[0]);
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче