github.com/mponton/terratest@v0.44.0/modules/aws/s3_test.go (about) 1 // Integration tests that validate S3-related code in AWS. 2 package aws 3 4 import ( 5 "fmt" 6 "math/rand" 7 "strconv" 8 "strings" 9 "testing" 10 11 "github.com/aws/aws-sdk-go/aws" 12 "github.com/aws/aws-sdk-go/service/s3" 13 "github.com/aws/aws-sdk-go/service/s3/s3manager" 14 "github.com/mponton/terratest/modules/logger" 15 "github.com/mponton/terratest/modules/random" 16 "github.com/stretchr/testify/assert" 17 "github.com/stretchr/testify/require" 18 ) 19 20 func TestCreateAndDestroyS3Bucket(t *testing.T) { 21 t.Parallel() 22 23 region := GetRandomStableRegion(t, nil, nil) 24 id := random.UniqueId() 25 logger.Logf(t, "Random values selected. Region = %s, Id = %s\n", region, id) 26 27 s3BucketName := "gruntwork-terratest-" + strings.ToLower(id) 28 29 CreateS3Bucket(t, region, s3BucketName) 30 DeleteS3Bucket(t, region, s3BucketName) 31 } 32 33 func TestAssertS3BucketExistsNoFalseNegative(t *testing.T) { 34 t.Parallel() 35 36 region := GetRandomStableRegion(t, nil, nil) 37 s3BucketName := "gruntwork-terratest-" + strings.ToLower(random.UniqueId()) 38 logger.Logf(t, "Random values selected. Region = %s, s3BucketName = %s\n", region, s3BucketName) 39 40 CreateS3Bucket(t, region, s3BucketName) 41 defer DeleteS3Bucket(t, region, s3BucketName) 42 43 AssertS3BucketExists(t, region, s3BucketName) 44 } 45 46 func TestAssertS3BucketExistsNoFalsePositive(t *testing.T) { 47 t.Parallel() 48 49 region := GetRandomStableRegion(t, nil, nil) 50 s3BucketName := "gruntwork-terratest-" + strings.ToLower(random.UniqueId()) 51 logger.Logf(t, "Random values selected. Region = %s, s3BucketName = %s\n", region, s3BucketName) 52 53 // We elect not to create the S3 bucket to confirm that our function correctly reports it doesn't exist. 54 //aws.CreateS3Bucket(region, s3BucketName) 55 56 err := AssertS3BucketExistsE(t, region, s3BucketName) 57 if err == nil { 58 t.Fatalf("Function claimed that S3 Bucket '%s' exists, but in fact it does not.", s3BucketName) 59 } 60 } 61 62 func TestAssertS3BucketVersioningEnabled(t *testing.T) { 63 t.Parallel() 64 65 region := GetRandomStableRegion(t, nil, nil) 66 s3BucketName := "gruntwork-terratest-" + strings.ToLower(random.UniqueId()) 67 logger.Logf(t, "Random values selected. Region = %s, s3BucketName = %s\n", region, s3BucketName) 68 69 CreateS3Bucket(t, region, s3BucketName) 70 defer DeleteS3Bucket(t, region, s3BucketName) 71 PutS3BucketVersioning(t, region, s3BucketName) 72 73 AssertS3BucketVersioningExists(t, region, s3BucketName) 74 } 75 76 func TestEmptyS3Bucket(t *testing.T) { 77 t.Parallel() 78 79 // region := GetRandomStableRegion(t, nil, nil) 80 region := "us-east-1" 81 id := random.UniqueId() 82 logger.Logf(t, "Random values selected. Region = %s, Id = %s\n", region, id) 83 84 s3BucketName := "gruntwork-terratest-" + strings.ToLower(id) 85 86 CreateS3Bucket(t, region, s3BucketName) 87 defer DeleteS3Bucket(t, region, s3BucketName) 88 89 s3Client, err := NewS3ClientE(t, region) 90 if err != nil { 91 t.Fatal(err) 92 } 93 94 testEmptyBucket(t, s3Client, region, s3BucketName) 95 } 96 97 func TestEmptyS3BucketVersioned(t *testing.T) { 98 t.Parallel() 99 100 region := GetRandomStableRegion(t, nil, nil) 101 102 id := random.UniqueId() 103 logger.Logf(t, "Random values selected. Region = %s, Id = %s\n", region, id) 104 105 s3BucketName := "gruntwork-terratest-" + strings.ToLower(id) 106 107 CreateS3Bucket(t, region, s3BucketName) 108 defer DeleteS3Bucket(t, region, s3BucketName) 109 110 s3Client, err := NewS3ClientE(t, region) 111 if err != nil { 112 t.Fatal(err) 113 } 114 115 versionInput := &s3.PutBucketVersioningInput{ 116 Bucket: aws.String(s3BucketName), 117 VersioningConfiguration: &s3.VersioningConfiguration{ 118 MFADelete: aws.String("Disabled"), 119 Status: aws.String("Enabled"), 120 }, 121 } 122 123 _, err = s3Client.PutBucketVersioning(versionInput) 124 if err != nil { 125 t.Fatal(err) 126 } 127 128 testEmptyBucket(t, s3Client, region, s3BucketName) 129 } 130 131 func TestAssertS3BucketPolicyExists(t *testing.T) { 132 t.Parallel() 133 134 region := GetRandomStableRegion(t, nil, nil) 135 136 id := random.UniqueId() 137 logger.Logf(t, "Random values selected. Region = %s, Id = %s\n", region, id) 138 139 s3BucketName := "gruntwork-terratest-" + strings.ToLower(id) 140 exampleBucketPolicy := fmt.Sprintf(`{"Version":"2012-10-17","Statement":[{"Effect":"Deny","Principal":{"AWS":["*"]},"Action":"s3:Get*","Resource":"arn:aws:s3:::%s/*","Condition":{"Bool":{"aws:SecureTransport":"false"}}}]}`, s3BucketName) 141 142 CreateS3Bucket(t, region, s3BucketName) 143 defer DeleteS3Bucket(t, region, s3BucketName) 144 PutS3BucketPolicy(t, region, s3BucketName, exampleBucketPolicy) 145 146 AssertS3BucketPolicyExists(t, region, s3BucketName) 147 148 } 149 150 func TestGetS3BucketTags(t *testing.T) { 151 t.Parallel() 152 153 region := GetRandomStableRegion(t, nil, nil) 154 id := random.UniqueId() 155 logger.Logf(t, "Random values selected. Region = %s, Id = %s\n", region, id) 156 s3BucketName := "gruntwork-terratest-" + strings.ToLower(id) 157 158 CreateS3Bucket(t, region, s3BucketName) 159 defer DeleteS3Bucket(t, region, s3BucketName) 160 161 s3Client, err := NewS3ClientE(t, region) 162 if err != nil { 163 t.Fatal(err) 164 } 165 166 _, err = s3Client.PutBucketTagging(&s3.PutBucketTaggingInput{ 167 Bucket: &s3BucketName, 168 Tagging: &s3.Tagging{ 169 TagSet: []*s3.Tag{ 170 { 171 Key: aws.String("Key1"), 172 Value: aws.String("Value1"), 173 }, 174 { 175 Key: aws.String("Key2"), 176 Value: aws.String("Value2"), 177 }, 178 }, 179 }, 180 }) 181 if err != nil { 182 t.Fatal(err) 183 } 184 185 actualTags := GetS3BucketTags(t, region, s3BucketName) 186 assert.True(t, actualTags["Key1"] == "Value1") 187 assert.True(t, actualTags["Key2"] == "Value2") 188 assert.True(t, actualTags["NonExistentKey"] == "") 189 } 190 191 func testEmptyBucket(t *testing.T, s3Client *s3.S3, region string, s3BucketName string) { 192 expectedFileCount := rand.Intn(1000) 193 logger.Logf(t, "Uploading %s files to bucket %s", strconv.Itoa(expectedFileCount), s3BucketName) 194 195 deleted := 0 196 197 // Upload expectedFileCount files 198 for i := 1; i <= expectedFileCount; i++ { 199 key := fmt.Sprintf("test-%s", strconv.Itoa(i)) 200 body := strings.NewReader("This is the body") 201 202 params := &s3manager.UploadInput{ 203 Bucket: aws.String(s3BucketName), 204 Key: &key, 205 Body: body, 206 } 207 208 uploader := NewS3Uploader(t, region) 209 210 _, err := uploader.Upload(params) 211 if err != nil { 212 t.Fatal(err) 213 } 214 215 // Delete the first 10 files to be able to test if all files, including delete markers are deleted 216 if i < 10 { 217 _, err := s3Client.DeleteObject(&s3.DeleteObjectInput{ 218 Bucket: aws.String(s3BucketName), 219 Key: aws.String(key), 220 }) 221 if err != nil { 222 t.Fatal(err) 223 } 224 deleted++ 225 } 226 227 if i != 0 && i%100 == 0 { 228 logger.Logf(t, "Uploaded %s files to bucket %s successfully", strconv.Itoa(i), s3BucketName) 229 } 230 } 231 232 logger.Logf(t, "Uploaded %s files to bucket %s successfully", strconv.Itoa(expectedFileCount), s3BucketName) 233 234 // verify bucket contains 1 file now 235 listObjectsParams := &s3.ListObjectsV2Input{ 236 Bucket: aws.String(s3BucketName), 237 } 238 239 logger.Logf(t, "Verifying %s files were uploaded to bucket %s", strconv.Itoa(expectedFileCount), s3BucketName) 240 actualCount := 0 241 for { 242 bucketObjects, err := s3Client.ListObjectsV2(listObjectsParams) 243 if err != nil { 244 t.Fatal(err) 245 } 246 247 pageLength := len((*bucketObjects).Contents) 248 actualCount += pageLength 249 250 if !*bucketObjects.IsTruncated { 251 break 252 } 253 254 listObjectsParams.ContinuationToken = bucketObjects.NextContinuationToken 255 } 256 257 require.Equal(t, expectedFileCount-deleted, actualCount) 258 259 //empty bucket 260 logger.Logf(t, "Emptying bucket %s", s3BucketName) 261 EmptyS3Bucket(t, region, s3BucketName) 262 263 // verify the bucket is empty 264 bucketObjects, err := s3Client.ListObjectsV2(listObjectsParams) 265 if err != nil { 266 t.Fatal(err) 267 } 268 require.Equal(t, 0, len((*bucketObjects).Contents)) 269 }