e2e: Reuse a single experimental build of Terraform in tests for experimental features (#38678)

In the e2etest package tests reuse a single build of Terraform accessible via this global scope var: `terraformBin` in internal/command/e2etest/main_test.go.  A setup function (`func TestMain(m *testing.M)` in the same file) runs once before any tests run, makes a Terraform binary, and enables tests to reuse that binary like this:

```go
fixturePath := filepath.Join("testdata", "full-workflow-null") 
 tf := e2e.NewBinary(t, terraformBin, fixturePath) 
```

This change updates that process to also build a binary with experiments enabled, which can be reused in tests that cover experimental features. By preventing experimental tests from all building their separate experimental builds of Terraform we can reduce the package's test suite duration by about half.

---------

Co-authored-by: Daniel Banck <dbanck@users.noreply.github.com>
pull/38679/head
Sarah French 5 days ago committed by GitHub
parent b2fc2caf72
commit 7615b9397a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -471,10 +471,8 @@ func TestInitStateStoreUsingUnmanagedProvider(t *testing.T) {
}
}
t.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
fixturePath := filepath.Join("testdata", "initialized-directory-with-state-store-unmanaged")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
// Assert the existing lockfile describes the older version of the provider.
lockFile := tf.Path(".terraform.lock.hcl")

@ -12,7 +12,13 @@ import (
"github.com/hashicorp/terraform/internal/e2e"
)
var terraformBin string
var (
// Path to a build of Terraform reused in multiple E2E tests. Experiments are disabled.
terraformBin string
// Path to a build of Terraform reused in multiple E2E tests. Experiments are enabled.
experimentalTerraformBin string
)
// canRunGoBuild is a short-term compromise to account for the fact that we
// have a small number of tests that work by building helper programs using
@ -48,11 +54,16 @@ func setup() func() {
return func() {}
}
// Make a non-experimental TF executable available for use in tests
tmpFilename := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
// Make the executable available for use in tests
terraformBin = tmpFilename
// Make an experimental TF executable available for use in tests
os.Setenv(e2e.TestExperimentFlag, "true")
defer os.Unsetenv(e2e.TestExperimentFlag)
tmpExperimentalFilename := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
experimentalTerraformBin = tmpExperimentalFilename
// Tests running in the ad-hoc testing mode are allowed to use "go build"
// and similar to produce other test executables.
// (See the comment on this variable's declaration for more information.)
@ -60,6 +71,7 @@ func setup() func() {
return func() {
os.Remove(tmpFilename)
os.Remove(tmpExperimentalFilename)
}
}

@ -38,9 +38,7 @@ func TestPrimary_stateStore_unmanaged_separatePlan(t *testing.T) {
fixturePath := filepath.Join("testdata", "full-workflow-with-state-store-fs")
t.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
reattachStr, provider := reattachedProviderForTest(t, addrs.NewDefaultProvider("simple6"), 6)
tf.AddEnv("TF_REATTACH_PROVIDERS=" + string(reattachStr))
@ -121,11 +119,8 @@ func TestPrimary_stateStore_workspaceCmd(t *testing.T) {
t.Skip("can't run without building a new provider executable")
}
t.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
fixturePath := filepath.Join("testdata", "full-workflow-with-state-store-fs")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
workspaceDirName := "states" // See workspace_dir value in the configuration
// In order to test integration with PSS we need a provider plugin implementing a state store.
@ -226,11 +221,8 @@ func TestPrimary_stateStore_stateCmds(t *testing.T) {
t.Skip("can't run without building a new provider executable")
}
t.Setenv(e2e.TestExperimentFlag, "true")
tfBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
fixturePath := filepath.Join("testdata", "initialized-directory-with-state-store-fs")
tf := e2e.NewBinary(t, tfBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
workspaceDirName := "states" // see test fixture value for workspace_dir
@ -302,11 +294,8 @@ func TestPrimary_stateStore_outputCmd(t *testing.T) {
t.Skip("can't run without building a new provider executable")
}
t.Setenv(e2e.TestExperimentFlag, "true")
tfBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
fixturePath := filepath.Join("testdata", "initialized-directory-with-state-store-fs")
tf := e2e.NewBinary(t, tfBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
workspaceDirName := "states" // see test fixture value for workspace_dir
@ -371,11 +360,8 @@ func TestPrimary_stateStore_showCmd(t *testing.T) {
t.Skip("can't run without building a new provider executable")
}
t.Setenv(e2e.TestExperimentFlag, "true")
tfBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
fixturePath := filepath.Join("testdata", "initialized-directory-with-state-store-fs")
tf := e2e.NewBinary(t, tfBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
workspaceDirName := "states" // see test fixture value for workspace_dir
@ -496,10 +482,8 @@ func TestPrimary_stateStore_providerCmds(t *testing.T) {
t.Skip("can't run without building a new provider executable")
}
t.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
fixturePath := filepath.Join("testdata", "full-workflow-with-state-store-fs")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
workspaceDirName := "states" // See workspace_dir value in the configuration
// Add a state file describing a resource from the simple (v5) provider, so

@ -247,11 +247,8 @@ func TestPrimary_stateStore(t *testing.T) {
t.Skip("can't run without building a new provider executable")
}
t.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
fixturePath := filepath.Join("testdata", "full-workflow-with-state-store-fs")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
workspaceDirName := "states" // See workspace_dir value in the configuration
// In order to test integration with PSS we need a provider plugin implementing a state store.
@ -321,11 +318,8 @@ func TestPrimary_stateStore_planFile(t *testing.T) {
t.Skip("can't run without building a new provider executable")
}
t.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
fixturePath := filepath.Join("testdata", "full-workflow-with-state-store-fs")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
// In order to test integration with PSS we need a provider plugin implementing a state store.
// Here will build the simple6 (built with protocol v6) provider, which implements PSS.
@ -410,9 +404,7 @@ func TestPrimary_stateStore_swapProviderSupplyMode_betweenInitAndPlanApply(t *te
fixturePath := filepath.Join("testdata", "full-workflow-with-state-store-fs")
t.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
reattachStr, _ := reattachedProviderForTest(t, addrs.NewDefaultProvider("simple6"), 6)
tf.AddEnv("TF_REATTACH_PROVIDERS=" + string(reattachStr))
@ -493,9 +485,7 @@ func TestPrimary_stateStore_swapProviderSupplyMode_betweenInitAndPlanApply(t *te
fixturePath := filepath.Join("testdata", "full-workflow-with-state-store-fs")
t.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
// Build provider binaries that will be used via a filesystem mirror/-plugin-dir flag.
simple6Provider := filepath.Join(tf.WorkDir(), "terraform-provider-simple6")
@ -589,9 +579,7 @@ func TestPrimary_stateStore_swapProviderSupplyMode_betweenInitAndPlanApply(t *te
fixturePath := filepath.Join("testdata", "full-workflow-with-state-store-fs")
t.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
// Build a new provider binary and direct Terraform to use it via CLI configuration file.
simple6Provider := filepath.Join(tf.WorkDir(), "terraform-provider-simple6")
@ -697,9 +685,7 @@ func TestPrimary_stateStore_swapProviderSupplyMode_betweenSuccessiveInits(t *tes
fixturePath := filepath.Join("testdata", "full-workflow-with-state-store-fs")
t.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
reattachStr, _ := reattachedProviderForTest(t, addrs.NewDefaultProvider("simple6"), 6)
tf.AddEnv("TF_REATTACH_PROVIDERS=" + string(reattachStr))
@ -774,9 +760,7 @@ func TestPrimary_stateStore_swapProviderSupplyMode_betweenSuccessiveInits(t *tes
fixturePath := filepath.Join("testdata", "full-workflow-with-state-store-fs")
t.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
// Build provider binaries that will be used via a filesystem mirror/-plugin-dir flag.
simple6Provider := filepath.Join(tf.WorkDir(), "terraform-provider-simple6")
@ -864,9 +848,7 @@ func TestPrimary_stateStore_swapProviderSupplyMode_betweenSuccessiveInits(t *tes
fixturePath := filepath.Join("testdata", "full-workflow-with-state-store-fs")
t.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
tf := e2e.NewBinary(t, terraformBin, fixturePath)
tf := e2e.NewBinary(t, experimentalTerraformBin, fixturePath)
// Build a new provider binary and direct Terraform to use it via CLI configuration file.
simple6Provider := filepath.Join(tf.WorkDir(), "terraform-provider-simple6")

@ -7,7 +7,6 @@ import (
"context"
"encoding/json"
"io"
"os"
"path/filepath"
"regexp"
"strings"
@ -53,8 +52,6 @@ func TestUnmanagedQuery(t *testing.T) {
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
os.Setenv(e2e.TestExperimentFlag, "true")
terraformBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
fixturePath := filepath.Join("testdata", "query-provider")
tf := e2e.NewBinary(t, terraformBin, fixturePath)

Loading…
Cancel
Save