Skip to content

test(base): kill surviving Gremlins mutants in wire helpers (#290) - #296

Merged
ffumero2003 merged 1 commit into
mainfrom
test-base-issue-290-mutants
Nov 5, 2026
Merged

ffumero2003 merged 1 commit into
mainfrom
test-base-issue-290-mutants

Conversation

@ffumero2003

Copy link
Copy Markdown
Contributor

Context

Part A of #290 targets the 26 surviving mutants in base/base.go at 59104c6. Existing tests leave gaps in wire mapping, branch outcomes and download boundaries.

Changes

  • Strengthen existing tests for repeated User-Agent options, bucket type and encryption normalization, source-only/destination-only replication, omitted/empty/populated update fields, and SSE-B2 conflicts with either customer field.
  • Cover large-file start success/failure and literal explicit/trailing part checksums.
  • Pin empty HTTP 200 responses, zero-start and single-byte HTTP 206 ranges, validation of overlong replies, bounded body reads, open-ended reads, and forwarding Close for both download entry points.
  • Change five base test files only. No production changes, Part B coverage work, or other streams' files.

Target outcomes

All 19 behavior-changing mutants were hand-applied individually, killed by the named focused test, restored, and followed by a passing run. No Gremlins rerun was needed or performed. Source locations below refer to 59104c6; columns distinguish mutants sharing a line.

Site Mutation Killing test
741:18 CN User-Agent empty check inverted TestUserAgentOptionReachesTheWire
820:28 CN empty SSE mode check inverted TestCreateBucketNormalizesTypeAndEncryption
830:11 CN allPublic check inverted TestCreateBucketNormalizesTypeAndEncryption
883:34 CN replication source nil check inverted TestCreateBucketReadsEachReplicationRole
883:79 CN replication destination nil check inverted TestCreateBucketReadsEachReplicationRole
931:22 CN lifecycle rules nil check inverted TestUpdateBucketDistinguishesUnsetEmptyAndPopulatedFields
943:12 CN bucket info nil check inverted TestUpdateBucketDistinguishesUnsetEmptyAndPopulatedFields
1198:69 CN customer key empty check inverted TestSSEB2AndSSECConflictIsRejected
1198:97 CN customer digest empty check inverted TestSSEB2AndSSECConflictIsRejected
1417:155 CN start-large-file error check inverted TestStartLargeFileReturnsRequestResult
1559:10 CN trailing SHA1 mode check inverted TestUploadPartPreservesExplicitAndTrailingSHA1
1844:34 CB Content-Length < 0 → <= 0 TestValidateRangeResponse
1873:28 CB start < 0 → <= 0 TestValidateRangeResponse
1873:39 CB end < start → <= start TestValidateRangeResponse
1949:9 CN range-present check inverted TestDownloadsValidateRangesAndLimitBodies
1949:35 CN HTTP 200 check inverted TestDownloadsValidateRangesAndLimitBodies
1949:71 CN HTTP 206 check inverted TestDownloadsValidateRangesAndLimitBodies
1954:11 CB size > 0 → >= 0 TestDownloadsValidateRangesAndLimitBodies
1954:11 CN size > 0 → <= 0 TestDownloadsValidateRangesAndLimitBodies

CN = CONDITIONALS_NEGATION; CB = CONDITIONALS_BOUNDARY.

Equivalent / redundant mutants skipped

Each was replayed individually and the relevant tests still pass. These do not warrant tests that pin internal control flow or incidental diagnostic text.

Site Mutation Reason
189:13 CB seconds <= 0 → < 0 At zero, the fallthrough returns the same zero.
192:13 CB seconds >= 30 → > 30 At 30, the fallthrough returns the same 30.
238:13 CB retry > 30 → >= 30 Either branch returns 30 seconds at equality.
1047:38 CB allowed buckets > 1 → >= 1 A single allowed bucket produces the same single bucket-ID-filtered request and the same result, including nil for no buckets.
1847:11 CB size <= 0 → < 0 The changed case requires HTTP 200 at offset=0, size=0. Both public download paths generate no Range then and bypass range validation.
1873:56 CB total <= end → < end Equality is still rejected by the following exact-span check: end-start+1 exceeds total-start. The error class remains ErrInvalidRangeResponse; diagnostic wording differs.
1877:22 CB size < expected → <= expected At equality, assigning size stores the existing expected value.

Verification

All commands ran with B2_APPLICATION_KEY_ID, B2_APPLICATION_KEY, B2_ACCOUNT_ID and B2_ACCOUNT_KEY empty.

  • go build ./... — pass.
  • go vet ./... — pass.
  • go test -count=1 -timeout=120s ./base/... — pass.
  • make ci — pass, including lint, race tests and cross-builds.
  • Each of the 19 breaks: go test -count=1 -timeout=30s ./base -run '^<named-test>$' — FAIL with the mutation, PASS after restoring base/base.go. No compile failures or test timeouts counted as kills.

Representative red → green output:

741 CN:
User-Agent[1] = "outer/2.0 blazer/0.9.0", want "outer/2.0 acme-app/1.2 blazer/0.9.0"
ok github.com/Backblaze/blazer/base

931 CN:
request lifecycleRules = <nil> (present=false), want []interface {}{}
ok github.com/Backblaze/blazer/base

1844 CB:
range request at offset 0 returned invalid Content-Length "0", invalid range error = true, want false
ok github.com/Backblaze/blazer/base

1954 CB:
downloaded body = "", error=<nil>; want "bcdef" and nil
ok github.com/Backblaze/blazer/base

1954 CN:
downloaded body = "bcEXTRA", error=<nil>; want "bc" and nil
ok github.com/Backblaze/blazer/base

Live B2 and simulator contracts were not run: this change strengthens hermetic tests and changes no SDK behavior or harness scenario. Base wire/auth test changes require human code-owner review.

Part of #290

Pin wire normalization, bucket update field presence, SSE conflicts, large-file results and checksums, and exact download range behavior with hermetic tests.

Part of #290
@ffumero2003 ffumero2003 self-assigned this Nov 5, 2026
@ffumero2003
ffumero2003 merged commit b8db391 into main Nov 5, 2026
27 of 28 checks passed
@ffumero2003
ffumero2003 deleted the test-base-issue-290-mutants branch November 5, 2026 22:38
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.

1 participant