Skip to content

fix: correct mutation discovery and execution regressions - #46

Closed
fchimpan wants to merge 3 commits into
mainfrom
fix/mutation-correctness-and-regressions
Closed

fchimpan wants to merge 3 commits into
mainfrom
fix/mutation-correctness-and-regressions

Conversation

@fchimpan

@fchimpan fchimpan commented Sep 13, 2026 •

Copy link
Copy Markdown
Owner

Valid comparisons could be silently omitted, fail to compile after instrumentation, or produce misleading mutation scores. This fixes discovery, instrumentation, process cleanup, and reporting, with regression tests for the original failures and regressions found during before/after verification.

Changes

  • Restore zero-boundary len/cap comparisons; discover cgo files; propagate parse/read failures; use physical positions for //line and skip directives.
  • Preserve defined boolean types and arbitrary-precision constants during instrumentation. Resolve dependency export data from the original package patterns, including relative imports and vendoring, and use go env GOARCH for target type sizes.
  • Restrict error-propagation skipping to simple error returns. Skip equivalent clamps only for local integer variables assigned the same constant, with no else; retain floats, map entries, globals, calls, and different assigned values.
  • Make discovery, diff, builds, and tests cancellable; terminate process groups on Unix and process trees on Windows; bound captured build/test logs and concurrent builds; clean up partially instrumented packages and remove the leaking cleanup goroutine.
  • Prevent shared-fixture collisions by running mutants within a package sequentially, while retaining parallel execution across packages.
  • Use unrounded scores for thresholds, reject NaN/Inf, propagate output failures, align exit codes with the documented contract, and emit every canceled mutant in NDJSON without duplicate interruption diagnostics.
  • Make diff discovery independent of Git prefix/relative settings and support quoted paths. Correct the README's equivalent-mutation example.

Fixes #43.

Behavioral impact

Single-package runs can take longer because their mutant tests are now sequential. Type information loading can also add discovery time, particularly with a cold build cache. Each process retains at most the last 64 KiB of diagnostic output, with a truncation marker.

Validation

  • go test ./... -race -count=1 and go test ./... -race -cover — all nine packages passed.
  • go run . -diff origin/main -threshold 100 ./... — 67 killed, 0 survived, score 100%. Added package-local tests for 17 surviving mutants; documented one equivalent buffer boundary and replaced an equivalent exit-code boundary with ProcessState.Exited().
  • go vet ./..., go fix ./..., and git diff --check passed.
  • Fourteen before/after cases matched exit codes and normalized results: test-only packages, relative imports, target architecture, generics, a go 1.20 module directive, JSON/NDJSON, test filtering, packages without tests, multiple packages, build tags, embed, and workspaces.
  • Sent SIGTERM during an actual mutant run: both started and pending mutants were reported as canceled, exit code was 1, and instrumented temporary directories were removed.
  • Windows amd64 and Linux amd64 cross-builds passed.

Execution checks ran on Go 1.27.0 / macOS arm64. Cross-builds do not establish runtime behavior on Windows/Linux; the go 1.20 directive case was run with Go 1.27, not a Go 1.20 toolchain.

@fchimpan
fchimpan force-pushed the fix/mutation-correctness-and-regressions branch from 08ebbfb to 090377c Compare September 13, 2026 07:56
@fchimpan fchimpan closed this Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auto-skip equivalent mutants in clamp patterns (if x < C { x = C })

1 participant