terraform/internal/command/jsonplan/values_test.go

327 lines
7.3 KiB
Go
Raw Normal View History

package jsonplan
import (
"encoding/json"
"reflect"
"testing"
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/terraform"
"github.com/zclconf/go-cty/cty"
)
func TestMarshalAttributeValues(t *testing.T) {
tests := []struct {
Attr cty.Value
Schema *configschema.Block
Want attributeValues
}{
{
cty.NilVal,
&configschema.Block{
Attributes: map[string]*configschema.Attribute{
"foo": {
Type: cty.String,
Optional: true,
},
},
},
nil,
},
{
cty.NullVal(cty.String),
&configschema.Block{
Attributes: map[string]*configschema.Attribute{
"foo": {
Type: cty.String,
Optional: true,
},
},
},
nil,
},
{
cty.ObjectVal(map[string]cty.Value{
"foo": cty.StringVal("bar"),
}),
&configschema.Block{
Attributes: map[string]*configschema.Attribute{
"foo": {
Type: cty.String,
Optional: true,
},
},
},
mildwonkey/b-show-state (#20032) * command/show: properly marshal attribute values to json marshalAttributeValues in jsonstate and jsonplan packages was returning a cty.Value, which json/encoding could not marshal. These functions now convert those cty.Values into json.RawMessages. * command/jsonplan: planned values should include resources that are not changing * command/jsonplan: return a filtered list of proposed 'after' attributes Previously, proposed 'after' attributes were not being shown if the attributes were not WhollyKnown. jsonplan now iterates through all the `after` attributes, omitting those which are not wholly known. The same was roughly true for after_unknown, and that structure is now correctly populated. In the future we may choose to filter the after_unknown structure to _only_ display unknown attributes, instead of all attributes. * command/jsonconfig: use a unique key for providers so that aliased providers don't get munged together This now uses the same "provider" key from configs.Module, e.g. `providername.provideralias`. * command/jsonplan: unknownAsBool needs to iterate through objects that are not wholly known * command/jsonplan: properly display actions as strings according to the RFC, instead of a plans.Action string. For example: a plans.Action string DeleteThenCreate should be displayed as ["delete", "create"] Tests have been updated to reflect this. * command/jsonplan: return "null" for unknown list items. The length of a list could be meaningful on its own, so we will turn unknowns into "null". The same is less likely true for maps and objects, so we will continue to omit unknown values from those.
2019-01-23 20:46:53 +01:00
attributeValues{"foo": json.RawMessage(`"bar"`)},
},
{
cty.ObjectVal(map[string]cty.Value{
"foo": cty.NullVal(cty.String),
}),
&configschema.Block{
Attributes: map[string]*configschema.Attribute{
"foo": {
Type: cty.String,
Optional: true,
},
},
},
mildwonkey/b-show-state (#20032) * command/show: properly marshal attribute values to json marshalAttributeValues in jsonstate and jsonplan packages was returning a cty.Value, which json/encoding could not marshal. These functions now convert those cty.Values into json.RawMessages. * command/jsonplan: planned values should include resources that are not changing * command/jsonplan: return a filtered list of proposed 'after' attributes Previously, proposed 'after' attributes were not being shown if the attributes were not WhollyKnown. jsonplan now iterates through all the `after` attributes, omitting those which are not wholly known. The same was roughly true for after_unknown, and that structure is now correctly populated. In the future we may choose to filter the after_unknown structure to _only_ display unknown attributes, instead of all attributes. * command/jsonconfig: use a unique key for providers so that aliased providers don't get munged together This now uses the same "provider" key from configs.Module, e.g. `providername.provideralias`. * command/jsonplan: unknownAsBool needs to iterate through objects that are not wholly known * command/jsonplan: properly display actions as strings according to the RFC, instead of a plans.Action string. For example: a plans.Action string DeleteThenCreate should be displayed as ["delete", "create"] Tests have been updated to reflect this. * command/jsonplan: return "null" for unknown list items. The length of a list could be meaningful on its own, so we will turn unknowns into "null". The same is less likely true for maps and objects, so we will continue to omit unknown values from those.
2019-01-23 20:46:53 +01:00
attributeValues{"foo": json.RawMessage(`null`)},
},
{
cty.ObjectVal(map[string]cty.Value{
"bar": cty.MapVal(map[string]cty.Value{
"hello": cty.StringVal("world"),
}),
"baz": cty.ListVal([]cty.Value{
cty.StringVal("goodnight"),
cty.StringVal("moon"),
}),
}),
&configschema.Block{
Attributes: map[string]*configschema.Attribute{
"bar": {
Type: cty.Map(cty.String),
Required: true,
},
"baz": {
Type: cty.List(cty.String),
Optional: true,
},
},
},
attributeValues{
mildwonkey/b-show-state (#20032) * command/show: properly marshal attribute values to json marshalAttributeValues in jsonstate and jsonplan packages was returning a cty.Value, which json/encoding could not marshal. These functions now convert those cty.Values into json.RawMessages. * command/jsonplan: planned values should include resources that are not changing * command/jsonplan: return a filtered list of proposed 'after' attributes Previously, proposed 'after' attributes were not being shown if the attributes were not WhollyKnown. jsonplan now iterates through all the `after` attributes, omitting those which are not wholly known. The same was roughly true for after_unknown, and that structure is now correctly populated. In the future we may choose to filter the after_unknown structure to _only_ display unknown attributes, instead of all attributes. * command/jsonconfig: use a unique key for providers so that aliased providers don't get munged together This now uses the same "provider" key from configs.Module, e.g. `providername.provideralias`. * command/jsonplan: unknownAsBool needs to iterate through objects that are not wholly known * command/jsonplan: properly display actions as strings according to the RFC, instead of a plans.Action string. For example: a plans.Action string DeleteThenCreate should be displayed as ["delete", "create"] Tests have been updated to reflect this. * command/jsonplan: return "null" for unknown list items. The length of a list could be meaningful on its own, so we will turn unknowns into "null". The same is less likely true for maps and objects, so we will continue to omit unknown values from those.
2019-01-23 20:46:53 +01:00
"bar": json.RawMessage(`{"hello":"world"}`),
"baz": json.RawMessage(`["goodnight","moon"]`),
},
},
}
for _, test := range tests {
got := marshalAttributeValues(test.Attr, test.Schema)
eq := reflect.DeepEqual(got, test.Want)
if !eq {
mildwonkey/b-show-state (#20032) * command/show: properly marshal attribute values to json marshalAttributeValues in jsonstate and jsonplan packages was returning a cty.Value, which json/encoding could not marshal. These functions now convert those cty.Values into json.RawMessages. * command/jsonplan: planned values should include resources that are not changing * command/jsonplan: return a filtered list of proposed 'after' attributes Previously, proposed 'after' attributes were not being shown if the attributes were not WhollyKnown. jsonplan now iterates through all the `after` attributes, omitting those which are not wholly known. The same was roughly true for after_unknown, and that structure is now correctly populated. In the future we may choose to filter the after_unknown structure to _only_ display unknown attributes, instead of all attributes. * command/jsonconfig: use a unique key for providers so that aliased providers don't get munged together This now uses the same "provider" key from configs.Module, e.g. `providername.provideralias`. * command/jsonplan: unknownAsBool needs to iterate through objects that are not wholly known * command/jsonplan: properly display actions as strings according to the RFC, instead of a plans.Action string. For example: a plans.Action string DeleteThenCreate should be displayed as ["delete", "create"] Tests have been updated to reflect this. * command/jsonplan: return "null" for unknown list items. The length of a list could be meaningful on its own, so we will turn unknowns into "null". The same is less likely true for maps and objects, so we will continue to omit unknown values from those.
2019-01-23 20:46:53 +01:00
t.Fatalf("wrong result:\nGot: %#v\nWant: %#v\n", got, test.Want)
}
}
}
func TestMarshalPlannedOutputs(t *testing.T) {
after, _ := plans.NewDynamicValue(cty.StringVal("after"), cty.DynamicPseudoType)
tests := []struct {
Changes *plans.Changes
Want map[string]output
Err bool
}{
{
&plans.Changes{},
nil,
false,
},
{
&plans.Changes{
Outputs: []*plans.OutputChangeSrc{
{
Addr: addrs.OutputValue{Name: "bar"}.Absolute(addrs.RootModuleInstance),
ChangeSrc: plans.ChangeSrc{
Action: plans.Create,
After: after,
},
Sensitive: false,
},
},
},
map[string]output{
"bar": {
Sensitive: false,
Value: json.RawMessage(`"after"`),
},
},
false,
},
{ // Delete action
&plans.Changes{
Outputs: []*plans.OutputChangeSrc{
{
Addr: addrs.OutputValue{Name: "bar"}.Absolute(addrs.RootModuleInstance),
ChangeSrc: plans.ChangeSrc{
Action: plans.Delete,
},
Sensitive: false,
},
},
},
map[string]output{},
false,
},
}
for _, test := range tests {
got, err := marshalPlannedOutputs(test.Changes)
if test.Err {
if err == nil {
t.Fatal("succeeded; want error")
}
return
} else if err != nil {
t.Fatalf("unexpected error: %s", err)
}
eq := reflect.DeepEqual(got, test.Want)
if !eq {
t.Fatalf("wrong result:\nGot: %#v\nWant: %#v\n", got, test.Want)
}
}
}
func TestMarshalPlanResources(t *testing.T) {
command/jsonplan: Don't panic with mixtures of known/unknown/empty The omitUnknowns and unknownAsBool functions were previously trying hard to preserve the same collection types in the output as they had in the input, by attempting to keep everything matched up so that the results would be valid. Unfortunately, this turns out to be a harder problem than we originally thought: it was possible for a collection value going in to produce inconsistent element types out (and thus a panic) in the following situations: - when a collection with mixed known and unknown values was passed in to omitUnknowns. - when a collection of collections where the inner collections are a mixture of empty and not empty in unknownAsNull. The results of these functions are only used to marshal to JSON anyway, and JSON serialization can't distinguish between the three sequence types or the two mapping types, so in practice we can just standardize on converting all sequences to tuple and all mappings to object here and not change the resulting output at all, and then we don't have to worry about making sure all of the inner types get preserved exactly. A nice consequence of that relaxation is that we can now do what we originally wanted to do with unknownAsBool, and omit map keys and object attributes altogether if their values would've been false, producing a much more compact result. This is easiest to do now when there's only one known user of this JSON plan output, and we know that user will treat both false and omitted as the same here.
2019-05-25 01:30:58 +02:00
tests := map[string]struct {
Action plans.Action
Before cty.Value
After cty.Value
Want []resource
Err bool
}{
"create with unknowns": {
Action: plans.Create,
Before: cty.NullVal(cty.EmptyObject),
After: cty.ObjectVal(map[string]cty.Value{
"woozles": cty.UnknownVal(cty.String),
"foozles": cty.UnknownVal(cty.String),
}),
Want: []resource{resource{
Address: "test_thing.example",
Mode: "managed",
Type: "test_thing",
Name: "example",
Index: addrs.InstanceKey(nil),
ProviderName: "registry.terraform.io/hashicorp/test",
SchemaVersion: 1,
command/jsonplan: Don't panic with mixtures of known/unknown/empty The omitUnknowns and unknownAsBool functions were previously trying hard to preserve the same collection types in the output as they had in the input, by attempting to keep everything matched up so that the results would be valid. Unfortunately, this turns out to be a harder problem than we originally thought: it was possible for a collection value going in to produce inconsistent element types out (and thus a panic) in the following situations: - when a collection with mixed known and unknown values was passed in to omitUnknowns. - when a collection of collections where the inner collections are a mixture of empty and not empty in unknownAsNull. The results of these functions are only used to marshal to JSON anyway, and JSON serialization can't distinguish between the three sequence types or the two mapping types, so in practice we can just standardize on converting all sequences to tuple and all mappings to object here and not change the resulting output at all, and then we don't have to worry about making sure all of the inner types get preserved exactly. A nice consequence of that relaxation is that we can now do what we originally wanted to do with unknownAsBool, and omit map keys and object attributes altogether if their values would've been false, producing a much more compact result. This is easiest to do now when there's only one known user of this JSON plan output, and we know that user will treat both false and omitted as the same here.
2019-05-25 01:30:58 +02:00
AttributeValues: attributeValues{},
}},
Err: false,
},
command/jsonplan: Don't panic with mixtures of known/unknown/empty The omitUnknowns and unknownAsBool functions were previously trying hard to preserve the same collection types in the output as they had in the input, by attempting to keep everything matched up so that the results would be valid. Unfortunately, this turns out to be a harder problem than we originally thought: it was possible for a collection value going in to produce inconsistent element types out (and thus a panic) in the following situations: - when a collection with mixed known and unknown values was passed in to omitUnknowns. - when a collection of collections where the inner collections are a mixture of empty and not empty in unknownAsNull. The results of these functions are only used to marshal to JSON anyway, and JSON serialization can't distinguish between the three sequence types or the two mapping types, so in practice we can just standardize on converting all sequences to tuple and all mappings to object here and not change the resulting output at all, and then we don't have to worry about making sure all of the inner types get preserved exactly. A nice consequence of that relaxation is that we can now do what we originally wanted to do with unknownAsBool, and omit map keys and object attributes altogether if their values would've been false, producing a much more compact result. This is easiest to do now when there's only one known user of this JSON plan output, and we know that user will treat both false and omitted as the same here.
2019-05-25 01:30:58 +02:00
"delete": {
Action: plans.Delete,
Before: cty.NullVal(cty.EmptyObject),
After: cty.NilVal,
Want: nil,
Err: false,
},
command/jsonplan: Don't panic with mixtures of known/unknown/empty The omitUnknowns and unknownAsBool functions were previously trying hard to preserve the same collection types in the output as they had in the input, by attempting to keep everything matched up so that the results would be valid. Unfortunately, this turns out to be a harder problem than we originally thought: it was possible for a collection value going in to produce inconsistent element types out (and thus a panic) in the following situations: - when a collection with mixed known and unknown values was passed in to omitUnknowns. - when a collection of collections where the inner collections are a mixture of empty and not empty in unknownAsNull. The results of these functions are only used to marshal to JSON anyway, and JSON serialization can't distinguish between the three sequence types or the two mapping types, so in practice we can just standardize on converting all sequences to tuple and all mappings to object here and not change the resulting output at all, and then we don't have to worry about making sure all of the inner types get preserved exactly. A nice consequence of that relaxation is that we can now do what we originally wanted to do with unknownAsBool, and omit map keys and object attributes altogether if their values would've been false, producing a much more compact result. This is easiest to do now when there's only one known user of this JSON plan output, and we know that user will treat both false and omitted as the same here.
2019-05-25 01:30:58 +02:00
"update without unknowns": {
Action: plans.Update,
Before: cty.ObjectVal(map[string]cty.Value{
"woozles": cty.StringVal("foo"),
"foozles": cty.StringVal("bar"),
}),
After: cty.ObjectVal(map[string]cty.Value{
"woozles": cty.StringVal("baz"),
"foozles": cty.StringVal("bat"),
}),
Want: []resource{resource{
Address: "test_thing.example",
Mode: "managed",
Type: "test_thing",
Name: "example",
Index: addrs.InstanceKey(nil),
ProviderName: "registry.terraform.io/hashicorp/test",
SchemaVersion: 1,
AttributeValues: attributeValues{
mildwonkey/b-show-state (#20032) * command/show: properly marshal attribute values to json marshalAttributeValues in jsonstate and jsonplan packages was returning a cty.Value, which json/encoding could not marshal. These functions now convert those cty.Values into json.RawMessages. * command/jsonplan: planned values should include resources that are not changing * command/jsonplan: return a filtered list of proposed 'after' attributes Previously, proposed 'after' attributes were not being shown if the attributes were not WhollyKnown. jsonplan now iterates through all the `after` attributes, omitting those which are not wholly known. The same was roughly true for after_unknown, and that structure is now correctly populated. In the future we may choose to filter the after_unknown structure to _only_ display unknown attributes, instead of all attributes. * command/jsonconfig: use a unique key for providers so that aliased providers don't get munged together This now uses the same "provider" key from configs.Module, e.g. `providername.provideralias`. * command/jsonplan: unknownAsBool needs to iterate through objects that are not wholly known * command/jsonplan: properly display actions as strings according to the RFC, instead of a plans.Action string. For example: a plans.Action string DeleteThenCreate should be displayed as ["delete", "create"] Tests have been updated to reflect this. * command/jsonplan: return "null" for unknown list items. The length of a list could be meaningful on its own, so we will turn unknowns into "null". The same is less likely true for maps and objects, so we will continue to omit unknown values from those.
2019-01-23 20:46:53 +01:00
"woozles": json.RawMessage(`"baz"`),
"foozles": json.RawMessage(`"bat"`),
},
}},
Err: false,
},
}
command/jsonplan: Don't panic with mixtures of known/unknown/empty The omitUnknowns and unknownAsBool functions were previously trying hard to preserve the same collection types in the output as they had in the input, by attempting to keep everything matched up so that the results would be valid. Unfortunately, this turns out to be a harder problem than we originally thought: it was possible for a collection value going in to produce inconsistent element types out (and thus a panic) in the following situations: - when a collection with mixed known and unknown values was passed in to omitUnknowns. - when a collection of collections where the inner collections are a mixture of empty and not empty in unknownAsNull. The results of these functions are only used to marshal to JSON anyway, and JSON serialization can't distinguish between the three sequence types or the two mapping types, so in practice we can just standardize on converting all sequences to tuple and all mappings to object here and not change the resulting output at all, and then we don't have to worry about making sure all of the inner types get preserved exactly. A nice consequence of that relaxation is that we can now do what we originally wanted to do with unknownAsBool, and omit map keys and object attributes altogether if their values would've been false, producing a much more compact result. This is easiest to do now when there's only one known user of this JSON plan output, and we know that user will treat both false and omitted as the same here.
2019-05-25 01:30:58 +02:00
for name, test := range tests {
t.Run(name, func(t *testing.T) {
before, err := plans.NewDynamicValue(test.Before, test.Before.Type())
if err != nil {
t.Fatal(err)
}
command/jsonplan: Don't panic with mixtures of known/unknown/empty The omitUnknowns and unknownAsBool functions were previously trying hard to preserve the same collection types in the output as they had in the input, by attempting to keep everything matched up so that the results would be valid. Unfortunately, this turns out to be a harder problem than we originally thought: it was possible for a collection value going in to produce inconsistent element types out (and thus a panic) in the following situations: - when a collection with mixed known and unknown values was passed in to omitUnknowns. - when a collection of collections where the inner collections are a mixture of empty and not empty in unknownAsNull. The results of these functions are only used to marshal to JSON anyway, and JSON serialization can't distinguish between the three sequence types or the two mapping types, so in practice we can just standardize on converting all sequences to tuple and all mappings to object here and not change the resulting output at all, and then we don't have to worry about making sure all of the inner types get preserved exactly. A nice consequence of that relaxation is that we can now do what we originally wanted to do with unknownAsBool, and omit map keys and object attributes altogether if their values would've been false, producing a much more compact result. This is easiest to do now when there's only one known user of this JSON plan output, and we know that user will treat both false and omitted as the same here.
2019-05-25 01:30:58 +02:00
after, err := plans.NewDynamicValue(test.After, test.After.Type())
if err != nil {
t.Fatal(err)
}
testChange := &plans.Changes{
Resources: []*plans.ResourceInstanceChangeSrc{
{
Addr: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "example",
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
ProviderAddr: addrs.AbsProviderConfig{
Provider: addrs.NewDefaultProvider("test"),
Module: addrs.RootModule,
},
command/jsonplan: Don't panic with mixtures of known/unknown/empty The omitUnknowns and unknownAsBool functions were previously trying hard to preserve the same collection types in the output as they had in the input, by attempting to keep everything matched up so that the results would be valid. Unfortunately, this turns out to be a harder problem than we originally thought: it was possible for a collection value going in to produce inconsistent element types out (and thus a panic) in the following situations: - when a collection with mixed known and unknown values was passed in to omitUnknowns. - when a collection of collections where the inner collections are a mixture of empty and not empty in unknownAsNull. The results of these functions are only used to marshal to JSON anyway, and JSON serialization can't distinguish between the three sequence types or the two mapping types, so in practice we can just standardize on converting all sequences to tuple and all mappings to object here and not change the resulting output at all, and then we don't have to worry about making sure all of the inner types get preserved exactly. A nice consequence of that relaxation is that we can now do what we originally wanted to do with unknownAsBool, and omit map keys and object attributes altogether if their values would've been false, producing a much more compact result. This is easiest to do now when there's only one known user of this JSON plan output, and we know that user will treat both false and omitted as the same here.
2019-05-25 01:30:58 +02:00
ChangeSrc: plans.ChangeSrc{
Action: test.Action,
Before: before,
After: after,
},
},
},
command/jsonplan: Don't panic with mixtures of known/unknown/empty The omitUnknowns and unknownAsBool functions were previously trying hard to preserve the same collection types in the output as they had in the input, by attempting to keep everything matched up so that the results would be valid. Unfortunately, this turns out to be a harder problem than we originally thought: it was possible for a collection value going in to produce inconsistent element types out (and thus a panic) in the following situations: - when a collection with mixed known and unknown values was passed in to omitUnknowns. - when a collection of collections where the inner collections are a mixture of empty and not empty in unknownAsNull. The results of these functions are only used to marshal to JSON anyway, and JSON serialization can't distinguish between the three sequence types or the two mapping types, so in practice we can just standardize on converting all sequences to tuple and all mappings to object here and not change the resulting output at all, and then we don't have to worry about making sure all of the inner types get preserved exactly. A nice consequence of that relaxation is that we can now do what we originally wanted to do with unknownAsBool, and omit map keys and object attributes altogether if their values would've been false, producing a much more compact result. This is easiest to do now when there's only one known user of this JSON plan output, and we know that user will treat both false and omitted as the same here.
2019-05-25 01:30:58 +02:00
}
command/jsonplan: Don't panic with mixtures of known/unknown/empty The omitUnknowns and unknownAsBool functions were previously trying hard to preserve the same collection types in the output as they had in the input, by attempting to keep everything matched up so that the results would be valid. Unfortunately, this turns out to be a harder problem than we originally thought: it was possible for a collection value going in to produce inconsistent element types out (and thus a panic) in the following situations: - when a collection with mixed known and unknown values was passed in to omitUnknowns. - when a collection of collections where the inner collections are a mixture of empty and not empty in unknownAsNull. The results of these functions are only used to marshal to JSON anyway, and JSON serialization can't distinguish between the three sequence types or the two mapping types, so in practice we can just standardize on converting all sequences to tuple and all mappings to object here and not change the resulting output at all, and then we don't have to worry about making sure all of the inner types get preserved exactly. A nice consequence of that relaxation is that we can now do what we originally wanted to do with unknownAsBool, and omit map keys and object attributes altogether if their values would've been false, producing a much more compact result. This is easiest to do now when there's only one known user of this JSON plan output, and we know that user will treat both false and omitted as the same here.
2019-05-25 01:30:58 +02:00
ris := testResourceAddrs()
command/jsonplan: Don't panic with mixtures of known/unknown/empty The omitUnknowns and unknownAsBool functions were previously trying hard to preserve the same collection types in the output as they had in the input, by attempting to keep everything matched up so that the results would be valid. Unfortunately, this turns out to be a harder problem than we originally thought: it was possible for a collection value going in to produce inconsistent element types out (and thus a panic) in the following situations: - when a collection with mixed known and unknown values was passed in to omitUnknowns. - when a collection of collections where the inner collections are a mixture of empty and not empty in unknownAsNull. The results of these functions are only used to marshal to JSON anyway, and JSON serialization can't distinguish between the three sequence types or the two mapping types, so in practice we can just standardize on converting all sequences to tuple and all mappings to object here and not change the resulting output at all, and then we don't have to worry about making sure all of the inner types get preserved exactly. A nice consequence of that relaxation is that we can now do what we originally wanted to do with unknownAsBool, and omit map keys and object attributes altogether if their values would've been false, producing a much more compact result. This is easiest to do now when there's only one known user of this JSON plan output, and we know that user will treat both false and omitted as the same here.
2019-05-25 01:30:58 +02:00
got, err := marshalPlanResources(testChange, ris, testSchemas())
if test.Err {
if err == nil {
t.Fatal("succeeded; want error")
}
return
} else if err != nil {
t.Fatalf("unexpected error: %s", err)
}
command/jsonplan: Don't panic with mixtures of known/unknown/empty The omitUnknowns and unknownAsBool functions were previously trying hard to preserve the same collection types in the output as they had in the input, by attempting to keep everything matched up so that the results would be valid. Unfortunately, this turns out to be a harder problem than we originally thought: it was possible for a collection value going in to produce inconsistent element types out (and thus a panic) in the following situations: - when a collection with mixed known and unknown values was passed in to omitUnknowns. - when a collection of collections where the inner collections are a mixture of empty and not empty in unknownAsNull. The results of these functions are only used to marshal to JSON anyway, and JSON serialization can't distinguish between the three sequence types or the two mapping types, so in practice we can just standardize on converting all sequences to tuple and all mappings to object here and not change the resulting output at all, and then we don't have to worry about making sure all of the inner types get preserved exactly. A nice consequence of that relaxation is that we can now do what we originally wanted to do with unknownAsBool, and omit map keys and object attributes altogether if their values would've been false, producing a much more compact result. This is easiest to do now when there's only one known user of this JSON plan output, and we know that user will treat both false and omitted as the same here.
2019-05-25 01:30:58 +02:00
eq := reflect.DeepEqual(got, test.Want)
if !eq {
t.Fatalf("wrong result:\nGot: %#v\nWant: %#v\n", got, test.Want)
}
})
}
}
func testSchemas() *terraform.Schemas {
return &terraform.Schemas{
Providers: map[addrs.Provider]*terraform.ProviderSchema{
addrs.NewDefaultProvider("test"): &terraform.ProviderSchema{
ResourceTypes: map[string]*configschema.Block{
"test_thing": {
Attributes: map[string]*configschema.Attribute{
"woozles": {Type: cty.String, Optional: true, Computed: true},
"foozles": {Type: cty.String, Optional: true},
},
},
},
ResourceTypeSchemaVersions: map[string]uint64{
"test_thing": 1,
},
},
},
}
}
func testResourceAddrs() []addrs.AbsResourceInstance {
return []addrs.AbsResourceInstance{
mustAddr("test_thing.example"),
}
}
func mustAddr(str string) addrs.AbsResourceInstance {
addr, diags := addrs.ParseAbsResourceInstanceStr(str)
if diags.HasErrors() {
panic(diags.Err())
}
return addr
}