test(config): DraftValidator accepts driver-less equipment + driverless equipment namespace
This commit is contained in:
@@ -297,6 +297,65 @@ public sealed class DraftValidatorTests
|
||||
string.Join("; ", errors.Select(e => $"[{e.Code}] {e.Message}")));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// Driver-less Equipment namespace — core safety claim (feat/driverless-equipment-namespace)
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>Characterisation test: a draft that contains an Equipment-kind namespace with
|
||||
/// ZERO <see cref="DriverInstance"/> rows, and a single <see cref="Equipment"/> whose
|
||||
/// <see cref="Equipment.DriverInstanceId"/> is <see langword="null"/>, must pass
|
||||
/// <see cref="DraftValidator.Validate"/> with no errors. This locks in the design's core
|
||||
/// safety claim — the validator must never implicitly require a driver for Equipment-namespace
|
||||
/// equipment.</summary>
|
||||
[Fact]
|
||||
public void Validate_accepts_driverless_equipment_in_driverless_equipment_namespace()
|
||||
{
|
||||
// An Equipment-kind namespace — no DriverInstance rows at all for this namespace.
|
||||
var eqNamespace = new Namespace
|
||||
{
|
||||
NamespaceId = "MAIN-OPCUA-equipment",
|
||||
ClusterId = "MAIN",
|
||||
Kind = NamespaceKind.Equipment,
|
||||
NamespaceUri = "urn:zb:main:equipment",
|
||||
};
|
||||
|
||||
// UNS topology required by ValidateUnsSegments / ValidatePathLength.
|
||||
var area = new UnsArea { UnsAreaId = "area-filling", ClusterId = "MAIN", Name = "filling" };
|
||||
var line = new UnsLine { UnsLineId = "line-1", UnsAreaId = area.UnsAreaId, Name = "line-1" };
|
||||
|
||||
// Canonical EquipmentId derived from UUID — satisfies ValidateEquipmentIdDerivation.
|
||||
var uuid = Guid.NewGuid();
|
||||
var equipment = new Equipment
|
||||
{
|
||||
EquipmentUuid = uuid,
|
||||
EquipmentId = DraftValidator.DeriveEquipmentId(uuid),
|
||||
Name = "rinser-01",
|
||||
DriverInstanceId = null, // ← driver-less: the property under test
|
||||
UnsLineId = line.UnsLineId,
|
||||
MachineCode = "machine_001",
|
||||
ZTag = null,
|
||||
SAPID = null,
|
||||
};
|
||||
|
||||
var draft = new DraftSnapshot
|
||||
{
|
||||
GenerationId = 0,
|
||||
ClusterId = string.Empty, // global snapshot — matches DraftSnapshotFactory.FromConfigDbAsync
|
||||
Namespaces = [eqNamespace], // Equipment namespace present
|
||||
DriverInstances = [], // ← zero drivers: the other half of the safety claim
|
||||
UnsAreas = [area],
|
||||
UnsLines = [line],
|
||||
Equipment = [equipment],
|
||||
};
|
||||
|
||||
var errors = DraftValidator.Validate(draft);
|
||||
|
||||
errors.ShouldBeEmpty(
|
||||
"a driver-less Equipment in an Equipment-kind namespace with no DriverInstances must pass " +
|
||||
"all validator rules; firing rules: " +
|
||||
string.Join("; ", errors.Select(e => $"[{e.Code}] {e.Message}")));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// ValidateNoEquipmentSignalNameCollision — Tag/VirtualTag NodeId collision
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user