Skip to content

Commit

Permalink
test: update test framework to use current dependencies (#100)
Browse files Browse the repository at this point in the history
  • Loading branch information
gmeligio authored Jun 25, 2024
1 parent 41e8647 commit cb776c0
Show file tree
Hide file tree
Showing 13 changed files with 1,405 additions and 397 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ Available targets:

| Name | Source | Version |
|------|--------|---------|
| <a name="module_dns_master"></a> [dns\_master](#module\_dns\_master) | cloudposse/route53-cluster-hostname/aws | 0.12.2 |
| <a name="module_dns_replicas"></a> [dns\_replicas](#module\_dns\_replicas) | cloudposse/route53-cluster-hostname/aws | 0.12.2 |
| <a name="module_ssm_write_db_password"></a> [ssm\_write\_db\_password](#module\_ssm\_write\_db\_password) | cloudposse/ssm-parameter-store/aws | 0.11.0 |
| <a name="module_dns_master"></a> [dns\_master](#module\_dns\_master) | cloudposse/route53-cluster-hostname/aws | 0.13.0 |
| <a name="module_dns_replicas"></a> [dns\_replicas](#module\_dns\_replicas) | cloudposse/route53-cluster-hostname/aws | 0.13.0 |
| <a name="module_ssm_write_db_password"></a> [ssm\_write\_db\_password](#module\_ssm\_write\_db\_password) | cloudposse/ssm-parameter-store/aws | 0.13.0 |
| <a name="module_this"></a> [this](#module\_this) | cloudposse/label/null | 0.25.0 |

## Resources
Expand Down
6 changes: 3 additions & 3 deletions docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

| Name | Source | Version |
|------|--------|---------|
| <a name="module_dns_master"></a> [dns\_master](#module\_dns\_master) | cloudposse/route53-cluster-hostname/aws | 0.12.2 |
| <a name="module_dns_replicas"></a> [dns\_replicas](#module\_dns\_replicas) | cloudposse/route53-cluster-hostname/aws | 0.12.2 |
| <a name="module_ssm_write_db_password"></a> [ssm\_write\_db\_password](#module\_ssm\_write\_db\_password) | cloudposse/ssm-parameter-store/aws | 0.11.0 |
| <a name="module_dns_master"></a> [dns\_master](#module\_dns\_master) | cloudposse/route53-cluster-hostname/aws | 0.13.0 |
| <a name="module_dns_replicas"></a> [dns\_replicas](#module\_dns\_replicas) | cloudposse/route53-cluster-hostname/aws | 0.13.0 |
| <a name="module_ssm_write_db_password"></a> [ssm\_write\_db\_password](#module\_ssm\_write\_db\_password) | cloudposse/ssm-parameter-store/aws | 0.13.0 |
| <a name="module_this"></a> [this](#module\_this) | cloudposse/label/null | 0.25.0 |

## Resources
Expand Down
7 changes: 3 additions & 4 deletions examples/complete/fixtures.us-east-2.tfvars
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
enabled = true

region = "us-east-2"

availability_zones = ["us-east-2a", "us-east-2b"]
Expand All @@ -12,7 +10,7 @@ name = "documentdb-cluster"

vpc_cidr_block = "172.16.0.0/16"

instance_class = "db.r4.large"
instance_class = "db.t4g.medium"

cluster_size = 1

Expand All @@ -26,7 +24,8 @@ retention_period = 5

preferred_backup_window = "07:00-09:00"

cluster_family = "docdb3.6"
cluster_family = "docdb5.0"
engine_version = "5.0.0"

engine = "docdb"

Expand Down
4 changes: 2 additions & 2 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ provider "aws" {

module "vpc" {
source = "cloudposse/vpc/aws"
version = "2.1.0"
version = "2.1.1"

ipv4_primary_cidr_block = var.vpc_cidr_block

Expand All @@ -25,7 +25,7 @@ module "vpc" {

module "subnets" {
source = "cloudposse/dynamic-subnets/aws"
version = "2.3.0"
version = "2.4.2"

availability_zones = var.availability_zones
vpc_id = module.vpc.vpc_id
Expand Down
6 changes: 3 additions & 3 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ locals {

module "dns_master" {
source = "cloudposse/route53-cluster-hostname/aws"
version = "0.12.2"
version = "0.13.0"

enabled = module.this.enabled && var.zone_id != "" ? true : false
dns_name = local.cluster_dns_name
Expand All @@ -144,7 +144,7 @@ module "dns_master" {

module "dns_replicas" {
source = "cloudposse/route53-cluster-hostname/aws"
version = "0.12.2"
version = "0.13.0"

enabled = module.this.enabled && var.zone_id != "" ? true : false
dns_name = local.replicas_dns_name
Expand All @@ -156,7 +156,7 @@ module "dns_replicas" {

module "ssm_write_db_password" {
source = "cloudposse/ssm-parameter-store/aws"
version = "0.11.0"
version = "0.13.0"

enabled = module.this.enabled && var.ssm_parameter_enabled == true ? true : false
parameter_write = [
Expand Down
4 changes: 2 additions & 2 deletions test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ clean:
all: module examples/complete

## Run basic sanity checks against the module itself
module: export TESTS ?= installed lint get-modules module-pinning get-plugins provider-pinning validate terraform-docs input-descriptions output-descriptions
module: export TESTS ?= installed lint module-pinning provider-pinning validate terraform-docs input-descriptions output-descriptions
module: deps
$(call RUN_TESTS, ../)

## Run tests against example
examples/complete: export TESTS ?= installed lint get-modules get-plugins validate
examples/complete: export TESTS ?= installed lint validate
examples/complete: deps
$(call RUN_TESTS, ../$@)
7 changes: 3 additions & 4 deletions test/src/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export TF_CLI_ARGS_init ?= -get-plugins=true
export TERRAFORM_VERSION ?= $(shell curl -s https://checkpoint-api.hashicorp.com/v1/check/terraform | jq -r -M '.current_version' | cut -d. -f1-2)
export TERRAFORM_VERSION ?= $(shell curl -s https://checkpoint-api.hashicorp.com/v1/check/terraform | jq -r -M '.current_version' | cut -d. -f1)

.DEFAULT_GOAL : all

Expand All @@ -16,7 +15,7 @@ init:
## Run tests
test: init
go mod download
go test -v -timeout 60m -run TestExamplesComplete
go test -v -timeout 60m -run '^Test[^_]'

## Run tests in docker container
docker/test:
Expand All @@ -27,4 +26,4 @@ docker/test:
.PHONY : clean
## Clean up files
clean:
rm -rf ../../examples/complete/*.tfstate*
rm -rf $(TF_DATA_DIR)
89 changes: 89 additions & 0 deletions test/src/aws_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// This file is a work-in-progress proposed set of utility functions
// to be standardized across all Cloud Posse Terraform modules.
// Most, if not all, of these functions will be replaced by
// Terratest functions as they become available.
// This file should be considered a temporary solution as of June 2024 and should not be duplicated

package test

// Support AWS operations
// See https://aws.github.io/aws-sdk-go-v2/docs/getting-started/
// and https://pkg.go.dev/github.com/aws/aws-sdk-go-v2
//
// For type conversions, see https://pkg.go.dev/github.com/aws/[email protected]/aws#hdr-Value_and_Pointer_Conversion_Utilities

import (
"context"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/ssm"
"github.com/stretchr/testify/assert"
"log"
"testing"
)

func AWSConfig() aws.Config {
return AWSConfigWithRegion("us-east-2")
}

func AWSConfigWithRegion(region string) aws.Config {
// Load the Shared AWS Configuration (~/.aws/config)
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
if err != nil {
log.Fatal(err)
}

return cfg
}

func AssertSSMParameterEqual(t *testing.T, ssmClient *ssm.Client, output map[string]interface{}, ssmPathOutput string, expectedValueOutput string) {

if assert.NotEmpty(t, output[expectedValueOutput], "Missing "+expectedValueOutput) &&
assert.NotEmpty(t, output[ssmPathOutput], "Missing "+ssmPathOutput) {

withDecryption := true
param, err := ssmClient.GetParameter(context.TODO(), &ssm.GetParameterInput{
Name: aws.String(output[ssmPathOutput].(string)),
WithDecryption: &withDecryption,
})

if assert.Nil(t, err, "Unable to retrieve "+ssmPathOutput+" from SSM Parameter Store") {
assert.Equal(t, output[expectedValueOutput].(string), aws.ToString(param.Parameter.Value))
}
}
}

func AssertSSMParameterEmpty(t *testing.T, ssmClient *ssm.Client, output map[string]interface{}, ssmPathOutput string) {

// No path given
if output[ssmPathOutput] == nil || output[ssmPathOutput] == "" {
return
}

withDecryption := true
param, err := ssmClient.GetParameter(context.TODO(), &ssm.GetParameterInput{
Name: aws.String(output[ssmPathOutput].(string)),
WithDecryption: &withDecryption,
})

// If a path is given, there should be an empty value to go with it
if assert.Nil(t, err, "Unable to retrieve "+ssmPathOutput+" from SSM Parameter Store") {
assert.Empty(t, aws.ToString(param.Parameter.Value), "Found non-empty value for "+ssmPathOutput)
}
}

func AssertSSMParameterNotEmpty(t *testing.T, ssmClient *ssm.Client, output map[string]interface{}, ssmPathOutput string) {

if assert.NotEmpty(t, output[ssmPathOutput], "Missing "+ssmPathOutput) {

withDecryption := true
param, err := ssmClient.GetParameter(context.TODO(), &ssm.GetParameterInput{
Name: aws.String(output[ssmPathOutput].(string)),
WithDecryption: &withDecryption,
})

if assert.Nil(t, err, "Unable to retrieve "+ssmPathOutput+" from SSM Parameter Store") {
assert.NotEmpty(t, aws.ToString(param.Parameter.Value), "Retrieved empty value for "+ssmPathOutput)
}
}
}
82 changes: 82 additions & 0 deletions test/src/default_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// This file is a work-in-progress proposed set of `go` Test wrappers
// to be standardized across all Cloud Posse Terraform modules.
// This is likely to change, especially as we move from local helpers
// to Terratest helpers.
// This file should be considered a temporary solution as of June 2024 and should not be duplicated

package test

import (
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
"os"
"regexp"
"strings"
"testing"
)

// Test the Terraform module in examples/complete using Terratest.
func TestExamplesComplete(t *testing.T) {
t.Parallel()

testRunner(t, nil, testExamplesComplete)
}

func TestExamplesCompleteDisabled(t *testing.T) {
t.Parallel()

vars := map[string]interface{}{
"enabled": false,
}
testRunner(t, vars, testExamplesCompleteDisabled)
}

func testExamplesCompleteDisabled(t *testing.T, terraformOptions *terraform.Options, randID string, results string) {
// Should complete successfully without creating or changing any resources.
// Extract the "Resources:" section of the output to make the error message more readable.
re := regexp.MustCompile(`Resources: [^.]+\.`)
match := re.FindString(results)
assert.Equal(t, "Resources: 0 added, 0 changed, 0 destroyed.", match, "Re-applying the same configuration should not change any resources")
}

// To speed up debugging, allow running the tests on an existing deployment,
// without creating and destroying one.
// Run this manually by creating a deployment in examples/complete with:
//
// export EXISTING_DEPLOYMENT_ATTRIBUTE="<your-name>"
// terraform init -upgrade
// terraform apply -var-file fixtures.us-east-2.tfvars -var "attributes=[\"$EXISTING_DEPLOYMENT_ATTRIBUTE\"]"
//
// then in this directory (test/src) run
// go test -run Test_ExistingDeployment

func Test_ExistingDeployment(t *testing.T) {
randID := strings.ToLower(os.Getenv("EXISTING_DEPLOYMENT_ATTRIBUTE"))
if randID == "" {
t.Skip("(This is normal): EXISTING_DEPLOYMENT_ATTRIBUTE is not set, skipping...")
return
}

attributes := []string{randID}

varFiles := []string{"fixtures.us-east-2.tfvars"}

terraformOptions := &terraform.Options{
// The path to where our Terraform code is located
TerraformDir: "../../examples/complete",
Upgrade: true,
// Variables to pass to our Terraform code using -var-file options
VarFiles: varFiles,
Vars: map[string]interface{}{
"attributes": attributes,
},
}

// Keep the output quiet
if !testing.Verbose() {
terraformOptions.Logger = logger.Discard
}

testExamplesComplete(t, terraformOptions, randID, "")
}
Loading

0 comments on commit cb776c0

Please sign in to comment.