using EntKube.Provisioning.Domain; using FluentAssertions; namespace EntKube.Provisioning.Tests.Domain; /// /// Tests for the MinioInstance aggregate. This tracks adopted MinIO deployments /// that the platform uses as backup targets for CNPG clusters. /// public class MinioInstanceTests { [Fact] public void Adopt_WithValidInputs_CreatesInstanceInRunningState() { // Arrange & Act — Adopt an existing MinIO deployment discovered on the cluster. Guid clusterId = Guid.NewGuid(); MinioInstance minio = MinioInstance.Adopt( clusterId: clusterId, name: "platform-minio", ns: "minio-system", endpoint: "minio.minio-system.svc:9000", consoleEndpoint: "minio-console.minio-system.svc:9001", credentialsSecret: "minio-root-credentials", totalCapacity: "500Gi", usedCapacity: "120Gi", buckets: new List { "cnpg-backups", "loki-logs", "velero" }); // Assert — Adopted instances are already running. minio.Id.Should().NotBe(Guid.Empty); minio.ClusterId.Should().Be(clusterId); minio.Name.Should().Be("platform-minio"); minio.Namespace.Should().Be("minio-system"); minio.Endpoint.Should().Be("minio.minio-system.svc:9000"); minio.ConsoleEndpoint.Should().Be("minio-console.minio-system.svc:9001"); minio.CredentialsSecret.Should().Be("minio-root-credentials"); minio.Status.Should().Be(MinioInstanceStatus.Running); minio.Buckets.Should().HaveCount(3); minio.Buckets.Should().Contain("cnpg-backups"); } [Fact] public void Adopt_WithEmptyName_ThrowsArgumentException() { // Arrange & Act Action act = () => MinioInstance.Adopt( Guid.NewGuid(), "", "ns", "endpoint:9000", null, "secret", "500Gi", null, null); // Assert act.Should().Throw().WithParameterName("name"); } [Fact] public void Adopt_WithEmptyEndpoint_ThrowsArgumentException() { // Arrange & Act Action act = () => MinioInstance.Adopt( Guid.NewGuid(), "minio", "ns", "", null, "secret", "500Gi", null, null); // Assert act.Should().Throw().WithParameterName("endpoint"); } [Fact] public void Adopt_WithEmptyCredentials_ThrowsArgumentException() { // Arrange & Act Action act = () => MinioInstance.Adopt( Guid.NewGuid(), "minio", "ns", "endpoint:9000", null, "", "500Gi", null, null); // Assert act.Should().Throw().WithParameterName("credentialsSecret"); } [Fact] public void CreateBucket_WhenRunning_AddsBucketToList() { // Arrange — A running MinIO instance. MinioInstance minio = CreateTestInstance(); // Act — CNPG provisioning requests a new bucket for WAL storage. EntKube.SharedKernel.Domain.Result result = minio.CreateBucket("new-pg-backups"); // Assert result.IsSuccess.Should().BeTrue(); minio.Buckets.Should().Contain("new-pg-backups"); } [Fact] public void CreateBucket_DuplicateName_ReturnsFailure() { // Arrange MinioInstance minio = MinioInstance.Adopt( Guid.NewGuid(), "minio", "ns", "minio:9000", null, "secret", "500Gi", null, new List { "existing-bucket" }); // Act EntKube.SharedKernel.Domain.Result result = minio.CreateBucket("existing-bucket"); // Assert result.IsFailure.Should().BeTrue(); result.Error.Should().Contain("already exists"); } [Fact] public void CreateBucket_WhenDegraded_ReturnsFailure() { // Arrange — A degraded MinIO can't serve new bucket requests. MinioInstance minio = CreateTestInstance(); minio.MarkDegraded("Storage pool full"); // Act EntKube.SharedKernel.Domain.Result result = minio.CreateBucket("new-bucket"); // Assert result.IsFailure.Should().BeTrue(); result.Error.Should().Contain("running"); } [Fact] public void MarkDegraded_SetsStatusAndMessage() { // Arrange MinioInstance minio = CreateTestInstance(); // Act minio.MarkDegraded("Drive offline"); // Assert minio.Status.Should().Be(MinioInstanceStatus.Degraded); minio.StatusMessage.Should().Be("Drive offline"); } [Fact] public void MarkRunning_ClearsDegradedStatus() { // Arrange — A previously degraded instance recovers. MinioInstance minio = CreateTestInstance(); minio.MarkDegraded("Temporary issue"); // Act minio.MarkRunning(); // Assert minio.Status.Should().Be(MinioInstanceStatus.Running); minio.StatusMessage.Should().BeNull(); } [Fact] public void GetBackupCredentials_ReturnsEndpointAndSecret() { // Arrange — CNPG needs to know where to send backups. MinioInstance minio = MinioInstance.Adopt( Guid.NewGuid(), "minio", "minio-system", "minio.minio-system.svc:9000", null, "minio-root-credentials", "1Ti", null, null); // Act MinioBackupTarget target = minio.GetBackupTarget("cnpg-backups"); // Assert target.Endpoint.Should().Be("minio.minio-system.svc:9000"); target.Bucket.Should().Be("cnpg-backups"); target.CredentialsSecret.Should().Be("minio-root-credentials"); } private static MinioInstance CreateTestInstance() { return MinioInstance.Adopt( Guid.NewGuid(), "platform-minio", "minio-system", "minio.minio-system.svc:9000", "minio-console:9001", "minio-root-credentials", "500Gi", "120Gi", new List { "cnpg-backups" }); } }