diff --git a/src/CommunityToolkit.Aspire.Hosting.GoFeatureFlag/GoFeatureFlagBuilderExtensions.cs b/src/CommunityToolkit.Aspire.Hosting.GoFeatureFlag/GoFeatureFlagBuilderExtensions.cs index bd274feb4..06103a457 100644 --- a/src/CommunityToolkit.Aspire.Hosting.GoFeatureFlag/GoFeatureFlagBuilderExtensions.cs +++ b/src/CommunityToolkit.Aspire.Hosting.GoFeatureFlag/GoFeatureFlagBuilderExtensions.cs @@ -4,6 +4,7 @@ using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.Utils; using CommunityToolkit.Aspire.Hosting.GoFeatureFlag; +using Microsoft.Extensions.Logging; namespace Aspire.Hosting; @@ -55,11 +56,11 @@ public static IResourceBuilder AddGoFeatureFlag( return builder.AddResource(goFeatureFlagResource) .WithImage(GoFeatureFlagContainerImageTags.Image, GoFeatureFlagContainerImageTags.Tag) .WithImageRegistry(GoFeatureFlagContainerImageTags.Registry) - .WithHttpEndpoint(targetPort: GoFeatureFlagPort, port: port, name: GoFeatureFlagResource.PrimaryEndpointName) + .WithHttpEndpoint(targetPort: GoFeatureFlagPort, port: port, + name: GoFeatureFlagResource.PrimaryEndpointName) .WithHttpHealthCheck("/health") .WithEntrypoint("/go-feature-flag") - .WithArgs(args) - .WithOtlpExporter(); + .WithArgs(args); } /// @@ -120,4 +121,33 @@ public static IResourceBuilder WithGoffBindMount(this IRe return builder.WithBindMount(source, "/goff"); } + + /// + /// Configures logging level for the GO Feature Flag container resource. + /// + /// The resource builder. + /// The log level to set. + /// The . + /// + /// The only supported by GO Feature Flag are , + /// , and . + /// + public static IResourceBuilder WithLogLevel( + this IResourceBuilder builder, + LogLevel logLevel + ) + { + ArgumentNullException.ThrowIfNull(builder, nameof(builder)); + + string value = logLevel switch + { + LogLevel.Error => "ERROR", + LogLevel.Warning => "WARN", + LogLevel.Information => "INFO", + LogLevel.Debug => "DEBUG", + _ => throw new ArgumentOutOfRangeException(nameof(logLevel), "This log level is not supported by GO Feature Flag.") + }; + + return builder.WithEnvironment("LOGLEVEL", value); + } } \ No newline at end of file diff --git a/src/CommunityToolkit.Aspire.Hosting.SurrealDb/SurrealDbBuilderExtensions.cs b/src/CommunityToolkit.Aspire.Hosting.SurrealDb/SurrealDbBuilderExtensions.cs index 30dbbf801..6472c3131 100644 --- a/src/CommunityToolkit.Aspire.Hosting.SurrealDb/SurrealDbBuilderExtensions.cs +++ b/src/CommunityToolkit.Aspire.Hosting.SurrealDb/SurrealDbBuilderExtensions.cs @@ -427,6 +427,30 @@ public static IResourceBuilder WithInitFiles(this IReso context.EnvironmentVariables[ImportFileEnvVarName] = initFilePath; }); } + + /// + /// Configures logging level for the SurrealDB container resource. + /// + /// The resource builder. + /// The log level to set. + /// The . + public static IResourceBuilder WithLogLevel( + this IResourceBuilder builder, + LogLevel logLevel + ) + { + ArgumentNullException.ThrowIfNull(builder, nameof(builder)); + + string value = logLevel switch + { + LogLevel.Critical => "full", + LogLevel.Information => "info", + LogLevel.Warning => "warn", + _ => logLevel.ToString().ToLowerInvariant() + }; + + return builder.WithEnvironment("SURREAL_LOG", value); + } /// /// Adds a Surrealist UI instance for SurrealDB to the application model. diff --git a/tests/CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests/AddGoFeatureFlagTests.cs b/tests/CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests/AddGoFeatureFlagTests.cs index c2ff27e26..a4089ee72 100644 --- a/tests/CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests/AddGoFeatureFlagTests.cs +++ b/tests/CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests/AddGoFeatureFlagTests.cs @@ -3,6 +3,7 @@ using System.Net.Sockets; using Aspire.Hosting; +using Microsoft.Extensions.Logging; namespace CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests; @@ -89,4 +90,42 @@ public async Task GoFeatureFlagCreatesConnectionString() Assert.Equal($"Endpoint=http://localhost:27020", connectionString); Assert.Equal("Endpoint=http://{goff.bindings.http.host}:{goff.bindings.http.port}", connectionStringResource.ConnectionStringExpression.ValueExpression); } + + [Theory] + [InlineData(LogLevel.Debug, "DEBUG")] + [InlineData(LogLevel.Information, "INFO")] + [InlineData(LogLevel.Warning, "WARN")] + [InlineData(LogLevel.Error, "ERROR")] + public async Task AddSurrealServerContainerWithLogLevel(LogLevel logLevel, string? expected) + { + var appBuilder = DistributedApplication.CreateBuilder(); + + var goff = appBuilder + .AddGoFeatureFlag("goff") + .WithLogLevel(logLevel); + + using var app = appBuilder.Build(); + + var config = await goff.Resource.GetEnvironmentVariableValuesAsync(); + + bool hasValue = config.TryGetValue("LOGLEVEL", out var value); + + Assert.True(hasValue); + Assert.Equal(expected, value); + } + + [Theory] + [InlineData(LogLevel.Trace)] + [InlineData(LogLevel.Critical)] + [InlineData(LogLevel.None)] + public void AddSurrealServerContainerWithLogLevelThrowsOnUnsupportedLogLevel(LogLevel logLevel) + { + var appBuilder = DistributedApplication.CreateBuilder(); + + var func = () => appBuilder + .AddGoFeatureFlag("goff") + .WithLogLevel(logLevel); + + Assert.Throws(func); + } } diff --git a/tests/CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests/GoFeatureFlagPublicApiTests.cs b/tests/CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests/GoFeatureFlagPublicApiTests.cs index b73a932fb..9518bde90 100644 --- a/tests/CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests/GoFeatureFlagPublicApiTests.cs +++ b/tests/CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests/GoFeatureFlagPublicApiTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Aspire.Hosting; +using Microsoft.Extensions.Logging; namespace CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests; @@ -79,4 +80,17 @@ public void CtorGoFeatureFlagResourceShouldThrowWhenNameIsNull() var exception = Assert.Throws(action); Assert.Equal(nameof(name), exception.ParamName); } + + [Fact] + public void WithLogLevelShouldThrowWhenBuilderIsNull() + { + IResourceBuilder builder = null!; + +#pragma warning disable CTASPIRE002 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + var action = () => builder.WithLogLevel(LogLevel.Trace); +#pragma warning restore CTASPIRE002 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + + var exception = Assert.Throws(action); + Assert.Equal(nameof(builder), exception.ParamName); + } } diff --git a/tests/CommunityToolkit.Aspire.Hosting.SurrealDb.Tests/AddSurrealServerTests.cs b/tests/CommunityToolkit.Aspire.Hosting.SurrealDb.Tests/AddSurrealServerTests.cs index 4ec182b27..f4486872f 100644 --- a/tests/CommunityToolkit.Aspire.Hosting.SurrealDb.Tests/AddSurrealServerTests.cs +++ b/tests/CommunityToolkit.Aspire.Hosting.SurrealDb.Tests/AddSurrealServerTests.cs @@ -3,6 +3,7 @@ using Aspire.Hosting; using Aspire.Hosting.Utils; +using Microsoft.Extensions.Logging; using System.Net.Sockets; namespace CommunityToolkit.Aspire.Hosting.SurrealDb.Tests; @@ -180,4 +181,30 @@ public void CanAddDatabasesWithTheSameNameOnMultipleServers() Assert.Equal("{ns1.connectionString};Database=imports", db1.Resource.ConnectionStringExpression.ValueExpression); Assert.Equal("{ns2.connectionString};Database=imports", db2.Resource.ConnectionStringExpression.ValueExpression); } + + [Theory] + [InlineData(LogLevel.Trace, "trace")] + [InlineData(LogLevel.Debug, "debug")] + [InlineData(LogLevel.Information, "info")] + [InlineData(LogLevel.Warning, "warn")] + [InlineData(LogLevel.Error, "error")] + [InlineData(LogLevel.Critical, "full")] + [InlineData(LogLevel.None, "none")] + public async Task AddSurrealServerContainerWithLogLevel(LogLevel logLevel, string expected) + { + var appBuilder = DistributedApplication.CreateBuilder(); + + var surrealServer = appBuilder + .AddSurrealServer("surreal") + .WithLogLevel(logLevel); + + using var app = appBuilder.Build(); + + var config = await surrealServer.Resource.GetEnvironmentVariableValuesAsync(); + + bool hasValue = config.TryGetValue("SURREAL_LOG", out var value); + + Assert.True(hasValue); + Assert.Equal(expected, value); + } } \ No newline at end of file diff --git a/tests/CommunityToolkit.Aspire.Hosting.SurrealDb.Tests/SurrealDbPublicApiTests.cs b/tests/CommunityToolkit.Aspire.Hosting.SurrealDb.Tests/SurrealDbPublicApiTests.cs index 23e7147d4..a1b025547 100644 --- a/tests/CommunityToolkit.Aspire.Hosting.SurrealDb.Tests/SurrealDbPublicApiTests.cs +++ b/tests/CommunityToolkit.Aspire.Hosting.SurrealDb.Tests/SurrealDbPublicApiTests.cs @@ -3,6 +3,7 @@ using Aspire.Hosting; using Aspire.Hosting.Utils; +using Microsoft.Extensions.Logging; namespace CommunityToolkit.Aspire.Hosting.SurrealDb.Tests; @@ -121,7 +122,6 @@ public void WithDataBindMountShouldThrowWhenSourceIsNull() Assert.Equal(nameof(source), exception.ParamName); } - [Fact(Skip = "Feature is unstable and blocking the release")] public void WithInitFilesShouldThrowWhenBuilderIsNull() { @@ -154,6 +154,19 @@ public void WithInitFilesShouldThrowWhenSourceIsNullOrEmpty(bool isNull) : Assert.Throws(action); Assert.Equal(nameof(source), exception.ParamName); } + + [Fact] + public void WithLogLevelShouldThrowWhenBuilderIsNull() + { + IResourceBuilder builder = null!; + +#pragma warning disable CTASPIRE002 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + var action = () => builder.WithLogLevel(LogLevel.Trace); +#pragma warning restore CTASPIRE002 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + + var exception = Assert.Throws(action); + Assert.Equal(nameof(builder), exception.ParamName); + } [Fact] public void WithSurrealistShouldThrowWhenBuilderIsNull()