Skip to content

Commit

Permalink
Merge pull request #287 from kbalk/add-provider-alias
Browse files Browse the repository at this point in the history
Allow a test to specify a provider alias
  • Loading branch information
kbalk authored Sep 24, 2021
2 parents aa32c75 + 2875e6d commit 79966b4
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.17.1
current_version = 0.18.0
commit = True
message = Bumps version to {new_version}
tag = False
Expand Down
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,36 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).

### 0.18.0

**Released**: 2021.09.13

**Commit Delta**: [Change from 0.17.1 release](https://github.com/plus3it/tardigrade-ci/compare/0.17.1..0.18.0)

**Summary**:

* The new environment variable "PROVIDER_ALIAS" can be used to specify the
name of a Terraform provider alias. Used as a value for the new "--alias"
command line option, it instructs the automated integration test tool
to create the aliased provider information in preparation for a test run.

* When running Terraform tests, the Firehose service will now be provided
by moto and not LocalStack.

* Updates tool versions:
* black 21.9b0
* cfn-lint 0.54.1
* pylint 2.11.1
* pytest 6.2.5
* terragrunt 0.31.10
* terraform 1.0.7
* terraform-docs 0.15.0
* terratest 0.37.8
* yamllint 1.26.3
* yq 4.13.2
* Docker now using golang:1.17.1-buster
* Docker now using python:3.9.7-buster

### 0.17.1

**Released**: 2021.07.30
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,11 @@ python/format:

# Run pytests, typically for unit tests.
PYTEST_ARGS ?=
PYTEST_ALIAS_ARG ?= $(if $(PROVIDER_ALIAS),--alias $(PROVIDER_ALIAS),)
pytest/%: | guard/program/pytest
pytest/%:
@ echo "[$@] Starting Python tests found under the directory \"$*\""
pytest $* $(PYTEST_ARGS)
pytest $* $(PYTEST_ARGS) $(PYTEST_ALIAS_ARG)
@ echo "[$@]: Tests executed!"

## Lints terraform files
Expand Down
11 changes: 11 additions & 0 deletions tests/terraform_pytest/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ def pytest_addoption(parser):
default=str(Path(Path.cwd() / "tests")),
help="Directory of Terraform files under test; default: './tests'",
)
parser.addoption(
"--alias",
action="store",
help="Name of Terraform provider alias to include in test",
)


@pytest.fixture(scope="function")
Expand Down Expand Up @@ -87,6 +92,12 @@ def tf_dir(request):
return Path(terraform_dir).resolve()


@pytest.fixture(scope="session")
def provider_alias(request):
"""Return name of alias for provider, if one was given."""
return request.config.getoption("--alias")


def pytest_generate_tests(metafunc):
"""Generate list of subdirectories under test.
Expand Down
25 changes: 2 additions & 23 deletions tests/terraform_pytest/mockstack.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ provider "aws" {
cloudwatch = "http://${var.mockstack_host}:${var.mockstack_port}"
cloudwatchevents = "http://${var.mockstack_host}:${var.mockstack_port}"
cloudwatchlogs = "http://${var.mockstack_host}:${var.mockstack_port}"
configservice = "http://${var.mockstack_host}:${var.mockstack_port}"
dynamodb = "http://${var.mockstack_host}:${var.mockstack_port}"
ec2 = "http://${var.mockstack_host}:${var.mockstack_port}"
firehose = "http://${var.mockstack_host}:${var.mockstack_port}"
iam = "http://${var.mockstack_host}:${var.mockstack_port}"
kinesis = "http://${var.mockstack_host}:${var.mockstack_port}"
kms = "http://${var.mockstack_host}:${var.mockstack_port}"
Expand All @@ -29,27 +29,6 @@ provider "aws" {
stepfunctions = "http://${var.mockstack_host}:${var.mockstack_port}"
sts = "http://${var.mockstack_host}:${var.mockstack_port}"

configservice = "http://${var.mockstack_host}:${var.moto_port}"
firehose = "http://${var.mockstack_host}:${var.moto_port}"
}
}

variable "mockstack_host" {
description = "Hostname for mock AWS endpoint"
type = string
default = "localhost"
}

variable "mockstack_port" {
description = "Port for mock AWS endpoint"
type = string
default = "4566"
}

# Port 4615 was chosen to be used for moto because that port is used by
# LocalStack for the organizations service. We'll piggyback onto that
# port for other moto-specific services.
variable "moto_port" {
description = "Port for moto; for services not provided by LocalStack"
type = string
default = "4615"
}
20 changes: 20 additions & 0 deletions tests/terraform_pytest/mockstack_variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
variable "mockstack_host" {
description = "Hostname for mock AWS endpoint"
type = string
default = "localhost"
}

variable "mockstack_port" {
description = "Port for mock AWS endpoint"
type = string
default = "4566"
}

# Port 4615 was chosen to be used for moto because that port is used by
# LocalStack for the organizations service. We'll piggyback onto that
# port for other moto-specific services.
variable "moto_port" {
description = "Port for moto; for services not provided by LocalStack"
type = string
default = "4615"
}
36 changes: 30 additions & 6 deletions tests/terraform_pytest/test_terraform_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,48 @@
MOCKSTACK_PORT = "4566"
MOTO_PORT = "4615"

VARIABLES_TF_FILENAME = "mockstack_variables.tf"
MOCKSTACK_TF_FILENAME = "mockstack.tf"
AWS_TF_FILENAME = "aws.tf"


@pytest.fixture(scope="function")
def tf_test_object(is_mock, tf_dir):
def tf_test_object(is_mock, provider_alias, tf_dir, tmp_path):
"""Return function that will create tf_test object using given subdir."""

def create_provider_alias_file(alias_path):
"""Create copy of Terraform file to insert alias into provider block.
It's not possible with Terraform to use a variable for an alias.
"""
with open(str(alias_path), encoding="utf8") as fhandle:
all_lines = fhandle.readlines()
all_lines.insert(1, f' alias = "{provider_alias}"\n\n')

path = tmp_path / f"{alias_path.stem}_alias.tf"
path.write_text("".join(all_lines))
return str(path)

def make_tf_test(tf_module):
"""Return a TerraformTest object for given module."""
tf_test = tftest.TerraformTest(tf_module, basedir=str(tf_dir), env=None)

# Use the appropriate endpoints, either for a simulated AWS stack
# or the real deal.
provider_tf = MOCKSTACK_TF_FILENAME if is_mock else AWS_TF_FILENAME

# Create a list of provider files that contain endpoints for all
# the services in use. The endpoints will be represented by
# Terraform variables.
current_dir = Path(__file__).resolve().parent
tf_test.setup(extra_files=[str(Path(current_dir / provider_tf))])
copy_files = [str(Path(current_dir / VARIABLES_TF_FILENAME))]

if is_mock:
tf_provider_path = Path(current_dir / MOCKSTACK_TF_FILENAME)
else:
tf_provider_path = Path(current_dir / AWS_TF_FILENAME)
copy_files.append(str(tf_provider_path))

if provider_alias:
copy_files.append(create_provider_alias_file(tf_provider_path))

tf_test.setup(extra_files=copy_files)
return tf_test

return make_tf_test
Expand Down

0 comments on commit 79966b4

Please sign in to comment.