Merge pull request #19590 from hashicorp/t-cmd-format
command/format: Add tests for ResourceChange renderer
This commit is contained in:
commit
c77fe806f5
|
@ -0,0 +1,152 @@
|
||||||
|
package format
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/addrs"
|
||||||
|
"github.com/hashicorp/terraform/configs/configschema"
|
||||||
|
"github.com/hashicorp/terraform/plans"
|
||||||
|
"github.com/mitchellh/colorstring"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestResourceChange(t *testing.T) {
|
||||||
|
testCases := map[string]struct {
|
||||||
|
Action plans.Action
|
||||||
|
Mode addrs.ResourceMode
|
||||||
|
Before cty.Value
|
||||||
|
After cty.Value
|
||||||
|
Schema *configschema.Block
|
||||||
|
RequiredReplace cty.PathSet
|
||||||
|
ExpectedOutput string
|
||||||
|
}{
|
||||||
|
"creation": {
|
||||||
|
Action: plans.Create,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.NullVal(cty.EmptyObject),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Computed: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(),
|
||||||
|
ExpectedOutput: ` # test_instance.example will be created
|
||||||
|
+ resource "test_instance" "example" {
|
||||||
|
+ id = (known after apply)
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"deletion": {
|
||||||
|
Action: plans.Delete,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
}),
|
||||||
|
After: cty.NullVal(cty.EmptyObject),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Computed: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(),
|
||||||
|
ExpectedOutput: ` # test_instance.example will be destroyed
|
||||||
|
- resource "test_instance" "example" {
|
||||||
|
- id = "i-02ae66f368e8518a9" -> null
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"simple in-place update": {
|
||||||
|
Action: plans.Update,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-BEFORE"),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-AFTER"),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(),
|
||||||
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
||||||
|
~ resource "test_instance" "example" {
|
||||||
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
||||||
|
id = "i-02ae66f368e8518a9"
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"simple force-new update": {
|
||||||
|
Action: plans.DeleteThenCreate,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-BEFORE"),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
"ami": cty.StringVal("ami-AFTER"),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
||||||
|
cty.GetAttrStep{Name: "ami"},
|
||||||
|
}),
|
||||||
|
ExpectedOutput: ` # test_instance.example must be replaced
|
||||||
|
-/+ resource "test_instance" "example" {
|
||||||
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
||||||
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
color := &colorstring.Colorize{Colors: colorstring.DefaultColors, Disable: true}
|
||||||
|
|
||||||
|
for name, tc := range testCases {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
beforeVal := tc.Before
|
||||||
|
before, err := plans.NewDynamicValue(beforeVal, beforeVal.Type())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
afterVal := tc.After
|
||||||
|
after, err := plans.NewDynamicValue(afterVal, afterVal.Type())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
change := &plans.ResourceInstanceChangeSrc{
|
||||||
|
Addr: addrs.Resource{
|
||||||
|
Mode: tc.Mode,
|
||||||
|
Type: "test_instance",
|
||||||
|
Name: "example",
|
||||||
|
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
|
||||||
|
ProviderAddr: addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance),
|
||||||
|
ChangeSrc: plans.ChangeSrc{
|
||||||
|
Action: tc.Action,
|
||||||
|
Before: before,
|
||||||
|
After: after,
|
||||||
|
},
|
||||||
|
RequiredReplace: tc.RequiredReplace,
|
||||||
|
}
|
||||||
|
|
||||||
|
output := ResourceChange(change, tc.Schema, color)
|
||||||
|
if output != tc.ExpectedOutput {
|
||||||
|
t.Fatalf("Unexpected diff.\nExpected:\n%s\nGiven:\n%s\n", tc.ExpectedOutput, output)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue