1package main 2 3import ( 4 "bytes" 5 "fmt" 6 7 "github.com/aws/aws-sdk-go/aws" 8 "github.com/aws/aws-sdk-go/service/s3" 9) 10 11// Here we are checking to see if a bucket that has never had versioning enabled 12// will respond successfully to ListVersions; turns out it will. 13// 14// Discoveries: 15// 16// - S3 responds to ListVersions even if the bucket has never been versioned. 17// We will probably need to fake this in in the GoFakeS3 struct to use the 18// normal bucket listing API when the backend does not implement versioning, 19// but this will probably need to wait until we implement proper pagination. 20// 21// - The API returns the _string_ 'null' for the version ID, which the Go SDK 22// happily returns as the *string* value 'null' (yecch!). GoFakeS3 backend 23// implementers should be able to simply return the empty string; GoFakeS3 24// itself should handle this particular bit of jank once and once only. 25// 26type S300005ListVersionsWithNeverVersionedBucket struct{} 27 28func (s S300005ListVersionsWithNeverVersionedBucket) Run(ctx *Context) error { 29 client := ctx.S3Client() 30 config := ctx.Config() 31 bucket := aws.String(config.BucketUnversioned()) 32 33 if err := ctx.EnsureVersioningNeverEnabled(client, config.BucketUnversioned()); err != nil { 34 return err 35 } 36 37 prefix := ctx.RandString(50) 38 key1, key2 := prefix+ctx.RandString(100), prefix+ctx.RandString(100) 39 keys := []string{key1, key2} 40 41 versions := map[string][]string{} 42 for _, key := range keys { 43 for i := 0; i < 2; i++ { 44 body := ctx.RandBytes(32) 45 vrs, err := client.PutObject(&s3.PutObjectInput{ 46 Key: aws.String(key), 47 Bucket: bucket, 48 Body: bytes.NewReader(body), 49 }) 50 if err != nil { 51 return err 52 } 53 versions[key] = append(versions[key], aws.StringValue(vrs.VersionId)) 54 } 55 } 56 57 { // Sanity check version length 58 rs, err := client.ListObjectVersions(&s3.ListObjectVersionsInput{ 59 Bucket: bucket, 60 Prefix: aws.String(prefix), 61 }) 62 if err != nil { 63 return err 64 } 65 66 // We have uploaded two keys, two versions per key, but as we have never 67 // enabled versioning, we only expect two results 68 if len(rs.Versions) != 2 { 69 return fmt.Errorf("unexpected version length") 70 } 71 72 for _, ver := range rs.Versions { 73 // This is pretty bad... the AWS SDK returns the *STRING* 'null' if there's no version ID. 74 if aws.StringValue(ver.VersionId) != "null" { 75 return fmt.Errorf("version id was not nil; found %q", aws.StringValue(ver.VersionId)) 76 } 77 } 78 } 79 80 return nil 81} 82