diff --git a/command/apply_test.go b/command/apply_test.go index f6402ae44..21401ed47 100644 --- a/command/apply_test.go +++ b/command/apply_test.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" "reflect" + "strings" "sync" "testing" "time" @@ -580,13 +581,16 @@ func TestApply_state(t *testing.T) { } // Verify that the provider was called with the existing state - expectedState := originalState.RootModule().Resources["test_instance.foo"] - if !reflect.DeepEqual(p.DiffState, expectedState) { - t.Fatalf("bad: %#v", p.DiffState) + actual := strings.TrimSpace(p.DiffState.String()) + expected := strings.TrimSpace(testApplyStateDiffStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) } - if !reflect.DeepEqual(p.ApplyState, expectedState) { - t.Fatalf("bad: %#v", p.ApplyState) + actual = strings.TrimSpace(p.ApplyState.String()) + expected = strings.TrimSpace(testApplyStateStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) } // Verify a new state exists @@ -866,22 +870,7 @@ func TestApply_backup(t *testing.T) { } func TestApply_disableBackup(t *testing.T) { - originalState := &terraform.State{ - Modules: []*terraform.ModuleState{ - &terraform.ModuleState{ - Path: []string{"root"}, - Resources: map[string]*terraform.ResourceState{ - "test_instance.foo": &terraform.ResourceState{ - Type: "test_instance", - Primary: &terraform.InstanceState{ - ID: "bar", - }, - }, - }, - }, - }, - } - + originalState := testState() statePath := testStateFile(t, originalState) p := testProvider() @@ -912,13 +901,16 @@ func TestApply_disableBackup(t *testing.T) { } // Verify that the provider was called with the existing state - expectedState := originalState.RootModule().Resources["test_instance.foo"] - if !reflect.DeepEqual(p.DiffState, expectedState) { - t.Fatalf("bad: %#v", p.DiffState) + actual := strings.TrimSpace(p.DiffState.String()) + expected := strings.TrimSpace(testApplyDisableBackupStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) } - if !reflect.DeepEqual(p.ApplyState, expectedState) { - t.Fatalf("bad: %#v", p.ApplyState) + actual = strings.TrimSpace(p.ApplyState.String()) + expected = strings.TrimSpace(testApplyDisableBackupStateStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) } // Verify a new state exists @@ -950,3 +942,19 @@ func TestApply_disableBackup(t *testing.T) { const applyVarFile = ` foo = "bar" ` + +const testApplyDisableBackupStr = ` +ID = bar +` + +const testApplyDisableBackupStateStr = ` +ID = bar +` + +const testApplyStateStr = ` +ID = bar +` + +const testApplyStateDiffStr = ` +ID = bar +` diff --git a/command/plan_test.go b/command/plan_test.go index 2f9ec37e2..a22426f32 100644 --- a/command/plan_test.go +++ b/command/plan_test.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "reflect" + "strings" "testing" "github.com/hashicorp/terraform/terraform" @@ -124,11 +125,10 @@ func TestPlan_noState(t *testing.T) { } // Verify that the provider was called with the existing state - expectedState := &terraform.ResourceState{ - Type: "test_instance", - } - if !reflect.DeepEqual(p.DiffState, expectedState) { - t.Fatalf("bad: %#v", p.DiffState) + actual := strings.TrimSpace(p.DiffState.String()) + expected := strings.TrimSpace(testPlanNoStateStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) } } @@ -204,22 +204,7 @@ func TestPlan_state(t *testing.T) { statePath := tf.Name() defer os.Remove(tf.Name()) - originalState := &terraform.State{ - Modules: []*terraform.ModuleState{ - &terraform.ModuleState{ - Path: []string{"root"}, - Resources: map[string]*terraform.ResourceState{ - "test_instance.foo": &terraform.ResourceState{ - Type: "test_instance", - Primary: &terraform.InstanceState{ - ID: "bar", - }, - }, - }, - }, - }, - } - + originalState := testState() err = terraform.WriteState(originalState, tf) tf.Close() if err != nil { @@ -244,28 +229,15 @@ func TestPlan_state(t *testing.T) { } // Verify that the provider was called with the existing state - expectedState := originalState.RootModule().Resources["test_instance.foo"] - if !reflect.DeepEqual(p.DiffState, expectedState) { - t.Fatalf("bad: %#v", p.DiffState) + actual := strings.TrimSpace(p.DiffState.String()) + expected := strings.TrimSpace(testPlanStateStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) } } func TestPlan_stateDefault(t *testing.T) { - originalState := &terraform.State{ - Modules: []*terraform.ModuleState{ - &terraform.ModuleState{ - Path: []string{"root"}, - Resources: map[string]*terraform.ResourceState{ - "test_instance.foo": &terraform.ResourceState{ - Type: "test_instance", - Primary: &terraform.InstanceState{ - ID: "bar", - }, - }, - }, - }, - }, - } + originalState := testState() // Write the state file in a temporary directory with the // default filename. @@ -312,9 +284,10 @@ func TestPlan_stateDefault(t *testing.T) { } // Verify that the provider was called with the existing state - expectedState := originalState.RootModule().Resources["test_instance.foo"] - if !reflect.DeepEqual(p.DiffState, expectedState) { - t.Fatalf("bad: %#v", p.DiffState) + actual := strings.TrimSpace(p.DiffState.String()) + expected := strings.TrimSpace(testPlanStateDefaultStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) } } @@ -502,9 +475,10 @@ func TestPlan_backup(t *testing.T) { } // Verify that the provider was called with the existing state - expectedState := originalState.RootModule().Resources["test_instance.foo"] - if !reflect.DeepEqual(p.DiffState, expectedState) { - t.Fatalf("bad: %#v", p.DiffState) + actual := strings.TrimSpace(p.DiffState.String()) + expected := strings.TrimSpace(testPlanBackupStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) } // Verify the backup exist @@ -574,9 +548,10 @@ func TestPlan_disableBackup(t *testing.T) { } // Verify that the provider was called with the existing state - expectedState := originalState.RootModule().Resources["test_instance.foo"] - if !reflect.DeepEqual(p.DiffState, expectedState) { - t.Fatalf("bad: %#v", p.DiffState) + actual := strings.TrimSpace(p.DiffState.String()) + expected := strings.TrimSpace(testPlanDisableBackupStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) } // Ensure there is no backup @@ -589,3 +564,23 @@ func TestPlan_disableBackup(t *testing.T) { const planVarFile = ` foo = "bar" ` + +const testPlanBackupStr = ` +ID = bar +` + +const testPlanDisableBackupStr = ` +ID = bar +` + +const testPlanNoStateStr = ` + +` + +const testPlanStateStr = ` +ID = bar +` + +const testPlanStateDefaultStr = ` +ID = bar +` diff --git a/command/refresh_test.go b/command/refresh_test.go index 073be20cd..b301fa022 100644 --- a/command/refresh_test.go +++ b/command/refresh_test.go @@ -6,6 +6,7 @@ import ( "path/filepath" "reflect" "testing" + "strings" "github.com/hashicorp/terraform/terraform" "github.com/mitchellh/cli" @@ -50,10 +51,10 @@ func TestRefresh(t *testing.T) { t.Fatalf("err: %s", err) } - actual := newState.RootModule().Resources["test_instance.foo"] - expected := p.RefreshReturn - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("bad: %#v", actual) + actual := strings.TrimSpace(newState.String()) + expected := strings.TrimSpace(testRefreshStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) } } @@ -123,10 +124,10 @@ func TestRefresh_cwd(t *testing.T) { t.Fatalf("err: %s", err) } - actual := newState.RootModule().Resources["test_instance.foo"] - expected := p.RefreshReturn - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("bad: %#v", actual) + actual := strings.TrimSpace(newState.String()) + expected := strings.TrimSpace(testRefreshCwdStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) } } @@ -579,3 +580,12 @@ func TestRefresh_disableBackup(t *testing.T) { const refreshVarFile = ` foo = "bar" ` + +const testRefreshStr = ` +test_instance.foo: + ID = yes +` +const testRefreshCwdStr = ` +test_instance.foo: + ID = yes +` diff --git a/terraform/state.go b/terraform/state.go index 73cb7edec..a2f116651 100644 --- a/terraform/state.go +++ b/terraform/state.go @@ -449,6 +449,37 @@ func (i *InstanceState) GoString() string { return fmt.Sprintf("*%#v", *i) } +func (i *InstanceState) String() string { + var buf bytes.Buffer + + if i.ID == "" { + return "" + } + + buf.WriteString(fmt.Sprintf("ID = %s\n", i.ID)) + if i.Tainted { + buf.WriteString(fmt.Sprintf("Tainted = true")) + } + + attributes := i.Attributes + attrKeys := make([]string, 0, len(attributes)) + for ak, _ := range attributes { + if ak == "id" { + continue + } + + attrKeys = append(attrKeys, ak) + } + sort.Strings(attrKeys) + + for _, ak := range attrKeys { + av := attributes[ak] + buf.WriteString(fmt.Sprintf("%s = %s\n", ak, av)) + } + + return buf.String() +} + // EphemeralState is used for transient state that is only kept in-memory type EphemeralState struct { // ConnInfo is used for the providers to export information which is