Repository navigation
test(b2): pin core edges found by mutation testing - #249
Merged
Merged
Conversation
david-santacruz-backblaze
suggested changes
Oct 30, 2026
david-santacruz-backblaze
left a comment
There was a problem hiding this comment.
Two small things before approval, please check:
intent/b2-edge-assertions/has onlyplan.md, while sibling slices (e.g.b2-mapping-edges) haveintent.md,spec.mdandplan.md. Could you add the other two, or dropplan.mdand move the mutation table into the PR description?- AGENTS.md asks for the tail of
make ciin the PR. Could you paste it? CI is green, so this is just for the record.
Contributor
Author
|
@david-santacruz-backblaze Thanks, both done:
|
david-santacruz-backblaze
approved these changes
Oct 30, 2026
This was referenced Oct 30, 2026
ffumero2003
added a commit
that referenced
this pull request
Oct 30, 2026
…ext canceled (#252) * test(b2): reproduce writes after copy cancellation Pin delayed source reads that resume after copyContext returns and Writer.ReadFrom has been cancelled and closed. Part of #229 * fix(b2): stop a cancelled copy from writing after copyContext returns A cancelled copy could return while its source Read was still blocked. When that Read resumed, the copy goroutine could write to a Writer that the caller had already closed, causing the slice-bounds panic seen in CI run 40925001975. Guard destination writes and mark the guard stopped before returning on cancellation. Waiting for the copy goroutine is not an option because the source Read may block forever. Preserve the closer path that closes the body and waits for its copy to finish. Closes #229 * test(b2): match the abandoned-copy error with errors.Is and document ReadFrom cancellation Address the panel's nits on #229: the regression test compared the error text, so wrapping errCopyAbandoned would break it while the guard still works; and ReadFrom's godoc did not say that a Read already in progress on a non-seekable source can outlive a cancelled call. * docs(b2): state exactly what ReadFrom guarantees after a cancelled copy The comment said nothing a pending Read returns is written, but the guard only stops writes once copyContext returns: a Write already in progress, with data read before the cancellation, can still complete. Say what the code guarantees: after ReadFrom returns, nothing more from r reaches the Writer. * test(b2): pin ReadFrom cancellation during blocked error cleanup Hold cancel_large_file or WithCancelOnError callbacks behind channels after producer and worker upload failures. ReadFrom must return on cancellation before those channels are released, and the callback must receive the cancellation request result (#229). * fix(b2): release the copy guard before upload error cleanup Keep the existing Writer error path and release the copy guard only on terminal write errors. No buffer writes follow that hook, and the stopped check still gates every later write, so no source bytes can reach the destination after a cancelled copy returns. Release the error-state mutex before cancel_large_file and errf as well, so a producer observing a worker failure does not wait behind cleanup. Close joins its existing worker wait group on error exits to preserve delivery of the cleanup result to WithCancelOnError callers. Reject a separate deferred error-recording and cleanup mechanism: reusing setErr preserves first-error ownership and callback semantics without adding parallel state. The public API and ReadFrom godoc remain unchanged. Closes #229 * test(b2): pin error mutex release and Close cleanup waiting Hold the producer inside buffer allocation until a worker enters blocked cancellation cleanup, then release it into getErr while the copy guard is still held. This makes moving cleanup back under emux fail deterministically. Gate the worker cancellation request separately and verify that its nonblocking error callback has completed when Close returns. Removing the deferred worker wait now fails without making the callback depend on Close. Keep the existing cancellation cases and production code unchanged. * docs(b2): document Writer.Close callback wait * test(b2): make Writer.Close callback proof deterministic * test(b2): pin Writer.ReadFrom upload error precedence * fix(b2): preserve upload errors from Writer.ReadFrom * test(b2): pin ReadFrom caller cancellation with recorded transport errors * fix(b2): preserve caller cancellation cause in Writer.ReadFrom * test(b2): pin caller custom causes in Writer.ReadFrom * fix(b2): distinguish Writer cancellation from caller causes * test(b2): start ReadFrom deadline after upload setup * docs(b2): clarify Writer ReadFrom error identity * test(b2): bound copy cancellation and Close cleanup waits * docs(b2): clarify cancellation and breaking Close wait contract * test(b2): acknowledge cancellation stub body close results * test(b2): inline the folder-delete test setup removed by #247 #247 removed objectForDeleteOptionTest from b2_test.go while #249's TestObjectDeleteRejectsFolderStatus still used it, so the b2 tests no longer compile on main. Use the same setup as TestObjectDeleteAllowsCopyStatus.
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.
Context
Part of the test-integrity audit (#97). Mutation testing (Gremlins) found single-line changes to
b2production code that no test catches. This PR covers those items from #204's### b2section (slice C3).Changes
Test-only. New tests in
b2/accountinfo_edges_test.goandb2/core_edges_test.go:baseline.goupdateFileRetentionandupdateFileLegalHold): after an update,Infois fetched again instead of served from the stale cache.accountinfo.go, write and read): a session of exactly 1,048,576 bytes is accepted and 1,048,577 bytes is rejected, on both write and read.b2.goObject.Delete): returns the non-regular-file error.memoryBuffer.Closetwice (buffer.go): idempotent, no panic.progress.go): no duplicate callback.TestAccountInfoFileRoundTripAndPermissions:AuthDatahas no key field, so it could never fail.TestAccountInfoFileResumeAndClearOn401already covers it.Not covered here: three items need a small test hook in production code, which a test-only change can't add. They're filed as #246:
accountinfo.go:135);file.Sync()before rename (accountinfo.go:146);buffer.go:148).Verification
Each mutation was applied alone; the new test failed, then passed after revert:
post-update marker="before" calls=2 (want 3)>→>=/ guard deletedSet 1048576-byte session: ... exceeds/Set 1048577-byte session error = <nil>>→>=/ guard deletedAuthData() for 1048576-byte session: ok=false/... 1048577-byte session: ok=trueDelete(folder) error = <nil>, want non-regular-file rejectionCloseguard flipped / deletedClose retained the buffer/ nil-pointer panic on secondClosen > 0flipped / deletedprogress callbacks = [0 0]/[1 1 1]With no B2 credentials set:
go test -race -count=5 -shuffle=on ./b2/..., a 30-run-racecheck of the buffer and progress tests,go vet ./...,GOOS=windows go vet ./b2/...andmake cipass.make ci(tail)Part of #204