diff --git a/builtin/providers/aws/resource_aws_s3_bucket_object_test.go b/builtin/providers/aws/resource_aws_s3_bucket_object_test.go index ad0e932ae5..0ba226cd00 100644 --- a/builtin/providers/aws/resource_aws_s3_bucket_object_test.go +++ b/builtin/providers/aws/resource_aws_s3_bucket_object_test.go @@ -27,6 +27,7 @@ func TestAccAWSS3BucketObject_source(t *testing.T) { if err != nil { t.Fatal(err) } + var obj s3.GetObjectOutput resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -35,7 +36,7 @@ func TestAccAWSS3BucketObject_source(t *testing.T) { Steps: []resource.TestStep{ resource.TestStep{ Config: testAccAWSS3BucketObjectConfigSource(rInt, tmpFile.Name()), - Check: testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object"), + Check: testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj), }, }, }) @@ -43,6 +44,7 @@ func TestAccAWSS3BucketObject_source(t *testing.T) { func TestAccAWSS3BucketObject_content(t *testing.T) { rInt := acctest.RandInt() + var obj s3.GetObjectOutput resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -52,7 +54,7 @@ func TestAccAWSS3BucketObject_content(t *testing.T) { resource.TestStep{ PreConfig: func() {}, Config: testAccAWSS3BucketObjectConfigContent(rInt), - Check: testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object"), + Check: testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj), }, }, }) @@ -72,6 +74,8 @@ func TestAccAWSS3BucketObject_withContentCharacteristics(t *testing.T) { t.Fatal(err) } + var obj s3.GetObjectOutput + resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -80,7 +84,7 @@ func TestAccAWSS3BucketObject_withContentCharacteristics(t *testing.T) { resource.TestStep{ Config: testAccAWSS3BucketObjectConfig_withContentCharacteristics(rInt, tmpFile.Name()), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object"), + testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj), resource.TestCheckResourceAttr( "aws_s3_bucket_object.object", "content_type", "binary/octet-stream"), ), @@ -101,6 +105,7 @@ func TestAccAWSS3BucketObject_updates(t *testing.T) { if err != nil { t.Fatal(err) } + var obj s3.GetObjectOutput resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -110,7 +115,7 @@ func TestAccAWSS3BucketObject_updates(t *testing.T) { resource.TestStep{ Config: testAccAWSS3BucketObjectConfig_updates(rInt, tmpFile.Name()), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object"), + testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj), resource.TestCheckResourceAttr("aws_s3_bucket_object.object", "etag", "647d1d58e1011c743ec67d5e8af87b53"), ), }, @@ -123,7 +128,7 @@ func TestAccAWSS3BucketObject_updates(t *testing.T) { }, Config: testAccAWSS3BucketObjectConfig_updates(rInt, tmpFile.Name()), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object"), + testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj), resource.TestCheckResourceAttr("aws_s3_bucket_object.object", "etag", "1c7fd13df1515c2a13ad9eb068931f09"), ), }, @@ -131,6 +136,68 @@ func TestAccAWSS3BucketObject_updates(t *testing.T) { }) } +func TestAccAWSS3BucketObject_updatesWithVersioning(t *testing.T) { + tmpFile, err := ioutil.TempFile("", "tf-acc-s3-obj-updates-w-versions") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmpFile.Name()) + + rInt := acctest.RandInt() + err = ioutil.WriteFile(tmpFile.Name(), []byte("initial versioned object state"), 0644) + if err != nil { + t.Fatal(err) + } + + var originalObj, modifiedObj s3.GetObjectOutput + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSS3BucketObjectDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSS3BucketObjectConfig_updatesWithVersioning(rInt, tmpFile.Name()), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &originalObj), + resource.TestCheckResourceAttr("aws_s3_bucket_object.object", "etag", "cee4407fa91906284e2a5e5e03e86b1b"), + ), + }, + resource.TestStep{ + PreConfig: func() { + err = ioutil.WriteFile(tmpFile.Name(), []byte("modified versioned object"), 0644) + if err != nil { + t.Fatal(err) + } + }, + Config: testAccAWSS3BucketObjectConfig_updatesWithVersioning(rInt, tmpFile.Name()), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &modifiedObj), + resource.TestCheckResourceAttr("aws_s3_bucket_object.object", "etag", "00b8c73b1b50e7cc932362c7225b8e29"), + testAccCheckAWSS3BucketObjectVersionIdDiffers(&originalObj, &modifiedObj), + ), + }, + }, + }) +} + +func testAccCheckAWSS3BucketObjectVersionIdDiffers(first, second *s3.GetObjectOutput) resource.TestCheckFunc { + return func(s *terraform.State) error { + if first.VersionId == nil { + return fmt.Errorf("Expected first object to have VersionId: %s", first) + } + if second.VersionId == nil { + return fmt.Errorf("Expected second object to have VersionId: %s", second) + } + + if *first.VersionId == *second.VersionId { + return fmt.Errorf("Expected Version IDs to differ, but they are equal (%s)", *first.VersionId) + } + + return nil + } +} + func testAccCheckAWSS3BucketObjectDestroy(s *terraform.State) error { s3conn := testAccProvider.Meta().(*AWSClient).s3conn @@ -152,7 +219,7 @@ func testAccCheckAWSS3BucketObjectDestroy(s *terraform.State) error { return nil } -func testAccCheckAWSS3BucketObjectExists(n string) resource.TestCheckFunc { +func testAccCheckAWSS3BucketObjectExists(n string, obj *s3.GetObjectOutput) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -164,7 +231,7 @@ func testAccCheckAWSS3BucketObjectExists(n string) resource.TestCheckFunc { } s3conn := testAccProvider.Meta().(*AWSClient).s3conn - _, err := s3conn.GetObject( + out, err := s3conn.GetObject( &s3.GetObjectInput{ Bucket: aws.String(rs.Primary.Attributes["bucket"]), Key: aws.String(rs.Primary.Attributes["key"]), @@ -173,6 +240,9 @@ func testAccCheckAWSS3BucketObjectExists(n string) resource.TestCheckFunc { if err != nil { return fmt.Errorf("S3Bucket Object error: %s", err) } + + *obj = *out + return nil } } @@ -234,3 +304,21 @@ resource "aws_s3_bucket_object" "object" { } `, randInt, source, source) } + +func testAccAWSS3BucketObjectConfig_updatesWithVersioning(randInt int, source string) string { + return fmt.Sprintf(` +resource "aws_s3_bucket" "object_bucket_3" { + bucket = "tf-object-test-bucket-%d" + versioning { + enabled = true + } +} + +resource "aws_s3_bucket_object" "object" { + bucket = "${aws_s3_bucket.object_bucket_3.bucket}" + key = "updateable-key" + source = "%s" + etag = "${md5(file("%s"))}" +} +`, randInt, source, source) +}