Skip to content

Commit

Permalink
chore(tests): use detected Terraform if available.
Browse files Browse the repository at this point in the history
Add support for running e2e tests with a different version of
Terraform when exporting the `TM_TEST_TERRAFORM_REQUIRED_VERSION`
environment variable.

Additionally, the tests now detect if Terraform is already
installed and then the detected version is used. If the detected
version does not match the version provided in the environment
variable, then it's installed as before.

Signed-off-by: Tiago Natel <t.nateldemoura@gmail.com>
  • Loading branch information
i4ki committed Oct 18, 2023
1 parent 3668835 commit 7225bd1
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"format_version":"1.2","terraform_version":"1.5.0","variables":{"content":{"value":"REDACTED_SENSITIVE"}},"planned_values":{"root_module":{"resources":[{"address":"local_file.foo","mode":"managed","type":"local_file","name":"foo","provider_name":"registry.terraform.io/hashicorp/local","schema_version":0,"values":{"content":"REDACTED_SENSITIVE","content_base64":null,"directory_permission":"0777","file_permission":"0777","filename":"./foo.bar","sensitive_content":"REDACTED_SENSITIVE","source":null},"sensitive_values":{"content":true}}]}},"resource_changes":[{"address":"local_file.foo","mode":"managed","type":"local_file","name":"foo","provider_name":"registry.terraform.io/hashicorp/local","change":{"actions":["create"],"before":null,"after":{"content":"REDACTED_SENSITIVE","content_base64":null,"directory_permission":"0777","file_permission":"0777","filename":"./foo.bar","sensitive_content":"REDACTED_SENSITIVE","source":null},"after_unknown":{"content_base64sha256":true,"content_base64sha512":true,"content_md5":true,"content_sha1":true,"content_sha256":true,"content_sha512":true,"id":true},"before_sensitive":false,"after_sensitive":{"content":true,"sensitive_content":true}}}],"configuration":{"provider_config":{"local":{"name":"local","full_name":"registry.terraform.io/hashicorp/local"}},"root_module":{"resources":[{"address":"local_file.foo","mode":"managed","type":"local_file","name":"foo","provider_config_key":"local","expressions":{"content":{"references":["var.content"]},"filename":{"references":["path.module"]}},"schema_version":0}],"variables":{"content":{"sensitive":true}}}},"timestamp":"2023-10-12T14:03:39Z"}
{"format_version":"1.2","terraform_version":"__terraform_version__","variables":{"content":{"value":"REDACTED_SENSITIVE"}},"planned_values":{"root_module":{"resources":[{"address":"local_file.foo","mode":"managed","type":"local_file","name":"foo","provider_name":"registry.terraform.io/hashicorp/local","schema_version":0,"values":{"content":"REDACTED_SENSITIVE","content_base64":null,"directory_permission":"0777","file_permission":"0777","filename":"./foo.bar","sensitive_content":"REDACTED_SENSITIVE","source":null},"sensitive_values":{"content":true}}]}},"resource_changes":[{"address":"local_file.foo","mode":"managed","type":"local_file","name":"foo","provider_name":"registry.terraform.io/hashicorp/local","change":{"actions":["create"],"before":null,"after":{"content":"REDACTED_SENSITIVE","content_base64":null,"directory_permission":"0777","file_permission":"0777","filename":"./foo.bar","sensitive_content":"REDACTED_SENSITIVE","source":null},"after_unknown":{"content_base64sha256":true,"content_base64sha512":true,"content_md5":true,"content_sha1":true,"content_sha256":true,"content_sha512":true,"id":true},"before_sensitive":false,"after_sensitive":{"content":true,"sensitive_content":true}}}],"configuration":{"provider_config":{"local":{"name":"local","full_name":"registry.terraform.io/hashicorp/local"}},"root_module":{"resources":[{"address":"local_file.foo","mode":"managed","type":"local_file","name":"foo","provider_config_key":"local","expressions":{"content":{"references":["var.content"]},"filename":{"references":["path.module"]}},"schema_version":0}],"variables":{"content":{"sensitive":true}}}},"timestamp":"2023-10-12T14:03:39Z"}
51 changes: 38 additions & 13 deletions cmd/terramate/e2etests/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
"time"

Expand All @@ -22,14 +23,17 @@ import (
"github.com/terramate-io/terramate/errors"
)

const terraformVersion = "1.5.0"
const terraformInstallVersion = "1.5.0"

// terramateTestBin is the path to the terramate binary we compiled for test purposes
var terramateTestBin string

// terraformTestBin is the path to the installed terraform binary.
var terraformTestBin string

// terraformVersion is the detected or installed Terraform version.
var terraformVersion string

// testHelperBin is the path to the test binary we compiled for test purposes
var testHelperBin string

Expand Down Expand Up @@ -89,21 +93,14 @@ func setupAndRunTests(m *testing.M) (status int) {
EOF
)}`, testHelperBin)

tfExecPath, installer, err := installTerraform()
tfExecPath, cleanup, err := installTerraform()
if err != nil {
log.Printf("failed to setup Terraform binary")
return 1
}

defer cleanup()
terraformTestBin = tfExecPath

defer func() {
err := installer.Remove(context.Background())
if err != nil {
log.Printf("failed to remove terraform installation")
}
}()

return m.Run()
}

Expand Down Expand Up @@ -146,12 +143,33 @@ func buildTerramate(goBin, projectRoot, binDir string) (string, error) {
return outBinPath, nil
}

func installTerraform() (string, *install.Installer, error) {
func installTerraform() (string, func(), error) {
requireVersion := os.Getenv("TM_TEST_TERRAFORM_REQUIRED_VERSION")
tfExecPath, err := exec.LookPath("terraform")
if err == nil {
cmd := exec.Command("terraform", "version")
output, err := cmd.Output()
if err == nil && len(output) > 0 {
lines := strings.Split(string(output), "\n")
terraformVersion = strings.TrimPrefix(strings.TrimSpace(lines[0]), "Terraform v")

if requireVersion == "" || terraformVersion == requireVersion {
log.Printf("Terraform detected version: %s", terraformVersion)
return tfExecPath, func() {}, nil
}
}
}

installVersion := terraformInstallVersion
if requireVersion != "" {
installVersion = requireVersion
}

ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()

installer := install.NewInstaller()
version := version.Must(version.NewVersion(terraformVersion))
version := version.Must(version.NewVersion(installVersion))

execPath, err := installer.Install(ctx, []src.Installable{
&releases.ExactVersion{
Expand All @@ -162,7 +180,14 @@ func installTerraform() (string, *install.Installer, error) {
if err != nil {
return "", nil, errors.E(err, "installing Terraform")
}
return execPath, installer, nil
terraformVersion = installVersion
log.Printf("Terraform installed version: %s", terraformVersion)
return execPath, func() {
err := installer.Remove(context.Background())
if err != nil {
log.Printf("failed to remove terraform installation")
}
}, nil
}

func lookupGoBin() (string, error) {
Expand Down
17 changes: 14 additions & 3 deletions cmd/terramate/e2etests/run_cloud_drift_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ func TestCLIRunWithCloudSyncDriftStatus(t *testing.T) {
Status: stack.Drifted,
Details: &cloud.DriftDetails{
Provisioner: "terraform",
ChangesetJSON: string(test.ReadFile(t, "_testdata/cloud-sync-drift-plan-file", "sanitized.plan.json")),
ChangesetJSON: loadJSONPlan(t, "_testdata/cloud-sync-drift-plan-file/sanitized.plan.json"),
},
},
ChangesetASCIIRegexes: []string{
Expand All @@ -399,7 +399,7 @@ func TestCLIRunWithCloudSyncDriftStatus(t *testing.T) {
Status: stack.Drifted,
Details: &cloud.DriftDetails{
Provisioner: "terraform",
ChangesetJSON: string(test.ReadFile(t, "_testdata/cloud-sync-drift-plan-file", "sanitized.plan.json")),
ChangesetJSON: loadJSONPlan(t, "_testdata/cloud-sync-drift-plan-file/sanitized.plan.json"),
},
},
ChangesetASCIIRegexes: []string{
Expand Down Expand Up @@ -512,10 +512,21 @@ func assertRunDrifts(t *testing.T, expectedDrifts expectedDriftStackPayloadReque
assert.NoError(t, json.Unmarshal([]byte(got.Details.ChangesetJSON), &gotPlan))
assert.NoError(t, json.Unmarshal([]byte(expected.Details.ChangesetJSON), &wantPlan))

if diff := cmp.Diff(gotPlan, wantPlan, cmpopts.IgnoreFields(tfjson.Plan{}, "Timestamp")); diff != "" {
if diff := cmp.Diff(gotPlan, wantPlan, cmpopts.IgnoreFields(tfjson.Plan{}, "Timestamp", "FormatVersion")); diff != "" {
t.Logf("want: %+v", expected.Details.ChangesetJSON)
t.Logf("got: %+v", got.Details.ChangesetJSON)
t.Fatal(diff)
}
}
}

func loadJSONPlan(t *testing.T, fname string) string {
fname = filepath.FromSlash(fname)
jsonBytes := test.ReadFile(t, filepath.Dir(fname), filepath.Base(fname))
var plan tfjson.Plan
assert.NoError(t, json.Unmarshal(jsonBytes, &plan))
plan.TerraformVersion = terraformVersion
jsonNewBytes, err := json.Marshal(&plan)
assert.NoError(t, err)
return string(jsonNewBytes)
}

0 comments on commit 7225bd1

Please sign in to comment.