From e276cc3f79b00a95137c046e290637f13cbdc330 Mon Sep 17 00:00:00 2001 From: cpriti-os Date: Sun, 8 Mar 2026 04:54:12 +0000 Subject: [PATCH 1/2] test(storage): add retry test for chunk size 0 uploads --- storage/retry_conformance_test.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/storage/retry_conformance_test.go b/storage/retry_conformance_test.go index e69e55ef77d5..0aa352a06443 100644 --- a/storage/retry_conformance_test.go +++ b/storage/retry_conformance_test.go @@ -707,6 +707,30 @@ var methods = map[string][]retryFunc{ }, }, "storage.objects.insert": { + // Single-shot upload with ChunkSize = 0 (bufferless/one-shot). + // This tests the zero-copy optimization path in gRPC and ensures the + // client can retry correctly when the internal buffer is disabled. + 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) + 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") From fadb1444cae473dce444376af2b25da95d89d98d Mon Sep 17 00:00:00 2001 From: cpriti-os Date: Tue, 24 Mar 2026 09:58:41 +0000 Subject: [PATCH 2/2] fix test for http --- storage/retry_conformance_test.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/storage/retry_conformance_test.go b/storage/retry_conformance_test.go index 0aa352a06443..765b0dd7d2f8 100644 --- a/storage/retry_conformance_test.go +++ b/storage/retry_conformance_test.go @@ -707,18 +707,21 @@ var methods = map[string][]retryFunc{ }, }, "storage.objects.insert": { - // Single-shot upload with ChunkSize = 0 (bufferless/one-shot). - // This tests the zero-copy optimization path in gRPC and ensures the - // client can retry correctly when the internal buffer is disabled. + // 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) - objW.ChunkSize = 0 + + // 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.