diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests/AbLegacyDeadDeviceIsolationTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests/AbLegacyDeadDeviceIsolationTests.cs index 2e5be188..64eb19fb 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests/AbLegacyDeadDeviceIsolationTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests/AbLegacyDeadDeviceIsolationTests.cs @@ -47,19 +47,23 @@ public sealed class AbLegacyDeadDeviceIsolationTests(AbLegacyServerFixture sim) await drv.InitializeAsync("{}", ct); string[] refs = ["Live", .. dead.Select(d => d.Name)]; - var sw = Stopwatch.StartNew(); - var first = await drv.ReadAsync(refs, ct); - sw.Stop(); + // Two consecutive comms faults mark the device down. With coalescing on, the dead device's 20 tags are ONE + // block (one fault per poll), so the window can open on the second poll rather than the first — either way + // at most two timeouts are paid before the device stops being dialled. + var total = TimeSpan.Zero; + TimeSpan last = default; + for (var poll = 0; poll < 3; poll++) + { + var sw = Stopwatch.StartNew(); + var r = await drv.ReadAsync(refs, ct); + sw.Stop(); + total += last = sw.Elapsed; + r[0].StatusCode.ShouldBe(AbLegacyStatusMapper.Good, $"poll {poll}: the live device must be served in the same poll"); + r.Skip(1).ShouldAllBe(s => s.StatusCode != AbLegacyStatusMapper.Good); + } - first[0].StatusCode.ShouldBe(AbLegacyStatusMapper.Good, "the live device must be served in the same poll"); - first.Skip(1).ShouldAllBe(s => s.StatusCode != AbLegacyStatusMapper.Good); - sw.Elapsed.ShouldBeLessThan(timeout * 3, "a dead device may cost at most two timeouts per backoff window"); - - sw.Restart(); - var second = await drv.ReadAsync(refs, ct); - sw.Stop(); - second[0].StatusCode.ShouldBe(AbLegacyStatusMapper.Good); - sw.Elapsed.ShouldBeLessThan(timeout, "inside the backoff window the dead device is not dialled"); + total.ShouldBeLessThan(timeout * 2.5, "a dead device may cost at most two timeouts per backoff window"); + last.ShouldBeLessThan(timeout, "inside the backoff window the dead device is not dialled"); drv.GetHealth().State.ShouldBe(DriverState.Degraded); } }