[WIP] Re-enable the end-to-end tests (#20044)
* internal/initwd: Allow deprecated relative module paths In Terraform 0.11 we deprecated this form but didn't have any explicit warning for it. Now we'll still accept it but generate a warning. In a future major release we will drop this form altogether, since it is ambiguous with registry module source addresses. This codepath is covered by the command/e2etest suite. * e2e: Skip copying .exists file, if present We use this only in the "empty" test fixture in order to let git know that the directory exists. We need to skip copying it so that we can test "terraform init -from-module=...", which expects to find an empty directory. * command/e2etests: Re-enable and fix up the e2etest "acctests" We disabled all of the tests that accessed remote services like the Terraform Registry while they were being updated to support the new protocols we now expect. With those services now in place, we can re-enable these tests. Some details of exactly what output we print, etc, have intentionally changed since these tests were last updated. * e2e: refactor for modern states and plans * command/e2etest: re-enable e2etests and update for tf 0.12 compatibility plugin/discovery: mkdirAll instead of mkdir when creating cache dir
This commit is contained in:
parent
4e78d97f8f
commit
eed605ac05
|
@ -7,7 +7,6 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/hashicorp/terraform/e2e"
|
||||
)
|
||||
|
||||
|
@ -41,11 +40,11 @@ func TestPlanApplyInAutomation(t *testing.T) {
|
|||
|
||||
// Make sure we actually downloaded the plugins, rather than picking up
|
||||
// copies that might be already installed globally on the system.
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"template\"") {
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"template") {
|
||||
t.Errorf("template provider download message is missing from init output:\n%s", stdout)
|
||||
t.Logf("(this can happen if you have a copy of the plugin in one of the global plugin search dirs)")
|
||||
}
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"null\"") {
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"null") {
|
||||
t.Errorf("null provider download message is missing from init output:\n%s", stdout)
|
||||
t.Logf("(this can happen if you have a copy of the plugin in one of the global plugin search dirs)")
|
||||
}
|
||||
|
@ -71,14 +70,11 @@ func TestPlanApplyInAutomation(t *testing.T) {
|
|||
t.Fatalf("failed to read plan file: %s", err)
|
||||
}
|
||||
|
||||
stateResources := plan.State.RootModule().Resources
|
||||
diffResources := plan.Diff.RootModule().Resources
|
||||
// stateResources := plan.Changes.Resources
|
||||
diffResources := plan.Changes.Resources
|
||||
|
||||
if len(stateResources) != 1 || stateResources["data.template_file.test"] == nil {
|
||||
t.Errorf("incorrect state in plan; want just data.template_file.test to have been rendered, but have:\n%s", spew.Sdump(stateResources))
|
||||
}
|
||||
if len(diffResources) != 1 || diffResources["null_resource.test"] == nil {
|
||||
t.Errorf("incorrect diff in plan; want just null_resource.test to have been rendered, but have:\n%s", spew.Sdump(diffResources))
|
||||
if len(diffResources) != 1 || diffResources[0].Addr.String() != "null_resource.test" {
|
||||
t.Errorf("incorrect number of resources in plan")
|
||||
}
|
||||
|
||||
//// APPLY
|
||||
|
@ -96,9 +92,9 @@ func TestPlanApplyInAutomation(t *testing.T) {
|
|||
t.Fatalf("failed to read state file: %s", err)
|
||||
}
|
||||
|
||||
stateResources = state.RootModule().Resources
|
||||
stateResources := state.RootModule().Resources
|
||||
var gotResources []string
|
||||
for n := range stateResources {
|
||||
for n, _ := range stateResources {
|
||||
gotResources = append(gotResources, n)
|
||||
}
|
||||
sort.Strings(gotResources)
|
||||
|
@ -139,11 +135,11 @@ func TestAutoApplyInAutomation(t *testing.T) {
|
|||
|
||||
// Make sure we actually downloaded the plugins, rather than picking up
|
||||
// copies that might be already installed globally on the system.
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"template\"") {
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"template") {
|
||||
t.Errorf("template provider download message is missing from init output:\n%s", stdout)
|
||||
t.Logf("(this can happen if you have a copy of the plugin in one of the global plugin search dirs)")
|
||||
}
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"null\"") {
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"null") {
|
||||
t.Errorf("null provider download message is missing from init output:\n%s", stdout)
|
||||
t.Logf("(this can happen if you have a copy of the plugin in one of the global plugin search dirs)")
|
||||
}
|
||||
|
@ -206,11 +202,11 @@ func TestPlanOnlyInAutomation(t *testing.T) {
|
|||
|
||||
// Make sure we actually downloaded the plugins, rather than picking up
|
||||
// copies that might be already installed globally on the system.
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"template\"") {
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"template") {
|
||||
t.Errorf("template provider download message is missing from init output:\n%s", stdout)
|
||||
t.Logf("(this can happen if you have a copy of the plugin in one of the global plugin search dirs)")
|
||||
}
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"null\"") {
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"null") {
|
||||
t.Errorf("null provider download message is missing from init output:\n%s", stdout)
|
||||
t.Logf("(this can happen if you have a copy of the plugin in one of the global plugin search dirs)")
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ func TestInitProviders(t *testing.T) {
|
|||
t.Errorf("success message is missing from output:\n%s", stdout)
|
||||
}
|
||||
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"template\"") {
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"template\" (terraform-providers/template)") {
|
||||
t.Errorf("provider download message is missing from output:\n%s", stdout)
|
||||
t.Logf("(this can happen if you have a copy of the plugin in one of the global plugin search dirs)")
|
||||
}
|
||||
|
@ -112,10 +112,10 @@ func TestInitProviders_pluginCache(t *testing.T) {
|
|||
|
||||
stderr := cmd.Stderr.(*bytes.Buffer).String()
|
||||
if stderr != "" {
|
||||
t.Errorf("unexpected stderr output:\n%s", stderr)
|
||||
t.Errorf("unexpected stderr output:\n%s\n", stderr)
|
||||
}
|
||||
|
||||
path := fmt.Sprintf(".terraform/plugins/%s_%s/terraform-provider-template_v0.1.0_x4", runtime.GOOS, runtime.GOARCH)
|
||||
path := fmt.Sprintf(".terraform/plugins/%s_%s/terraform-provider-template_v2.1.0_x4", runtime.GOOS, runtime.GOARCH)
|
||||
content, err := tf.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read installed plugin from %s: %s", path, err)
|
||||
|
@ -124,11 +124,11 @@ func TestInitProviders_pluginCache(t *testing.T) {
|
|||
t.Errorf("template plugin was not installed from local cache")
|
||||
}
|
||||
|
||||
if !tf.FileExists(fmt.Sprintf(".terraform/plugins/%s_%s/terraform-provider-null_v0.1.0_x4", runtime.GOOS, runtime.GOARCH)) {
|
||||
if !tf.FileExists(fmt.Sprintf(".terraform/plugins/%s_%s/terraform-provider-null_v2.1.0_x4", runtime.GOOS, runtime.GOARCH)) {
|
||||
t.Errorf("null plugin was not installed")
|
||||
}
|
||||
|
||||
if !tf.FileExists(fmt.Sprintf("cache/%s_%s/terraform-provider-null_v0.1.0_x4", runtime.GOOS, runtime.GOARCH)) {
|
||||
if !tf.FileExists(fmt.Sprintf("cache/%s_%s/terraform-provider-null_v2.1.0_x4", runtime.GOOS, runtime.GOARCH)) {
|
||||
t.Errorf("null plugin is not in cache after install")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,10 +56,4 @@ func skipIfCannotAccessNetwork(t *testing.T) {
|
|||
if !canAccessNetwork() {
|
||||
t.Skip("network access not allowed; use TF_ACC=1 to enable")
|
||||
}
|
||||
|
||||
// During the early part of the Terraform v0.12 release process, certain
|
||||
// upstream resources are not yet ready to support it and so these
|
||||
// tests cannot be run. These will be re-enabled prior to Terraform v0.12.0
|
||||
// final.
|
||||
t.Skip("all tests with external network access are temporarily disabled until upstream services are updated")
|
||||
}
|
||||
|
|
|
@ -38,11 +38,11 @@ func TestPrimarySeparatePlan(t *testing.T) {
|
|||
|
||||
// Make sure we actually downloaded the plugins, rather than picking up
|
||||
// copies that might be already installed globally on the system.
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"template\"") {
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"template") {
|
||||
t.Errorf("template provider download message is missing from init output:\n%s", stdout)
|
||||
t.Logf("(this can happen if you have a copy of the plugin in one of the global plugin search dirs)")
|
||||
}
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"null\"") {
|
||||
if !strings.Contains(stdout, "- Downloading plugin for provider \"null") {
|
||||
t.Errorf("null provider download message is missing from init output:\n%s", stdout)
|
||||
t.Logf("(this can happen if you have a copy of the plugin in one of the global plugin search dirs)")
|
||||
}
|
||||
|
@ -69,13 +69,8 @@ func TestPrimarySeparatePlan(t *testing.T) {
|
|||
t.Fatalf("failed to read plan file: %s", err)
|
||||
}
|
||||
|
||||
stateResources := plan.State.RootModule().Resources
|
||||
diffResources := plan.Diff.RootModule().Resources
|
||||
|
||||
if len(stateResources) != 1 || stateResources["data.template_file.test"] == nil {
|
||||
t.Errorf("incorrect state in plan; want just data.template_file.test to have been rendered, but have:\n%s", spew.Sdump(stateResources))
|
||||
}
|
||||
if len(diffResources) != 1 || diffResources["null_resource.test"] == nil {
|
||||
diffResources := plan.Changes.Resources
|
||||
if len(diffResources) != 1 || diffResources[0].Addr.String() != "null_resource.test" {
|
||||
t.Errorf("incorrect diff in plan; want just null_resource.test to have been rendered, but have:\n%s", spew.Sdump(diffResources))
|
||||
}
|
||||
|
||||
|
@ -94,9 +89,9 @@ func TestPrimarySeparatePlan(t *testing.T) {
|
|||
t.Fatalf("failed to read state file: %s", err)
|
||||
}
|
||||
|
||||
stateResources = state.RootModule().Resources
|
||||
stateResources := state.RootModule().Resources
|
||||
var gotResources []string
|
||||
for n := range stateResources {
|
||||
for n, _ := range stateResources {
|
||||
gotResources = append(gotResources, n)
|
||||
}
|
||||
sort.Strings(gotResources)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
provider "template" {
|
||||
version = "0.1.0"
|
||||
version = "2.1.0"
|
||||
}
|
||||
|
||||
provider "null" {
|
||||
version = "0.1.0"
|
||||
version = "2.1.0"
|
||||
}
|
||||
|
|
50
e2e/e2e.go
50
e2e/e2e.go
|
@ -9,7 +9,10 @@ import (
|
|||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
tfcore "github.com/hashicorp/terraform/terraform"
|
||||
"github.com/hashicorp/terraform/plans"
|
||||
"github.com/hashicorp/terraform/plans/planfile"
|
||||
"github.com/hashicorp/terraform/states"
|
||||
"github.com/hashicorp/terraform/states/statefile"
|
||||
)
|
||||
|
||||
// Type binary represents the combination of a compiled binary
|
||||
|
@ -48,6 +51,12 @@ func NewBinary(binaryPath, workingDir string) *binary {
|
|||
return nil
|
||||
}
|
||||
|
||||
if filepath.Base(path) == ".exists" {
|
||||
// We use this file just to let git know the "empty" fixture
|
||||
// exists. It is not used by any test.
|
||||
return nil
|
||||
}
|
||||
|
||||
srcFn := path
|
||||
|
||||
path, err = filepath.Rel(workingDir, path)
|
||||
|
@ -170,43 +179,52 @@ func (b *binary) FileExists(path ...string) bool {
|
|||
|
||||
// LocalState is a helper for easily reading the local backend's state file
|
||||
// terraform.tfstate from the working directory.
|
||||
func (b *binary) LocalState() (*tfcore.State, error) {
|
||||
func (b *binary) LocalState() (*states.State, error) {
|
||||
f, err := b.OpenFile("terraform.tfstate")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
return tfcore.ReadState(f)
|
||||
|
||||
stateFile, err := statefile.Read(f)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error reading statefile: %s", err)
|
||||
}
|
||||
return stateFile.State, nil
|
||||
}
|
||||
|
||||
// Plan is a helper for easily reading a plan file from the working directory.
|
||||
func (b *binary) Plan(path ...string) (*tfcore.Plan, error) {
|
||||
f, err := b.OpenFile(path...)
|
||||
func (b *binary) Plan(path string) (*plans.Plan, error) {
|
||||
path = b.Path(path)
|
||||
pr, err := planfile.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
return tfcore.ReadPlan(f)
|
||||
plan, err := pr.ReadPlan()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return plan, nil
|
||||
}
|
||||
|
||||
// SetLocalState is a helper for easily writing to the file the local backend
|
||||
// uses for state in the working directory. This does not go through the
|
||||
// actual local backend code, so processing such as management of serials
|
||||
// does not apply and the given state will simply be written verbatim.
|
||||
func (b *binary) SetLocalState(state *tfcore.State) error {
|
||||
func (b *binary) SetLocalState(state *states.State) error {
|
||||
path := b.Path("terraform.tfstate")
|
||||
f, err := os.OpenFile(path, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to create temporary state file %s: %s", path, err)
|
||||
}
|
||||
defer func() {
|
||||
err := f.Close()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to close state file after writing: %s", err))
|
||||
}
|
||||
}()
|
||||
defer f.Close()
|
||||
|
||||
return tfcore.WriteState(state, f)
|
||||
sf := &statefile.File{
|
||||
Serial: 0,
|
||||
Lineage: "fake-for-testing",
|
||||
State: state,
|
||||
}
|
||||
return statefile.Write(sf, f)
|
||||
}
|
||||
|
||||
// Close cleans up the temporary resources associated with the object,
|
||||
|
|
|
@ -298,7 +298,7 @@ func (i *ProviderInstaller) install(provider string, version Version, url string
|
|||
// check if the target dir exists, and create it if not
|
||||
var err error
|
||||
if _, StatErr := os.Stat(i.Dir); os.IsNotExist(StatErr) {
|
||||
err = os.Mkdir(i.Dir, 0700)
|
||||
err = os.MkdirAll(i.Dir, 0700)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in New Issue