Skip to content

process_timeouts in MeshRouter has no test exercising the full timeout-exhaustion to DeliveryFailed path #248

Description

@forkwright

Finding

MeshRouter::process_timeouts is the only production path that turns timeout events into DeliveryFailure::MaxRetries records, and it is untested. The existing router tests cover nak_triggers_retry_then_failure, which exercises the NAK branch (outbound.handle_nak), but no test drives the timeout chain outbound.check_timeouts -> outbound.retry -> delivery.mark_failed. There is no time-based test (#[tokio::test(start_paused = true)] or any time-advance) that calls process_timeouts with a timed-out inflight packet and asserts the resulting failure state.

Evidence

crates/kerykeion/src/router.rs:187:

pub fn process_timeouts(&mut self) -> Vec<PacketId> {

This function (router.rs:187-200) is the sole producer of DeliveryFailure::MaxRetries. The router.rs mod tests contains no #[tokio::test(start_paused = true)] test and no time-advance covering this function; coverage of the failure path comes only from nak_triggers_retry_then_failure, which routes through the NAK branch rather than the timeout branch.

Why this matters

process_timeouts is the primary durability gate for the outbound queue under radio silence: when a mesh node stops ACKing, this path decides whether messages are retried or marked failed. Under the counter-surveillance threat model, a node going dark (jamming, seizure, or an adversary suppressing ACKs) is an expected condition, not an edge case. A regression here — double-retry, delivery state not updated, or the wrong packet ID returned — would silently corrupt the delivery log: the operator could believe a message was delivered when it was lost, or retry a message that should have been abandoned. Because no test exercises the chain, such a regression is invisible to CI.

Desired correction

Add a #[tokio::test(start_paused = true)] test to the router.rs test module that: sends a packet, tracks it as inflight with a short ACK timeout, advances virtual time past the timeout, calls process_timeouts, and asserts that (a) the returned Vec<PacketId> contains the sent packet's ID, and (b) the delivery tracker reports Some(DeliveryStatus::Failed { .. }) for that packet. Cover both the single-timeout-to-retry and the retry-exhaustion-to-failure transitions.

Done when: a time-based test for process_timeouts exhausting retries passes and is part of the router test module.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions