command: Fix even more of the "terraform refresh" tests

This commit is contained in:
Martin Atkins 2018-10-14 16:07:42 -07:00
parent 5d1d6a95f9
commit 89d0944e5b
2 changed files with 242 additions and 297 deletions

View File

@ -242,7 +242,10 @@ func testState() *states.State {
Name: "foo", Name: "foo",
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
&states.ResourceInstanceObjectSrc{ &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, Status: states.ObjectReady,
}, },
addrs.ProviderConfig{ addrs.ProviderConfig{

View File

@ -7,17 +7,21 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"strings" "strings"
"testing" "testing"
"github.com/davecgh/go-spew/spew"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
"github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/helper/copy" "github.com/hashicorp/terraform/helper/copy"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/states"
"github.com/hashicorp/terraform/states/statefile" "github.com/hashicorp/terraform/states/statefile"
"github.com/hashicorp/terraform/states/statemgr"
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
) )
@ -209,164 +213,142 @@ func TestRefresh_cwd(t *testing.T) {
} }
func TestRefresh_defaultState(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 // Write the state file in a temporary directory with the
// default filename. // default filename.
statePath := testStateFile(t, originalState) statePath := testStateFile(t, originalState)
localState := &state.LocalState{Path: statePath} localState := statemgr.NewFilesystem(statePath)
if err := localState.RefreshState(); err != nil { if err := localState.RefreshState(); err != nil {
t.Fatal(err) t.Fatal(err)
} }
s := localState.State() s := localState.State()
if s == nil { if s == nil {
t.Fatal("empty test state") t.Fatal("empty test state")
} }
serial := s.Serial
// Change to that directory // Change to that directory
cwd, err := os.Getwd() cwd, err := os.Getwd()
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
if err := os.Chdir(filepath.Dir(statePath)); err != nil { if err := os.Chdir(filepath.Dir(statePath)); err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
defer os.Chdir(cwd) defer os.Chdir(cwd)
p := testProvider() p := testProvider()
ui := new(cli.MockUi) ui := new(cli.MockUi)
c := &RefreshCommand{ c := &RefreshCommand{
Meta: Meta{ Meta: Meta{
testingOverrides: metaOverridesForProvider(p), testingOverrides: metaOverridesForProvider(p),
Ui: ui, Ui: ui,
}, },
} }
p.GetSchemaReturn = refreshFixtureSchema() p.GetSchemaReturn = refreshFixtureSchema()
p.RefreshFn = nil p.ReadResourceFn = nil
p.RefreshReturn = newInstanceState("yes") p.ReadResourceResponse = providers.ReadResourceResponse{
NewState: cty.ObjectVal(map[string]cty.Value{
"id": cty.StringVal("yes"),
}),
}
args := []string{ args := []string{
"-state", statePath, "-state", statePath,
testFixturePath("refresh"), testFixturePath("refresh"),
} }
if code := c.Run(args); code != 0 { if code := c.Run(args); code != 0 {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
} }
if !p.RefreshCalled { if !p.ReadResourceCalled {
t.Fatal("refresh should be called") 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 actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current
expected := p.RefreshReturn expected := &states.ResourceInstanceObjectSrc{
if !reflect.DeepEqual(actual, expected) { Status: states.ObjectReady,
t.Logf("expected:\n%#v", expected) AttrsJSON: []byte("{\n \"ami\": null,\n \"id\": \"yes\"\n }"),
t.Fatalf("bad:\n%#v", actual) 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 actual = backupState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current
expected = originalState.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) { if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual) t.Fatalf("wrong new object\ngot: %swant: %s", spew.Sdump(actual), spew.Sdump(expected))
} }
*/
} }
func TestRefresh_outPath(t *testing.T) { 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 // Output path
outf, err := ioutil.TempFile(testingDir, "tf") outf, err := ioutil.TempFile(testingDir, "tf")
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
outPath := outf.Name() outPath := outf.Name()
outf.Close() outf.Close()
os.Remove(outPath) os.Remove(outPath)
p := testProvider() p := testProvider()
ui := new(cli.MockUi) ui := new(cli.MockUi)
c := &RefreshCommand{ c := &RefreshCommand{
Meta: Meta{ Meta: Meta{
testingOverrides: metaOverridesForProvider(p), testingOverrides: metaOverridesForProvider(p),
Ui: ui, Ui: ui,
}, },
} }
p.GetSchemaReturn = refreshFixtureSchema() p.GetSchemaReturn = refreshFixtureSchema()
p.RefreshFn = nil p.ReadResourceFn = nil
p.RefreshReturn = newInstanceState("yes") p.ReadResourceResponse = providers.ReadResourceResponse{
NewState: cty.ObjectVal(map[string]cty.Value{
"id": cty.StringVal("yes"),
}),
}
args := []string{ args := []string{
"-state", statePath, "-state", statePath,
"-state-out", outPath, "-state-out", outPath,
testFixturePath("refresh"), testFixturePath("refresh"),
} }
if code := c.Run(args); code != 0 { if code := c.Run(args); code != 0 {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
} }
f, err := os.Open(statePath) newState := testStateRead(t, statePath)
if err != nil { if !reflect.DeepEqual(newState, state) {
t.Fatalf("err: %s", err) t.Fatalf("bad: %#v", newState)
} }
newState, err := terraform.ReadState(f) newState = testStateRead(t, outPath)
f.Close() actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current
if err != nil { expected := &states.ResourceInstanceObjectSrc{
t.Fatalf("err: %s", err) 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) { backupState := testStateRead(t, outPath + DefaultBackupExtension)
t.Fatalf("bad: %#v", newState) actualStr := strings.TrimSpace(backupState.String())
} expectedStr := strings.TrimSpace(state.String())
if actualStr != expectedStr {
f, err = os.Open(outPath) t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr)
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)
}
*/
} }
func TestRefresh_var(t *testing.T) { func TestRefresh_var(t *testing.T) {
@ -520,183 +502,143 @@ func TestRefresh_varsUnset(t *testing.T) {
} }
func TestRefresh_backup(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 // Output path
outf, err := ioutil.TempFile(testingDir, "tf") outf, err := ioutil.TempFile(testingDir, "tf")
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
outPath := outf.Name() outPath := outf.Name()
outf.Close() outf.Close()
os.Remove(outPath) os.Remove(outPath)
// Backup path // Backup path
backupf, err := ioutil.TempFile(testingDir, "tf") backupf, err := ioutil.TempFile(testingDir, "tf")
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
backupPath := backupf.Name() backupPath := backupf.Name()
backupf.Close() backupf.Close()
os.Remove(backupPath) os.Remove(backupPath)
p := testProvider() p := testProvider()
ui := new(cli.MockUi) ui := new(cli.MockUi)
c := &RefreshCommand{ c := &RefreshCommand{
Meta: Meta{ Meta: Meta{
testingOverrides: metaOverridesForProvider(p), testingOverrides: metaOverridesForProvider(p),
Ui: ui, Ui: ui,
}, },
} }
p.GetSchemaReturn = refreshFixtureSchema() p.GetSchemaReturn = refreshFixtureSchema()
p.RefreshFn = nil p.ReadResourceFn = nil
p.RefreshReturn = newInstanceState("yes") p.ReadResourceResponse = providers.ReadResourceResponse{
NewState: cty.ObjectVal(map[string]cty.Value{
"id": cty.StringVal("changed"),
}),
}
args := []string{ args := []string{
"-state", statePath, "-state", statePath,
"-state-out", outPath, "-state-out", outPath,
"-backup", backupPath, "-backup", backupPath,
testFixturePath("refresh"), testFixturePath("refresh"),
} }
if code := c.Run(args); code != 0 { if code := c.Run(args); code != 0 {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
} }
f, err := os.Open(statePath) newState := testStateRead(t, statePath)
if err != nil { if !reflect.DeepEqual(newState, state) {
t.Fatalf("err: %s", err) t.Fatalf("bad: %#v", newState)
} }
newState, err := terraform.ReadState(f) newState = testStateRead(t, outPath)
f.Close() actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current
if err != nil { expected := &states.ResourceInstanceObjectSrc{
t.Fatalf("err: %s", err) 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) { backupState := testStateRead(t, outPath + DefaultBackupExtension)
t.Fatalf("bad: %#v", newState) actualStr := strings.TrimSpace(backupState.String())
} expectedStr := strings.TrimSpace(state.String())
if actualStr != expectedStr {
f, err = os.Open(outPath) t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr)
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)
}
*/
} }
func TestRefresh_disableBackup(t *testing.T) { 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 // Output path
outf, err := ioutil.TempFile(testingDir, "tf") outf, err := ioutil.TempFile(testingDir, "tf")
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
outPath := outf.Name() outPath := outf.Name()
outf.Close() outf.Close()
os.Remove(outPath) os.Remove(outPath)
p := testProvider() p := testProvider()
ui := new(cli.MockUi) ui := new(cli.MockUi)
c := &RefreshCommand{ c := &RefreshCommand{
Meta: Meta{ Meta: Meta{
testingOverrides: metaOverridesForProvider(p), testingOverrides: metaOverridesForProvider(p),
Ui: ui, Ui: ui,
}, },
} }
p.GetSchemaReturn = refreshFixtureSchema() p.GetSchemaReturn = refreshFixtureSchema()
p.RefreshFn = nil p.ReadResourceFn = nil
p.RefreshReturn = newInstanceState("yes") p.ReadResourceResponse = providers.ReadResourceResponse{
NewState: cty.ObjectVal(map[string]cty.Value{
"id": cty.StringVal("yes"),
}),
}
args := []string{ args := []string{
"-state", statePath, "-state", statePath,
"-state-out", outPath, "-state-out", outPath,
"-backup", "-", "-backup", "-",
testFixturePath("refresh"), testFixturePath("refresh"),
} }
if code := c.Run(args); code != 0 { if code := c.Run(args); code != 0 {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
} }
f, err := os.Open(statePath) newState := testStateRead(t, statePath)
if err != nil { if !reflect.DeepEqual(newState, state) {
t.Fatalf("err: %s", err) t.Fatalf("bad: %#v", newState)
} }
newState, err := terraform.ReadState(f) newState = testStateRead(t, outPath)
f.Close() actual := newState.RootModule().Resources["test_instance.foo"].Instances[addrs.NoKey].Current
if err != nil { expected := &states.ResourceInstanceObjectSrc{
t.Fatalf("err: %s", err) 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) { // Ensure there is no backup
t.Fatalf("bad: %#v", newState) _, err = os.Stat(outPath + DefaultBackupExtension)
} if err == nil || !os.IsNotExist(err) {
t.Fatalf("backup should not exist")
f, err = os.Open(outPath) }
if err != nil { _, err = os.Stat("-")
t.Fatalf("err: %s", err) if err == nil || !os.IsNotExist(err) {
} t.Fatalf("backup should not exist")
}
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")
}
*/
} }
func TestRefresh_displaysOutputs(t *testing.T) { func TestRefresh_displaysOutputs(t *testing.T) {