feat(deploy): activate full DraftValidator gate (reject on any validation error)
This commit is contained in:
@@ -43,19 +43,24 @@ public sealed class AdminOperationsActorTests : ControlPlaneActorTestBase
|
||||
db.ConfigEdits.Single().EntityType.ShouldBe("Deployment");
|
||||
}
|
||||
|
||||
/// <summary>Verifies the surgical DraftValidator gate: a Tag↔VirtualTag NodeId collision in
|
||||
/// the live config rejects the deploy (422-mapped <see cref="StartDeploymentOutcome.Rejected"/>)
|
||||
/// before any coordinator dispatch — and inserts no Deployment row.</summary>
|
||||
/// <summary>Verifies the full DraftValidator gate (reject on ANY error): a Tag↔VirtualTag
|
||||
/// NodeId collision in the live config rejects the deploy (422-mapped
|
||||
/// <see cref="StartDeploymentOutcome.Rejected"/>) before any coordinator dispatch — and inserts
|
||||
/// no Deployment row. The colliding equipment uses a canonical EquipmentId so the rejection is
|
||||
/// attributable to the collision rule, not to EquipmentIdNotDerived.</summary>
|
||||
[Fact]
|
||||
public void StartDeployment_rejects_on_Tag_VirtualTag_NodeId_collision()
|
||||
{
|
||||
var uuid = Guid.NewGuid();
|
||||
var equipmentId = Configuration.Validation.DraftValidator.DeriveEquipmentId(uuid);
|
||||
|
||||
var dbFactory = NewInMemoryDbFactory();
|
||||
using (var db = dbFactory.CreateDbContext())
|
||||
{
|
||||
db.Equipment.Add(new Configuration.Entities.Equipment
|
||||
{
|
||||
EquipmentUuid = Guid.NewGuid(),
|
||||
EquipmentId = "eq-1",
|
||||
EquipmentUuid = uuid,
|
||||
EquipmentId = equipmentId,
|
||||
Name = "eq",
|
||||
DriverInstanceId = "d",
|
||||
UnsLineId = "line-a",
|
||||
@@ -65,7 +70,7 @@ public sealed class AdminOperationsActorTests : ControlPlaneActorTestBase
|
||||
{
|
||||
TagId = "tag-speed",
|
||||
DriverInstanceId = "d",
|
||||
EquipmentId = "eq-1",
|
||||
EquipmentId = equipmentId,
|
||||
Name = "speed",
|
||||
DataType = "Float",
|
||||
AccessLevel = TagAccessLevel.Read,
|
||||
@@ -74,7 +79,7 @@ public sealed class AdminOperationsActorTests : ControlPlaneActorTestBase
|
||||
db.VirtualTags.Add(new Configuration.Entities.VirtualTag
|
||||
{
|
||||
VirtualTagId = "vtag-speed",
|
||||
EquipmentId = "eq-1",
|
||||
EquipmentId = equipmentId,
|
||||
Name = "speed",
|
||||
DataType = "Float",
|
||||
ScriptId = "s-1",
|
||||
@@ -91,7 +96,46 @@ public sealed class AdminOperationsActorTests : ControlPlaneActorTestBase
|
||||
var reply = ExpectMsg<StartDeploymentResult>(TimeSpan.FromSeconds(3));
|
||||
reply.Outcome.ShouldBe(StartDeploymentOutcome.Rejected);
|
||||
reply.Message.ShouldNotBeNull();
|
||||
reply.Message.ShouldContain("collide"); // the rule's message text
|
||||
reply.Message.ShouldContain("EquipmentSignalNameCollision"); // the rule's error code
|
||||
reply.Message.ShouldContain("collide"); // the rule's message text
|
||||
|
||||
using var verify = dbFactory.CreateDbContext();
|
||||
verify.Deployments.Count().ShouldBe(0);
|
||||
}
|
||||
|
||||
/// <summary>Verifies the full gate rejects a config whose Equipment carries a NON-canonical
|
||||
/// EquipmentId (not == <c>DraftValidator.DeriveEquipmentId(uuid)</c>): the deploy is
|
||||
/// <see cref="StartDeploymentOutcome.Rejected"/> with <c>EquipmentIdNotDerived</c> in the message,
|
||||
/// no coordinator dispatch, and no Deployment row. This is the rule the surgical gate used to
|
||||
/// let through and the reason the full activation was probed first.</summary>
|
||||
[Fact]
|
||||
public void StartDeployment_rejects_on_non_canonical_EquipmentId()
|
||||
{
|
||||
var dbFactory = NewInMemoryDbFactory();
|
||||
using (var db = dbFactory.CreateDbContext())
|
||||
{
|
||||
db.Equipment.Add(new Configuration.Entities.Equipment
|
||||
{
|
||||
EquipmentUuid = Guid.NewGuid(),
|
||||
EquipmentId = "EQ-operator-typed", // NOT derived from the UUID
|
||||
Name = "rinser-01",
|
||||
DriverInstanceId = "d",
|
||||
UnsLineId = "line-a",
|
||||
MachineCode = "m",
|
||||
});
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
var coordinator = CreateTestProbe("coord");
|
||||
var actor = Sys.ActorOf(AdminOperationsActor.Props(dbFactory, coordinator.Ref, Enumerable.Empty<IDriverProbe>()));
|
||||
|
||||
actor.Tell(new StartDeployment("joe", CorrelationId.NewId()));
|
||||
|
||||
coordinator.ExpectNoMsg(TimeSpan.FromMilliseconds(500));
|
||||
var reply = ExpectMsg<StartDeploymentResult>(TimeSpan.FromSeconds(3));
|
||||
reply.Outcome.ShouldBe(StartDeploymentOutcome.Rejected);
|
||||
reply.Message.ShouldNotBeNull();
|
||||
reply.Message.ShouldContain("EquipmentIdNotDerived");
|
||||
|
||||
using var verify = dbFactory.CreateDbContext();
|
||||
verify.Deployments.Count().ShouldBe(0);
|
||||
|
||||
Reference in New Issue
Block a user