461133235a
FOCAS, AbLegacy, AbCip, TwinCAT, S7 and OpcUaClient orphaned the previous probe/recycle/fixed-tree loops and clients when re-initialised on a live driver. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
31 lines
1.2 KiB
C#
31 lines
1.2 KiB
C#
using Moq;
|
|
using Opc.Ua.Client;
|
|
using Shouldly;
|
|
using Xunit;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests;
|
|
|
|
/// <summary>
|
|
/// #630 (same pattern) — <c>InitializeAsync</c> on a live driver (no <c>ShutdownAsync</c> first) used to
|
|
/// overwrite <c>Session</c> and orphan the previous session + its keep-alive handler.
|
|
/// </summary>
|
|
[Trait("Category", "Unit")]
|
|
public sealed class OpcUaClientReinitializeReleasesSessionTests
|
|
{
|
|
/// <summary>A second Initialize disposes the live session before attempting to build a new one.</summary>
|
|
[Fact]
|
|
public async Task Initialize_OnLiveDriver_DisposesThePreviousSession()
|
|
{
|
|
var options = new OpcUaClientDriverOptions { EndpointUrl = "opc.tcp://127.0.0.1:1" };
|
|
using var drv = new OpcUaClientDriver(options, "opcua-reinit");
|
|
var old = new Mock<ISession>();
|
|
drv.SetSessionForTest(old.Object);
|
|
|
|
// The new connect is refused (nothing listens on port 1) — what matters is what happened to the old one.
|
|
await Should.ThrowAsync<Exception>(() => drv.InitializeAsync("{}", TestContext.Current.CancellationToken));
|
|
|
|
old.Verify(s => s.Dispose(), Times.AtLeastOnce);
|
|
drv.Session.ShouldBeNull();
|
|
}
|
|
}
|