diff --git a/backend/s3/s3.go b/backend/s3/s3.go index 40f157179..991385525 100644 --- a/backend/s3/s3.go +++ b/backend/s3/s3.go @@ -87,8 +87,15 @@ func (bb *s3Blob) Finalize(t backend.Type, name string) error { bb.final = true path := s3path(t, name) + + // Check key does not already exist + key, err := bb.b.bucket.GetKey(path) + if err == nil && key.Key == path { + return errors.New("key already exists!") + } + bb.b.mput.Lock() - err := bb.b.bucket.Put(path, bb.buf.Bytes(), "binary/octet-stream", "private") + err = bb.b.bucket.Put(path, bb.buf.Bytes(), "binary/octet-stream", "private") bb.b.mput.Unlock() bb.buf.Reset() return err diff --git a/backend/s3_test.go b/backend/s3_test.go index 68cf8a079..64a23b9a1 100644 --- a/backend/s3_test.go +++ b/backend/s3_test.go @@ -5,39 +5,49 @@ import ( "github.com/mitchellh/goamz/aws" "github.com/mitchellh/goamz/s3" - "github.com/mitchellh/goamz/testutil" + "github.com/mitchellh/goamz/s3/s3test" bes3 "github.com/restic/restic/backend/s3" . "github.com/restic/restic/test" ) -var testServer = testutil.NewHTTPServer() +type LocalServer struct { + auth aws.Auth + region aws.Region + srv *s3test.Server + config *s3test.Config +} + +var s LocalServer func setupS3Backend(t *testing.T) *bes3.S3 { - testServer.Start() - auth := aws.Auth{"abc", "123", ""} - service := s3.New(auth, aws.Region{Name: "faux-region-1", S3Endpoint: testServer.URL}) + s.config = &s3test.Config{ + Send409Conflict: true, + } + srv, err := s3test.NewServer(s.config) + OK(t, err) + s.srv = srv + + s.region = aws.Region{ + Name: "faux-region-1", + S3Endpoint: srv.URL(), + S3LocationConstraint: true, // s3test server requires a LocationConstraint + } + + s.auth = aws.Auth{"abc", "123", ""} + + service := s3.New(s.auth, s.region) bucket := service.Bucket("testbucket") - err := bucket.PutBucket("private") + err = bucket.PutBucket("private") OK(t, err) - t.Logf("created s3 backend locally at %s", testServer.URL) + t.Logf("created s3 backend locally") return bes3.OpenS3Bucket(bucket, "testbucket") } -func teardownS3Backend(t *testing.T, b *bes3.S3) { - if !*TestCleanup { - t.Logf("leaving backend at %s\n", b.Location()) - return - } - - testServer.Flush() -} - func TestS3Backend(t *testing.T) { s := setupS3Backend(t) - defer teardownS3Backend(t, s) testBackend(s, t) }