From 6c22c36188d121704f69c9bd6dc15c4177faa1f9 Mon Sep 17 00:00:00 2001 From: Dietmar Borgards Date: Tue, 27 Oct 2026 06:07:41 +0100 Subject: [PATCH] test(j1939): clock retry confirmation during echo grace --- .../TestCases/J1939/J1939NodeTests.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/CanKit.Pro.Tests/TestCases/J1939/J1939NodeTests.cs b/tests/CanKit.Pro.Tests/TestCases/J1939/J1939NodeTests.cs index ba5106d1..6c8e8a88 100644 --- a/tests/CanKit.Pro.Tests/TestCases/J1939/J1939NodeTests.cs +++ b/tests/CanKit.Pro.Tests/TestCases/J1939/J1939NodeTests.cs @@ -770,7 +770,8 @@ public async Task A_Retry_During_Claim_Echo_Grace_Is_Not_Stolen_By_The_Late_Echo { using var clock = new VirtualClock(); using var bus = ControllableBus.DeferredEchoCapable(NewSession()); - using var raw = new CanBusService(bus); + var confirmationActor = clock.NewActor(); + using var raw = new ClockedCanBusService(bus, confirmationActor); using var scripted = new ScriptedClaimBus(raw, ScriptedClaimBus.Script.HoldFirstClaim); var actor = clock.NewActor(); var announce = TimeSpan.FromMilliseconds(80); @@ -788,10 +789,18 @@ public async Task A_Retry_During_Claim_Echo_Grace_Is_Not_Stolen_By_The_Late_Echo Func failed = () => first.WithTimeout(ShortTimeout); await failed.Should().ThrowAsync(); + // Start the retry inside the predecessor's grace, so that grace can expire while + // its real one-second confirmation deadline is still in the future. + var halfGrace = TimeSpan.FromTicks(J1939NodeImpl.ClaimEchoGrace.Ticks / 2); + await clock.WaitUntilTimerArmedAsync(actor, J1939NodeImpl.ClaimEchoGrace, ShortTimeout); + await clock.AdvanceAsync(halfGrace); + var retry = node.ClaimAddressAsync(0x11); await bus.DeferredEchoes.WaitForEnqueuedAsync(1, ShortTimeout); - await clock.WaitUntilTimerArmedAsync(actor, J1939NodeImpl.ClaimEchoGrace, ShortTimeout); - await clock.AdvanceAsync(J1939NodeImpl.ClaimEchoGrace); + await clock.WaitUntilTimerArmedAsync(confirmationActor, TimeSpan.FromSeconds(1), ShortTimeout); + await clock.WaitUntilTimerArmedAsync(actor, halfGrace, ShortTimeout); + await clock.AdvanceAsync(halfGrace); + await clock.WaitUntilTimerArmedAsync(confirmationActor, halfGrace, ShortTimeout); await DrainObservedAsync(node, bus, AddressClaim(sourceAddress: 0x11, nameBytes)); bus.DeferredEchoes.ReleaseAll().Should().Be(1);