Skip to content

Test WorkerHooks::notify_drained_if_empty directly to catch negation mutants #153

Description

@leynos

Context

Scheduled mutation run 29495843050 (2026-07-16, first green run after the baseline fix in #140) exercised 22 mutants across crates/comenqd/src/listener.rs, crates/comenqd/src/logging.rs, and crates/comenqd/src/worker.rs: 4 caught, 3 missed, 4 timed out, 11 unviable.

Two of the three missed mutants are negations of the same predicate in WorkerHooks::notify_drained_if_empty:

crates/comenqd/src/worker.rs:94:25: delete ! in WorkerHooks::notify_drained_if_empty
crates/comenqd/src/worker.rs:96:26: delete ! in WorkerHooks::notify_drained_if_empty
#[cfg(any(test, feature = "test-support"))]
fn notify_drained_if_empty(&self, queue_path: &Path) -> std::io::Result<()> {
    if let Some(n) = &self.drained {
        // Ignore sentinel files left by the queue implementation and
        // consider the directory empty when no other files remain.
        let empty = !stdfs::read_dir(queue_path)?
            .filter_map(Result::ok)
            .any(|e| !is_metadata_file(e.file_name()));
        if empty {
            n.notify_one();
        }
    }
    ...
}

Analysis

This helper is cfg-gated to test and test-support builds, and exists specifically so integration tests can wait for the queue to drain. Because it is test synchronisation machinery, an inverted empty calculation would not fail functionally — it would either notify on every poll (masking a real drain) or never notify (causing waiters to hang or fall back to a timeout), which is exactly the kind of failure that manifests as flaky or slow tests rather than a clean assertion failure. That is consistent with it going undetected by the current suite: nothing exercises the predicate directly, only indirectly through tests that use the notification as one of several synchronisation signals.

Proposed next step

Add a direct unit test for notify_drained_if_empty that covers: an empty directory (should notify), a directory containing only sentinel/metadata files (should notify), and a directory containing at least one non-metadata file (should not notify). This directly exercises the !...any(...) predicate and its negation, independent of the higher-level integration tests that currently rely on it only incidentally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    mediumCould be disruptive, but might not happentesting

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions