diff --git a/storage/retry_conformance_test.go b/storage/retry_conformance_test.go index e69e55ef77d5..765b0dd7d2f8 100644 --- a/storage/retry_conformance_test.go +++ b/storage/retry_conformance_test.go @@ -707,6 +707,33 @@ var methods = map[string][]retryFunc{ }, }, "storage.objects.insert": { + // Single-shot upload with ChunkSize = 0 (bufferless/one-shot) for gRPC. + // This tests the zero-copy optimization path in gRPC. + // For HTTP, we fallback to default buffering to allow retries. + func(ctx context.Context, c *Client, fs *resources, preconditions bool) error { + obj := c.Bucket(fs.bucket.Name).Object("new-object-oneshot.txt") + if preconditions { + obj = obj.If(Conditions{DoesNotExist: true}) + } + + objW := obj.NewWriter(ctx) + + // Only set ChunkSize = 0 for gRPC, as HTTP cannot retry without a buffer. + if _, ok := c.tc.(*grpcStorageClient); ok { + objW.ChunkSize = 0 + } + + // Using a 3 MiB object to ensure the upload spans several 2 MiB + // gRPC messages, testing retries across message boundaries. + if _, err := objW.Write(randomBytes3MiB); err != nil { + return fmt.Errorf("Writer.Write: %v", err) + } + if err := objW.Close(); err != nil { + return fmt.Errorf("Writer.Close: %v", err) + } + return nil + }, + // Single-shot upload that is sent in a single message. func(ctx context.Context, c *Client, fs *resources, preconditions bool) error { obj := c.Bucket(fs.bucket.Name).Object("new-object.txt")