provider/aws: Add tests for Lambda function updates

This commit is contained in:
Radek Simko 2016-02-21 20:54:30 +00:00
parent fdc21aad25
commit d777141a7b
4 changed files with 254 additions and 0 deletions

View File

@ -192,6 +192,7 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e
err := resource.Retry(1*time.Minute, func() *resource.RetryError { err := resource.Retry(1*time.Minute, func() *resource.RetryError {
_, err := conn.CreateFunction(params) _, err := conn.CreateFunction(params)
if err != nil { if err != nil {
log.Printf("[ERROR] Received %q, retrying CreateFunction", err)
if awserr, ok := err.(awserr.Error); ok { if awserr, ok := err.(awserr.Error); ok {
if awserr.Code() == "InvalidParameterValueException" { if awserr.Code() == "InvalidParameterValueException" {
log.Printf("[DEBUG] InvalidParameterValueException creating Lambda Function: %s", awserr) log.Printf("[DEBUG] InvalidParameterValueException creating Lambda Function: %s", awserr)

View File

@ -1,7 +1,11 @@
package aws package aws
import ( import (
"archive/zip"
"fmt" "fmt"
"io/ioutil"
"os"
"path/filepath"
"strings" "strings"
"testing" "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 { func testAccCheckLambdaFunctionDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).lambdaconn 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 = ` const baseAccAWSLambdaConfig = `
resource "aws_iam_role_policy" "iam_policy_for_lambda" { resource "aws_iam_role_policy" "iam_policy_for_lambda" {
name = "iam_policy_for_lambda" name = "iam_policy_for_lambda"
@ -303,3 +457,84 @@ resource "aws_lambda_function" "lambda_function_s3test" {
handler = "exports.example" handler = "exports.example"
} }
`, acctest.RandInt()) `, acctest.RandInt())
const testAccAWSLambdaFunctionConfig_local_tpl = `
resource "aws_iam_role" "iam_for_lambda" {
name = "iam_for_lambda"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_lambda_function" "lambda_function_local" {
filename = "%s"
source_code_hash = "${base64sha256(file("%s"))}"
function_name = "tf_acc_lambda_name_local"
role = "${aws_iam_role.iam_for_lambda.arn}"
handler = "exports.example"
}
`
func genAWSLambdaFunctionConfig_local(filePath string) string {
return fmt.Sprintf(testAccAWSLambdaFunctionConfig_local_tpl,
filePath, filePath)
}
const testAccAWSLambdaFunctionConfig_s3_tpl = `
resource "aws_s3_bucket" "artifacts" {
bucket = "%s"
acl = "private"
force_destroy = true
versioning {
enabled = true
}
}
resource "aws_s3_bucket_object" "o" {
bucket = "${aws_s3_bucket.artifacts.bucket}"
key = "%s"
source = "%s"
etag = "${md5(file("%s"))}"
}
resource "aws_iam_role" "iam_for_lambda" {
name = "iam_for_lambda"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_lambda_function" "lambda_function_s3" {
s3_bucket = "${aws_s3_bucket_object.o.bucket}"
s3_key = "${aws_s3_bucket_object.o.key}"
s3_object_version = "${aws_s3_bucket_object.o.version_id}"
function_name = "tf_acc_lambda_name_s3"
role = "${aws_iam_role.iam_for_lambda.arn}"
handler = "exports.example"
}
`
func genAWSLambdaFunctionConfig_s3(bucket, key, path string) string {
return fmt.Sprintf(testAccAWSLambdaFunctionConfig_s3_tpl,
bucket, key, path, path)
}

View File

@ -0,0 +1,9 @@
var http = require('http')
exports.handler = function(event, context) {
http.get("http://requestb.in/10m32wg1", function(res) {
console.log("success", res.statusCode, res.body)
}).on('error', function(e) {
console.log("error", e)
})
}

View File

@ -0,0 +1,9 @@
var http = require('http')
exports.handler = function(event, context) {
http.get("http://requestb.in/MODIFIED", function(res) {
console.log("success", res.statusCode, res.body)
}).on('error', function(e) {
console.log("error", e)
})
}