provider/aws: Add tests for Lambda function updates
This commit is contained in:
parent
fdc21aad25
commit
d777141a7b
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
})
|
||||||
|
}
|
|
@ -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)
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue