From 89d0944e5bf134fecfb88470a796080421ae631a Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Sun, 14 Oct 2018 16:07:42 -0700 Subject: [PATCH] command: Fix even more of the "terraform refresh" tests --- command/command_test.go | 5 +- command/refresh_test.go | 534 ++++++++++++++++++---------------------- 2 files changed, 242 insertions(+), 297 deletions(-) diff --git a/command/command_test.go b/command/command_test.go index 55004ee6e..26a96123e 100644 --- a/command/command_test.go +++ b/command/command_test.go @@ -242,7 +242,10 @@ func testState() *states.State { Name: "foo", }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), &states.ResourceInstanceObjectSrc{ - AttrsJSON: []byte(`{"id":"bar"}`), + // The weird whitespace here is reflective of how this would + // get written out in a real state file, due to the indentation + // of all of the containing wrapping objects and arrays. + AttrsJSON: []byte("{\n \"id\": \"bar\"\n }"), Status: states.ObjectReady, }, addrs.ProviderConfig{ diff --git a/command/refresh_test.go b/command/refresh_test.go index 9a4360e08..a91f2479a 100644 --- a/command/refresh_test.go +++ b/command/refresh_test.go @@ -7,17 +7,21 @@ import ( "io/ioutil" "os" "path/filepath" + "reflect" "strings" "testing" + "github.com/davecgh/go-spew/spew" "github.com/mitchellh/cli" "github.com/zclconf/go-cty/cty" + "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/helper/copy" "github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states/statefile" + "github.com/hashicorp/terraform/states/statemgr" "github.com/hashicorp/terraform/terraform" ) @@ -209,164 +213,142 @@ func TestRefresh_cwd(t *testing.T) { } func TestRefresh_defaultState(t *testing.T) { - t.Fatal("not yet updated for new provider types") - /* - originalState := testState() + originalState := testState() - // Write the state file in a temporary directory with the - // default filename. - statePath := testStateFile(t, originalState) + // Write the state file in a temporary directory with the + // default filename. + statePath := testStateFile(t, originalState) - localState := &state.LocalState{Path: statePath} - if err := localState.RefreshState(); err != nil { - t.Fatal(err) - } - s := localState.State() - if s == nil { - t.Fatal("empty test state") - } - serial := s.Serial + localState := statemgr.NewFilesystem(statePath) + if err := localState.RefreshState(); err != nil { + t.Fatal(err) + } + s := localState.State() + if s == nil { + t.Fatal("empty test state") + } - // Change to that directory - cwd, err := os.Getwd() - if err != nil { - t.Fatalf("err: %s", err) - } - if err := os.Chdir(filepath.Dir(statePath)); err != nil { - t.Fatalf("err: %s", err) - } - defer os.Chdir(cwd) + // Change to that directory + cwd, err := os.Getwd() + if err != nil { + t.Fatalf("err: %s", err) + } + if err := os.Chdir(filepath.Dir(statePath)); err != nil { + t.Fatalf("err: %s", err) + } + defer os.Chdir(cwd) - p := testProvider() - ui := new(cli.MockUi) - c := &RefreshCommand{ - Meta: Meta{ - testingOverrides: metaOverridesForProvider(p), - Ui: ui, - }, - } + p := testProvider() + ui := new(cli.MockUi) + c := &RefreshCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: ui, + }, + } - p.GetSchemaReturn = refreshFixtureSchema() - p.RefreshFn = nil - p.RefreshReturn = newInstanceState("yes") + p.GetSchemaReturn = refreshFixtureSchema() + p.ReadResourceFn = nil + p.ReadResourceResponse = providers.ReadResourceResponse{ + NewState: cty.ObjectVal(map[string]cty.Value{ + "id": cty.StringVal("yes"), + }), + } - args := []string{ - "-state", statePath, - testFixturePath("refresh"), - } - if code := c.Run(args); code != 0 { - t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) - } + args := []string{ + "-state", statePath, + testFixturePath("refresh"), + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } - if !p.RefreshCalled { - t.Fatal("refresh should be called") - } + if !p.ReadResourceCalled { + t.Fatal("ReadResource should have been called") + } - newState := testStateRead(t, statePath) + newState := testStateRead(t, statePath) - actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current - expected := p.RefreshReturn - if !reflect.DeepEqual(actual, expected) { - t.Logf("expected:\n%#v", expected) - t.Fatalf("bad:\n%#v", actual) - } + actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current + expected := &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + AttrsJSON: []byte("{\n \"ami\": null,\n \"id\": \"yes\"\n }"), + Dependencies: []addrs.Referenceable{}, + } + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("wrong new object\ngot: %swant: %s", spew.Sdump(actual), spew.Sdump(expected)) + } - backupState := testStateRead(t, statePath+DefaultBackupExtension) + backupState := testStateRead(t, statePath+DefaultBackupExtension) - actual = backupState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current - expected = originalState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("bad: %#v", actual) - } - */ + actual = backupState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current + expected = originalState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("wrong new object\ngot: %swant: %s", spew.Sdump(actual), spew.Sdump(expected)) + } } func TestRefresh_outPath(t *testing.T) { - t.Fatal("not yet updated for new provider types") - /* - state := testState() - statePath := testStateFile(t, state) + state := testState() + statePath := testStateFile(t, state) - // Output path - outf, err := ioutil.TempFile(testingDir, "tf") - if err != nil { - t.Fatalf("err: %s", err) - } - outPath := outf.Name() - outf.Close() - os.Remove(outPath) + // Output path + outf, err := ioutil.TempFile(testingDir, "tf") + if err != nil { + t.Fatalf("err: %s", err) + } + outPath := outf.Name() + outf.Close() + os.Remove(outPath) - p := testProvider() - ui := new(cli.MockUi) - c := &RefreshCommand{ - Meta: Meta{ - testingOverrides: metaOverridesForProvider(p), - Ui: ui, - }, - } + p := testProvider() + ui := new(cli.MockUi) + c := &RefreshCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: ui, + }, + } - p.GetSchemaReturn = refreshFixtureSchema() - p.RefreshFn = nil - p.RefreshReturn = newInstanceState("yes") + p.GetSchemaReturn = refreshFixtureSchema() + p.ReadResourceFn = nil + p.ReadResourceResponse = providers.ReadResourceResponse{ + NewState: cty.ObjectVal(map[string]cty.Value{ + "id": cty.StringVal("yes"), + }), + } - args := []string{ - "-state", statePath, - "-state-out", outPath, - testFixturePath("refresh"), - } - if code := c.Run(args); code != 0 { - t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) - } + args := []string{ + "-state", statePath, + "-state-out", outPath, + testFixturePath("refresh"), + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } - f, err := os.Open(statePath) - if err != nil { - t.Fatalf("err: %s", err) - } + newState := testStateRead(t, statePath) + if !reflect.DeepEqual(newState, state) { + t.Fatalf("bad: %#v", newState) + } - newState, err := terraform.ReadState(f) - f.Close() - if err != nil { - t.Fatalf("err: %s", err) - } + newState = testStateRead(t, outPath) + actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current + expected := &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + AttrsJSON: []byte("{\n \"ami\": null,\n \"id\": \"yes\"\n }"), + Dependencies: []addrs.Referenceable{}, + } + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("wrong new object\ngot: %swant: %s", spew.Sdump(actual), spew.Sdump(expected)) + } - if !reflect.DeepEqual(newState, state) { - t.Fatalf("bad: %#v", newState) - } - - f, err = os.Open(outPath) - if err != nil { - t.Fatalf("err: %s", err) - } - - newState, err = terraform.ReadState(f) - f.Close() - if err != nil { - t.Fatalf("err: %s", err) - } - - actual := newState.RootModule().Resources["test_instance.foo"].Primary - expected := p.RefreshReturn - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("bad: %#v", actual) - } - - f, err = os.Open(outPath + DefaultBackupExtension) - if err != nil { - t.Fatalf("err: %s", err) - } - - backupState, err := terraform.ReadState(f) - f.Close() - if err != nil { - t.Fatalf("err: %s", err) - } - - actualStr := strings.TrimSpace(backupState.String()) - expectedStr := strings.TrimSpace(state.String()) - if actualStr != expectedStr { - t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr) - } - */ + backupState := testStateRead(t, outPath + DefaultBackupExtension) + actualStr := strings.TrimSpace(backupState.String()) + expectedStr := strings.TrimSpace(state.String()) + if actualStr != expectedStr { + t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr) + } } func TestRefresh_var(t *testing.T) { @@ -520,183 +502,143 @@ func TestRefresh_varsUnset(t *testing.T) { } func TestRefresh_backup(t *testing.T) { - t.Fatal("not yet updated for new provider types") - /* - state := testState() - statePath := testStateFile(t, state) + state := testState() + statePath := testStateFile(t, state) - // Output path - outf, err := ioutil.TempFile(testingDir, "tf") - if err != nil { - t.Fatalf("err: %s", err) - } - outPath := outf.Name() - outf.Close() - os.Remove(outPath) + // Output path + outf, err := ioutil.TempFile(testingDir, "tf") + if err != nil { + t.Fatalf("err: %s", err) + } + outPath := outf.Name() + outf.Close() + os.Remove(outPath) - // Backup path - backupf, err := ioutil.TempFile(testingDir, "tf") - if err != nil { - t.Fatalf("err: %s", err) - } - backupPath := backupf.Name() - backupf.Close() - os.Remove(backupPath) + // Backup path + backupf, err := ioutil.TempFile(testingDir, "tf") + if err != nil { + t.Fatalf("err: %s", err) + } + backupPath := backupf.Name() + backupf.Close() + os.Remove(backupPath) - p := testProvider() - ui := new(cli.MockUi) - c := &RefreshCommand{ - Meta: Meta{ - testingOverrides: metaOverridesForProvider(p), - Ui: ui, - }, - } + p := testProvider() + ui := new(cli.MockUi) + c := &RefreshCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: ui, + }, + } - p.GetSchemaReturn = refreshFixtureSchema() - p.RefreshFn = nil - p.RefreshReturn = newInstanceState("yes") + p.GetSchemaReturn = refreshFixtureSchema() + p.ReadResourceFn = nil + p.ReadResourceResponse = providers.ReadResourceResponse{ + NewState: cty.ObjectVal(map[string]cty.Value{ + "id": cty.StringVal("changed"), + }), + } - args := []string{ - "-state", statePath, - "-state-out", outPath, - "-backup", backupPath, - testFixturePath("refresh"), - } - if code := c.Run(args); code != 0 { - t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) - } + args := []string{ + "-state", statePath, + "-state-out", outPath, + "-backup", backupPath, + testFixturePath("refresh"), + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } - f, err := os.Open(statePath) - if err != nil { - t.Fatalf("err: %s", err) - } + newState := testStateRead(t, statePath) + if !reflect.DeepEqual(newState, state) { + t.Fatalf("bad: %#v", newState) + } - newState, err := terraform.ReadState(f) - f.Close() - if err != nil { - t.Fatalf("err: %s", err) - } + newState = testStateRead(t, outPath) + actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current + expected := &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + AttrsJSON: []byte("{\n \"ami\": null,\n \"id\": \"changed\"\n }"), + Dependencies: []addrs.Referenceable{}, + } + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("wrong new object\ngot: %swant: %s", spew.Sdump(actual), spew.Sdump(expected)) + } - if !reflect.DeepEqual(newState, state) { - t.Fatalf("bad: %#v", newState) - } - - f, err = os.Open(outPath) - if err != nil { - t.Fatalf("err: %s", err) - } - - newState, err = terraform.ReadState(f) - f.Close() - if err != nil { - t.Fatalf("err: %s", err) - } - - actual := newState.RootModule().Resources["test_instance.foo"].Primary - expected := p.RefreshReturn - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("bad: %#v", actual) - } - - f, err = os.Open(backupPath) - if err != nil { - t.Fatalf("err: %s", err) - } - - backupState, err := terraform.ReadState(f) - f.Close() - if err != nil { - t.Fatalf("err: %s", err) - } - - actualStr := strings.TrimSpace(backupState.String()) - expectedStr := strings.TrimSpace(state.String()) - if actualStr != expectedStr { - t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr) - } - */ + backupState := testStateRead(t, outPath + DefaultBackupExtension) + actualStr := strings.TrimSpace(backupState.String()) + expectedStr := strings.TrimSpace(state.String()) + if actualStr != expectedStr { + t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr) + } } func TestRefresh_disableBackup(t *testing.T) { - t.Fatal("not yet updated for new provider types") - /* - state := testState() - statePath := testStateFile(t, state) + state := testState() + statePath := testStateFile(t, state) - // Output path - outf, err := ioutil.TempFile(testingDir, "tf") - if err != nil { - t.Fatalf("err: %s", err) - } - outPath := outf.Name() - outf.Close() - os.Remove(outPath) + // Output path + outf, err := ioutil.TempFile(testingDir, "tf") + if err != nil { + t.Fatalf("err: %s", err) + } + outPath := outf.Name() + outf.Close() + os.Remove(outPath) - p := testProvider() - ui := new(cli.MockUi) - c := &RefreshCommand{ - Meta: Meta{ - testingOverrides: metaOverridesForProvider(p), - Ui: ui, - }, - } + p := testProvider() + ui := new(cli.MockUi) + c := &RefreshCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: ui, + }, + } - p.GetSchemaReturn = refreshFixtureSchema() - p.RefreshFn = nil - p.RefreshReturn = newInstanceState("yes") + p.GetSchemaReturn = refreshFixtureSchema() + p.ReadResourceFn = nil + p.ReadResourceResponse = providers.ReadResourceResponse{ + NewState: cty.ObjectVal(map[string]cty.Value{ + "id": cty.StringVal("yes"), + }), + } - args := []string{ - "-state", statePath, - "-state-out", outPath, - "-backup", "-", - testFixturePath("refresh"), - } - if code := c.Run(args); code != 0 { - t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) - } + args := []string{ + "-state", statePath, + "-state-out", outPath, + "-backup", "-", + testFixturePath("refresh"), + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } - f, err := os.Open(statePath) - if err != nil { - t.Fatalf("err: %s", err) - } + newState := testStateRead(t, statePath) + if !reflect.DeepEqual(newState, state) { + t.Fatalf("bad: %#v", newState) + } - newState, err := terraform.ReadState(f) - f.Close() - if err != nil { - t.Fatalf("err: %s", err) - } + newState = testStateRead(t, outPath) + actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current + expected := &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + AttrsJSON: []byte("{\n \"ami\": null,\n \"id\": \"yes\"\n }"), + Dependencies: []addrs.Referenceable{}, + } + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("wrong new object\ngot: %swant: %s", spew.Sdump(actual), spew.Sdump(expected)) + } - if !reflect.DeepEqual(newState, state) { - t.Fatalf("bad: %#v", newState) - } - - f, err = os.Open(outPath) - if err != nil { - t.Fatalf("err: %s", err) - } - - newState, err = terraform.ReadState(f) - f.Close() - if err != nil { - t.Fatalf("err: %s", err) - } - - actual := newState.RootModule().Resources["test_instance.foo"].Primary - expected := p.RefreshReturn - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("bad: %#v", actual) - } - - // Ensure there is no backup - _, err = os.Stat(outPath + DefaultBackupExtension) - if err == nil || !os.IsNotExist(err) { - t.Fatalf("backup should not exist") - } - _, err = os.Stat("-") - if err == nil || !os.IsNotExist(err) { - t.Fatalf("backup should not exist") - } - */ + // Ensure there is no backup + _, err = os.Stat(outPath + DefaultBackupExtension) + if err == nil || !os.IsNotExist(err) { + t.Fatalf("backup should not exist") + } + _, err = os.Stat("-") + if err == nil || !os.IsNotExist(err) { + t.Fatalf("backup should not exist") + } } func TestRefresh_displaysOutputs(t *testing.T) {