diff --git a/tests/CanKit.Pro.Tests/TestCases/IsoTp/IsoTpChannelIntegrationTests.cs b/tests/CanKit.Pro.Tests/TestCases/IsoTp/IsoTpChannelIntegrationTests.cs index 895960a..c74e338 100644 --- a/tests/CanKit.Pro.Tests/TestCases/IsoTp/IsoTpChannelIntegrationTests.cs +++ b/tests/CanKit.Pro.Tests/TestCases/IsoTp/IsoTpChannelIntegrationTests.cs @@ -411,7 +411,11 @@ public async Task Dispose_Unblocks_Pending_ReceiveAsync() using var busA = OpenClassic(session, 0); using var busB = OpenClassic(session, 1); - var channel = IsoTpFactory.Open(busA, IsoTpEndpoint.Normal(0x123, 0x321), FastOptions()); + // `using` on top of the two explicit calls below: the point of this test is that Dispose + // is idempotent, so a third call at scope exit changes nothing -- but without it a + // ReceiveAsync that throws would leave the channel open for the rest of the run + // (CodeQL cs/dispose-not-called-on-throw). + using var channel = IsoTpFactory.Open(busA, IsoTpEndpoint.Normal(0x123, 0x321), FastOptions()); var recvTask = channel.ReceiveAsync(); // Idempotent dispose channel.Dispose(); @@ -795,7 +799,10 @@ public async Task Send_Faults_With_The_Bus_Layer_Exception_And_Channel_Remains_U "the failure the bus layer reported must reach the caller unrewritten"); // Gate free and _tx cleared: the very next send goes through end to end. - var recvTask = receiver.ReceiveAsync(new CancellationTokenSource(ShortTimeout).Token); + // Owned rather than inline, so the timer it holds is released when the test ends and + // not when the finalizer gets round to it (CodeQL cs/local-not-disposed). + using var recvCts = new CancellationTokenSource(ShortTimeout); + var recvTask = receiver.ReceiveAsync(recvCts.Token); byte[] normal = { 0x11, 0x22, 0x33 }; await sender.SendAsync(normal).WaitAsync(ShortTimeout); (await recvTask).Should().Equal(normal);