using Akka.Actor; using Akka.TestKit; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Commons.Messages.Admin; using ZB.MOM.WW.OtOpcUa.Commons.Messages.Deploy; using ZB.MOM.WW.OtOpcUa.Commons.Types; using ZB.MOM.WW.OtOpcUa.Configuration.Enums; using ZB.MOM.WW.OtOpcUa.ControlPlane.AdminOperations; using ZB.MOM.WW.OtOpcUa.ControlPlane.Tests.Harness; namespace ZB.MOM.WW.OtOpcUa.ControlPlane.Tests; public sealed class AdminOperationsActorTests : ControlPlaneActorTestBase { [Fact] public void StartDeployment_inserts_deployment_and_dispatches_to_coordinator() { var dbFactory = NewInMemoryDbFactory(); var coordinator = CreateTestProbe("coord"); var actor = Sys.ActorOf(AdminOperationsActor.Props(dbFactory, coordinator.Ref)); actor.Tell(new StartDeployment("joe", CorrelationId.NewId())); var dispatch = coordinator.ExpectMsg(TimeSpan.FromSeconds(3)); dispatch.DeploymentId.Value.ShouldNotBe(Guid.Empty); dispatch.RevisionHash.Value.Length.ShouldBe(64); var reply = ExpectMsg(TimeSpan.FromSeconds(3)); reply.Outcome.ShouldBe(StartDeploymentOutcome.Accepted); reply.DeploymentId.ShouldBe(dispatch.DeploymentId); reply.RevisionHash.ShouldBe(dispatch.RevisionHash); using var db = dbFactory.CreateDbContext(); var row = db.Deployments.Single(); row.Status.ShouldBe(DeploymentStatus.Dispatching); row.CreatedBy.ShouldBe("joe"); row.ArtifactBlob.Length.ShouldBeGreaterThan(0); db.ConfigEdits.Count().ShouldBe(1); db.ConfigEdits.Single().EntityType.ShouldBe("Deployment"); } [Fact] public void StartDeployment_refuses_when_another_is_in_flight() { var dbFactory = NewInMemoryDbFactory(); // Seed an in-flight Deployment. using (var db = dbFactory.CreateDbContext()) { db.Deployments.Add(new Configuration.Entities.Deployment { RevisionHash = new string('a', 64), Status = DeploymentStatus.Dispatching, CreatedBy = "earlier", }); db.SaveChanges(); } var coordinator = CreateTestProbe("coord"); var actor = Sys.ActorOf(AdminOperationsActor.Props(dbFactory, coordinator.Ref)); actor.Tell(new StartDeployment("joe", CorrelationId.NewId())); coordinator.ExpectNoMsg(TimeSpan.FromMilliseconds(500)); var reply = ExpectMsg(TimeSpan.FromSeconds(3)); reply.Outcome.ShouldBe(StartDeploymentOutcome.AnotherDeploymentInFlight); reply.DeploymentId.ShouldNotBeNull(); } }