Skip to main content

max / synckit

2.5 KB · 44 lines History Blame Raw
1 # Mutants no test can kill, with the reason each is equivalent to the code it
2 # replaces.
3 #
4 # THE BAR IS IMPOSSIBILITY, NOT COST (infra `374e1971`, settled 2026-08-31). A
5 # mutant a test could kill, where nobody has written that test, stays a visible
6 # survivor with a GoingsOn task against it however unappealing the test looks.
7 # An exclusion list that also absorbs "not worth it" reports zero while real
8 # coverage gaps sit underneath it, which is the one thing the number is for.
9 #
10 # The two in-memory size guards are the worked example of the other direction.
11 # `data.len() > cap` and `total_in > cap` survived every run because the cap was
12 # a 4 GiB constant and `>`, `>=` and `==` agree at every size a fixture can
13 # reach. That is cost, not impossibility: the cap became a per-client field
14 # (`synckit@7bc19e6`) and two tests now stand on both sides of it. Neither is in
15 # this file.
16 #
17 # The patterns are regexes matched against the WHOLE listing line, `file:line:col`
18 # included, so `+`, `*` and `|` need escaping. A bare `||` is an empty
19 # alternation and silently excludes every mutant in the crate.
20 #
21 # Both entries carry a position because the description alone is ambiguous:
22 # cargo-mutants names a mutant by its operator and enclosing function and
23 # nothing else, and each of these functions holds other `<` comparisons that are
24 # caught. A stale anchor stops matching and the mutant returns as a visible
25 # survivor, which is the safe direction. Re-derive by diffing
26 # `cargo mutants --list` with and without this file.
27
28 exclude_re = [
29 # `next_part < start.part_count` in the part-filling loop. Every part but
30 # the last is exactly `part_size`, so the loop never sends the final part;
31 # `staged.len() >= part_size` can hold at `next_part == start.part_count`
32 # only when the ciphertext is an exact multiple of the part size, and the
33 # extra iteration then sends byte-identical bytes to the same URL before the
34 # function returns down the resume branch regardless. No observation
35 # distinguishes it.
36 "src/client/blob.rs:632:58: replace < with <= in SyncKitClient::stream_blob_parts",
37
38 # `next_chunk < h.chunk_count` in the chunk-peeling loop. One chunk past the
39 # count breaks on the next line against an empty buffer, before anything is
40 # decrypted or appended. The bound is written as the count because that is
41 # what the count means, not because it is what stops the loop.
42 "src/client/blob.rs:940:30: replace < with <= in SyncKitClient::blob_download",
43 ]
44