Skip to content

Commit

Permalink
Adding version compatibility check and e2e tests (#353)
Browse files Browse the repository at this point in the history
  • Loading branch information
bendbennett committed Jan 16, 2023
1 parent c387e4f commit e2c259b
Show file tree
Hide file tree
Showing 10 changed files with 229 additions and 0 deletions.
8 changes: 8 additions & 0 deletions tfexec/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,15 @@ func (tf *Terraform) Apply(ctx context.Context, opts ...ApplyOption) error {
}

// ApplyJSON represents the Terraform apply subcommand with the `-json` flag.
// Using the `-json` flag will result in
// [machine-readable](https://developer.hashicorp.com/terraform/internals/machine-readable-ui)
// JSON being written to the supplied `io.Writer`.
func (tf *Terraform) ApplyJSON(ctx context.Context, w io.Writer, opts ...ApplyOption) error {
err := tf.compatible(ctx, tf0_15_3, nil)
if err != nil {
return fmt.Errorf("terraform apply -json was added in 0.15.3: %w", err)
}

tf.SetStdout(w)

cmd, err := tf.applyJSONCmd(ctx, opts...)
Expand Down
8 changes: 8 additions & 0 deletions tfexec/destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,15 @@ func (tf *Terraform) Destroy(ctx context.Context, opts ...DestroyOption) error {
}

// DestroyJSON represents the Terraform destroy subcommand with the `-json` flag.
// Using the `-json` flag will result in
// [machine-readable](https://developer.hashicorp.com/terraform/internals/machine-readable-ui)
// JSON being written to the supplied `io.Writer`.
func (tf *Terraform) DestroyJSON(ctx context.Context, w io.Writer, opts ...DestroyOption) error {
err := tf.compatible(ctx, tf0_15_3, nil)
if err != nil {
return fmt.Errorf("terraform apply -json was added in 0.15.3: %w", err)
}

tf.SetStdout(w)

cmd, err := tf.destroyJSONCmd(ctx, opts...)
Expand Down
37 changes: 37 additions & 0 deletions tfexec/internal/e2etest/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package e2etest

import (
"context"
"io"
"regexp"
"testing"

"github.com/hashicorp/go-version"

"github.com/hashicorp/terraform-exec/tfexec"
"github.com/hashicorp/terraform-exec/tfexec/internal/testutil"
)

func TestApply(t *testing.T) {
Expand All @@ -22,3 +25,37 @@ func TestApply(t *testing.T) {
}
})
}

func TestApplyJSON_TF014AndEarlier(t *testing.T) {
versions := []string{testutil.Latest011, testutil.Latest012, testutil.Latest013, testutil.Latest014}

runTestWithVersions(t, "basic", versions, func(t *testing.T, tfv *version.Version, tf *tfexec.Terraform) {
err := tf.Init(context.Background())
if err != nil {
t.Fatalf("error running Init in test directory: %s", err)
}

re := regexp.MustCompile("terraform apply -json was added in 0.15.3")

err = tf.ApplyJSON(context.Background(), io.Discard)
if err != nil && !re.MatchString(err.Error()) {
t.Fatalf("error running Apply: %s", err)
}
})
}

func TestApplyJSON_TF015AndLater(t *testing.T) {
versions := []string{testutil.Latest015, testutil.Latest_v1, testutil.Latest_v1_1}

runTestWithVersions(t, "basic", versions, func(t *testing.T, tfv *version.Version, tf *tfexec.Terraform) {
err := tf.Init(context.Background())
if err != nil {
t.Fatalf("error running Init in test directory: %s", err)
}

err = tf.ApplyJSON(context.Background(), io.Discard)
if err != nil {
t.Fatalf("error running Apply: %s", err)
}
})
}
37 changes: 37 additions & 0 deletions tfexec/internal/e2etest/destroy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package e2etest

import (
"context"
"io"
"regexp"
"testing"

"github.com/hashicorp/go-version"

"github.com/hashicorp/terraform-exec/tfexec"
"github.com/hashicorp/terraform-exec/tfexec/internal/testutil"
)

func TestDestroy(t *testing.T) {
Expand All @@ -27,3 +30,37 @@ func TestDestroy(t *testing.T) {
}
})
}

func TestDestroyJSON_TF014AndEarlier(t *testing.T) {
versions := []string{testutil.Latest011, testutil.Latest012, testutil.Latest013, testutil.Latest014}

runTestWithVersions(t, "basic", versions, func(t *testing.T, tfv *version.Version, tf *tfexec.Terraform) {
err := tf.Init(context.Background())
if err != nil {
t.Fatalf("error running Init in test directory: %s", err)
}

re := regexp.MustCompile("terraform apply -json was added in 0.15.3")

err = tf.DestroyJSON(context.Background(), io.Discard)
if err != nil && !re.MatchString(err.Error()) {
t.Fatalf("error running Apply: %s", err)
}
})
}

func TestDestroyJSON_TF015AndLater(t *testing.T) {
versions := []string{testutil.Latest015, testutil.Latest_v1, testutil.Latest_v1_1}

runTestWithVersions(t, "basic", versions, func(t *testing.T, tfv *version.Version, tf *tfexec.Terraform) {
err := tf.Init(context.Background())
if err != nil {
t.Fatalf("error running Init in test directory: %s", err)
}

err = tf.DestroyJSON(context.Background(), io.Discard)
if err != nil {
t.Fatalf("error running Apply: %s", err)
}
})
}
42 changes: 42 additions & 0 deletions tfexec/internal/e2etest/plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package e2etest

import (
"context"
"io"
"regexp"
"testing"

"github.com/hashicorp/go-version"

"github.com/hashicorp/terraform-exec/tfexec"
"github.com/hashicorp/terraform-exec/tfexec/internal/testutil"
)

func TestPlan(t *testing.T) {
Expand Down Expand Up @@ -45,5 +48,44 @@ func TestPlanWithState(t *testing.T) {
t.Fatalf("expected: false, got: %t", hasChanges)
}
})
}

func TestPlanJSON_TF014AndEarlier(t *testing.T) {
versions := []string{testutil.Latest011, testutil.Latest012, testutil.Latest013, testutil.Latest014}

runTestWithVersions(t, "basic", versions, func(t *testing.T, tfv *version.Version, tf *tfexec.Terraform) {
err := tf.Init(context.Background())
if err != nil {
t.Fatalf("error running Init in test directory: %s", err)
}

re := regexp.MustCompile("terraform apply -json was added in 0.15.3")

hasChanges, err := tf.PlanJSON(context.Background(), io.Discard)
if err != nil && !re.MatchString(err.Error()) {
t.Fatalf("error running Apply: %s", err)
}
if hasChanges {
t.Fatalf("expected: false, got: %t", hasChanges)
}
})
}

func TestPlanJSON_TF015AndLater(t *testing.T) {
versions := []string{testutil.Latest015, testutil.Latest_v1, testutil.Latest_v1_1}

runTestWithVersions(t, "basic", versions, func(t *testing.T, tfv *version.Version, tf *tfexec.Terraform) {
err := tf.Init(context.Background())
if err != nil {
t.Fatalf("error running Init in test directory: %s", err)
}

hasChanges, err := tf.PlanJSON(context.Background(), io.Discard)
if err != nil {
t.Fatalf("error running Apply: %s", err)
}
if !hasChanges {
t.Fatalf("expected: true, got: %t", hasChanges)
}
})
}
37 changes: 37 additions & 0 deletions tfexec/internal/e2etest/refresh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package e2etest

import (
"context"
"io"
"regexp"
"testing"

"github.com/hashicorp/go-version"

"github.com/hashicorp/terraform-exec/tfexec"
"github.com/hashicorp/terraform-exec/tfexec/internal/testutil"
)

func TestRefresh(t *testing.T) {
Expand All @@ -27,3 +30,37 @@ func TestRefresh(t *testing.T) {
}
})
}

func TestRefreshJSON_TF014AndEarlier(t *testing.T) {
versions := []string{testutil.Latest011, testutil.Latest012, testutil.Latest013, testutil.Latest014}

runTestWithVersions(t, "basic", versions, func(t *testing.T, tfv *version.Version, tf *tfexec.Terraform) {
err := tf.Init(context.Background())
if err != nil {
t.Fatalf("error running Init in test directory: %s", err)
}

re := regexp.MustCompile("terraform apply -json was added in 0.15.3")

err = tf.RefreshJSON(context.Background(), io.Discard)
if err != nil && !re.MatchString(err.Error()) {
t.Fatalf("error running Apply: %s", err)
}
})
}

func TestRefreshJSON_TF015AndLater(t *testing.T) {
versions := []string{testutil.Latest015, testutil.Latest_v1, testutil.Latest_v1_1}

runTestWithVersions(t, "basic", versions, func(t *testing.T, tfv *version.Version, tf *tfexec.Terraform) {
err := tf.Init(context.Background())
if err != nil {
t.Fatalf("error running Init in test directory: %s", err)
}

err = tf.RefreshJSON(context.Background(), io.Discard)
if err != nil {
t.Fatalf("error running Apply: %s", err)
}
})
}
41 changes: 41 additions & 0 deletions tfexec/internal/e2etest/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,47 @@ func runTest(t *testing.T, fixtureName string, cb func(t *testing.T, tfVersion *
runTestVersions(t, versions, fixtureName, cb)
}

func runTestWithVersions(t *testing.T, fixtureName string, versions []string, cb func(t *testing.T, tfVersion *version.Version, tf *tfexec.Terraform)) {
t.Helper()

if override := os.Getenv("TFEXEC_E2ETEST_VERSIONS"); override != "" {
versions = strings.Split(override, ",")
}

// If the env var TFEXEC_E2ETEST_TERRAFORM_PATH is set to the path of a
// valid Terraform executable, only tests appropriate to that
// executable's version will be run.
if localBinPath := os.Getenv("TFEXEC_E2ETEST_TERRAFORM_PATH"); localBinPath != "" {
// By convention, every new Terraform struct is given a clean
// temp dir, even if we are only invoking tf.Version(). This
// prevents any possible confusion that could result from
// reusing an os.TempDir() (for example) that already contained
// Terraform files.
td, err := ioutil.TempDir("", "tf")
if err != nil {
t.Fatalf("error creating temporary test directory: %s", err)
}
t.Cleanup(func() {
os.RemoveAll(td)
})
ltf, err := tfexec.NewTerraform(td, localBinPath)
if err != nil {
t.Fatal(err)
}

ltf.SetAppendUserAgent("tfexec-e2etest")

lVersion, _, err := ltf.Version(context.Background(), false)
if err != nil {
t.Fatalf("unable to determine version of Terraform binary at %s: %s", localBinPath, err)
}

versions = []string{lVersion.String()}
}

runTestVersions(t, versions, fixtureName, cb)
}

func runTestVersions(t *testing.T, versions []string, fixtureName string, cb func(t *testing.T, tfVersion *version.Version, tf *tfexec.Terraform)) {
t.Helper()

Expand Down
9 changes: 9 additions & 0 deletions tfexec/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,21 @@ func (tf *Terraform) Plan(ctx context.Context, opts ...PlanOption) (bool, error)
// PlanJSON executes `terraform plan` with the specified options as well as the
// `-json` flag and waits for it to complete.
//
// Using the `-json` flag will result in
// [machine-readable](https://developer.hashicorp.com/terraform/internals/machine-readable-ui)
// JSON being written to the supplied `io.Writer`.
//
// The returned boolean is false when the plan diff is empty (no changes) and
// true when the plan diff is non-empty (changes present).
//
// The returned error is nil if `terraform plan` has been executed and exits
// with either 0 or 2.
func (tf *Terraform) PlanJSON(ctx context.Context, w io.Writer, opts ...PlanOption) (bool, error) {
err := tf.compatible(ctx, tf0_15_3, nil)
if err != nil {
return false, fmt.Errorf("terraform apply -json was added in 0.15.3: %w", err)
}

tf.SetStdout(w)

cmd, err := tf.planJSONCmd(ctx, opts...)
Expand Down
9 changes: 9 additions & 0 deletions tfexec/refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tfexec

import (
"context"
"fmt"
"io"
"os/exec"
"strconv"
Expand Down Expand Up @@ -80,7 +81,15 @@ func (tf *Terraform) Refresh(ctx context.Context, opts ...RefreshCmdOption) erro
}

// RefreshJSON represents the Terraform refresh subcommand with the `-json` flag.
// Using the `-json` flag will result in
// [machine-readable](https://developer.hashicorp.com/terraform/internals/machine-readable-ui)
// JSON being written to the supplied `io.Writer`.
func (tf *Terraform) RefreshJSON(ctx context.Context, w io.Writer, opts ...RefreshCmdOption) error {
err := tf.compatible(ctx, tf0_15_3, nil)
if err != nil {
return fmt.Errorf("terraform apply -json was added in 0.15.3: %w", err)
}

tf.SetStdout(w)

cmd, err := tf.refreshJSONCmd(ctx, opts...)
Expand Down
1 change: 1 addition & 0 deletions tfexec/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var (
tf0_14_0 = version.Must(version.NewVersion("0.14.0"))
tf0_15_0 = version.Must(version.NewVersion("0.15.0"))
tf0_15_2 = version.Must(version.NewVersion("0.15.2"))
tf0_15_3 = version.Must(version.NewVersion("0.15.3"))
tf1_1_0 = version.Must(version.NewVersion("1.1.0"))
)

Expand Down

0 comments on commit e2c259b

Please sign in to comment.