Skip to content

ConnectionActor::compute_availability lacks shutdown-suppression coverage (mutation timeouts, not caught) #622

Description

@leynos

Context

Run 29560607689 (schedule, 2026-07-17). src/connection/mod.rs was in the changed-file set. Two mutants in ConnectionActor::compute_availability timed out rather than being caught or missed:

src/connection/mod.rs:314:67: delete ! in ConnectionActor<F, E>::compute_availability
src/connection/mod.rs:315:59: delete ! in ConnectionActor<F, E>::compute_availability

Analysis

fn compute_availability(&self, state: &ActorState) -> EventAvailability {
    EventAvailability {
        high: self.high_rx.is_some(),
        low: self.low_rx.is_some(),
        multi_packet: self.active_output.is_multi_packet() && !state.is_shutting_down(),
        response: self.active_output.is_response() && !state.is_shutting_down(),
    }
}

Deleting either ! makes the corresponding channel report as available during shutdown instead of unavailable. compute_availability's result feeds the biased tokio::select! in the actor's run loop (documented a few lines below as observing shutdown first, then high/low pushes, multi-packet, then the response stream, with a final else branch to avoid panicking "if all guards are false"). If a source is wrongly reported available during shutdown, the corresponding select! arm can stay armed and the loop can keep servicing it instead of terminating — consistent with these mutants hanging the test binary until the mutation-testing timeout, rather than failing an assertion.

This is a distinct pair of survivor sites from #569 (which covers ActorState::is_shutting_down()'s own polarity, asserted via ActorStateHarness::start_shutdown); no existing test exercises compute_availability's consumption of that flag for the multi-packet or response sources specifically.

Proposed next step

Add a unit test that puts the actor into shutdown with an active multi-packet channel and/or response stream still installed, calls compute_availability (or exercises it via the run loop with a bounded timeout), and asserts multi_packet == false and response == false. This both kills the two timeout mutants and gives an assertable regression guard against the hang scenario described above, rather than relying on the mutation-testing timeout to (eventually) surface it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions