d0697beb

By: Tom Sydney Kerckhove <syd@cs-syd.eu>

Retry mutation overruns, and stop scoring them as kills

A mutation check failed with nothing wrong with the code, and could not be
retried without deleting things out of the nix store by hand. The run that
prompted this reported 1132 killed, 0 survived, and 2 "failed" controls, both
of them timeouts at 30s and 50s, on a 64-core machine at load average 42.

Three things were wrong.

One overrun decided a control. A control is a no-op, so a suite that kills
one is unsound however often it is repeated, and concluding that on the first
run is right. A suite that merely overruns its budget has shown nothing of
the sort: the budget is ten times a baseline measured on an idle machine.
Only an outcome that says nothing is retried now, three attempts, for
controls and ordinary mutations alike. A kill and a survival are both
observations and stand on the first run, because repeating either would bias
the score towards whatever we repeated into -- the trap sydtest's own 'flaky'
warns about, seen from the other side.

An overrun was scored as a kill. So a loaded machine raised the score: those
ten mutations counted as caught while the tests had caught nothing. It is its
own category now, named in the report and in the assert-score total, and
asserted on nowhere, because a mutation that makes the code hang runs out of
time however idle the machine and failing on that would leave no way to pass.

The verdict was then stored where it would be read forever. 'run' exited zero
whatever the controls did, so the expensive derivation succeeded while
recording a failing verdict; nix caches successes, so every later attempt
read the stored copy rather than running anything. Retrying meant deleting
the report path, which was itself pinned by a gc root. An unsound run exits
non-zero now, so nothing is stored and the next attempt runs the mutations
again.

That makes the two nix derivations mean something they only happened to mean
before: the report gates soundness and assert-score gates the score. A score
is reproducible, so running for it once and reading the answer as often as
asked is what a derivation is for. Soundness is not, because what makes a run
unsound is a suite nobody can rely on, so there is nothing worth keeping.
'runSoundness' is the name for the distinction.

Total

17m38s

Created Started Finished

Time to Start Worker time Duration Time to finish Idle
Config 6m45s 1s 1s 6m46s 6m45s
Eval 6m50s 19s 19s 7m09s 4s
Build 7m09s 0s 16m48s 23m57s 16m47s
Deploy 23m57s 26s 26s 24m23s 0s
Suite 6m45s 46s 17m38s 24m23s 23m37s

Timeline

Config Eval Build Deploy Compressed gap
0s7m24m24m10s24m20s