Skip to content

test(comdelay): host-side unit tests for latch/divider pacing (target: perf/comdelay-divider0-passthrough, stacks on #475) - #478

Closed
Mikefly123 wants to merge 2 commits into
perf/comdelay-divider0-passthroughfrom
test/comdelay-ut
Closed

test(comdelay): host-side unit tests for latch/divider pacing (target: perf/comdelay-divider0-passthrough, stacks on #475)#478
Mikefly123 wants to merge 2 commits into
perf/comdelay-divider0-passthroughfrom
test/comdelay-ut

Conversation

@Mikefly123

Copy link
Copy Markdown
Contributor

Summary

Stacks on #475 (perf/comdelay-divider0-passthrough). Extracts ComDelay's latch/divider pacing into a header-only, F'-free DelayCore.hpp and adds host-side gtest coverage, following the repo's established extracted-helper convention (test_LinkProfiles, test_DetumbleManager_*, test_RtcManager_RtcHelper in PROVESFlightControllerReference/test/unit-tests/). The component (ComDelay.cpp) keeps ownership of F' types and ports and delegates all timing decisions to the core — a behavior-preserving refactor plus tests.

Why: the divider-0 passthrough in #475 shipped hardware-validated on HWIL but with zero automated coverage of ComDelay's pacing semantics; this pins them. Pacing correctness directly gates the comStatus-driven downlink cadence that the S-Band/USP throughput-ladder work (#439 and follow-ons) depends on.

Coverage (numbered per test plan)

  1. Tick-paced release only on counter==0 tick — LatchedStatusReleasedOnlyOnCounterZeroTick
  2. DIVIDER=N releases every N+1 ticks — DividerNReleasesEveryNPlusOneTicks; default 299 pinned in DefaultDivider299WrapsAt256 (see finding below)
  3. Exactly-once consumption — LatchedStatusConsumedExactlyOnce
  4. No emit without a latched status — NoEmitWithoutLatchedStatus
  5. Runtime divider change mid-cycle: no loss / no double-emit — RuntimeDividerChangeKeepsLatchedStatusExactlyOnce, LatchedStatusSurvivesRuntimeChangeToDividerZero
  6. Divider-0 passthrough (perf(comdelay): DIVIDER=0 passes comStatus straight through (TX-done-paced downlink) #475): immediate forward, latch untouched, DIVIDER>0 unchanged — DividerZeroPassesThroughWithoutLatching, DividerZeroThenNonZeroLatchingStillWorks
  7. Invalid/uninit param falls back to default divider — InvalidParamFallsBackToDefaultDivider

Finding: U8 tick-counter wrap

The tick counter is U8, so for DIVIDER >= 256 it wraps 255->0 before reaching the divider: the default DIVIDER=299 actually releases every 256 ticks (~25.6 s @ 1 Hz), not the intended 300 (30 s). DefaultDivider299WrapsAt256 pins the actual flight behavior and documents the fix path (widen to U16 in DelayCore + ComDelay). Left unfixed here to keep this PR behavior-preserving.

Notes

Do not merge before #475.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 730f8380-d753-4908-9c24-5b493bbed1be

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

ComDelay had no unit test coverage (CMakeLists UT block was a commented
template). Extract the tick/divider/latch state machine into a
host-testable ComDelayLogic class -- following this repo's established
pattern for passive-component logic extraction (RtcHelper, BDot,
Magnetorquer, StrategySelector, Bypasser, Parser/Validator/Authenticator)
-- and add it to the gtest suite driven by `make test-unit`.

ComDelay.cpp/.hpp now delegate to ComDelayLogic; behavior is unchanged
(verified against the pre-existing atomic compare_exchange consume-once
semantics and against the U8 tick-counter width).

Covers: tick-paced release, divider math (small N and the default
divider), exactly-once consumption, no-emit when nothing is latched,
runtime divider changes mid-cycle (shrink and grow), and param-invalid
fallback to the default divider.

Finding: DEFAULT_DIVIDER=299 does not actually yield a ~30s/300-tick
period as commented in ComDelay.fpp -- the production tick counter is a
U8 (max 255), so it wraps via 8-bit overflow at 256 ticks before ever
reaching the 299 comparison threshold. Tests pin the real (256-tick)
behavior rather than the aspirational one; no behavior change made here.
@Mikefly123

Copy link
Copy Markdown
Contributor Author

Closing: accidental duplicate of #479 — two agents collided on the same head branch (test/comdelay-ut), leaving this PR's diff against the stale pre-#477 base meaningless. #479 carries the ComDelay UT work (same ComDelayLogic extraction + tests, based on current feat/usp-radio). The divider-0 passthrough test cases should be added on #475's branch once it is updated against post-#477 feat/usp-radio.

@Mikefly123 Mikefly123 closed this Jul 27, 2026
@github-project-automation github-project-automation Bot moved this to Done in V1.X.X Jul 27, 2026
Mikefly123 added a commit that referenced this pull request Jul 31, 2026
Adds the passthrough test cases that belong with
perf/comdelay-divider0-passthrough (#475), mirroring the coverage
intended by closed PR #478:

- divider-0 forwards immediately (both SUCCESS and FAILURE values)
  without ever setting the latch, so run ticks cannot double-emit
- divider 0 -> N runtime transition latches/tick-paces again
- N -> 0 transition with a status already latched neither loses the
  latched status nor double-emits it (exactly one tick emission)
- invalid DIVIDER parameter falls back to the nonzero default and
  therefore latches, never passthroughs

Kept as a separate commit so the extraction/refactor layer diff of
this branch stays reviewable on its own.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant