test(push): pin tabular schema/type-inference boundaries#262
Merged
Conversation
…on survivors) Mutation testing (gremlins) found the pure SQL type-inference helpers had unguarded boundaries — the schema drives the ingestor's column dtypes, so an off-by-one there silently mis-types a column. Add targeted, fixture-free unit tests that each KILL a surviving mutant: - integerType: exactly int32Max/int32Min stays INT, one beyond widens to BIGINT (the INT-vs-BIGINT overflow boundary) - sqlBaseType: a "(255)"-only token has base "" (no-leading-identifier contract) - splitSchemaEntries: a stray ')' must not drive paren depth negative - containsASCIIDigit: '0' and '9' count; '/' and ':' don't (digit-range ends) - isIntegerType: INT/BIGINT true, everything else false All 5 mutation-proven (flip the operator → the matching test fails). Pure additive test file; no production change. make ci green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Author
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit cf92070. Configure here.
saadqbal
approved these changes
Jul 14, 2026
saadqbal
left a comment
Collaborator
There was a problem hiding this comment.
LGTM 👍 Genuinely mutation-aware — verified each case kills the mutant it names: the inclusive int32 width boundary, sqlBaseType("(255)")→"" (the i>=0 slice), and the paren-depth floor keeping a),b as two entries are the subtle ones and they all hold. Nice work closing out the audit.
saadqbal
pushed a commit
that referenced
this pull request
Jul 14, 2026
* test: SwapSeam helper + advisory gremlins mutation workflow internal/testutil.SwapSeam(t, ptr, stub) replaces the hand-rolled save/stub/restore blocks around package-level seam variables: swap, then LIFO-restore via t.Cleanup. Generic, so non-function seams (timeouts) work too. Converted the three blocks in internal/submit (watch_test.go x2, run_watch_test.go x1); internal/push has none. The ~26 blocks in internal/cli are deliberately left for the decomposition work to pick up; converting them here would collide. mutation.yml formalizes the gremlins ritual that produced #262-#264: workflow_dispatch only, one package per run, advisory (lived mutants never fail the job — no thresholds). Prints a survivors-to-triage summary, uploads the JSON report, and CONTRIBUTING.md documents how survivors get triaged into pinning-test issues. Fixes #295 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci: harden gremlins mutation workflow (Bugbot #306) - Reject a zero timeout-coefficient. The digit check accepted `0`/`00`, which collapses gremlins' per-mutant timeout so survivors report TIMED OUT instead of KILLED/LIVED — the exact failure mode this input guards against. Now require a positive integer (> 0), matching the error text. - Add `set -o pipefail` to the run step. The implicit default shell is `bash -e {0}` (no pipefail), so `gremlins | tee` masked a non-zero gremlins exit behind tee's 0, letting a broken suite pass the job — contradicting the workflow's "tool/test health fails the run" contract. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First follow-up from the mutation-testing pass. Gremlins found the
internal/pushSQL type-inference / schema helpers had unguarded boundaries. The schema drives the ingestor's column dtypes, so an off-by-one here silently mis-types a column (e.g. an INT that should be BIGINT overflows on write). These are pure functions, so the fixes are targeted, fixture-free unit tests — each chosen to kill a specific surviving mutant.integerTypev > int32Max→>=,v < int32Min→<=int32Max/int32Minstays INT; one beyond widens to BIGINTsqlBaseTypei >= 0→i > 0"(255)"-only token has base""(no-leading-identifier contract)splitSchemaEntriesdepth > 0→depth >= 0)must not drive paren depth negative (else it swallows the next separator)containsASCIIDigit>= '0'→> '0',<= '9'→< '9''0'/'9'count as digits;'/'/':'(just outside) don'tisIntegerType==→!=(both terms)All 5 are mutation-proven: flipping the operator in the source makes the matching test fail. Pure additive test file — no production change.
(Equivalent/impractical mutants in the same cluster — e.g.
cleanTokens's cap slice andvarcharOf's> nwhere the boundary value produces identical output — were deliberately not chased.)Test plan
make cigreen (build, vet, gofmt -s,go test -race, errcheck/ineffassign/misspell, schema-check).🤖 Generated with Claude Code
Note
Low Risk
Additive tests only; no runtime or schema logic is modified.
Overview
Adds
internal/push/tabular_schema_test.go, a pure test-only follow-up to gremlins mutation testing. It locks down boundary behavior for schema helpers that drive ingestor column dtypes:integerType(INT vs BIGINT at int32 limits and VARCHAR past int64),sqlBaseType(including"(255)"→ empty base),splitSchemaEntries(stray)must not merge entries),containsASCIIDigit(ASCII'0'/'9'edges), andisIntegerType(INT/BIGINT only).No production code changes — each test is documented as targeting a specific surviving mutant operator flip.
Reviewed by Cursor Bugbot for commit cf92070. Bugbot is set up for automated code reviews on this repo. Configure here.