diff --git a/integration/README.md b/integration/README.md new file mode 100644 index 00000000..69eeec3e --- /dev/null +++ b/integration/README.md @@ -0,0 +1,10 @@ +# Integration tests + +This directory contains integration tests for our apps. Tests are written using the [terraform test framework](https://developer.hashicorp.com/terraform/language/tests) + +To run the full test suite, run: + +``` +terraform init +terraform test +``` diff --git a/integration/main.tf b/integration/main.tf new file mode 100644 index 00000000..175c9f37 --- /dev/null +++ b/integration/main.tf @@ -0,0 +1,12 @@ +data "aws_region" "current" {} + +resource "aws_cloudformation_stack" "this" { + name = var.name + template_body = file("../.aws-sam/build/${var.app}/${data.aws_region.current.name}/packaged.yaml") + parameters = var.parameters + capabilities = var.capabilities +} + +output "stack" { + value = aws_cloudformation_stack.this +} diff --git a/integration/scripts/test.sh b/integration/scripts/test.sh new file mode 100755 index 00000000..18637820 --- /dev/null +++ b/integration/scripts/test.sh @@ -0,0 +1,6 @@ +#!/bin/bash +cat << EOF +{ + "error": "it failed!" +} +EOF diff --git a/integration/tests/check/main.tf b/integration/tests/check/main.tf new file mode 100644 index 00000000..7967fd6d --- /dev/null +++ b/integration/tests/check/main.tf @@ -0,0 +1,5 @@ +data "external" "check" { + program = var.program + query = var.query + working_dir = var.working_dir +} diff --git a/integration/tests/check/outputs.tf b/integration/tests/check/outputs.tf new file mode 100644 index 00000000..b5e32da1 --- /dev/null +++ b/integration/tests/check/outputs.tf @@ -0,0 +1,3 @@ +output "result" { + value = data.external.check.result +} diff --git a/integration/tests/check/variables.tf b/integration/tests/check/variables.tf new file mode 100644 index 00000000..62d3cf8c --- /dev/null +++ b/integration/tests/check/variables.tf @@ -0,0 +1,28 @@ +variable "program" { + description = <<-EOF + A list of strings, whose first element is the program to run and whose + subsequent elements are optional command line arguments to the program. + Terraform does not execute the program through a shell, so it is not + necessary to escape shell metacharacters nor add quotes around arguments + containing spaces. + EOF + type = list(string) + nullable = false +} + +variable "query" { + description = <<-EOF + A map of string values to pass to the external program as the query + arguments. If not supplied, the program will receive an empty object as its + input. + EOF + type = map(string) + default = {} + nullable = false +} + +variable "working_dir" { + description = "Working directory of the program" + type = string + default = null +} diff --git a/integration/tests/check/verify.sh b/integration/tests/check/verify.sh new file mode 100755 index 00000000..0812b744 --- /dev/null +++ b/integration/tests/check/verify.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Exit if any of the intermediate steps fail +set -e + +# Extract "foo" and "baz" arguments from the input into +# FOO and BAZ shell variables. +# jq will ensure that the values are properly quoted +# and escaped for consumption by the shell. +eval "$(jq -r '@sh "FOO=\(.foo) BAZ=\(.baz)"')" + +# Placeholder for whatever data-fetching logic your script implements +FOOBAZ="$FOO $BAZ" + +# Safely produce a JSON object containing the result value. +# jq will ensure that the value is properly quoted +# and escaped to produce a valid JSON string. +jq -n --arg foobaz "$FOOBAZ" '{"foobaz":$foobaz}' diff --git a/integration/tests/check/versions.tf b/integration/tests/check/versions.tf new file mode 100644 index 00000000..55220346 --- /dev/null +++ b/integration/tests/check/versions.tf @@ -0,0 +1,11 @@ +terraform { + required_version = "~> 1.6" + required_providers { + external = { + source = "hashicorp/external" + version = "~> 2.3" + } + } +} + + diff --git a/integration/tests/forwarder.tftest.hcl b/integration/tests/forwarder.tftest.hcl new file mode 100644 index 00000000..27021f20 --- /dev/null +++ b/integration/tests/forwarder.tftest.hcl @@ -0,0 +1,20 @@ +run "setup" { + module { + source = "./tests/setup" + } +} + +run "install_forwarder" { + variables { + name = run.setup.id + app = "forwarder" + parameters = { + DataAccessPointArn = run.setup.source.arn + DestinationUri = "s3://${run.setup.source.alias}" + } + capabilities = [ + "CAPABILITY_NAMED_IAM", + "CAPABILITY_AUTO_EXPAND", + ] + } +} diff --git a/integration/tests/scripts/test.sh b/integration/tests/scripts/test.sh new file mode 100755 index 00000000..3461096e --- /dev/null +++ b/integration/tests/scripts/test.sh @@ -0,0 +1 @@ +echo "tes" diff --git a/integration/tests/setup/main.tf b/integration/tests/setup/main.tf new file mode 100644 index 00000000..199c1627 --- /dev/null +++ b/integration/tests/setup/main.tf @@ -0,0 +1,16 @@ +resource "random_pet" "run" { + length = 2 +} + +resource "aws_s3_bucket" "source" { + bucket = "${random_pet.run.id}-source" +} + +resource "aws_s3_bucket" "destination" { + bucket = "${random_pet.run.id}-destination" +} + +resource "aws_s3_access_point" "source" { + bucket = aws_s3_bucket.source.id + name = random_pet.run.id +} diff --git a/integration/tests/setup/outputs.tf b/integration/tests/setup/outputs.tf new file mode 100644 index 00000000..6aba6723 --- /dev/null +++ b/integration/tests/setup/outputs.tf @@ -0,0 +1,14 @@ +output "id" { + value = random_pet.run.id + description = "Random test identifier" +} + +output "source" { + value = aws_s3_access_point.source + description = "S3 bucket where files are copied from" +} + +output "destination" { + value = aws_s3_bucket.destination + description = "S3 bucket where files are copied to" +} diff --git a/integration/tests/setup/versions.tf b/integration/tests/setup/versions.tf new file mode 100644 index 00000000..480b347b --- /dev/null +++ b/integration/tests/setup/versions.tf @@ -0,0 +1,13 @@ +terraform { + required_version = "~> 1.6" + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.3" + } + random = { + source = "hashicorp/random" + version = ">= 3.5.1" + } + } +} diff --git a/integration/tests/simple.tftest.hcl b/integration/tests/simple.tftest.hcl new file mode 100644 index 00000000..68505f81 --- /dev/null +++ b/integration/tests/simple.tftest.hcl @@ -0,0 +1,20 @@ +run "setup" { + module { + source = "./tests/setup" + } +} + +run "check" { + module { + source = "./tests/check" + } + + variables { + program = ["./scripts/test.sh", run.setup.id ] + } + + assert { + condition = output.result.error == "" + error_message = "Failed to test thing" + } +} diff --git a/integration/variables.tf b/integration/variables.tf new file mode 100644 index 00000000..54f2109e --- /dev/null +++ b/integration/variables.tf @@ -0,0 +1,21 @@ +variable "name" { + description = "Stack name" + type = string +} + +variable "app" { + description = "App name" + type = string +} + +variable "parameters" { + description = "Stack parameters" + type = map(string) +} + +variable "capabilities" { + description = "Stack capabilities" + type = list(string) +} + + diff --git a/integration/versions.tf b/integration/versions.tf new file mode 100644 index 00000000..876c0f73 --- /dev/null +++ b/integration/versions.tf @@ -0,0 +1,11 @@ +terraform { + required_version = "~> 1.6" + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.3" + } + } +} + +