Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add module tests #48

Merged
merged 14 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
path: ["cg_space", "clamav", "database", "domain", "redis", "s3"]
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: terraform validate ${{ matrix.path }}
uses: dflook/terraform-validate@v1
Expand All @@ -31,7 +31,7 @@ jobs:
path: ["cg_space", "clamav", "database", "domain", "redis", "s3"]
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: terraform fmt ${{ matrix.path }}
uses: dflook/terraform-fmt-check@v1
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Terraform Test

on:
pull_request:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest
name: Integration test
strategy:
fail-fast: false
max-parallel: 2
matrix:
module: ["s3", "database", "redis"]
steps:
- uses: actions/checkout@v4

- name: terraform test ${{ matrix.module }}
uses: dflook/terraform-test@v1
env:
CF_USER: ${{ secrets.CF_USER }}
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
with:
path: ${{ matrix.module }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Local .terraform directories
**/.terraform/*
**/.terraform.lock.hcl

# .tfstate files
*.tfstate
Expand Down
1 change: 1 addition & 0 deletions .terraform-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.8.5
rahearn marked this conversation as resolved.
Show resolved Hide resolved
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ Creates a new cloud.gov space, such as when creating an egress space, and output

`managers`, `developers`, and `deployers` are all optional, but you probably want to set at least one of them, depending on your use case.

* `managers` are granted the [Space Manager](https://docs.cloudfoundry.org/concepts/roles.html#activeroles) role
* `developers` are granted the [Space Developer](https://docs.cloudfoundry.org/concepts/roles.html#activeroles) role
* `deployers` are granted both manager and developer roles

```
module "egress_space" {
source = "github.com/18f/terraform-cloudgov//cg_space?ref=v1.0.0"
Expand All @@ -140,3 +144,12 @@ module "egress_space" {
]
}
```

## Testing

[Terraform tests](https://developer.hashicorp.com/terraform/language/tests) are in progress of being written. To run for any module with a `tests` directory:
rahearn marked this conversation as resolved.
Show resolved Hide resolved

1. Set `CF_USER` and `CF_PASSWORD` env variables with SpaceDeployer credentials that can access the space(s) being used for tests
1. cd to module root. Example: `cd s3`
1. Run `terraform init`
1. Run `terraform test`
87 changes: 87 additions & 0 deletions cg_space/tests/creation.tftest.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
mock_provider "cloudfoundry" {
override_data {
target = data.cloudfoundry_user.managers["user.manager@gsa.gov"]
values = {
id = "1e5143a4-aa47-483c-8352-557988d5cc7a"
}
}
override_data {
target = data.cloudfoundry_user.deployers["user.manager@gsa.gov"]
values = {
id = "1e5143a4-aa47-483c-8352-557988d5cc7a"
}
}
override_data {
target = data.cloudfoundry_user.developers["user.developer@gsa.gov"]
values = {
id = "2c945842-13ee-4383-84ad-34ecbcde5ce6"
}
}
}

variables {
cf_org_name = "gsa-tts-devtools-prototyping"
cf_space_name = "terraform-cloudgov-ci-tests-egress"
}

run "test_space_creation" {
assert {
condition = cloudfoundry_space.space.id == output.space_id
error_message = "Space ID output must match the new space"
}

assert {
condition = cloudfoundry_space.space.name == var.cf_space_name
error_message = "Space name should match the cf_space_name variable"
}
}

run "test_manager_only" {
variables {
managers = ["user.manager@gsa.gov"]
}

assert {
condition = cloudfoundry_space_users.space_permissions.managers == toset(["1e5143a4-aa47-483c-8352-557988d5cc7a"])
error_message = "Should be able to set Space Managers"
}

assert {
condition = length(cloudfoundry_space_users.space_permissions.developers) == 0
error_message = "Should not have set any Space Developers"
}
}

run "test_individual_permissions" {
variables {
managers = ["user.manager@gsa.gov"]
developers = ["user.developer@gsa.gov"]
}

assert {
condition = cloudfoundry_space_users.space_permissions.managers == toset(["1e5143a4-aa47-483c-8352-557988d5cc7a"])
error_message = "Should be able to set Space Managers"
}

assert {
condition = cloudfoundry_space_users.space_permissions.developers == toset(["2c945842-13ee-4383-84ad-34ecbcde5ce6"])
error_message = "Should be able to set Space Developers"
}
}

run "test_deployer_permissions" {
variables {
developers = ["user.developer@gsa.gov"]
deployers = ["user.manager@gsa.gov"]
}

assert {
condition = cloudfoundry_space_users.space_permissions.managers == toset(["1e5143a4-aa47-483c-8352-557988d5cc7a"])
error_message = "Should be able to set Space Managers via var.deployers"
}

assert {
condition = cloudfoundry_space_users.space_permissions.developers == toset(["2c945842-13ee-4383-84ad-34ecbcde5ce6", "1e5143a4-aa47-483c-8352-557988d5cc7a"])
error_message = "Should set Space Developers to var.developers + var.deployers"
}
}
47 changes: 47 additions & 0 deletions database/tests/creation.tftest.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
mock_provider "cloudfoundry" {
mock_data "cloudfoundry_service" {
defaults = {
service_plans = {
"micro-psql" = "03c93c7b-3e1c-47c5-a6c3-1df151d280dd"
}
}
}
}

variables {
cf_org_name = "gsa-tts-devtools-prototyping"
cf_space_name = "terraform-cloudgov-ci-tests"
rds_plan_name = "micro-psql"
name = "terraform-cloudgov-rds-test"
tags = ["terraform-cloudgov", "tests"]
json_params = jsonencode({
backup_retention_period = 30
})
}

run "test_db_creation" {
assert {
condition = cloudfoundry_service_instance.rds.id == output.instance_id
error_message = "Instance ID output must match the service instance"
}

assert {
condition = cloudfoundry_service_instance.rds.service_plan == data.cloudfoundry_service.rds.service_plans[var.rds_plan_name]
error_message = "Service Plan should match the rds_plan_name variable"
}

assert {
condition = cloudfoundry_service_instance.rds.name == var.name
error_message = "Service instance name should match the name variable"
}

assert {
condition = cloudfoundry_service_instance.rds.tags == var.tags
error_message = "Service instance tags should match the tags variable"
}

assert {
condition = cloudfoundry_service_instance.rds.json_params == "{\"backup_retention_period\":30}"
error_message = "Service instance json_params should be configurable"
}
}
47 changes: 47 additions & 0 deletions redis/tests/creation.tftest.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
mock_provider "cloudfoundry" {
mock_data "cloudfoundry_service" {
defaults = {
service_plans = {
"redis-dev" = "03c93c7b-3e1c-47c5-a6c3-1df151d280dd"
}
}
}
}

variables {
cf_org_name = "gsa-tts-devtools-prototyping"
cf_space_name = "terraform-cloudgov-ci-tests"
redis_plan_name = "redis-dev"
name = "terraform-cloudgov-redis-test"
tags = ["terraform-cloudgov", "tests"]
json_params = jsonencode({
engineVersion = "7.0"
})
}

run "test_redis_creation" {
assert {
condition = cloudfoundry_service_instance.redis.id == output.instance_id
error_message = "Instance ID output must match the service instance"
}

assert {
condition = cloudfoundry_service_instance.redis.service_plan == data.cloudfoundry_service.redis.service_plans[var.redis_plan_name]
error_message = "Service Plan should match the redis_plan_name variable"
}

assert {
condition = cloudfoundry_service_instance.redis.name == var.name
error_message = "Service instance name should match the name variable"
}

assert {
condition = cloudfoundry_service_instance.redis.tags == var.tags
error_message = "Service instance tags should match the tags variable"
}

assert {
condition = cloudfoundry_service_instance.redis.json_params == "{\"engineVersion\":\"7.0\"}"
error_message = "Service instance json_params should be configurable"
}
}
54 changes: 54 additions & 0 deletions s3/tests/creation.tftest.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
provider "cloudfoundry" {
api_url = "https://api.fr.cloud.gov"
# cf_user and cf_password are passed in via CF_USER and CF_PASSWORD env vars
}

variables {
cf_org_name = "gsa-tts-devtools-prototyping"
cf_space_name = "terraform-cloudgov-ci-tests"
s3_plan_name = "basic"
name = "terraform-cloudgov-s3-test"
tags = ["terraform-cloudgov", "tests"]
}

run "test_bucket_creation" {
assert {
condition = can(regex("^\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}$", output.bucket_id))
error_message = "Bucket ID should be a GUID"
}

assert {
condition = cloudfoundry_service_instance.bucket.id == output.bucket_id
error_message = "Bucket ID output must match the service instance"
}

assert {
condition = cloudfoundry_service_instance.bucket.service_plan == data.cloudfoundry_service.s3.service_plans[var.s3_plan_name]
error_message = "Service Plan should match the s3_plan_name variable"
}

assert {
condition = cloudfoundry_service_instance.bucket.name == var.name
error_message = "Service instance name should match the name variable"
}

assert {
condition = cloudfoundry_service_instance.bucket.tags == var.tags
error_message = "Service instance tags should match the tags variable"
}
}

run "test_json_params" {
command = plan

variables {
json_params = jsonencode({
object_ownership = "BucketOwnerEnforced"
})
}

assert {
condition = cloudfoundry_service_instance.bucket.json_params == "{\"object_ownership\":\"BucketOwnerEnforced\"}"
error_message = "Service instance json_params should be configurable"
}
}