diff --git a/command/refresh.go b/command/refresh.go index 186df8e3e..f3038f96a 100644 --- a/command/refresh.go +++ b/command/refresh.go @@ -94,7 +94,7 @@ func (c *RefreshCommand) Run(args []string) int { } // Create a backup of the state before updating - if backupPath != "-" { + if backupPath != "-" && c.State != nil { log.Printf("[INFO] Writing backup state to: %s", backupPath) f, err := os.Create(backupPath) if err == nil { diff --git a/command/refresh_test.go b/command/refresh_test.go index 9525c68a9..ab345c169 100644 --- a/command/refresh_test.go +++ b/command/refresh_test.go @@ -221,6 +221,23 @@ func TestRefresh_defaultState(t *testing.T) { if !reflect.DeepEqual(actual, expected) { t.Fatalf("bad: %#v", actual) } + + f, err = os.Open(statePath + DefaultBackupExtention) + if err != nil { + t.Fatalf("err: %s", err) + } + + backupState, err := terraform.ReadState(f) + f.Close() + if err != nil { + t.Fatalf("err: %s", err) + } + + actual = backupState.Resources["test_instance.foo"] + expected = originalState.Resources["test_instance.foo"] + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: %#v", actual) + } } func TestRefresh_outPath(t *testing.T) { @@ -295,6 +312,21 @@ func TestRefresh_outPath(t *testing.T) { if !reflect.DeepEqual(actual, expected) { t.Fatalf("bad: %#v", actual) } + + f, err = os.Open(outPath + DefaultBackupExtention) + if err != nil { + t.Fatalf("err: %s", err) + } + + backupState, err := terraform.ReadState(f) + f.Close() + if err != nil { + t.Fatalf("err: %s", err) + } + + if !reflect.DeepEqual(backupState, state) { + t.Fatalf("bad: %#v", backupState) + } } func TestRefresh_var(t *testing.T) { @@ -376,6 +408,105 @@ func TestRefresh_varFile(t *testing.T) { } } +func TestRefresh_backup(t *testing.T) { + state := &terraform.State{ + Resources: map[string]*terraform.ResourceState{ + "test_instance.foo": &terraform.ResourceState{ + ID: "bar", + Type: "test_instance", + }, + }, + } + statePath := testStateFile(t, state) + + // Output path + outf, err := ioutil.TempFile("", "tf") + if err != nil { + t.Fatalf("err: %s", err) + } + outPath := outf.Name() + outf.Close() + os.Remove(outPath) + + // Backup path + backupf, err := ioutil.TempFile("", "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{ + ContextOpts: testCtxConfig(p), + Ui: ui, + }, + } + + p.RefreshFn = nil + p.RefreshReturn = &terraform.ResourceState{ID: "yes"} + + 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, err := terraform.ReadState(f) + f.Close() + if err != nil { + t.Fatalf("err: %s", err) + } + + 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.Resources["test_instance.foo"] + 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) + } + + if !reflect.DeepEqual(backupState, state) { + t.Fatalf("bad: %#v", backupState) + } +} + const refreshVarFile = ` foo = "bar" `