mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-28 18:01:01 -06:00
29999c1d6f
For resources which are planned to move, render the previous run address as additional information in the plan UI. For the case of a move-only resource (which otherwise is unchanged), we also render that as a planned change, but without any corresponding action symbol. If all changes in the plan are moves without changes, the plan is no longer considered "empty". In this case, we skip rendering the action symbols in the UI.
160 lines
3.4 KiB
Go
160 lines
3.4 KiB
Go
package plans
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/terraform/internal/addrs"
|
|
"github.com/hashicorp/terraform/internal/lang/marks"
|
|
"github.com/zclconf/go-cty/cty"
|
|
)
|
|
|
|
func TestChangesEmpty(t *testing.T) {
|
|
testCases := map[string]struct {
|
|
changes *Changes
|
|
want bool
|
|
}{
|
|
"no changes": {
|
|
&Changes{},
|
|
true,
|
|
},
|
|
"resource change": {
|
|
&Changes{
|
|
Resources: []*ResourceInstanceChangeSrc{
|
|
{
|
|
Addr: addrs.Resource{
|
|
Mode: addrs.ManagedResourceMode,
|
|
Type: "test_thing",
|
|
Name: "woot",
|
|
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
|
|
PrevRunAddr: addrs.Resource{
|
|
Mode: addrs.ManagedResourceMode,
|
|
Type: "test_thing",
|
|
Name: "woot",
|
|
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
|
|
ChangeSrc: ChangeSrc{
|
|
Action: Update,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
"resource change with no-op action": {
|
|
&Changes{
|
|
Resources: []*ResourceInstanceChangeSrc{
|
|
{
|
|
Addr: addrs.Resource{
|
|
Mode: addrs.ManagedResourceMode,
|
|
Type: "test_thing",
|
|
Name: "woot",
|
|
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
|
|
PrevRunAddr: addrs.Resource{
|
|
Mode: addrs.ManagedResourceMode,
|
|
Type: "test_thing",
|
|
Name: "woot",
|
|
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
|
|
ChangeSrc: ChangeSrc{
|
|
Action: NoOp,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
true,
|
|
},
|
|
"resource moved with no-op change": {
|
|
&Changes{
|
|
Resources: []*ResourceInstanceChangeSrc{
|
|
{
|
|
Addr: addrs.Resource{
|
|
Mode: addrs.ManagedResourceMode,
|
|
Type: "test_thing",
|
|
Name: "woot",
|
|
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
|
|
PrevRunAddr: addrs.Resource{
|
|
Mode: addrs.ManagedResourceMode,
|
|
Type: "test_thing",
|
|
Name: "toot",
|
|
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
|
|
ChangeSrc: ChangeSrc{
|
|
Action: NoOp,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
"output change": {
|
|
&Changes{
|
|
Outputs: []*OutputChangeSrc{
|
|
{
|
|
Addr: addrs.OutputValue{
|
|
Name: "result",
|
|
}.Absolute(addrs.RootModuleInstance),
|
|
ChangeSrc: ChangeSrc{
|
|
Action: Update,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
},
|
|
"output change no-op": {
|
|
&Changes{
|
|
Outputs: []*OutputChangeSrc{
|
|
{
|
|
Addr: addrs.OutputValue{
|
|
Name: "result",
|
|
}.Absolute(addrs.RootModuleInstance),
|
|
ChangeSrc: ChangeSrc{
|
|
Action: NoOp,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
true,
|
|
},
|
|
}
|
|
|
|
for name, tc := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
if got, want := tc.changes.Empty(), tc.want; got != want {
|
|
t.Fatalf("unexpected result: got %v, want %v", got, want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestChangeEncodeSensitive(t *testing.T) {
|
|
testVals := []cty.Value{
|
|
cty.ObjectVal(map[string]cty.Value{
|
|
"ding": cty.StringVal("dong").Mark(marks.Sensitive),
|
|
}),
|
|
cty.StringVal("bleep").Mark("bloop"),
|
|
cty.ListVal([]cty.Value{cty.UnknownVal(cty.String).Mark("sup?")}),
|
|
}
|
|
|
|
for _, v := range testVals {
|
|
t.Run(fmt.Sprintf("%#v", v), func(t *testing.T) {
|
|
change := Change{
|
|
Before: cty.NullVal(v.Type()),
|
|
After: v,
|
|
}
|
|
|
|
encoded, err := change.Encode(v.Type())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
decoded, err := encoded.Decode(v.Type())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !v.RawEquals(decoded.After) {
|
|
t.Fatalf("%#v != %#v\n", decoded.After, v)
|
|
}
|
|
})
|
|
}
|
|
}
|