100 lines
4.2 KiB
C#
100 lines
4.2 KiB
C#
using System.Text.Json;
|
|
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.Runtime.Drivers;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Drivers;
|
|
|
|
/// <summary>
|
|
/// Verifies the artifact-decode mirror (<see cref="DeploymentArtifact.ParseComposition(System.ReadOnlySpan{byte})"/>)
|
|
/// treats a Galaxy point as an ordinary equipment tag — an equipment-scoped tag (non-null
|
|
/// <c>EquipmentId</c>) bound to a <c>GalaxyMxGateway</c> driver in an <c>Equipment</c>-kind namespace —
|
|
/// into the decoded <c>EquipmentTags</c> with byte-parity to the live-edit composer path: same FullName,
|
|
/// EquipmentId, DriverInstanceId, Name, DataType. Both data-contract sites gate purely on the namespace
|
|
/// Kind being <c>Equipment</c> (no Galaxy/DriverType exception — the SystemPlatform-mirror contract is
|
|
/// retired), so they agree on which tags qualify.
|
|
/// </summary>
|
|
public sealed class DeploymentArtifactAliasParityTests
|
|
{
|
|
/// <summary>An artifact JSON blob with a GalaxyMxGateway driver in an Equipment (Kind=0) namespace and
|
|
/// one equipment-scoped tag (EquipmentId set, FolderPath null, FullName = the Galaxy ref). Decode must
|
|
/// surface the tag in EquipmentTags carrying its driver-side FullName, coalescing the null FolderPath to
|
|
/// <c>string.Empty</c>.</summary>
|
|
[Fact]
|
|
public void ParseComposition_admits_galaxy_equipment_tag_in_equipment_tags()
|
|
{
|
|
var blob = JsonSerializer.SerializeToUtf8Bytes(new
|
|
{
|
|
Namespaces = new[]
|
|
{
|
|
new { NamespaceId = "ns-eq", Kind = 0 }, // NamespaceKind.Equipment
|
|
},
|
|
DriverInstances = new[]
|
|
{
|
|
new { DriverInstanceId = "drv-galaxy", DriverType = "GalaxyMxGateway", DriverConfig = "{}", NamespaceId = "ns-eq" },
|
|
},
|
|
Tags = new object[]
|
|
{
|
|
new
|
|
{
|
|
TagId = "tag-galaxy",
|
|
DriverInstanceId = "drv-galaxy",
|
|
EquipmentId = "eq-1",
|
|
Name = "TestChangingInt",
|
|
FolderPath = (string?)null,
|
|
DataType = "Int32",
|
|
TagConfig = "{\"FullName\":\"TestMachine_020.TestChangingInt\"}",
|
|
},
|
|
},
|
|
});
|
|
|
|
var c = DeploymentArtifact.ParseComposition(blob);
|
|
|
|
var tag = c.EquipmentTags.ShouldHaveSingleItem();
|
|
tag.TagId.ShouldBe("tag-galaxy");
|
|
tag.EquipmentId.ShouldBe("eq-1");
|
|
tag.DriverInstanceId.ShouldBe("drv-galaxy");
|
|
tag.Name.ShouldBe("TestChangingInt");
|
|
tag.DataType.ShouldBe("Int32");
|
|
tag.FolderPath.ShouldBe(string.Empty);
|
|
tag.FullName.ShouldBe("TestMachine_020.TestChangingInt");
|
|
}
|
|
|
|
/// <summary>An equipment-scoped GalaxyMxGateway tag in a SystemPlatform-kind namespace must NOT surface
|
|
/// in EquipmentTags — byte-parity with the composer's pure <c>ns.Kind == NamespaceKind.Equipment</c>
|
|
/// predicate. The retired SystemPlatform-mirror contract no longer carried a DriverType exception, so a
|
|
/// non-Equipment namespace excludes the tag regardless of driver type.</summary>
|
|
[Fact]
|
|
public void ParseComposition_excludes_galaxy_tag_in_non_equipment_namespace()
|
|
{
|
|
var blob = JsonSerializer.SerializeToUtf8Bytes(new
|
|
{
|
|
Namespaces = new[]
|
|
{
|
|
new { NamespaceId = "ns-sp", Kind = 1 }, // NamespaceKind.SystemPlatform
|
|
},
|
|
DriverInstances = new[]
|
|
{
|
|
new { DriverInstanceId = "drv-galaxy", DriverType = "GalaxyMxGateway", DriverConfig = "{}", NamespaceId = "ns-sp" },
|
|
},
|
|
Tags = new object[]
|
|
{
|
|
new
|
|
{
|
|
TagId = "tag-x",
|
|
DriverInstanceId = "drv-galaxy",
|
|
EquipmentId = "eq-1",
|
|
Name = "Source",
|
|
FolderPath = (string?)null,
|
|
DataType = "Int32",
|
|
TagConfig = "{\"FullName\":\"TestMachine_020.Source\"}",
|
|
},
|
|
},
|
|
});
|
|
|
|
var c = DeploymentArtifact.ParseComposition(blob);
|
|
|
|
c.EquipmentTags.ShouldBeEmpty();
|
|
}
|
|
}
|