package aws import ( "fmt" "log" "os" "strings" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/firehose" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" ) func TestAccAWSKinesisFirehoseDeliveryStream_s3basic(t *testing.T) { var stream firehose.DeliveryStreamDescription ri := acctest.RandInt() config := fmt.Sprintf(testAccKinesisFirehoseDeliveryStreamConfig_s3basic, ri, os.Getenv("AWS_ACCOUNT_ID"), ri, ri, ri) resource.Test(t, resource.TestCase{ PreCheck: testAccKinesisFirehosePreCheck(t), Providers: testAccProviders, CheckDestroy: testAccCheckKinesisFirehoseDeliveryStreamDestroy, Steps: []resource.TestStep{ { Config: config, Check: resource.ComposeTestCheckFunc( testAccCheckKinesisFirehoseDeliveryStreamExists("aws_kinesis_firehose_delivery_stream.test_stream", &stream), testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, nil, nil, nil), ), }, }, }) } func TestAccAWSKinesisFirehoseDeliveryStream_s3WithCloudwatchLogging(t *testing.T) { var stream firehose.DeliveryStreamDescription ri := acctest.RandInt() resource.Test(t, resource.TestCase{ PreCheck: testAccKinesisFirehosePreCheck(t), Providers: testAccProviders, CheckDestroy: testAccCheckKinesisFirehoseDeliveryStreamDestroy, Steps: []resource.TestStep{ { Config: testAccKinesisFirehoseDeliveryStreamConfig_s3WithCloudwatchLogging(os.Getenv("AWS_ACCOUNT_ID"), ri), Check: resource.ComposeTestCheckFunc( testAccCheckKinesisFirehoseDeliveryStreamExists("aws_kinesis_firehose_delivery_stream.test_stream", &stream), testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, nil, nil, nil), ), }, }, }) } func TestAccAWSKinesisFirehoseDeliveryStream_s3ConfigUpdates(t *testing.T) { var stream firehose.DeliveryStreamDescription ri := acctest.RandInt() preConfig := fmt.Sprintf(testAccKinesisFirehoseDeliveryStreamConfig_s3basic, ri, os.Getenv("AWS_ACCOUNT_ID"), ri, ri, ri) postConfig := fmt.Sprintf(testAccKinesisFirehoseDeliveryStreamConfig_s3Updates, ri, os.Getenv("AWS_ACCOUNT_ID"), ri, ri, ri) updatedS3DestinationConfig := &firehose.S3DestinationDescription{ BufferingHints: &firehose.BufferingHints{ IntervalInSeconds: aws.Int64(400), SizeInMBs: aws.Int64(10), }, } resource.Test(t, resource.TestCase{ PreCheck: testAccKinesisFirehosePreCheck(t), Providers: testAccProviders, CheckDestroy: testAccCheckKinesisFirehoseDeliveryStreamDestroy, Steps: []resource.TestStep{ { Config: preConfig, Check: resource.ComposeTestCheckFunc( testAccCheckKinesisFirehoseDeliveryStreamExists("aws_kinesis_firehose_delivery_stream.test_stream", &stream), testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, nil, nil, nil), ), }, { Config: postConfig, Check: resource.ComposeTestCheckFunc( testAccCheckKinesisFirehoseDeliveryStreamExists("aws_kinesis_firehose_delivery_stream.test_stream", &stream), testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, updatedS3DestinationConfig, nil, nil), ), }, }, }) } func TestAccAWSKinesisFirehoseDeliveryStream_RedshiftConfigUpdates(t *testing.T) { var stream firehose.DeliveryStreamDescription ri := acctest.RandInt() preConfig := fmt.Sprintf(testAccKinesisFirehoseDeliveryStreamConfig_RedshiftBasic, ri, os.Getenv("AWS_ACCOUNT_ID"), ri, ri, ri, ri) postConfig := fmt.Sprintf(testAccKinesisFirehoseDeliveryStreamConfig_RedshiftUpdates, ri, os.Getenv("AWS_ACCOUNT_ID"), ri, ri, ri, ri) updatedRedshiftConfig := &firehose.RedshiftDestinationDescription{ CopyCommand: &firehose.CopyCommand{ CopyOptions: aws.String("GZIP"), }, } resource.Test(t, resource.TestCase{ PreCheck: testAccKinesisFirehosePreCheck(t), Providers: testAccProviders, CheckDestroy: testAccCheckKinesisFirehoseDeliveryStreamDestroy, Steps: []resource.TestStep{ { Config: preConfig, Check: resource.ComposeTestCheckFunc( testAccCheckKinesisFirehoseDeliveryStreamExists("aws_kinesis_firehose_delivery_stream.test_stream", &stream), testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, nil, nil, nil), ), }, { Config: postConfig, Check: resource.ComposeTestCheckFunc( testAccCheckKinesisFirehoseDeliveryStreamExists("aws_kinesis_firehose_delivery_stream.test_stream", &stream), testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, nil, updatedRedshiftConfig, nil), ), }, }, }) } func TestAccAWSKinesisFirehoseDeliveryStream_ElasticsearchConfigUpdates(t *testing.T) { var stream firehose.DeliveryStreamDescription ri := acctest.RandInt() awsAccountId := os.Getenv("AWS_ACCOUNT_ID") preConfig := fmt.Sprintf(testAccKinesisFirehoseDeliveryStreamConfig_ElasticsearchBasic, ri, awsAccountId, ri, ri, ri, awsAccountId, awsAccountId, ri, ri) postConfig := fmt.Sprintf(testAccKinesisFirehoseDeliveryStreamConfig_ElasticsearchUpdate, ri, awsAccountId, ri, ri, ri, awsAccountId, awsAccountId, ri, ri) updatedElasticSearchConfig := &firehose.ElasticsearchDestinationDescription{ BufferingHints: &firehose.ElasticsearchBufferingHints{ IntervalInSeconds: aws.Int64(500), }, } resource.Test(t, resource.TestCase{ PreCheck: testAccKinesisFirehosePreCheck(t), Providers: testAccProviders, CheckDestroy: testAccCheckKinesisFirehoseDeliveryStreamDestroy, Steps: []resource.TestStep{ { Config: preConfig, Check: resource.ComposeTestCheckFunc( testAccCheckKinesisFirehoseDeliveryStreamExists("aws_kinesis_firehose_delivery_stream.test_stream_es", &stream), testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, nil, nil, nil), ), }, { Config: postConfig, Check: resource.ComposeTestCheckFunc( testAccCheckKinesisFirehoseDeliveryStreamExists("aws_kinesis_firehose_delivery_stream.test_stream_es", &stream), testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, nil, nil, updatedElasticSearchConfig), ), }, }, }) } func testAccCheckKinesisFirehoseDeliveryStreamExists(n string, stream *firehose.DeliveryStreamDescription) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] log.Printf("State: %#v", s.RootModule().Resources) if !ok { return fmt.Errorf("Not found: %s", n) } if rs.Primary.ID == "" { return fmt.Errorf("No Kinesis Firehose ID is set") } conn := testAccProvider.Meta().(*AWSClient).firehoseconn describeOpts := &firehose.DescribeDeliveryStreamInput{ DeliveryStreamName: aws.String(rs.Primary.Attributes["name"]), } resp, err := conn.DescribeDeliveryStream(describeOpts) if err != nil { return err } *stream = *resp.DeliveryStreamDescription return nil } } func testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(stream *firehose.DeliveryStreamDescription, s3config interface{}, redshiftConfig interface{}, elasticsearchConfig interface{}) resource.TestCheckFunc { return func(s *terraform.State) error { if !strings.HasPrefix(*stream.DeliveryStreamName, "terraform-kinesis-firehose") { return fmt.Errorf("Bad Stream name: %s", *stream.DeliveryStreamName) } for _, rs := range s.RootModule().Resources { if rs.Type != "aws_kinesis_firehose_delivery_stream" { continue } if *stream.DeliveryStreamARN != rs.Primary.Attributes["arn"] { return fmt.Errorf("Bad Delivery Stream ARN\n\t expected: %s\n\tgot: %s\n", rs.Primary.Attributes["arn"], *stream.DeliveryStreamARN) } if s3config != nil { s := s3config.(*firehose.S3DestinationDescription) // Range over the Stream Destinations, looking for the matching S3 // destination. For simplicity, our test only have a single S3 or // Redshift destination, so at this time it's safe to match on the first // one var match bool for _, d := range stream.Destinations { if d.S3DestinationDescription != nil { if *d.S3DestinationDescription.BufferingHints.SizeInMBs == *s.BufferingHints.SizeInMBs { match = true } } } if !match { return fmt.Errorf("Mismatch s3 buffer size, expected: %s, got: %s", s, stream.Destinations) } } if redshiftConfig != nil { r := redshiftConfig.(*firehose.RedshiftDestinationDescription) // Range over the Stream Destinations, looking for the matching Redshift // destination var match bool for _, d := range stream.Destinations { if d.RedshiftDestinationDescription != nil { if *d.RedshiftDestinationDescription.CopyCommand.CopyOptions == *r.CopyCommand.CopyOptions { match = true } } } if !match { return fmt.Errorf("Mismatch Redshift CopyOptions, expected: %s, got: %s", r, stream.Destinations) } } if elasticsearchConfig != nil { es := elasticsearchConfig.(*firehose.ElasticsearchDestinationDescription) // Range over the Stream Destinations, looking for the matching Elasticsearch destination var match bool for _, d := range stream.Destinations { if d.ElasticsearchDestinationDescription != nil { match = true } } if !match { return fmt.Errorf("Mismatch Elasticsearch Buffering Interval, expected: %s, got: %s", es, stream.Destinations) } } } return nil } } func testAccCheckKinesisFirehoseDeliveryStreamDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "aws_kinesis_firehose_delivery_stream" { continue } conn := testAccProvider.Meta().(*AWSClient).firehoseconn describeOpts := &firehose.DescribeDeliveryStreamInput{ DeliveryStreamName: aws.String(rs.Primary.Attributes["name"]), } resp, err := conn.DescribeDeliveryStream(describeOpts) if err == nil { if resp.DeliveryStreamDescription != nil && *resp.DeliveryStreamDescription.DeliveryStreamStatus != "DELETING" { return fmt.Errorf("Error: Delivery Stream still exists") } } return nil } return nil } func testAccKinesisFirehosePreCheck(t *testing.T) func() { return func() { testAccPreCheck(t) if os.Getenv("AWS_ACCOUNT_ID") == "" { t.Fatal("AWS_ACCOUNT_ID must be set") } } } const testAccKinesisFirehoseDeliveryStreamBaseConfig = ` resource "aws_iam_role" "firehose" { name = "tf_acctest_firehose_delivery_role_%d" assume_role_policy = <