feat(opcua): remove SystemPlatform mirror producer + Galaxy exception from Phase7Composer

This commit is contained in:
Joseph Doherty
2026-06-12 21:17:39 -04:00
parent 47cb5725a9
commit e2c6c15ae0
2 changed files with 37 additions and 76 deletions
@@ -6,35 +6,36 @@ using ZB.MOM.WW.OtOpcUa.Configuration.Enums;
namespace ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests;
/// <summary>
/// Verifies the live-edit compose seam (<see cref="Phase7Composer.Compose"/>) admits a Galaxy
/// alias tag — an equipment-scoped <see cref="Tag"/> (non-null <see cref="Tag.EquipmentId"/>)
/// bound to a <c>GalaxyMxGateway</c> driver that lives in a <c>SystemPlatform</c>-kind namespace.
/// The broadened equipment-tag filter must surface the alias under
/// <see cref="Phase7CompositionResult.EquipmentTags"/> (carrying its driver-side FullName) while a
/// sibling SystemPlatform mirror tag (null EquipmentId) on the same driver stays in
/// <see cref="Phase7CompositionResult.GalaxyTags"/> and never double-counts.
/// Verifies the live-edit compose seam (<see cref="Phase7Composer.Compose"/>) treats a Galaxy
/// point as an ordinary equipment tag now that <c>GalaxyMxGateway</c> is a standard
/// Equipment-kind driver. An equipment-scoped <see cref="Tag"/> (non-null
/// <see cref="Tag.EquipmentId"/>) bound to a <c>GalaxyMxGateway</c> driver living in an
/// <c>Equipment</c>-kind namespace must surface under
/// <see cref="Phase7CompositionResult.EquipmentTags"/> (carrying its driver-side FullName), and
/// the retired SystemPlatform-mirror producer means <see cref="Phase7CompositionResult.GalaxyTags"/>
/// is always empty.
/// </summary>
public sealed class Phase7ComposerAliasTagTests
{
/// <summary>A <c>GalaxyMxGateway</c> driver in a SystemPlatform namespace carries two tags: an
/// equipment-scoped alias (EquipmentId set, FolderPath null, TagConfig FullName = the Galaxy ref)
/// and a SystemPlatform mirror (EquipmentId null, FolderPath set). Compose must put the alias in
/// EquipmentTags with its FullName and keep the mirror in GalaxyTags only.</summary>
/// <summary>A <c>GalaxyMxGateway</c> driver in an Equipment-kind namespace carries an
/// equipment-scoped Galaxy tag (EquipmentId set, FolderPath null, TagConfig FullName = the Galaxy
/// ref). Compose must put it in EquipmentTags with its FullName, and GalaxyTags must be empty
/// (the SystemPlatform mirror producer is gone).</summary>
[Fact]
public void Compose_admits_galaxy_alias_tag_in_equipment_tags()
public void Compose_admits_galaxy_equipment_tag_in_equipment_tags()
{
var ns = new Namespace
{
NamespaceId = "ns-sp",
NamespaceId = "ns-eq",
ClusterId = "c1",
Kind = NamespaceKind.SystemPlatform,
NamespaceUri = "urn:sp",
Kind = NamespaceKind.Equipment,
NamespaceUri = "urn:eq",
};
var driver = new DriverInstance
{
DriverInstanceId = "drv-galaxy",
ClusterId = "c1",
NamespaceId = "ns-sp",
NamespaceId = "ns-eq",
Name = "Galaxy1",
DriverType = "GalaxyMxGateway",
DriverConfig = "{}",
@@ -50,10 +51,10 @@ public sealed class Phase7ComposerAliasTagTests
MachineCode = "TESTMACHINE_020",
};
// (a) Equipment-scoped alias: EquipmentId set, FolderPath null, FullName = Galaxy ref.
var aliasTag = new Tag
// Equipment-scoped Galaxy tag: EquipmentId set, FolderPath null, FullName = Galaxy ref.
var galaxyTag = new Tag
{
TagId = "tag-alias",
TagId = "tag-galaxy",
DriverInstanceId = "drv-galaxy",
EquipmentId = "eq-1",
FolderPath = null,
@@ -63,36 +64,21 @@ public sealed class Phase7ComposerAliasTagTests
TagConfig = "{\"FullName\":\"TestMachine_020.TestChangingInt\"}",
};
// (b) SystemPlatform mirror: EquipmentId null, FolderPath set → stays a Galaxy tag.
var mirrorTag = new Tag
{
TagId = "tag-mirror",
DriverInstanceId = "drv-galaxy",
EquipmentId = null,
FolderPath = "TestMachine_020",
Name = "Speed",
DataType = "Float",
AccessLevel = TagAccessLevel.Read,
TagConfig = "{\"FullName\":\"TestMachine_020.Speed\"}",
};
var result = Phase7Composer.Compose(
new[] { area }, new[] { line }, new[] { equip },
new[] { driver }, Array.Empty<ScriptedAlarm>(),
new[] { aliasTag, mirrorTag }, new[] { ns });
new[] { galaxyTag }, new[] { ns });
// (a) the alias survives composition as an equipment tag, carrying its Galaxy FullName.
var alias = result.EquipmentTags.ShouldHaveSingleItem();
alias.TagId.ShouldBe("tag-alias");
alias.EquipmentId.ShouldBe("eq-1");
alias.DriverInstanceId.ShouldBe("drv-galaxy");
alias.Name.ShouldBe("TestChangingInt");
alias.DataType.ShouldBe("Int32");
alias.FullName.ShouldBe("TestMachine_020.TestChangingInt");
// The Galaxy point survives composition as an equipment tag, carrying its Galaxy FullName.
var tag = result.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.FullName.ShouldBe("TestMachine_020.TestChangingInt");
// (b) the SystemPlatform mirror stays in GalaxyTags and is NOT double-counted as equipment.
result.GalaxyTags.ShouldContain(g => g.TagId == "tag-mirror");
result.GalaxyTags.ShouldNotContain(g => g.TagId == "tag-alias");
result.EquipmentTags.ShouldNotContain(t => t.TagId == "tag-mirror");
// The SystemPlatform-mirror producer is retired → GalaxyTags is always empty.
result.GalaxyTags.ShouldBeEmpty();
}
}