Record the mutation score after the exit-status fix
src/error.c now scores 81.4%: 245 of 301 mutants killed, 211 by a failing test, 24 by failing to compile, and 10 by hanging the suite. The population grew by 8 with akerr_exit(), and all 8 die, as do the 4 in akerr_default_handler_unhandled_error() -- no survivor anywhere in either function. Two of those are worth naming. Mutating the guard to status < 1 (the sentinel-for-zero behaviour this library deliberately does not have) and mutating the NULL-context exit(1) to exit(0) both die, so the tests pin the two ways an exit could start claiming success rather than just the one that was broken. That moves the default handler out of the "needs a subprocess test" survivor category noted here: it has one now. The default *logger* is still in it -- every other test swaps in the capturing logger, so nothing watches what the real one writes to stderr. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -94,8 +94,8 @@ Re-run after adding tests and confirm the score went up.
|
||||
|
||||
## Current status
|
||||
|
||||
`src/error.c` scores 81.2% — 238 of 293 mutants killed (204 by a failing test,
|
||||
24 by failing to compile, 10 by hanging the suite), 55 surviving. The CI gate is
|
||||
`src/error.c` scores 81.4% — 245 of 301 mutants killed (211 by a failing test,
|
||||
24 by failing to compile, 10 by hanging the suite), 56 surviving. The CI gate is
|
||||
set to 65% for headroom.
|
||||
|
||||
The ten timeout kills are all in the locking: deleting `akerr_mutex_init()` or
|
||||
@@ -123,10 +123,16 @@ The remaining survivors are dominated by:
|
||||
it never sees that. Deleting an `akerr_init()` call survives for a duller
|
||||
reason: something else has always initialized the library by the time that
|
||||
line runs.
|
||||
* **Default logger / handler internals** (`vfprintf`, `va_end`, the
|
||||
`errctx == NULL` branch, `exit(1)`): killing these needs a subprocess-based
|
||||
test that captures a child's stderr and exit code, rather than the in-process
|
||||
capturing logger the other tests use.
|
||||
* **The default logger** (`vfprintf`, `va_end`, and the `return` in the
|
||||
no-stdlib branch): the other tests replace `akerr_log_method` with the
|
||||
in-process capturing logger, so nothing observes what the default one writes
|
||||
to a real stderr. Killing these needs a test that captures a child's stderr.
|
||||
The *handler* internals next to them are no longer in this category:
|
||||
`tests/err_unhandled_null.c` and `tests/err_exit_status.c` read a forked
|
||||
child's exit code, which kills every mutant in `akerr_exit()` and in
|
||||
`akerr_default_handler_unhandled_error()` — all twelve of them, including the
|
||||
`status < 0` → `status < 1` variant that only a test asserting
|
||||
`akerr_exit(0)` exits 0 can distinguish.
|
||||
* **Static assertions** (`akerr_assert_name_slots_pow2` and the occupancy cap
|
||||
it guards): a mutated compile-time assertion that still compiles has no
|
||||
runtime behavior to observe. Unkillable by construction — the assertion is
|
||||
|
||||
Reference in New Issue
Block a user