Skip to content

Commit d4a02be

Browse files
authored
blob/fileblob: ensure a failed write due to IfNotExist doesn't update metadata (#3726)
1 parent ab9d335 commit d4a02be

2 files changed

Lines changed: 40 additions & 8 deletions

File tree

blob/fileblob/fileblob.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -840,14 +840,6 @@ func (w *writerWithSidecar) Close() error {
840840
return err
841841
}
842842

843-
md5sum := w.md5hash.Sum(nil)
844-
w.attrs.MD5 = md5sum
845-
846-
// Write the attributes file.
847-
if err := setAttrs(w.path, w.attrs); err != nil {
848-
return err
849-
}
850-
851843
if w.ifNotExist {
852844
w.mu.Lock()
853845
defer w.mu.Unlock()
@@ -856,6 +848,12 @@ func (w *writerWithSidecar) Close() error {
856848
return gcerr.New(gcerrors.FailedPrecondition, err, 1, "File already exist")
857849
}
858850
}
851+
// Write the attributes file.
852+
md5sum := w.md5hash.Sum(nil)
853+
w.attrs.MD5 = md5sum
854+
if err := setAttrs(w.path, w.attrs); err != nil {
855+
return err
856+
}
859857
// Rename the temp file to path.
860858
if err := os.Rename(w.f.Name(), w.path); err != nil {
861859
_ = os.Remove(w.path + attrsExt)

blob/fileblob/fileblob_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,40 @@ func TestNewBucket(t *testing.T) {
260260
})
261261
}
262262

263+
func TestIfNotExistHasNoSideEffects(t *testing.T) {
264+
ctx := context.Background()
265+
dir := t.TempDir()
266+
const (
267+
key = "key"
268+
origContents = "hello world"
269+
)
270+
271+
b, err := OpenBucket(dir, nil)
272+
if err != nil {
273+
t.Fatal(err)
274+
}
275+
defer b.Close()
276+
if err := b.WriteAll(ctx, key, []byte(origContents), &blob.WriterOptions{
277+
Metadata: map[string]string{"md": "a"}}); err != nil {
278+
t.Fatalf("failed to write blob: %v", err)
279+
}
280+
if err := b.WriteAll(ctx, key, []byte("goodbye world"), &blob.WriterOptions{
281+
IfNotExist: true,
282+
Metadata: map[string]string{"md": "b"}}); err == nil || !errors.Is(err, gcerrors.ErrFailedPrecondition) {
283+
t.Fatalf("expected FailedPrecondition error, got %v", err)
284+
}
285+
if got, err := b.ReadAll(ctx, key); err != nil {
286+
t.Errorf("failed to read blob: %v", err)
287+
} else if string(got) != origContents {
288+
t.Errorf("expected to read original contents, got %q", string(got))
289+
}
290+
if attrs, err := b.Attributes(ctx, key); err != nil {
291+
t.Errorf("failed to get attributes for blob: %v", err)
292+
} else if attrs.Metadata["md"] != "a" {
293+
t.Errorf("expected metadata to be unchanged, got %v", attrs.Metadata)
294+
}
295+
}
296+
263297
func TestSignedURLReturnsUnimplementedWithNoURLSigner(t *testing.T) {
264298
dir := t.TempDir()
265299

0 commit comments

Comments
 (0)