Skip to content

Commit

Permalink
chore(tmc): use real terraform in e2e tests (#1177)
Browse files Browse the repository at this point in the history
## Reasons for this change

Before we used a fake terraform binary that mimicked some Terraform
behavior and it supported fully customization of the program's output.
The problem is that the fake terraform misses a lot of important
details:
- `terraform show` gives different error messages depending on different
requirements not met.
- `terraform show` requires an initialized terraform module and then
mimicking this behavior is hard.
- `terraform show` checks the lock files
- etc

if we ignore those details, we miss the opportunity to test those cases
and improve Terramate error messages for such errors.
_The error message improvements are not addressed in this PR_.

## Changes

- Now during the e2e test setup, the Terraform is installed in a temp
directory using the hashicorp official `hc-install` library.
- Tests were updated to use a real project.
- Sandbox library updated to support `copy` and `run` commands.
  • Loading branch information
i4k-tm committed Oct 19, 2023
2 parents 4f44c6e + 3668835 commit 26e1cc1
Show file tree
Hide file tree
Showing 21 changed files with 545 additions and 1,220 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright 2023 Terramate GmbH
* SPDX-License-Identifier: MPL-2.0
*/

resource "local_file" "foo" {
content = var.content
filename = "${path.module}/foo.bar"
}

variable "content" {
sensitive = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +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"}
1 change: 0 additions & 1 deletion cmd/terramate/e2etests/_testdata/sanitized.plan.json

This file was deleted.

841 changes: 0 additions & 841 deletions cmd/terramate/e2etests/_testdata/unsanitized.plan.json

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2023 Terramate GmbH
// SPDX-License-Identifier: MPL-2.0

// test is a test command that implements behaviors that are
// helper is a utility command that implements behaviors that are
// useful when testing terramate run features in a way that reduces
// dependencies on the environment to run the tests.
package main
Expand All @@ -20,7 +20,7 @@ import (
"github.com/hashicorp/terraform-json/sanitize"
)

func helper() {
func main() {
if len(os.Args) < 2 {
log.Fatalf("%s requires at least one subcommand argument", os.Args[0])
}
Expand Down
30 changes: 0 additions & 30 deletions cmd/terramate/e2etests/cmd/test/main.go

This file was deleted.

64 changes: 0 additions & 64 deletions cmd/terramate/e2etests/cmd/test/terraform.go

This file was deleted.

61 changes: 47 additions & 14 deletions cmd/terramate/e2etests/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,32 @@
package e2etest

import (
"context"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"runtime"
"testing"
"time"

"github.com/hashicorp/go-version"
install "github.com/hashicorp/hc-install"
"github.com/hashicorp/hc-install/product"
"github.com/hashicorp/hc-install/releases"
"github.com/hashicorp/hc-install/src"
"github.com/terramate-io/terramate/errors"
"github.com/terramate-io/terramate/test"
)

const terraformVersion = "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

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

Expand Down Expand Up @@ -67,7 +77,7 @@ func setupAndRunTests(m *testing.M) (status int) {
return 1
}

testCmdPath := filepath.Join(packageDir, "cmd", "test")
testCmdPath := filepath.Join(packageDir, "cmd", "helper")
testHelperBin, err = buildTestHelper(goBin, testCmdPath, binTmpDir)
if err != nil {
log.Printf("failed to setup e2e tests: %v", err)
Expand All @@ -79,6 +89,21 @@ func setupAndRunTests(m *testing.M) (status int) {
EOF
)}`, testHelperBin)

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

terraformTestBin = tfExecPath

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

return m.Run()
}

Expand All @@ -95,17 +120,6 @@ func buildTestHelper(goBin, testCmdPath, binDir string) (string, error) {
if err != nil {
return "", fmt.Errorf("failed to build test helper: %v (output: %s)", err, string(out))
}
data, err := ioutil.ReadFile(outBinPath)
if err != nil {
return "", errors.E(err, "reading helper binary")
}

tfPath := filepath.Join(binDir, "terraform"+platExeSuffix())
err = ioutil.WriteFile(tfPath, data, 0644)
if err != nil {
return "", errors.E(err, "writing fake terraform binary")
}
err = test.Chmod(tfPath, 0550)
return outBinPath, err
}

Expand All @@ -132,6 +146,25 @@ func buildTerramate(goBin, projectRoot, binDir string) (string, error) {
return outBinPath, nil
}

func installTerraform() (string, *install.Installer, error) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()

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

execPath, err := installer.Install(ctx, []src.Installable{
&releases.ExactVersion{
Product: product.Terraform,
Version: version,
},
})
if err != nil {
return "", nil, errors.E(err, "installing Terraform")
}
return execPath, installer, nil
}

func lookupGoBin() (string, error) {
exeSuffix := platExeSuffix()
path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix)
Expand Down

0 comments on commit 26e1cc1

Please sign in to comment.