Add runtime address space rebuild integration tests
Tests verify nodes can be added/removed from the OPC UA server at runtime by mutating FakeGalaxyRepository and triggering a rebuild. Uses real OPC UA client sessions to browse, subscribe, and observe changes. Tests cover: - Browse initial hierarchy via OPC UA client - Add object at runtime → new node appears on browse - Remove object → node disappears from browse - Subscribe to node, then remove it → publishes Bad quality - Surviving nodes still browsable after partial rebuild - Add/remove individual attributes at runtime Infrastructure: - OpcUaTestClient helper for programmatic OPC UA client connections - OpcUaServerFixture updated with GalaxyRepository/MxProxy accessors - OpcUaService.TriggerRebuild() exposed for test-driven rebuilds - Namespace index resolved dynamically via session namespace table Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,15 +25,37 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Helpers
|
||||
public int OpcUaPort { get; }
|
||||
public string EndpointUrl => $"opc.tcp://localhost:{OpcUaPort}/LmxOpcUa";
|
||||
|
||||
/// <summary>
|
||||
/// The fake Galaxy repository injected into the service. Mutate Hierarchy/Attributes
|
||||
/// then call Service.TriggerRebuild() to simulate a Galaxy redeployment.
|
||||
/// </summary>
|
||||
public FakeGalaxyRepository? GalaxyRepository { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The fake MxAccess client injected into the service (when using WithFakeMxAccessClient).
|
||||
/// </summary>
|
||||
public FakeMxAccessClient? MxAccessClient { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The fake MxProxy injected into the service (when using WithFakes).
|
||||
/// </summary>
|
||||
public FakeMxProxy? MxProxy { get; }
|
||||
|
||||
private readonly OpcUaServiceBuilder _builder;
|
||||
private bool _started;
|
||||
|
||||
public OpcUaServerFixture(OpcUaServiceBuilder builder)
|
||||
private OpcUaServerFixture(OpcUaServiceBuilder builder,
|
||||
FakeGalaxyRepository? repo = null,
|
||||
FakeMxAccessClient? mxClient = null,
|
||||
FakeMxProxy? mxProxy = null)
|
||||
{
|
||||
OpcUaPort = Interlocked.Increment(ref _nextPort);
|
||||
_builder = builder;
|
||||
_builder.WithOpcUaPort(OpcUaPort);
|
||||
_builder.DisableDashboard();
|
||||
GalaxyRepository = repo;
|
||||
MxAccessClient = mxClient;
|
||||
MxProxy = mxProxy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -56,7 +78,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Helpers
|
||||
.WithGalaxyRepository(r)
|
||||
.WithGalaxyName("TestGalaxy");
|
||||
|
||||
return new OpcUaServerFixture(builder);
|
||||
return new OpcUaServerFixture(builder, repo: r, mxProxy: p);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -79,7 +101,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Helpers
|
||||
.WithGalaxyRepository(r)
|
||||
.WithGalaxyName("TestGalaxy");
|
||||
|
||||
return new OpcUaServerFixture(builder);
|
||||
return new OpcUaServerFixture(builder, repo: r, mxClient: client);
|
||||
}
|
||||
|
||||
public Task InitializeAsync()
|
||||
|
||||
Reference in New Issue
Block a user