Add definition of integration tests with Postgres backend (#920)

Signed-off-by: Dmitry Kisler <admin@dkisler.com>
This commit is contained in:
Dmitry Kisler 2023-11-24 14:48:03 +01:00 committed by GitHub
parent 899f533835
commit 398a2cf4f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 23 deletions

View File

@ -114,6 +114,24 @@ TF_ACC=1 go test ./internal/initwd
Because the acceptance tests depend on services outside of the OpenTofu codebase, and because the acceptance tests are usually used only when making changes to the systems they cover, it is common and expected that drift in those external systems will cause test failures. Because of this, prior to working on a system covered by acceptance tests it's important to run the existing tests for that system in an *unchanged* work tree first and respond to any test failures that preexist, to avoid misinterpreting such failures as bugs in your new changes.
### Integration Tests: Testing interactions with external backends
OpenTofu supports various [backends](https://opentofu.org/docs/language/settings/backends/configuration). We run integration test against them to ensure no side effects when using OpenTofu.
Execute to list all available commands to run tests:
```commandline
make list-integration-tests
```
From the list of output commands, you can execute those which involve backends you intend to test against.
For example, execute the command to run integration tests with s3 backend:
```commandline
make test-s3
```
## Generated Code
Some files in the OpenTofu CLI codebase are generated. In most cases, we update these using `go generate`, which is the standard way to encapsulate code generation steps in a Go codebase.

View File

@ -62,3 +62,62 @@ bin/licensei-${LICENSEI_VERSION}:
# commands during the build process create temporary files that collide
# under parallel conditions.
.NOTPARALLEL:
# Integration tests
#
.PHONY: list-integration-tests
list-integration-tests: ## Lists tests.
@ grep -h -E '^(test|integration)-.+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[1m%-30s\033[0m %s\n", $$1, $$2}'
# integration test with s3 as backend
.PHONY: test-s3
define infoTestS3
Test requires:
* AWS Credentials to be configured
- https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
- https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
* IAM Permissions in us-west-2
- S3 CRUD operations on buckets which will follow the pattern tofu-test-*
- DynamoDB CRUD operations on a Table named dynamoTable
endef
test-s3: ## Runs tests with s3 bucket as the backend.
@ $(info $(infoTestS3))
@ TF_S3_TEST=1 go test ./internal/backend/remote-state/s3/...
# integration test with postgres as backend
.PHONY: test-pg test-pg-clean
PG_PORT := 5432
define infoTestPg
Test requires:
* Docker: https://docs.docker.com/engine/install/
* Port: $(PG_PORT)
endef
test-pg: ## Runs tests with local Postgres instance as the backend.
@ $(info $(infoTestPg))
@ echo "Starting database"
@ make test-pg-clean
@ docker run --rm -d --name tofu-pg \
-p $(PG_PORT):5432 \
-e POSTGRES_PASSWORD=tofu \
-e POSTGRES_USER=tofu \
postgres:16-alpine3.17 1> /dev/null
@ docker exec tofu-pg /bin/bash -c 'until psql -U tofu -c "\q" 2> /dev/null; do echo "Database is getting ready, waiting"; sleep 1; done'
@ DATABASE_URL="postgres://tofu:tofu@localhost:$(PG_PORT)/tofu?sslmode=disable" \
TF_PG_TEST=1 go test ./internal/backend/remote-state/pg/...
test-pg-clean: ## Cleans environment after `test-pg`.
@ docker rm -f tofu-pg 2> /dev/null
.PHONY:
integration-tests: test-s3 test-pg integration-tests-clean ## Runs all integration tests test.
.PHONY:
integration-tests-clean: test-pg-clean ## Cleans environment after all integration tests.

View File

@ -26,22 +26,22 @@ import (
//
// A running Postgres server identified by env variable
// DATABASE_URL is required for acceptance tests.
func testACC(t *testing.T) string {
skip := os.Getenv("TF_ACC") == ""
func testACC(t *testing.T) (connectionURI *url.URL) {
skip := os.Getenv("TF_ACC") == "" && os.Getenv("TF_PG_TEST") == ""
if skip {
t.Log("pg backend tests require setting TF_ACC")
t.Log("pg backend tests requires setting TF_ACC or TF_PG_TEST")
t.Skip()
}
databaseUrl, found := os.LookupEnv("DATABASE_URL")
if !found {
databaseUrl = "postgres://localhost/terraform_backend_pg_test?sslmode=disable"
os.Setenv("DATABASE_URL", databaseUrl)
t.Fatal("pg backend tests require setting DATABASE_URL")
}
u, err := url.Parse(databaseUrl)
if err != nil {
t.Fatal(err)
}
return u.Path[1:]
return u
}
func TestBackend_impl(t *testing.T) {
@ -49,8 +49,15 @@ func TestBackend_impl(t *testing.T) {
}
func TestBackendConfig(t *testing.T) {
databaseName := testACC(t)
connStr := getDatabaseUrl()
connectionURI := testACC(t)
connStr := os.Getenv("DATABASE_URL")
user := connectionURI.User.Username()
password, _ := connectionURI.User.Password()
databaseName := connectionURI.Path[1:]
connectionURIObfuscated := connectionURI
connectionURIObfuscated.User = nil
testCases := []struct {
Name string
@ -71,6 +78,8 @@ func TestBackendConfig(t *testing.T) {
EnvVars: map[string]string{
"PGSSLMODE": "disable",
"PGDATABASE": databaseName,
"PGUSER": user,
"PGPASSWORD": password,
},
Config: map[string]interface{}{
"schema_name": fmt.Sprintf("terraform_%s", t.Name()),
@ -92,10 +101,10 @@ func TestBackendConfig(t *testing.T) {
"PGPASSWORD": "badpassword",
},
Config: map[string]interface{}{
"conn_str": connStr,
"conn_str": connectionURIObfuscated.String(),
"schema_name": fmt.Sprintf("terraform_%s", t.Name()),
},
ExpectConnectionError: `role "baduser" does not exist`,
ExpectConnectionError: `authentication failed for user "baduser"`,
},
{
Name: "host-in-env-vars",
@ -117,6 +126,7 @@ func TestBackendConfig(t *testing.T) {
"PGDATABASE": databaseName,
},
Config: map[string]interface{}{
"conn_str": connStr,
"schema_name": fmt.Sprintf("terraform_%s", t.Name()),
},
},

View File

@ -1,13 +0,0 @@
cat <<EOT
$0 requires:
* AWS Credentials to be configured
- https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
- https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
* IAM Permissions in us-west-2
- S3 CRUD operations on buckets which will follow the pattern tofu-test-*
- DynamoDB CRUD operations on a Table named dynamoTable
EOT
TF_ACC=1 go test ./internal/backend/remote-state/s3/...
exit $?