File: Telemetry\CIEnvironmentDetectorTests.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.Telemetry;
using Aspire.Cli.Tests.Utils;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
 
namespace Aspire.Cli.Tests.Telemetry;
 
public class CIEnvironmentDetectorTests
{
    [Fact]
    public void IsCIEnvironment_ReturnsFalse_WhenNoVariablesSet()
    {
        var detector = new CIEnvironmentDetector(new TestEnvironment());
 
        Assert.False(detector.IsCIEnvironment());
    }
 
    [Theory]
    [InlineData("true", true)]
    [InlineData("True", true)]
    [InlineData("TRUE", true)]
    [InlineData("1", true)]
    [InlineData("yes", true)]
    [InlineData("YeS", true)]
    [InlineData("YES", true)]
    [InlineData("on", true)]
    [InlineData("On", true)]
    [InlineData("ON", true)]
    [InlineData(null, false)]
    [InlineData("", false)]
    [InlineData("false", false)]
    [InlineData("FALSE", false)]
    [InlineData("0", false)]
    [InlineData("no", false)]
    [InlineData("NO", false)]
    [InlineData("off", false)]
    [InlineData("OFF", false)]
    [InlineData("2", false)]
    [InlineData("-1", false)]
    [InlineData("01", false)]
    [InlineData("+1", false)]
    [InlineData(" true ", false)]
    [InlineData(" 1 ", false)]
    [InlineData(" yes ", false)]
    [InlineData(" on ", false)]
    [InlineData("\ttrue\n", false)]
    [InlineData(" ", false)]
    [InlineData("invalid", false)]
    public void IsCIEnvironment_MatchesDotNetBooleanValues(string? value, bool expected)
    {
        string[] variableNames = ["TF_BUILD", "GITHUB_ACTIONS", "APPVEYOR", "CI", "TRAVIS", "CIRCLECI"];
        foreach (var variableName in variableNames)
        {
            var environment = new TestEnvironment(new Dictionary<string, string?> { [variableName] = value });
            var detector = new CIEnvironmentDetector(environment);
 
            Assert.Equal(expected, detector.IsCIEnvironment());
        }
    }
 
    [Theory]
    [InlineData("build-123", "value", true)]
    [InlineData("build-123", null, false)]
    [InlineData(null, "value", false)]
    [InlineData("build-123", "", false)]
    [InlineData("", "value", false)]
    [InlineData(" ", " ", true)]
    [InlineData("false", "0", true)]
    public void IsCIEnvironment_RequiresBothPresenceVariables(string? firstValue, string? secondValue, bool expected)
    {
        (string First, string Second)[] variablePairs =
        [
            ("CODEBUILD_BUILD_ID", "AWS_REGION"),
            ("BUILD_ID", "BUILD_URL"),
            ("BUILD_ID", "PROJECT_ID")
        ];
        foreach (var (first, second) in variablePairs)
        {
            var environment = new TestEnvironment(new Dictionary<string, string?>
            {
                [first] = firstValue,
                [second] = secondValue
            });
            var detector = new CIEnvironmentDetector(environment);
 
            Assert.Equal(expected, detector.IsCIEnvironment());
        }
    }
 
    [Theory]
    [InlineData("2023.1", true)]
    [InlineData("https://space.example.com", true)]
    [InlineData("false", true)]
    [InlineData("0", true)]
    [InlineData(" ", true)]
    [InlineData("", false)]
    [InlineData(null, false)]
    public void IsCIEnvironment_MatchesPresenceOnlyVariables(string? value, bool expected)
    {
        string[] variableNames = ["TEAMCITY_VERSION", "JB_SPACE_API_URL"];
        foreach (var variableName in variableNames)
        {
            var environment = new TestEnvironment(new Dictionary<string, string?> { [variableName] = value });
            var detector = new CIEnvironmentDetector(environment);
 
            Assert.Equal(expected, detector.IsCIEnvironment());
        }
    }
 
    [Theory]
    [InlineData("true")]
    [InlineData("false")]
    [InlineData("0")]
    [InlineData("invalid")]
    public void IsCIEnvironment_DoesNotLetCIFlagOverrideOtherSignals(string ciValue)
    {
        var environment = new TestEnvironment(new Dictionary<string, string?>
        {
            ["CI"] = ciValue,
            ["GITHUB_ACTIONS"] = "true"
        });
        var detector = new CIEnvironmentDetector(environment);
 
        Assert.True(detector.IsCIEnvironment());
    }
 
    [Theory]
    [InlineData("AZURE_PIPELINES")]
    [InlineData("JENKINS_URL")]
    [InlineData("GITLAB_CI")]
    [InlineData("BUILDKITE")]
    [InlineData("BITBUCKET_BUILD_NUMBER")]
    public void IsCIEnvironment_IgnoresMarkersNotRecognizedByDotNet(string variableName)
    {
        var environment = new TestEnvironment(new Dictionary<string, string?> { [variableName] = "true" });
        var detector = new CIEnvironmentDetector(environment);
 
        Assert.False(detector.IsCIEnvironment());
    }
 
    [Theory]
    [InlineData("true", "false", true)]
    [InlineData("false", "true", false)]
    [InlineData(null, "true", false)]
    public void IsCIEnvironment_UsesEnvironmentInsteadOfConfiguration(string? environmentValue, string configurationValue, bool expected)
    {
        var configuration = new ConfigurationBuilder()
            .AddInMemoryCollection(new Dictionary<string, string?> { ["CI"] = configurationValue })
            .Build();
        var environment = new TestEnvironment(new Dictionary<string, string?> { ["CI"] = environmentValue });
        var services = new ServiceCollection();
        services.AddSingleton<IConfiguration>(configuration);
        services.AddSingleton<IEnvironment>(environment);
        services.AddTelemetryServices();
        using var provider = services.BuildServiceProvider();
 
        var detector = provider.GetRequiredService<ICIEnvironmentDetector>();
 
        Assert.Equal(expected, detector.IsCIEnvironment());
    }
 
    [Fact]
    public void IsCIEnvironment_PreservesCaseSensitiveEnvironmentLookup()
    {
        var environment = new TestEnvironment(new Dictionary<string, string?>(StringComparer.Ordinal)
        {
            ["ci"] = "true",
            ["github_actions"] = "true"
        });
        var detector = new CIEnvironmentDetector(environment);
 
        Assert.False(detector.IsCIEnvironment());
    }
}