127 lines
3.9 KiB
C#
127 lines
3.9 KiB
C#
using EntKube.Provisioning.Domain;
|
|
using FluentAssertions;
|
|
|
|
namespace EntKube.Provisioning.Tests.Domain;
|
|
|
|
public class ServiceInstanceTests
|
|
{
|
|
[Fact]
|
|
public void Provision_WithValidInputs_CreatesInstanceInPendingState()
|
|
{
|
|
// Arrange & Act — Request provisioning of a MinIO instance.
|
|
|
|
Guid environmentId = Guid.NewGuid();
|
|
Guid clusterId = Guid.NewGuid();
|
|
|
|
ServiceInstance instance = ServiceInstance.Provision(
|
|
environmentId,
|
|
ServiceType.MinIO,
|
|
"tenant-storage",
|
|
"minio-system",
|
|
clusterId);
|
|
|
|
// Assert — Starts pending until the reconciler deploys it.
|
|
|
|
instance.Id.Should().NotBe(Guid.Empty);
|
|
instance.EnvironmentId.Should().Be(environmentId);
|
|
instance.ClusterId.Should().Be(clusterId);
|
|
instance.ServiceType.Should().Be(ServiceType.MinIO);
|
|
instance.Name.Should().Be("tenant-storage");
|
|
instance.Namespace.Should().Be("minio-system");
|
|
instance.DesiredState.Should().Be(ServiceState.Running);
|
|
instance.CurrentState.Should().Be(ServiceState.Pending);
|
|
}
|
|
|
|
[Fact]
|
|
public void Provision_WithEmptyName_ThrowsArgumentException()
|
|
{
|
|
// Arrange & Act
|
|
|
|
Action act = () => ServiceInstance.Provision(Guid.NewGuid(), ServiceType.MinIO, "", "ns", Guid.NewGuid());
|
|
|
|
// Assert
|
|
|
|
act.Should().Throw<ArgumentException>()
|
|
.WithParameterName("name");
|
|
}
|
|
|
|
[Fact]
|
|
public void MarkRunning_UpdatesCurrentState()
|
|
{
|
|
// Arrange
|
|
|
|
ServiceInstance instance = ServiceInstance.Provision(Guid.NewGuid(), ServiceType.CloudNativePG, "db", "cnpg-system", Guid.NewGuid());
|
|
|
|
// Act
|
|
|
|
instance.MarkRunning();
|
|
|
|
// Assert
|
|
|
|
instance.CurrentState.Should().Be(ServiceState.Running);
|
|
instance.LastReconcileAt.Should().NotBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void RequestDecommission_SetsDesiredStateToDecommissioned()
|
|
{
|
|
// Arrange
|
|
|
|
ServiceInstance instance = ServiceInstance.Provision(Guid.NewGuid(), ServiceType.Keycloak, "auth", "keycloak-system", Guid.NewGuid());
|
|
instance.MarkRunning();
|
|
|
|
// Act — Tenant admin decides to tear down this service.
|
|
|
|
instance.RequestDecommission();
|
|
|
|
// Assert — Desired state changes but current state remains until reconciler acts.
|
|
|
|
instance.DesiredState.Should().Be(ServiceState.Decommissioned);
|
|
instance.CurrentState.Should().Be(ServiceState.Running);
|
|
}
|
|
|
|
[Fact]
|
|
public void ServiceType_IncludesGitea()
|
|
{
|
|
// Gitea is a shared service that can be provisioned on a cluster,
|
|
// so ServiceType must include it as a valid option.
|
|
|
|
ServiceType type = ServiceType.Gitea;
|
|
type.Should().BeDefined();
|
|
}
|
|
|
|
[Fact]
|
|
public void ServiceType_IncludesHarbor()
|
|
{
|
|
// Harbor is a shared container registry that can be provisioned
|
|
// on a cluster, so ServiceType must include it.
|
|
|
|
ServiceType type = ServiceType.Harbor;
|
|
type.Should().BeDefined();
|
|
}
|
|
|
|
[Fact]
|
|
public void Provision_Gitea_CreatesInstanceInPendingState()
|
|
{
|
|
// Gitea should be provisionable just like any other service type.
|
|
|
|
ServiceInstance instance = ServiceInstance.Provision(
|
|
Guid.NewGuid(), ServiceType.Gitea, "team-gitea", "gitea", Guid.NewGuid());
|
|
|
|
instance.ServiceType.Should().Be(ServiceType.Gitea);
|
|
instance.CurrentState.Should().Be(ServiceState.Pending);
|
|
}
|
|
|
|
[Fact]
|
|
public void Provision_Harbor_CreatesInstanceInPendingState()
|
|
{
|
|
// Harbor should be provisionable just like any other service type.
|
|
|
|
ServiceInstance instance = ServiceInstance.Provision(
|
|
Guid.NewGuid(), ServiceType.Harbor, "team-harbor", "harbor", Guid.NewGuid());
|
|
|
|
instance.ServiceType.Should().Be(ServiceType.Harbor);
|
|
instance.CurrentState.Should().Be(ServiceState.Pending);
|
|
}
|
|
}
|