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  }