test(opcua): #870 review — pin the 1000th-newest duplicate-window boundary; serialise the ring-queue switch users
Claude-Session: https://claude.ai/code/session_01GT67AD99zQQqpLCVm3p7xk
This commit is contained in:
+3
@@ -35,6 +35,9 @@ namespace ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests;
|
||||
/// compiles against the pre-#855 tree for a before/after comparison.</para>
|
||||
/// </remarks>
|
||||
[Trait("Category", "Perf")]
|
||||
// Shares a collection with the other user of OtOpcUaSdkServer.RingEventQueues (a process-wide switch the perf
|
||||
// harness flips), so the wiring assertion never observes it switched off (#870 review).
|
||||
[Collection(RingEventQueueSwitchCollection.Name)]
|
||||
public sealed class FolderEventDeliveryPerfTests
|
||||
{
|
||||
private const string OptInVariable = "OTOPCUA_EVENT_PERF";
|
||||
|
||||
+11
@@ -9,6 +9,9 @@ namespace ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests;
|
||||
/// item's queue is a <see cref="RingEventMonitoredItemQueue"/>; the SDK's <see cref="EventQueueHandler"/> always asks
|
||||
/// the server's factory), and data-change queues are still the SDK's own.
|
||||
/// </summary>
|
||||
// Shares a collection with the other user of OtOpcUaSdkServer.RingEventQueues (a process-wide switch the perf
|
||||
// harness flips), so the wiring assertion never observes it switched off (#870 review).
|
||||
[Collection(RingEventQueueSwitchCollection.Name)]
|
||||
public sealed class RingEventQueueWiringTests
|
||||
{
|
||||
[Fact]
|
||||
@@ -23,3 +26,11 @@ public sealed class RingEventQueueWiringTests
|
||||
factory.CreateDataChangeQueue(false, 2).ShouldBeOfType<DataChangeMonitoredItemQueue>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Serialises the tests that read or flip <c>OtOpcUaSdkServer.RingEventQueues</c>.</summary>
|
||||
[CollectionDefinition(Name)]
|
||||
public sealed class RingEventQueueSwitchCollection
|
||||
{
|
||||
/// <summary>The collection name.</summary>
|
||||
public const string Name = "RingEventQueueSwitch";
|
||||
}
|
||||
|
||||
+20
@@ -143,6 +143,26 @@ public sealed class RingEventMonitoredItemQueueParityTests
|
||||
Both(q => q.IsEventContainedInQueue(Targets[1]), sdk, ring, "absent").ShouldBeFalse();
|
||||
}
|
||||
|
||||
/// <summary>Upper boundary of the window: the entry exactly 1000th from newest is still found; 1001st is not.</summary>
|
||||
[Fact]
|
||||
public void Duplicate_check_includes_the_1000th_newest_entry()
|
||||
{
|
||||
var sdk = new EventMonitoredItemQueue(false, 1, Telemetry);
|
||||
var ring = new RingEventMonitoredItemQueue(1);
|
||||
sdk.SetQueueSize(3000, true);
|
||||
ring.SetQueueSize(3000, true);
|
||||
var outside = new Target();
|
||||
var boundary = new Target();
|
||||
void Add(EventFieldList e) { sdk.Enqueue(e); ring.Enqueue(e); }
|
||||
Add(new EventFieldList { Handle = outside });
|
||||
Add(new EventFieldList { Handle = boundary });
|
||||
for (var i = 0; i < 999; i++) Add(new EventFieldList { Handle = Targets[0] });
|
||||
|
||||
// 1001 entries: `boundary` is the 1000th newest (inside), `outside` the 1001st.
|
||||
Both(q => q.IsEventContainedInQueue(boundary), sdk, ring, "boundary").ShouldBeTrue();
|
||||
Both(q => q.IsEventContainedInQueue(outside), sdk, ring, "outside").ShouldBeFalse();
|
||||
}
|
||||
|
||||
/// <summary>Random interleavings of every queue operation, at small sizes (wrap-around, grow, shrink, size 0).</summary>
|
||||
[Theory]
|
||||
[MemberData(nameof(Seeds))]
|
||||
|
||||
Reference in New Issue
Block a user