From d777141a7b03ad135bd0e0485097f9ddccb8aefc Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Sun, 21 Feb 2016 20:54:30 +0000 Subject: [PATCH] provider/aws: Add tests for Lambda function updates --- .../aws/resource_aws_lambda_function.go | 1 + .../aws/resource_aws_lambda_function_test.go | 235 ++++++++++++++++++ .../aws/test-fixtures/lambda_func.js | 9 + .../aws/test-fixtures/lambda_func_modified.js | 9 + 4 files changed, 254 insertions(+) create mode 100644 builtin/providers/aws/test-fixtures/lambda_func.js create mode 100644 builtin/providers/aws/test-fixtures/lambda_func_modified.js diff --git a/builtin/providers/aws/resource_aws_lambda_function.go b/builtin/providers/aws/resource_aws_lambda_function.go index 692d1b0f3..6cd2fd062 100644 --- a/builtin/providers/aws/resource_aws_lambda_function.go +++ b/builtin/providers/aws/resource_aws_lambda_function.go @@ -192,6 +192,7 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e err := resource.Retry(1*time.Minute, func() *resource.RetryError { _, err := conn.CreateFunction(params) if err != nil { + log.Printf("[ERROR] Received %q, retrying CreateFunction", err) if awserr, ok := err.(awserr.Error); ok { if awserr.Code() == "InvalidParameterValueException" { log.Printf("[DEBUG] InvalidParameterValueException creating Lambda Function: %s", awserr) diff --git a/builtin/providers/aws/resource_aws_lambda_function_test.go b/builtin/providers/aws/resource_aws_lambda_function_test.go index ac3bcd42f..1530ec34a 100644 --- a/builtin/providers/aws/resource_aws_lambda_function_test.go +++ b/builtin/providers/aws/resource_aws_lambda_function_test.go @@ -1,7 +1,11 @@ package aws import ( + "archive/zip" "fmt" + "io/ioutil" + "os" + "path/filepath" "strings" "testing" @@ -74,6 +78,101 @@ func TestAccAWSLambdaFunction_s3(t *testing.T) { }) } +func TestAccAWSLambdaFunction_localUpdate(t *testing.T) { + var conf lambda.GetFunctionOutput + + path, zipFile, err := createTempFile("lambda_localUpdate") + if err != nil { + t.Fatal(err) + } + defer os.Remove(path) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckLambdaFunctionDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + PreConfig: func() { + testAccCreateZipFromFiles(map[string]string{"test-fixtures/lambda_func.js": "lambda.js"}, zipFile) + }, + Config: genAWSLambdaFunctionConfig_local(path), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_local", "tf_acc_lambda_name_local", &conf), + testAccCheckAwsLambdaFunctionName(&conf, "tf_acc_lambda_name_local"), + testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, "tf_acc_lambda_name_local"), + testAccCheckAwsLambdaSourceCodeHash(&conf, "un6qF9S9hKvXbWwJ6m2EYaVCWjcr0PCZWiTV3h4zB0I="), + ), + }, + resource.TestStep{ + PreConfig: func() { + testAccCreateZipFromFiles(map[string]string{"test-fixtures/lambda_func_modified.js": "lambda.js"}, zipFile) + }, + Config: genAWSLambdaFunctionConfig_local(path), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_local", "tf_acc_lambda_name_local", &conf), + testAccCheckAwsLambdaFunctionName(&conf, "tf_acc_lambda_name_local"), + testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, "tf_acc_lambda_name_local"), + testAccCheckAwsLambdaSourceCodeHash(&conf, "Y5Jf4Si63UDy1wKNfPs+U56ZL0NxsieKPt9EwRl4GQM="), + ), + }, + }, + }) +} + +func TestAccAWSLambdaFunction_s3Update(t *testing.T) { + var conf lambda.GetFunctionOutput + + path, zipFile, err := createTempFile("lambda_s3Update") + if err != nil { + t.Fatal(err) + } + defer os.Remove(path) + + bucketName := fmt.Sprintf("tf-acc-lambda-s3-deployments-%d", randomInteger) + key := "lambda-func.zip" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckLambdaFunctionDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + PreConfig: func() { + // Upload 1st version + testAccCreateZipFromFiles(map[string]string{"test-fixtures/lambda_func.js": "lambda.js"}, zipFile) + }, + Config: genAWSLambdaFunctionConfig_s3(bucketName, key, path), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_s3", "tf_acc_lambda_name_s3", &conf), + testAccCheckAwsLambdaFunctionName(&conf, "tf_acc_lambda_name_s3"), + testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, "tf_acc_lambda_name_s3"), + testAccCheckAwsLambdaSourceCodeHash(&conf, "un6qF9S9hKvXbWwJ6m2EYaVCWjcr0PCZWiTV3h4zB0I="), + ), + }, + resource.TestStep{ + ExpectNonEmptyPlan: true, + PreConfig: func() { + // Upload 2nd version + testAccCreateZipFromFiles(map[string]string{"test-fixtures/lambda_func_modified.js": "lambda.js"}, zipFile) + }, + Config: genAWSLambdaFunctionConfig_s3(bucketName, key, path), + }, + // Extra step because of missing ComputedWhen + // See https://github.com/hashicorp/terraform/pull/4846 & https://github.com/hashicorp/terraform/pull/5330 + resource.TestStep{ + Config: genAWSLambdaFunctionConfig_s3(bucketName, key, path), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_s3", "tf_acc_lambda_name_s3", &conf), + testAccCheckAwsLambdaFunctionName(&conf, "tf_acc_lambda_name_s3"), + testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, "tf_acc_lambda_name_s3"), + testAccCheckAwsLambdaSourceCodeHash(&conf, "Y5Jf4Si63UDy1wKNfPs+U56ZL0NxsieKPt9EwRl4GQM="), + ), + }, + }, + }) +} + func testAccCheckLambdaFunctionDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).lambdaconn @@ -157,6 +256,61 @@ func testAccCheckAwsLambdaFunctionArnHasSuffix(function *lambda.GetFunctionOutpu } } +func testAccCheckAwsLambdaSourceCodeHash(function *lambda.GetFunctionOutput, expectedHash string) resource.TestCheckFunc { + return func(s *terraform.State) error { + c := function.Configuration + if *c.CodeSha256 != expectedHash { + return fmt.Errorf("Expected code hash %s, got %s", expectedHash, *c.CodeSha256) + } + + return nil + } +} + +func testAccCreateZipFromFiles(files map[string]string, zipFile *os.File) error { + zipFile.Truncate(0) + zipFile.Seek(0, 0) + + w := zip.NewWriter(zipFile) + + for source, destination := range files { + f, err := w.Create(destination) + if err != nil { + return err + } + + fileContent, err := ioutil.ReadFile(source) + if err != nil { + return err + } + + _, err = f.Write(fileContent) + if err != nil { + return err + } + } + + err := w.Close() + if err != nil { + return err + } + + return w.Flush() +} + +func createTempFile(prefix string) (string, *os.File, error) { + f, err := ioutil.TempFile(os.TempDir(), prefix) + if err != nil { + return "", nil, err + } + + pathToFile, err := filepath.Abs(f.Name()) + if err != nil { + return "", nil, err + } + return pathToFile, f, nil +} + const baseAccAWSLambdaConfig = ` resource "aws_iam_role_policy" "iam_policy_for_lambda" { name = "iam_policy_for_lambda" @@ -303,3 +457,84 @@ resource "aws_lambda_function" "lambda_function_s3test" { handler = "exports.example" } `, acctest.RandInt()) + +const testAccAWSLambdaFunctionConfig_local_tpl = ` +resource "aws_iam_role" "iam_for_lambda" { + name = "iam_for_lambda" + assume_role_policy = <