Skip to content

Audit the test suite's 117 delay/sleep sites before converting any more of them #114

Description

@dborgards

Follow-up to #92 step 2 (#113). Not a conversion task — a counting task, and it should come before the next conversion.

Why this exists

#92 named three flaky tests in a table. #113 converted two of them and then found two more, each one by turning its own CI red:

found test how
#92 ISO-TP STmin pacing listed
#92 J1939 fixed-rate BAM listed
#113 round 3 DiscardPendingPdus_Drains_Completed_Pdus_And_Abort_Faults macOS went red
#113 round 5 J1939TpTests.Parallel_Bam_And_TwoCm_Sessions_Do_Not_Interfere macOS went red

Each was measured against main before being attributed, so none was caused by the branch:

test base branch
DiscardPendingPdus_… 4 / 6 4 / 6
Parallel_Bam_And_TwoCm_… 6 / 6 4 / 6

Six runs each under 2× load on a four-core box.

The problem is the discovery method. Converting members as CI trips over them makes any pull request unbounded, and it works through the population in the order the runner happens to lose its bets rather than in any order that reflects risk. #113 spent three of its five CI rounds on tests it did not touch.

What to produce

There are 117 Task.Delay / Thread.Sleep call sites under tests/CanKit.Pro.Tests/TestCases, across twenty files:

J1939/J1939NodeTests.cs                     21     ProtocolActorTimerTests.cs        4
CANopen/CanOpenNodeIntegrationTests.cs      17     IsoTp/IsoTpFunctionalClientTests   4
IsoTp/IsoTpChannelIntegrationTests.cs       14     BusStateMonitorTests.cs           4
ProtocolActorTests.cs                       10     RawCanSubscriptionTests.cs        3
DeadlineTests.cs                             9     Uds/SimulatedUdsEcu.cs            2
J1939TpTests.cs                              8     IsoTp/IsoTpBusOffTests.cs         2
Uds/UdsClientTests.cs                        5     …and six files with one each
CANopen/CanOpenDynamicMappingTests.cs        5

Classify each into:

  1. Waits for an effect — a bounded poll for something to become observable. Fine as it stands: a slow runner makes these slower, never wrong.
  2. Assumes work completed in a windowawait Task.Delay(50); /* it has surely arrived */. These are the defects. All four found so far are here.
  3. Whole-test budgets — a WithTimeout(5s) around work whose duration a loaded runner controls. Parallel_Bam_And_TwoCm_Sessions_Do_Not_Interfere is this shape, and it is not a sleep, so grepping for sleeps alone will miss it.

Output is a list, not a fix: which tests are in category 2 or 3, and for each, whether the interval it depends on runs on an actor that could be put on a VirtualClock.

What #113 already provides

VirtualClock with AdvanceAsync, AdvanceToAsync, RunUntilAsync and WaitUntilTimerArmedAsync; ProtocolActor.NextTimerDelayAsync as a sound arm-before-you-advance barrier; and injectable actors on IsoTpChannel and J1939NodeImpl.

J1939TpChannel and CanOpenNode still build their own actors, so anything in category 2 or 3 that lives in those layers needs the same seam first. Worth knowing before scoping, not after.

Two lessons from #113 worth carrying into any conversion

  • A jump over a deadline cannot distinguish it from any shorter one. Both converted tests initially verified that pacing existed and not that it had the configured value; halving the interval left them passing. Bracket from both sides.
  • The wire does not prove a timer is armed. A receiver sends flow control several statements before ArmNCr; a sender arms STmin from a thread-pool post. Move the clock in that window and the interval is armed from the new reading and never elapses.

Both were caught in review rather than by the tests failing, which is the argument for auditing rather than converting from memory.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: testsTest suite, coverage, API approvalstype: testsTest coverage — a missing, weak or flaky test

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions