github.com/darmach/terratest@v0.34.8-0.20210517103231-80931f95e3ff/test/terraform_aws_lambda_example_test.go (about) 1 package test 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/gruntwork-io/terratest/modules/aws" 8 "github.com/gruntwork-io/terratest/modules/random" 9 "github.com/gruntwork-io/terratest/modules/terraform" 10 test_structure "github.com/gruntwork-io/terratest/modules/test-structure" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 // An example of how to test the Terraform module in examples/terraform-aws-lambda-example using Terratest. 16 func TestTerraformAwsLambdaExample(t *testing.T) { 17 t.Parallel() 18 19 // Make a copy of the terraform module to a temporary directory. This allows running multiple tests in parallel 20 // against the same terraform module. 21 exampleFolder := test_structure.CopyTerraformFolderToTemp(t, "../", "examples/terraform-aws-lambda-example") 22 23 // Give this lambda function a unique ID for a name so we can distinguish it from any other lambdas 24 // in your AWS account 25 functionName := fmt.Sprintf("terratest-aws-lambda-example-%s", random.UniqueId()) 26 27 // Pick a random AWS region to test in. This helps ensure your code works in all regions. 28 awsRegion := aws.GetRandomStableRegion(t, nil, nil) 29 30 // Construct the terraform options with default retryable errors to handle the most common retryable errors in 31 // terraform testing. 32 terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ 33 // The path to where our Terraform code is located 34 TerraformDir: exampleFolder, 35 36 // Variables to pass to our Terraform code using -var options 37 Vars: map[string]interface{}{ 38 "function_name": functionName, 39 }, 40 41 // Environment variables to set when running Terraform 42 EnvVars: map[string]string{ 43 "AWS_DEFAULT_REGION": awsRegion, 44 }, 45 }) 46 47 // At the end of the test, run `terraform destroy` to clean up any resources that were created 48 defer terraform.Destroy(t, terraformOptions) 49 50 // This will run `terraform init` and `terraform apply` and fail the test if there are any errors 51 terraform.InitAndApply(t, terraformOptions) 52 53 // Invoke the function, so we can test its output 54 response := aws.InvokeFunction(t, awsRegion, functionName, ExampleFunctionPayload{ShouldFail: false, Echo: "hi!"}) 55 56 // This function just echos it's input as a JSON string when `ShouldFail` is `false`` 57 assert.Equal(t, `"hi!"`, string(response)) 58 59 // Invoke the function, this time causing it to error and capturing the error 60 _, err := aws.InvokeFunctionE(t, awsRegion, functionName, ExampleFunctionPayload{ShouldFail: true, Echo: "hi!"}) 61 62 // Function-specific errors have their own special return 63 functionError, ok := err.(*aws.FunctionError) 64 require.True(t, ok) 65 66 // Make sure the function-specific error comes back 67 assert.Contains(t, string(functionError.Payload), "Failed to handle") 68 } 69 70 // Annother example of how to test the Terraform module in 71 // examples/terraform-aws-lambda-example using Terratest, this time with 72 // the aws.InvokeFunctionWithParams. 73 func TestTerraformAwsLambdaWithParamsExample(t *testing.T) { 74 t.Parallel() 75 76 // Make a copy of the terraform module to a temporary directory. This allows running multiple tests in parallel 77 // against the same terraform module. 78 exampleFolder := test_structure.CopyTerraformFolderToTemp(t, "../", "examples/terraform-aws-lambda-example") 79 80 // Give this lambda function a unique ID for a name so we can distinguish it from any other lambdas 81 // in your AWS account 82 functionName := fmt.Sprintf("terratest-aws-lambda-withparams-example-%s", random.UniqueId()) 83 84 // Pick a random AWS region to test in. This helps ensure your code works in all regions. 85 awsRegion := aws.GetRandomStableRegion(t, nil, nil) 86 87 // Construct the terraform options with default retryable errors to handle the most common retryable errors in 88 // terraform testing. 89 terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ 90 // The path to where our Terraform code is located 91 TerraformDir: exampleFolder, 92 93 // Variables to pass to our Terraform code using -var options 94 Vars: map[string]interface{}{ 95 "function_name": functionName, 96 }, 97 98 // Environment variables to set when running Terraform 99 EnvVars: map[string]string{ 100 "AWS_DEFAULT_REGION": awsRegion, 101 }, 102 }) 103 104 // At the end of the test, run `terraform destroy` to clean up any resources that were created 105 defer terraform.Destroy(t, terraformOptions) 106 107 // This will run `terraform init` and `terraform apply` and fail the test if there are any errors 108 terraform.InitAndApply(t, terraformOptions) 109 110 // Call InvokeFunctionWithParms with an InvocationType of "DryRun". 111 // A "DryRun" invocation does not execute the function, so the example 112 // test function will not be checking the payload. 113 var invocationType aws.InvocationTypeOption = aws.InvocationTypeDryRun 114 input := &aws.LambdaOptions{InvocationType: &invocationType} 115 out := aws.InvokeFunctionWithParams(t, awsRegion, functionName, input) 116 117 // With "DryRun", there's no message in the output, but there is 118 // a status code which will have a value of 204 for a successful 119 // invocation. 120 assert.Equal(t, int(*out.StatusCode), 204) 121 122 // Invoke the function, this time causing the Lambda to error and 123 // capturing the error. 124 invocationType = aws.InvocationTypeRequestResponse 125 input = &aws.LambdaOptions{ 126 InvocationType: &invocationType, 127 Payload: ExampleFunctionPayload{ShouldFail: true, Echo: "hi!"}, 128 } 129 out, err := aws.InvokeFunctionWithParamsE(t, awsRegion, functionName, input) 130 131 // The Lambda executed, but should have failed. 132 assert.Error(t, err, "Unhandled") 133 134 // Make sure the function-specific error comes back 135 assert.Contains(t, string(out.Payload), "Failed to handle") 136 137 // Call InvokeFunctionWithParamsE with a LambdaOptions struct that has 138 // an unsupported InvocationType. The function should fail. 139 invocationType = "Event" 140 input = &aws.LambdaOptions{ 141 InvocationType: &invocationType, 142 Payload: ExampleFunctionPayload{ShouldFail: false, Echo: "hi!"}, 143 } 144 out, err = aws.InvokeFunctionWithParamsE(t, awsRegion, functionName, input) 145 require.NotNil(t, err) 146 assert.Contains(t, err.Error(), "LambdaOptions.InvocationType, if specified, must either be \"RequestResponse\" or \"DryRun\"") 147 } 148 149 type ExampleFunctionPayload struct { 150 Echo string 151 ShouldFail bool 152 }