节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
3.72 KiB
Stardust
using Stardust.Data.Nodes;
using Stardust.Models;
using Xunit;

namespace ServerTest.Nodes;

/// <summary>按指定产品编码匹配安装包(ProductRelease.MatchProduct)测试。
/// 语义:忽略节点自身产品编码,用于原生 Agent 引导安装完整版 StarAgent;
/// 先按 OSKind/Architecture 过滤(0 表示通用),精确匹配优先。</summary>
public class ProductReleaseMatchProductTests
{
    /// <summary>测试用发布版本与安装包,结束后清理。</summary>
    private sealed class ReleaseScope : IDisposable
    {
        private readonly List<ProductPackage> _packages = [];

        public ProductRelease Release { get; }

        public ReleaseScope(String productCode)
        {
            Release = new ProductRelease
            {
                Version = "9.9.9999." + Guid.NewGuid().ToString("n")[..8],
                ProductCode = productCode,
                Enable = true,
                Force = false,
                Channel = NodeChannels.Release,
            };
            Release.Insert();
        }

        public ProductPackage AddPackage(OSKind os, CpuArch arch, String runtime = "*")
        {
            var pkg = new ProductPackage
            {
                ReleaseId = Release.Id,
                OSKind = os,
                Architecture = arch,
                TargetRuntime = runtime,
                FileName = $"pkg-{Guid.NewGuid():n}.zip",
                Source = "http://127.0.0.1/files/pkg.zip",
                Size = 2048,
                FileHash = "0123456789abcdef0123456789abcdef",
            };
            pkg.Insert();
            _packages.Add(pkg);

            return pkg;
        }

        public void Dispose()
        {
            foreach (var pkg in _packages) pkg.Delete();
            Release.Delete();
        }
    }

    private static Node NewNode(String productCode, OSKinds osKind = OSKinds.Ubuntu, String arch = "Arm64") => new()
    {
        Code = "test-bs-" + Guid.NewGuid().ToString("n")[..8],
        Name = "test-bs",
        ProductCode = productCode,
        Runtime = "cpp20",
        OSKind = osKind,
        Architecture = arch,
        Version = "3.6.2026.0104",
        Enable = true,
    };

    /// <summary>节点是原生 Agent 时,仍能匹配到 .NET 版 StarAgent 的安装包。</summary>
    [Fact]
    [Trait("Category", "Nodes")]
    public void MatchProduct_IgnoresNodeProductCode()
    {
        using var scope = new ReleaseScope("StarAgent");
        var pkg = scope.AddPackage(OSKind.Linux, CpuArch.Arm64);

        var (release, package) = ProductRelease.MatchProduct(NewNode("StarAgent-Cpp"), "StarAgent");

        Assert.NotNull(release);
        Assert.Equal(scope.Release.Id, release.Id);
        Assert.NotNull(package);
        Assert.Equal(pkg.Id, package.Id);
    }

    /// <summary>精确匹配系统与架构优先于通用包。</summary>
    [Fact]
    [Trait("Category", "Nodes")]
    public void MatchProduct_PrefersExactOSAndArch()
    {
        using var scope = new ReleaseScope("StarAgent");
        scope.AddPackage(OSKind.Any, CpuArch.Any);
        scope.AddPackage(OSKind.Windows, CpuArch.X64);
        var exact = scope.AddPackage(OSKind.Linux, CpuArch.Arm64);

        var (_, package) = ProductRelease.MatchProduct(NewNode("StarAgent-Go"), "StarAgent");

        Assert.NotNull(package);
        Assert.Equal(exact.Id, package.Id);
    }

    /// <summary>目标产品没有可用发行版本时返回空。</summary>
    [Fact]
    [Trait("Category", "Nodes")]
    public void MatchProduct_NoRelease_ReturnsNull()
    {
        var (release, package) = ProductRelease.MatchProduct(NewNode("StarAgent-Cpp"), "NoSuchProduct-" + Guid.NewGuid().ToString("n")[..8]);

        Assert.Null(release);
        Assert.Null(package);
    }
}