File: Backchannel\TrayResourceHealthTests.cs
Web Access
Project: src\tests\Aspire.Cli.Tests\Aspire.Cli.Tests.csproj (Aspire.Cli.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using Aspire.Cli.Backchannel;
 
namespace Aspire.Cli.Tests.Backchannel;
 
public class TrayResourceHealthTests
{
    [Theory]
    [InlineData("Running", "Healthy", null, null, "healthy")]
    [InlineData("Running", null, null, null, "healthy")]
    [InlineData("Running", "Degraded", null, null, "warning")]
    [InlineData("Running", "Unhealthy", null, null, "unhealthy")]
    [InlineData("Starting", null, null, null, "warning")]
    [InlineData("Building", null, null, null, "warning")]
    [InlineData("Waiting", null, null, null, "warning")]
    [InlineData("Stopping", null, null, null, "warning")]
    [InlineData("NotStarted", null, null, null, "warning")]
    [InlineData("ValueMissing", null, null, null, "warning")]
    [InlineData("Unknown", null, null, null, "warning")]
    [InlineData("FailedToStart", null, null, null, "unhealthy")]
    [InlineData("RuntimeUnhealthy", null, null, null, "unhealthy")]
    [InlineData("Finished", null, null, 0, null)]
    [InlineData("Exited", null, null, 0, null)]
    [InlineData("Finished", null, null, 1, "unhealthy")]
    [InlineData("Exited", null, null, 1, "unhealthy")]
    [InlineData("CustomState", null, "warning", null, "warning")]
    [InlineData("CustomState", null, "error", null, "unhealthy")]
    [InlineData("Active", null, null, null, null)]
    [InlineData(null, null, null, null, null)]
    public void ResourceStateAndHealthDetermineAggregate(string? state, string? health, string? style, int? exitCode, string? expected)
    {
        var resource = new ResourceSnapshot
        {
            Name = "resource",
            State = state,
            StateStyle = style,
            HealthStatus = health,
            ExitCode = exitCode
        };
 
        Assert.Equal(expected, TrayResourceHealth.Aggregate([resource]));
    }
 
    [Theory]
    [InlineData(null, "warning")]
    [InlineData("Healthy", "warning")]
    [InlineData("Degraded", "warning")]
    [InlineData("Unhealthy", "unhealthy")]
    public void PendingHealthCheckIsWaitingButDoesNotHideAFailedCheck(string? otherStatus, string expected)
    {
        var resource = new ResourceSnapshot
        {
            Name = "api",
            State = "Running",
            HealthStatus = "Unhealthy",
            HealthReports =
            [
                new() { Name = "pending", Status = null },
                new() { Name = "other", Status = otherStatus }
            ]
        };
 
        Assert.Equal(expected, TrayResourceHealth.Aggregate([resource]));
    }
 
    [Fact]
    public void HiddenAndNonApplicableResourcesDoNotMaskVisibleHealth()
    {
        ResourceSnapshot[] resources =
        [
            new() { Name = "hidden-state", State = "Hidden", HealthStatus = "Unhealthy" },
            new() { Name = "hidden-flag", State = "FailedToStart", IsHidden = true },
            new() { Name = "parameter", ResourceType = "Parameter", State = "Active" },
            new() { Name = "connection", ResourceType = "ConnectionString" },
            new() { Name = "setup", State = "Finished", ExitCode = 0 }
        ];
        Assert.Null(TrayResourceHealth.Aggregate([]));
        Assert.Null(TrayResourceHealth.Aggregate(resources));
        Assert.Equal("healthy", TrayResourceHealth.Aggregate(
            [.. resources, new() { Name = "api", State = "Running", HealthStatus = "Healthy" }]));
    }
 
    [Theory]
    [InlineData(false)]
    [InlineData(true)]
    public void MostSevereVisibleResourceWinsRegardlessOfOrdering(bool reverse)
    {
        ResourceSnapshot[] resources =
        [
            new() { Name = "api", State = "Running", HealthStatus = "Healthy" },
            new() { Name = "worker", State = "Waiting" },
            new() { Name = "database", State = "Running", HealthStatus = "Unhealthy" }
        ];
 
        Assert.Equal("warning", TrayResourceHealth.Aggregate(resources.Take(2)));
        Assert.Equal("unhealthy", TrayResourceHealth.Aggregate(reverse ? resources.Reverse() : resources));
    }
}