test(v3): migrate OpcUaServer.Tests + Host.IntegrationTests to v3 dark address space

Migrate the server composer/applier + 2-node harness tests off the retired
Namespace/NamespaceKind + equipment→driver/device binding schema onto the v3
greenfield shape (raw-only Tag; DriverInstance-RawFolderId; equipment via UnsLine).

OpcUaServer.Tests (134 build errors -> green, 335 pass / 4 skip):
- LIVE (migrated, passing): VirtualTag-historize + ScriptedAlarm composition,
  composer purity/hierarchy, applier MaterialiseHierarchy + MaterialiseEquipmentTags
  idempotency (hand-fed applier, not dark).
- SKIP dark-until-Batch-4: {{equip}} token expansion, applier equipment-namespace
  E2E (equipment-tag variable materialization).
- RETIRE-with-comment / skip: alias-tag (Tag.EquipmentId binding gone) + device-host
  equipment binding (architecturally removed).
- Add local DarkAddressSpaceReasons Skip-reason constants (mirrors Runtime.Tests).

Host.IntegrationTests (green, in-memory): drop deleted-Namespace seeds from
MultiClusterScoping + DriverReconnect; reshape EquipmentNamespaceMaterialization to
assert the DARK contract (folder nodes decode, EquipmentTags empty despite a seeded
v3 raw tag) with the full raw-tag->EquipmentTag materialization kept as a
Batch-4-pending Skip.

Tests-only; no src/ changes.
This commit is contained in:
Joseph Doherty
2026-07-15 21:41:04 -04:00
parent aaba2ebd66
commit 2c7fc65bae
11 changed files with 186 additions and 282 deletions
@@ -65,7 +65,6 @@ public sealed class AddressSpaceComposerScriptedAlarmTests
var result = AddressSpaceComposer.Compose(
Array.Empty<UnsArea>(), Array.Empty<UnsLine>(), Array.Empty<Equipment>(),
Array.Empty<DriverInstance>(), new[] { alarm1, alarm2 },
Array.Empty<Tag>(), Array.Empty<Namespace>(),
virtualTags: Array.Empty<VirtualTag>(),
scripts: new[] { script1, script2 });
@@ -121,7 +120,6 @@ public sealed class AddressSpaceComposerScriptedAlarmTests
var result = AddressSpaceComposer.Compose(
Array.Empty<UnsArea>(), Array.Empty<UnsLine>(), Array.Empty<Equipment>(),
Array.Empty<DriverInstance>(), new[] { alarm },
Array.Empty<Tag>(), Array.Empty<Namespace>(),
scripts: new[] { script });
var plan = result.EquipmentScriptedAlarms.ShouldHaveSingleItem();
@@ -158,7 +156,6 @@ public sealed class AddressSpaceComposerScriptedAlarmTests
var result = AddressSpaceComposer.Compose(
Array.Empty<UnsArea>(), Array.Empty<UnsLine>(), Array.Empty<Equipment>(),
Array.Empty<DriverInstance>(), new[] { alarm },
Array.Empty<Tag>(), Array.Empty<Namespace>(),
scripts: new[] { script });
var plan = result.EquipmentScriptedAlarms.ShouldHaveSingleItem();
@@ -202,7 +199,6 @@ public sealed class AddressSpaceComposerScriptedAlarmTests
var result = AddressSpaceComposer.Compose(
Array.Empty<UnsArea>(), Array.Empty<UnsLine>(), Array.Empty<Equipment>(),
Array.Empty<DriverInstance>(), new[] { goodAlarm, orphanAlarm },
Array.Empty<Tag>(), Array.Empty<Namespace>(),
scripts: new[] { goodScript });
var plan = result.EquipmentScriptedAlarms.ShouldHaveSingleItem();
@@ -237,7 +233,6 @@ public sealed class AddressSpaceComposerScriptedAlarmTests
var result = AddressSpaceComposer.Compose(
Array.Empty<UnsArea>(), Array.Empty<UnsLine>(), Array.Empty<Equipment>(),
Array.Empty<DriverInstance>(), new[] { alarm },
Array.Empty<Tag>(), Array.Empty<Namespace>(),
scripts: new[] { script });
var plan = result.EquipmentScriptedAlarms.ShouldHaveSingleItem();
@@ -264,12 +259,12 @@ public sealed class AddressSpaceComposerScriptedAlarmTests
var r1 = AddressSpaceComposer.Compose(
Array.Empty<UnsArea>(), Array.Empty<UnsLine>(), Array.Empty<Equipment>(),
Array.Empty<DriverInstance>(), new[] { a1, a2, a3 },
Array.Empty<Tag>(), Array.Empty<Namespace>(), scripts: scripts);
scripts: scripts);
var r2 = AddressSpaceComposer.Compose(
Array.Empty<UnsArea>(), Array.Empty<UnsLine>(), Array.Empty<Equipment>(),
Array.Empty<DriverInstance>(), new[] { a3, a1, a2 },
Array.Empty<Tag>(), Array.Empty<Namespace>(), scripts: scripts);
scripts: scripts);
// Sorted by EquipmentId then ScriptedAlarmId: (eq-1,al-2), (eq-1,al-3), (eq-2,al-1).
r1.EquipmentScriptedAlarms.Select(p => p.ScriptedAlarmId)