-
Notifications
You must be signed in to change notification settings - Fork 1.5k
fix(storage): Fix takeover response handling. #13239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -731,6 +731,79 @@ var methods = map[string][]retryFunc{ | |||||
| return fmt.Errorf("Reader.Read: %w", err) | ||||||
| } | ||||||
|
|
||||||
| gotMd5 := md5.Sum(content) | ||||||
| expectedMd5 := md5.Sum(toWrite) | ||||||
| if d := cmp.Diff(gotMd5, expectedMd5); d != "" { | ||||||
| return fmt.Errorf("content mismatch, got %v bytes (md5: %v), want %v bytes (md5: %v)", | ||||||
| len(content), gotMd5, len(toWrite), expectedMd5) | ||||||
| } | ||||||
| return nil | ||||||
| }, | ||||||
| // Appendable upload using a takeover. | ||||||
| func(ctx context.Context, c *Client, fs *resources, preconditions bool) error { | ||||||
| bucketName := fmt.Sprintf("%s-appendable", bucketIDs.New()) | ||||||
| b := c.Bucket(bucketName) | ||||||
| if err := b.Create(ctx, projectID, nil); err != nil { | ||||||
| return err | ||||||
| } | ||||||
| defer b.Delete(ctx) | ||||||
|
|
||||||
| obj := b.Object(objectIDs.New()) | ||||||
| if preconditions { | ||||||
| obj = obj.If(Conditions{DoesNotExist: true}) | ||||||
| } | ||||||
|
|
||||||
| // Force multiple messages per chunk, and multiple chunks in the object. | ||||||
| chunkSize := 2 * maxPerMessageWriteSize | ||||||
| toWrite := generateRandomBytes(chunkSize * 3) | ||||||
|
|
||||||
| objW := obj.NewWriter(ctx) | ||||||
| objW.Append = true | ||||||
| objW.ChunkSize = chunkSize | ||||||
| if _, err := objW.Write(toWrite[0:maxPerMessageWriteSize]); err != nil { | ||||||
| return fmt.Errorf("Writer.Write: %w", err) | ||||||
| } | ||||||
| // Close this writer, which will create the appendable unfinalized object | ||||||
| // (there was not enough in Write to trigger a send). | ||||||
| if err := objW.Close(); err != nil { | ||||||
| return fmt.Errorf("Creation Writer.Close: %v", err) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To enable proper error unwrapping using
Suggested change
|
||||||
| } | ||||||
|
|
||||||
| generation := int64(0) | ||||||
| if preconditions { | ||||||
| generation = objW.Attrs().Generation | ||||||
| } | ||||||
| objT := b.Object(obj.ObjectName()).Generation(generation) | ||||||
| w, l, err := objT.NewWriterFromAppendableObject(ctx, &AppendableWriterOpts{ChunkSize: chunkSize}) | ||||||
| if err != nil { | ||||||
| return fmt.Errorf("NewWriterFromAppendableObject: %v", err) | ||||||
| } | ||||||
| if l != int64(maxPerMessageWriteSize) { | ||||||
| return fmt.Errorf("NewWriterFromAppendableObject unexpected len: got %v, want %v", l, maxPerMessageWriteSize) | ||||||
| } | ||||||
|
|
||||||
| if _, err := w.Write(toWrite[maxPerMessageWriteSize:]); err != nil { | ||||||
| return fmt.Errorf("Writer.Write: %v", err) | ||||||
| } | ||||||
| if err := w.Close(); err != nil { | ||||||
| return fmt.Errorf("Writer.Close: %v", err) | ||||||
| } | ||||||
|
|
||||||
| if w.Attrs() == nil { | ||||||
| return fmt.Errorf("Writer.Attrs: expected attrs for written object, got nil") | ||||||
| } | ||||||
|
|
||||||
| // Don't reuse obj, in case preconditions were set on the write request. | ||||||
| r, err := b.Object(obj.ObjectName()).NewReader(ctx) | ||||||
| defer r.Close() | ||||||
| if err != nil { | ||||||
| return fmt.Errorf("obj.NewReader: %v", err) | ||||||
| } | ||||||
| content, err := io.ReadAll(r) | ||||||
| if err != nil { | ||||||
| return fmt.Errorf("Reader.Read: %v", err) | ||||||
| } | ||||||
|
|
||||||
| gotMd5 := md5.Sum(content) | ||||||
| expectedMd5 := md5.Sum(toWrite) | ||||||
| if d := cmp.Diff(gotMd5, expectedMd5); d != "" { | ||||||
|
Comment on lines
+743
to
809
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This new test function is quite long (over 60 lines) and contains multiple logical steps, which can make it difficult to understand and maintain. Consider refactoring it by extracting distinct stages of the test into smaller, well-named helper functions. For example, you could have separate helpers for:
This would make the main test function a much clearer, high-level description of the test scenario.
Comment on lines
807
to
809
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This block of code for verifying content is duplicated from the test case above (lines 734-741). To improve maintainability and reduce code duplication, consider extracting this logic into a shared helper function. For example: func verifyContent(content, toWrite []byte) error {
gotMd5 := md5.Sum(content)
expectedMd5 := md5.Sum(toWrite)
if d := cmp.Diff(gotMd5, expectedMd5); d != "" {
return fmt.Errorf("content mismatch, got %v bytes (md5: %v), want %v bytes (md5: %v)",
len(content), gotMd5, len(toWrite), expectedMd5)
}
return nil
}Then both tests could simply call |
||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For better error diagnostics and consistency with other error handling in this function, consider wrapping this error with additional context.