diff --git a/src/Testcontainers.AspireDashboard/.editorconfig b/src/Testcontainers.AspireDashboard/.editorconfig new file mode 100644 index 000000000..6f066619d --- /dev/null +++ b/src/Testcontainers.AspireDashboard/.editorconfig @@ -0,0 +1 @@ +root = true \ No newline at end of file diff --git a/src/Testcontainers.AspireDashboard/AspireDashboardBuilder.cs b/src/Testcontainers.AspireDashboard/AspireDashboardBuilder.cs new file mode 100644 index 000000000..95163cf68 --- /dev/null +++ b/src/Testcontainers.AspireDashboard/AspireDashboardBuilder.cs @@ -0,0 +1,91 @@ +namespace Testcontainers.AspireDashboard; + +/// +[PublicAPI] +public sealed class AspireDashboardBuilder : ContainerBuilder +{ + public const string AspireDashboardImage = "mcr.microsoft.com/dotnet/aspire-dashboard:latest"; + + public const ushort AspireDashboardPort = 18888; + + public const ushort AspireDashboardOtlpPort = 18889; + + /// + /// Initializes a new instance of the class. + /// + public AspireDashboardBuilder() + : this(new AspireDashboardConfiguration(false, false)) + { + DockerResourceConfiguration = Init().DockerResourceConfiguration; + } + + /// + /// Initializes a new instance of the class. + /// + /// The Docker resource configuration. + private AspireDashboardBuilder(AspireDashboardConfiguration resourceConfiguration) + : base(resourceConfiguration) + { + DockerResourceConfiguration = resourceConfiguration; + } + + /// + /// Sets the AllowAnonymous mode. + /// + /// + /// A configured instance of . + public AspireDashboardBuilder AllowAnonymous(bool allowed) + { + return Merge(DockerResourceConfiguration, new AspireDashboardConfiguration(allowAnonymous: allowed)) + .WithEnvironment("DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS", allowed.ToString().ToLower()); + } + + /// + /// Sets the AllowAnonymous mode. + /// + /// + /// A configured instance of . + public AspireDashboardBuilder AllowUnsecuredTransport(bool allowed) + { + return Merge(DockerResourceConfiguration, new AspireDashboardConfiguration(allowUnsecuredTransport: allowed)) + .WithEnvironment("ASPIRE_ALLOW_UNSECURED_TRANSPORT", allowed.ToString().ToLower()); + } + + /// + protected override AspireDashboardConfiguration DockerResourceConfiguration { get; } + + /// + public override AspireDashboardContainer Build() + { + Validate(); + return new AspireDashboardContainer(DockerResourceConfiguration); + } + + /// + protected override AspireDashboardBuilder Init() + { + return base.Init() + .WithImage(AspireDashboardImage) + .WithPortBinding(AspireDashboardPort, AspireDashboardPort) + .WithPortBinding(AspireDashboardOtlpPort, true) + .WithWaitStrategy(Wait.ForUnixContainer().UntilHttpRequestIsSucceeded(r => r.ForPort(AspireDashboardPort))); + } + + /// + protected override AspireDashboardBuilder Clone(IResourceConfiguration resourceConfiguration) + { + return Merge(DockerResourceConfiguration, new AspireDashboardConfiguration(resourceConfiguration)); + } + + /// + protected override AspireDashboardBuilder Clone(IContainerConfiguration resourceConfiguration) + { + return Merge(DockerResourceConfiguration, new AspireDashboardConfiguration(resourceConfiguration)); + } + + /// + protected override AspireDashboardBuilder Merge(AspireDashboardConfiguration oldValue, AspireDashboardConfiguration newValue) + { + return new AspireDashboardBuilder(new AspireDashboardConfiguration(oldValue, newValue)); + } +} \ No newline at end of file diff --git a/src/Testcontainers.AspireDashboard/AspireDashboardConfiguration.cs b/src/Testcontainers.AspireDashboard/AspireDashboardConfiguration.cs new file mode 100644 index 000000000..c7446b370 --- /dev/null +++ b/src/Testcontainers.AspireDashboard/AspireDashboardConfiguration.cs @@ -0,0 +1,65 @@ +namespace Testcontainers.AspireDashboard; + +/// +[PublicAPI] +public sealed class AspireDashboardConfiguration : ContainerConfiguration +{ + /// + /// Initializes a new instance of the class. + /// + public AspireDashboardConfiguration(bool allowAnonymous = false, bool allowUnsecuredTransport = false) + { + AllowAnonymous = allowAnonymous; + AllowUnsecuredTransport = allowUnsecuredTransport; + } + + /// + /// Initializes a new instance of the class. + /// + /// The Docker resource configuration. + public AspireDashboardConfiguration(IResourceConfiguration resourceConfiguration) + : base(resourceConfiguration) + { + // Passes the configuration upwards to the base implementations to create an updated immutable copy. + } + + /// + /// Initializes a new instance of the class. + /// + /// The Docker resource configuration. + public AspireDashboardConfiguration(IContainerConfiguration resourceConfiguration) + : base(resourceConfiguration) + { + // Passes the configuration upwards to the base implementations to create an updated immutable copy. + } + + /// + /// Initializes a new instance of the class. + /// + /// The Docker resource configuration. + public AspireDashboardConfiguration(AspireDashboardConfiguration resourceConfiguration) + : this(new AspireDashboardConfiguration(), resourceConfiguration) + { + // Passes the configuration upwards to the base implementations to create an updated immutable copy. + } + + /// + /// Initializes a new instance of the class. + /// + /// The old Docker resource configuration. + /// The new Docker resource configuration. + public AspireDashboardConfiguration(AspireDashboardConfiguration oldValue, AspireDashboardConfiguration newValue) + : base(oldValue, newValue) + { + } + + /// + /// Gets AllowAnonymous mode. + /// + public bool AllowAnonymous { get; } + + /// + /// Gets AllowUnsecuredTransport mode. + /// + public bool AllowUnsecuredTransport { get; } +} \ No newline at end of file diff --git a/src/Testcontainers.AspireDashboard/AspireDashboardContainer.cs b/src/Testcontainers.AspireDashboard/AspireDashboardContainer.cs new file mode 100644 index 000000000..1daced392 --- /dev/null +++ b/src/Testcontainers.AspireDashboard/AspireDashboardContainer.cs @@ -0,0 +1,43 @@ +namespace Testcontainers.AspireDashboard; + +/// +[PublicAPI] +public sealed class AspireDashboardContainer : DockerContainer +{ + /// + /// Initializes a new instance of the class. + /// + /// The container configuration. + public AspireDashboardContainer(AspireDashboardConfiguration configuration) + : base(configuration) + { + } + + /// + /// Gets the AspireDashboard URL. + /// + /// The AspireDashboard URL. + public string GetDashboardUrl() + { + var endpoint = new UriBuilder( + Uri.UriSchemeHttp, + Hostname, + GetMappedPublicPort(AspireDashboardBuilder.AspireDashboardPort)); + + return endpoint.ToString(); + } + + /// + /// Gets the AspireDashboard OTLP endpoint URL. + /// + /// The AspireDashboard OTLP endpoint URL. + public string GetOtlpEndpointUrl() + { + var endpoint = new UriBuilder( + Uri.UriSchemeHttp, + Hostname, + GetMappedPublicPort(AspireDashboardBuilder.AspireDashboardOtlpPort)); + + return endpoint.ToString(); + } +} \ No newline at end of file diff --git a/src/Testcontainers.AspireDashboard/Testcontainers.CosmosDb.csproj b/src/Testcontainers.AspireDashboard/Testcontainers.CosmosDb.csproj new file mode 100644 index 000000000..8b2ed72c6 --- /dev/null +++ b/src/Testcontainers.AspireDashboard/Testcontainers.CosmosDb.csproj @@ -0,0 +1,12 @@ + + + net6.0;net8.0;netstandard2.0;netstandard2.1 + latest + + + + + + + + \ No newline at end of file diff --git a/src/Testcontainers.AspireDashboard/Usings.cs b/src/Testcontainers.AspireDashboard/Usings.cs new file mode 100644 index 000000000..8642a70f5 --- /dev/null +++ b/src/Testcontainers.AspireDashboard/Usings.cs @@ -0,0 +1,11 @@ +global using System; +global using System.Collections.Generic; +global using System.Linq; +global using System.Net.Http; +global using System.Threading; +global using System.Threading.Tasks; +global using Docker.DotNet.Models; +global using DotNet.Testcontainers.Builders; +global using DotNet.Testcontainers.Configurations; +global using DotNet.Testcontainers.Containers; +global using JetBrains.Annotations; \ No newline at end of file