refactor(opcuaserver): rename Phase7* address-space pipeline to AddressSpace*
v2-ci / build (push) Failing after 37s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped

The OPC UA address-space build pipeline was named after a v2-roadmap
milestone number rather than its domain. Rename the family to describe
what it does (build/diff/apply the OPC UA address space):

  Phase7Composer          -> AddressSpaceComposer
  Phase7CompositionResult -> AddressSpaceComposition
  Phase7Planner           -> AddressSpacePlanner
  Phase7Plan              -> AddressSpacePlan
  Phase7Applier           -> AddressSpaceApplier
  Phase7ApplyOutcome      -> AddressSpaceApplyOutcome

The 9 Phase7*Tests suites follow suit; Phase7ScriptingEntitiesTests ->
ScriptingEntitiesTests (it tests the scripting migration, not the
pipeline). Log-message prefixes move to the new class names.

Pure mechanical rename, no behavioral change. EF migration classes/IDs
(AddPhase7ScriptingTables, ExtendComputeGenerationDiffWithPhase7) are
immutable and left untouched, as are historical design docs.

Build clean; OpcUaServer 261/261, Runtime 272/272, ScriptingEntities
12/12 green.
This commit is contained in:
Joseph Doherty
2026-06-18 19:16:28 -04:00
parent 6af54ac935
commit 40e8a23e7c
44 changed files with 364 additions and 364 deletions
@@ -178,7 +178,7 @@ public sealed class DeploymentArtifactAliasParityTests
/// <summary>
/// The load-bearing direct byte-parity proof for the two equipment-tag producers: for the SAME
/// input draft, the live-edit composer (<see cref="Phase7Composer.Compose"/>) and the
/// input draft, the live-edit composer (<see cref="AddressSpaceComposer.Compose"/>) and the
/// artifact decoder (<see cref="DeploymentArtifact.ParseComposition(System.ReadOnlySpan{byte})"/>)
/// must emit IDENTICAL <c>EquipmentTags</c> — element-wise equal on every field
/// (TagId, EquipmentId, DriverInstanceId, FolderPath, Name, DataType, FullName) AND in the same
@@ -275,7 +275,7 @@ public sealed class DeploymentArtifactAliasParityTests
var namespaces = new[] { ns };
// ---- Side 1: the live-edit composer ----
var composed = Phase7Composer.Compose(
var composed = AddressSpaceComposer.Compose(
areas, lines, equipment, drivers, Array.Empty<ScriptedAlarm>(), tags, namespaces);
// ---- Side 2: serialise the SAME draft to the artifact blob shape ConfigComposer emits
@@ -349,7 +349,7 @@ public sealed class DeploymentArtifactAliasParityTests
/// The native-alarm <c>historizeToAveva</c> opt-out (bool?, the per-condition durable-AVEVA-write
/// gate) is parsed by BOTH equipment-tag producers' <c>ExtractTagAlarm</c> and MUST stay byte-parity:
/// for the SAME tag TagConfig carrying <c>alarm.historizeToAveva: true</c> (and <c>: false</c>), the
/// live-edit composer (<see cref="Phase7Composer.Compose"/>) and the artifact decoder
/// live-edit composer (<see cref="AddressSpaceComposer.Compose"/>) and the artifact decoder
/// (<see cref="DeploymentArtifact.ParseComposition(System.ReadOnlySpan{byte})"/>) must derive the
/// identical <c>EquipmentTagAlarmInfo.HistorizeToAveva</c>. The galaxy-tag parity test above already
/// covers the absent ⇒ null case; this pins the explicit-bool branch on both sides.
@@ -399,7 +399,7 @@ public sealed class DeploymentArtifactAliasParityTests
};
// ---- Side 1: the live-edit composer ----
var composed = Phase7Composer.Compose(
var composed = AddressSpaceComposer.Compose(
new[] { area }, new[] { line }, new[] { equip }, new[] { driver },
Array.Empty<ScriptedAlarm>(), new[] { alarmTag }, new[] { ns });
@@ -12,7 +12,7 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Drivers;
/// <summary>
/// Proves the Phase 4c array intent (<c>isArray</c> + optional <c>arrayLength</c>), which rides
/// inside the raw <c>TagConfig</c> JSON blob, round-trips with byte-parity through both
/// equipment-tag producers: the live-edit composer (<see cref="Phase7Composer.Compose"/>) and the
/// equipment-tag producers: the live-edit composer (<see cref="AddressSpaceComposer.Compose"/>) and the
/// artifact decoder (<see cref="DeploymentArtifact.ParseComposition(System.ReadOnlySpan{byte})"/>).
/// A secondary/follower node decoding a serialized deployment artifact MUST materialise array tags
/// identically to the primary, so the artifact side must derive <c>IsArray</c> / <c>ArrayLength</c>
@@ -153,7 +153,7 @@ public sealed class DeploymentArtifactArrayParityTests
var namespaces = new[] { ns };
// ---- Side 1: the live-edit composer ----
var composed = Phase7Composer.Compose(
var composed = AddressSpaceComposer.Compose(
areas, lines, equipment, drivers, Array.Empty<ScriptedAlarm>(), tags, namespaces);
// ---- Side 2: serialise the SAME draft to the artifact blob shape, then decode it ----
@@ -9,7 +9,7 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Drivers;
/// Verifies the artifact-decode mirror substitutes the reserved <c>{{equip}}</c> token in a
/// VirtualTag script's <c>ctx.GetTag("…")</c> literals with the owning equipment's tag base
/// (derived from its child Equipment-namespace tag's FullName) — byte-parity with
/// <c>Phase7Composer.Compose</c>'s live-edit path, using the same shared
/// <c>AddressSpaceComposer.Compose</c>'s live-edit path, using the same shared
/// <c>EquipmentScriptPaths</c> helper and the same equipmentTags-derived base.
/// </summary>
public sealed class DeploymentArtifactEquipTokenTests
@@ -12,7 +12,7 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Drivers;
/// <summary>
/// Proves the Phase C HistoryRead intent (<c>isHistorized</c> + optional <c>historianTagname</c>),
/// which rides inside the raw <c>TagConfig</c> JSON blob, round-trips with byte-parity through both
/// equipment-tag producers: the live-edit composer (<see cref="Phase7Composer.Compose"/>) and the
/// equipment-tag producers: the live-edit composer (<see cref="AddressSpaceComposer.Compose"/>) and the
/// artifact decoder (<see cref="DeploymentArtifact.ParseComposition(System.ReadOnlySpan{byte})"/>).
/// The artifact serializer re-parses the SAME <c>TagConfig</c> string both sides emit, so no
/// ConfigComposer change is needed — the flags are already carried in the blob.
@@ -120,7 +120,7 @@ public sealed class DeploymentArtifactHistorizeParityTests
var namespaces = new[] { ns };
// ---- Side 1: the live-edit composer ----
var composed = Phase7Composer.Compose(
var composed = AddressSpaceComposer.Compose(
areas, lines, equipment, drivers, Array.Empty<ScriptedAlarm>(), tags, namespaces);
// ---- Side 2: serialise the SAME draft to the artifact blob shape, then decode it ----
@@ -11,7 +11,7 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Drivers;
/// <summary>
/// Byte-parity tests for the scripted-alarm deployment-artifact decode path
/// (<c>DeploymentArtifact.BuildEquipmentScriptedAlarmPlans</c>) against the live compose seam
/// (<c>Phase7Composer.Compose</c>). Both sides derive <c>EquipmentScriptedAlarmPlan</c> from the
/// (<c>AddressSpaceComposer.Compose</c>). Both sides derive <c>EquipmentScriptedAlarmPlan</c> from the
/// same ScriptedAlarm + Script data via the shared <c>EquipmentScriptPaths.ExtractAlarmDependencyRefs</c>
/// helper, so the decoded plans must equal the composer's element-wise (the record has value
/// equality including DependencyRefs order). Mirrors the existing EquipmentVirtualTags parity
@@ -70,7 +70,7 @@ public sealed class DeploymentArtifactScriptedAlarmParityTests
Enabled = false,
};
var composed = Phase7Composer.Compose(
var composed = AddressSpaceComposer.Compose(
Array.Empty<UnsArea>(), Array.Empty<UnsLine>(), Array.Empty<Equipment>(),
Array.Empty<DriverInstance>(), new[] { alarm1, alarm2 },
Array.Empty<Tag>(), Array.Empty<Namespace>(),
@@ -189,7 +189,7 @@ public sealed class DeploymentArtifactScriptedAlarmParityTests
Enabled = true,
};
var composed = Phase7Composer.Compose(
var composed = AddressSpaceComposer.Compose(
Array.Empty<UnsArea>(), Array.Empty<UnsLine>(), Array.Empty<Equipment>(),
Array.Empty<DriverInstance>(), new[] { goodAlarm, orphanAlarm },
Array.Empty<Tag>(), Array.Empty<Namespace>(),
@@ -257,7 +257,7 @@ public sealed class DeploymentArtifactTests
/// Verifies ParseComposition surfaces Equipment-namespace VirtualTags (joined to their Script
/// by ScriptId for the expression source) as <c>EquipmentVirtualTags</c>, with the
/// <c>DependencyRefs</c> extracted from the script's <c>ctx.GetTag("…")</c> literals — the
/// artifact-decode mirror of <c>Phase7Composer.Compose</c>'s VirtualTag producer.
/// artifact-decode mirror of <c>AddressSpaceComposer.Compose</c>'s VirtualTag producer.
/// </summary>
[Fact]
public void ParseComposition_reads_EquipmentVirtualTags_from_virtualtags_and_scripts()
@@ -12,7 +12,7 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Drivers;
/// <summary>
/// Byte-parity tests for the VirtualTag <c>Historize</c> flag across the artifact-decode path
/// (<c>DeploymentArtifact.BuildEquipmentVirtualTagPlans</c>) and the live compose seam
/// (<c>Phase7Composer.Compose</c>) — H5b. The artifact JSON already carries a Pascal-case
/// (<c>AddressSpaceComposer.Compose</c>) — H5b. The artifact JSON already carries a Pascal-case
/// <c>"Historize"</c> bool (ConfigComposer serialises the whole VirtualTag entity with
/// <c>DefaultIgnoreCondition.Never</c>); the decode just had to read it. Both sides default to
/// <c>false</c> when the flag is unset/absent/non-bool, so the decoded plans must equal the
@@ -65,7 +65,7 @@ public sealed class DeploymentArtifactVirtualTagHistorizeParityTests
var vtHist = new VirtualTag { VirtualTagId = "vt-hist", EquipmentId = "eq-1", Name = "Historized", DataType = "Int32", ScriptId = "s-1", Historize = true };
var vtPlain = new VirtualTag { VirtualTagId = "vt-plain", EquipmentId = "eq-1", Name = "Plain", DataType = "Int32", ScriptId = "s-1", Historize = false };
var composed = Phase7Composer.Compose(
var composed = AddressSpaceComposer.Compose(
new[] { area }, new[] { line }, new[] { equip },
new[] { driver }, Array.Empty<ScriptedAlarm>(),
new[] { tag }, new[] { ns },
@@ -24,7 +24,7 @@ public sealed class OpcUaPublishActorRebuildTests : RuntimeActorTestBase
{
var db = NewInMemoryDbFactory();
var sink = new RecordingSink();
var applier = new Phase7Applier(sink, NullLogger<Phase7Applier>.Instance);
var applier = new AddressSpaceApplier(sink, NullLogger<AddressSpaceApplier>.Instance);
SeedDeployment(db, equipmentIds: new[] { "eq-1", "eq-2" }, driverIds: new[] { "drv-1" });
@@ -49,7 +49,7 @@ public sealed class OpcUaPublishActorRebuildTests : RuntimeActorTestBase
{
var db = NewInMemoryDbFactory();
var sink = new RecordingSink();
var applier = new Phase7Applier(sink, NullLogger<Phase7Applier>.Instance);
var applier = new AddressSpaceApplier(sink, NullLogger<AddressSpaceApplier>.Instance);
// No deployment seeded — LoadLatestArtifact returns empty blob.
var actor = Sys.ActorOf(OpcUaPublishActor.PropsForTests(
@@ -69,7 +69,7 @@ public sealed class OpcUaPublishActorRebuildTests : RuntimeActorTestBase
{
var db = NewInMemoryDbFactory();
var sink = new RecordingSink();
var applier = new Phase7Applier(sink, NullLogger<Phase7Applier>.Instance);
var applier = new AddressSpaceApplier(sink, NullLogger<AddressSpaceApplier>.Instance);
SeedDeployment(db, equipmentIds: new[] { "eq-1" }, driverIds: Array.Empty<string>());
var actor = Sys.ActorOf(OpcUaPublishActor.PropsForTests(
@@ -114,7 +114,7 @@ public sealed class OpcUaPublishActorRebuildTests : RuntimeActorTestBase
// --- SITE-A node: only the SITE-A tag's variable, never MAIN's. ---
var dbA = NewInMemoryDbFactory();
var sinkA = new RecordingSink();
var applierA = new Phase7Applier(sinkA, NullLogger<Phase7Applier>.Instance);
var applierA = new AddressSpaceApplier(sinkA, NullLogger<AddressSpaceApplier>.Instance);
SeedMultiClusterDeployment(dbA);
var siteActor = Sys.ActorOf(OpcUaPublishActor.PropsForTests(
@@ -134,7 +134,7 @@ public sealed class OpcUaPublishActorRebuildTests : RuntimeActorTestBase
// --- MAIN node: the mirror — only MAIN's tag's variable, never SITE-A's. ---
var dbM = NewInMemoryDbFactory();
var sinkM = new RecordingSink();
var applierM = new Phase7Applier(sinkM, NullLogger<Phase7Applier>.Instance);
var applierM = new AddressSpaceApplier(sinkM, NullLogger<AddressSpaceApplier>.Instance);
SeedMultiClusterDeployment(dbM);
var mainActor = Sys.ActorOf(OpcUaPublishActor.PropsForTests(