fix(deploy): cluster-attribute driver-less equipment via its UNS line area (BuildClusterSets)
This commit is contained in:
@@ -521,4 +521,90 @@ public sealed class DeploymentArtifactTests
|
||||
comp.UnsLines.Select(l => l.UnsLineId).ShouldBe(new[] { "line-1" });
|
||||
warnings.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
/// <summary>A multi-cluster artifact with one driver-less equipment (no <c>DriverInstanceId</c>
|
||||
/// property at all => null driver) attributed only via its UNS line's area cluster:
|
||||
/// UnsArea A1 (ClusterId = <paramref name="areaCluster"/>), UnsLine L1 (UnsAreaId = A1),
|
||||
/// Equipment E1 (UnsLineId = L1, no driver), plus an EquipmentVirtualTag on E1. The MAIN-cluster
|
||||
/// node always carries a driver so the artifact is genuinely multi-cluster (scoped, not None).</summary>
|
||||
private static byte[] DriverlessEquipmentBlob(string areaCluster) => BlobOf(new
|
||||
{
|
||||
Clusters = new[] { new { ClusterId = "C1" }, new { ClusterId = "C2" } },
|
||||
Nodes = new[]
|
||||
{
|
||||
new { NodeId = "c1-1:4053", ClusterId = "C1" },
|
||||
new { NodeId = "c2-1:4053", ClusterId = "C2" },
|
||||
},
|
||||
DriverInstances = new[]
|
||||
{
|
||||
new { DriverInstanceId = "c1-driver", DriverType = "Modbus", DriverConfig = "{}", ClusterId = "C1", NamespaceId = "c1-ns" },
|
||||
new { DriverInstanceId = "c2-driver", DriverType = "Modbus", DriverConfig = "{}", ClusterId = "C2", NamespaceId = "c2-ns" },
|
||||
},
|
||||
UnsAreas = new[] { new { UnsAreaId = "A1", Name = "Area1", ClusterId = areaCluster } },
|
||||
UnsLines = new[] { new { UnsLineId = "L1", UnsAreaId = "A1", Name = "Line1" } },
|
||||
// Driver-less equipment: the DriverInstanceId property is absent => the parser sees null.
|
||||
Equipment = new[]
|
||||
{
|
||||
new { EquipmentId = "E1", Name = "Equip1", UnsLineId = "L1" },
|
||||
},
|
||||
Scripts = new[] { new { ScriptId = "scr", SourceCode = "return 1;" } },
|
||||
VirtualTags = new[]
|
||||
{
|
||||
new { VirtualTagId = "vt-e1", EquipmentId = "E1", Name = "VE1", DataType = "Float", ScriptId = "scr" },
|
||||
},
|
||||
});
|
||||
|
||||
/// <summary>Verifies driver-less equipment (null DriverInstanceId) IS kept when its UNS line's area
|
||||
/// is in the node's cluster — attributed via the line→area→cluster chain rather than via a driver.
|
||||
/// Both the EquipmentNode and its EquipmentVirtualTag must survive the scoped parse.</summary>
|
||||
[Fact]
|
||||
public void Driverless_equipment_kept_when_its_line_area_is_in_cluster()
|
||||
{
|
||||
var comp = DeploymentArtifact.ParseComposition(
|
||||
DriverlessEquipmentBlob(areaCluster: "C1"), "c1-1:4053");
|
||||
|
||||
comp.EquipmentNodes.Select(e => e.EquipmentId).ShouldBe(new[] { "E1" });
|
||||
comp.EquipmentVirtualTags.Select(v => v.VirtualTagId).ShouldBe(new[] { "vt-e1" });
|
||||
}
|
||||
|
||||
/// <summary>Verifies driver-less equipment is EXCLUDED when its UNS line's area is in another cluster:
|
||||
/// the node scopes to C1 but area A1 (and thus line L1, equipment E1) lives in C2.</summary>
|
||||
[Fact]
|
||||
public void Driverless_equipment_excluded_when_its_line_area_in_other_cluster()
|
||||
{
|
||||
var comp = DeploymentArtifact.ParseComposition(
|
||||
DriverlessEquipmentBlob(areaCluster: "C2"), "c1-1:4053");
|
||||
|
||||
comp.EquipmentNodes.ShouldBeEmpty();
|
||||
comp.EquipmentVirtualTags.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
/// <summary>Verifies the unchanged driver-bound path: equipment with an in-cluster DriverInstanceId is
|
||||
/// kept even when (as here) no UNS line/area rows describe it — attribution is still by driver.</summary>
|
||||
[Fact]
|
||||
public void Driverbound_equipment_kept_when_driver_in_cluster()
|
||||
{
|
||||
var blob = BlobOf(new
|
||||
{
|
||||
Clusters = new[] { new { ClusterId = "C1" }, new { ClusterId = "C2" } },
|
||||
Nodes = new[]
|
||||
{
|
||||
new { NodeId = "c1-1:4053", ClusterId = "C1" },
|
||||
new { NodeId = "c2-1:4053", ClusterId = "C2" },
|
||||
},
|
||||
DriverInstances = new[]
|
||||
{
|
||||
new { DriverInstanceId = "c1-driver", DriverType = "Modbus", DriverConfig = "{}", ClusterId = "C1", NamespaceId = "c1-ns" },
|
||||
new { DriverInstanceId = "c2-driver", DriverType = "Modbus", DriverConfig = "{}", ClusterId = "C2", NamespaceId = "c2-ns" },
|
||||
},
|
||||
Equipment = new[]
|
||||
{
|
||||
new { EquipmentId = "E-c1", Name = "Eq-c1", UnsLineId = "l1", DriverInstanceId = "c1-driver" },
|
||||
new { EquipmentId = "E-c2", Name = "Eq-c2", UnsLineId = "l2", DriverInstanceId = "c2-driver" },
|
||||
},
|
||||
});
|
||||
|
||||
var comp = DeploymentArtifact.ParseComposition(blob, "c1-1:4053");
|
||||
comp.EquipmentNodes.Select(e => e.EquipmentId).ShouldBe(new[] { "E-c1" });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user