Skip to content

test(push): pin tabular schema/type-inference boundaries#262

Merged
saadqbal merged 1 commit into
developfrom
test/push-tabular-schema
Jul 14, 2026
Merged

test(push): pin tabular schema/type-inference boundaries#262
saadqbal merged 1 commit into
developfrom
test/push-tabular-schema

Conversation

@LukasWodka

@LukasWodka LukasWodka commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

First follow-up from the mutation-testing pass. Gremlins found the internal/push SQL 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.

Helper Mutant killed Test pins
integerType v > int32Max>=, v < int32Min<= exactly int32Max/int32Min stays INT; one beyond widens to BIGINT
sqlBaseType i >= 0i > 0 a "(255)"-only token has base "" (no-leading-identifier contract)
splitSchemaEntries depth > 0depth >= 0 a stray ) 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't
isIntegerType ==!= (both terms) INT/BIGINT true, everything else false

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 and varcharOf's > n where the boundary value produces identical output — were deliberately not chased.)

Test plan

  • make ci green (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), and isIntegerType (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.

…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>
@LukasWodka LukasWodka self-assigned this Jul 14, 2026
@LukasWodka

Copy link
Copy Markdown
Contributor Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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 saadqbal left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
saadqbal merged commit ca14f47 into develop Jul 14, 2026
22 checks passed
@saadqbal
saadqbal deleted the test/push-tabular-schema branch July 14, 2026 08:58
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>
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.

2 participants