From e76042b11358b1cef93e2aea39e167d11e932e8a Mon Sep 17 00:00:00 2001 From: Liam Cervante Date: Mon, 7 Nov 2022 17:25:53 +0100 Subject: [PATCH 1/4] Add test cases to verify all the default and optional issues are fixed --- internal/terraform/eval_variable_test.go | 218 +++++++++++++++++++++++ 1 file changed, 218 insertions(+) diff --git a/internal/terraform/eval_variable_test.go b/internal/terraform/eval_variable_test.go index 15d250ceb193..7ca63d7d247a 100644 --- a/internal/terraform/eval_variable_test.go +++ b/internal/terraform/eval_variable_test.go @@ -92,6 +92,94 @@ func TestPrepareFinalInputVariableValue(t *testing.T) { }) }) } + // https://github.com/hashicorp/terraform/issues/32152 + // This variable was originally added to test that optional attribute + // metadata is stripped from empty default collections. Essentially, you + // should be able to mix and match custom and default values for the + // optional_list attribute. + variable "complex_type_with_empty_default_and_nested_optional" { + type = list(object({ + name = string + optional_list = optional(list(object({ + string = string + optional_string = optional(string) + })), []) + })) + } + // https://github.com/hashicorp/terraform/issues/32160#issuecomment-1302783910 + // These variables were added to test the specific use case from this + // GitHub comment. + variable "empty_object_with_optional_nested_object_with_optional_bool" { + type = object({ + thing = optional(object({ + flag = optional(bool, false) + })) + }) + default = {} + } + variable "populated_object_with_optional_nested_object_with_optional_bool" { + type = object({ + thing = optional(object({ + flag = optional(bool, false) + })) + }) + default = { + thing = {} + } + } + variable "empty_object_with_default_nested_object_with_optional_bool" { + type = object({ + thing = optional(object({ + flag = optional(bool, false) + }), {}) + }) + default = {} + } + // https://github.com/hashicorp/terraform/issues/32160 + // This variable was originally added to test that optional objects do + // get created containing only their defaults. Instead they should be + // left empty. We do not expect nested_object to be created just because + // optional_string has a default value. + variable "object_with_nested_object_with_required_and_optional_attributes" { + type = object({ + nested_object = optional(object({ + string = string + optional_string = optional(string, "optional") + })) + }) + } + // https://github.com/hashicorp/terraform/issues/32157 + // Similar to above, we want to see that merging combinations of the + // nested_object into a single collection doesn't crash because of + // inconsistent elements. + variable "list_with_nested_object_with_required_and_optional_attributes" { + type = list(object({ + nested_object = optional(object({ + string = string + optional_string = optional(string, "optional") + })) + })) + } + // https://github.com/hashicorp/terraform/issues/32109 + // This variable was originally introduced to test the behaviour of + // the dynamic type constraint. You should be able to use the 'any' + // constraint and introduce empty, null, and populated values into the + // list. + variable "list_with_nested_list_of_any" { + type = list(object({ + a = string + b = optional(list(any)) + })) + default = [ + { + a = "a" + }, + { + a = "b" + b = [1] + } + ] + } ` cfg := testModuleInline(t, map[string]string{ "main.tf": cfgSrc, @@ -496,6 +584,136 @@ func TestPrepareFinalInputVariableValue(t *testing.T) { }), ``, }, + //{ + // "complex_type_with_empty_default_and_nested_optional", + // cty.ListVal([]cty.Value{ + // cty.ObjectVal(map[string]cty.Value{ + // "name": cty.StringVal("abc"), + // "optional_list": cty.ListVal([]cty.Value{ + // cty.ObjectVal(map[string]cty.Value{ + // "string": cty.StringVal("child"), + // "optional_string": cty.NullVal(cty.String), + // }), + // }), + // }), + // cty.ObjectVal(map[string]cty.Value{ + // "name": cty.StringVal("def"), + // "optional_list": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ + // "string": cty.String, + // "optional_string": cty.String, + // }))), + // }), + // }), + // cty.ListVal([]cty.Value{ + // cty.ObjectVal(map[string]cty.Value{ + // "name": cty.StringVal("abc"), + // "optional_list": cty.ListVal([]cty.Value{ + // cty.ObjectVal(map[string]cty.Value{ + // "string": cty.StringVal("child"), + // "optional_string": cty.NullVal(cty.String), + // }), + // }), + // }), + // cty.ObjectVal(map[string]cty.Value{ + // "name": cty.StringVal("def"), + // "optional_list": cty.ListValEmpty(cty.Object(map[string]cty.Type{ + // "string": cty.String, + // "optional_string": cty.String, + // })), + // }), + // }), + // ``, + //}, + { + "object_with_nested_object_with_required_and_optional_attributes", + cty.EmptyObjectVal, + cty.ObjectVal(map[string]cty.Value{ + "nested_object": cty.NullVal(cty.Object(map[string]cty.Type{ + "string": cty.String, + "optional_string": cty.String, + })), + }), + ``, + }, + { + "empty_object_with_optional_nested_object_with_optional_bool", + cty.NilVal, + cty.ObjectVal(map[string]cty.Value{ + "thing": cty.NullVal(cty.Object(map[string]cty.Type{ + "flag": cty.Bool, + })), + }), + ``, + }, + { + "populated_object_with_optional_nested_object_with_optional_bool", + cty.NilVal, + cty.ObjectVal(map[string]cty.Value{ + "thing": cty.ObjectVal(map[string]cty.Value{ + "flag": cty.False, + }), + }), + ``, + }, + { + "empty_object_with_default_nested_object_with_optional_bool", + cty.NilVal, + cty.ObjectVal(map[string]cty.Value{ + "thing": cty.ObjectVal(map[string]cty.Value{ + "flag": cty.False, + }), + }), + ``, + }, + //{ + // "list_with_nested_object_with_required_and_optional_attributes", + // cty.ListVal([]cty.Value{ + // cty.ObjectVal(map[string]cty.Value{ + // "nested_object": cty.ObjectVal(map[string]cty.Value{ + // "string": cty.StringVal("string"), + // "optional_string": cty.NullVal(cty.String), + // }), + // }), + // cty.ObjectVal(map[string]cty.Value{ + // "nested_object": cty.NullVal(cty.Object(map[string]cty.Type{ + // "string": cty.String, + // "optional_string": cty.String, + // })), + // }), + // }), + // cty.ListVal([]cty.Value{ + // cty.ObjectVal(map[string]cty.Value{ + // "nested_object": cty.ObjectVal(map[string]cty.Value{ + // "string": cty.StringVal("string"), + // "optional_string": cty.StringVal("optional"), + // }), + // }), + // cty.ObjectVal(map[string]cty.Value{ + // "nested_object": cty.NullVal(cty.Object(map[string]cty.Type{ + // "string": cty.String, + // "optional_string": cty.String, + // })), + // }), + // }), + // ``, + //}, + //{ + // "list_with_nested_list_of_any", + // cty.NilVal, + // cty.ListVal([]cty.Value{ + // cty.ObjectVal(map[string]cty.Value{ + // "a": cty.StringVal("a"), + // "b": cty.NullVal(cty.List(cty.Number)), + // }), + // cty.ObjectVal(map[string]cty.Value{ + // "a": cty.StringVal("b"), + // "b": cty.ListVal([]cty.Value{ + // cty.NumberIntVal(1), + // }), + // }), + // }), + // ``, + //}, // sensitive { From 9b2b8ecfddbe2e4c2013a4a5c88517f6119dd7ca Mon Sep 17 00:00:00 2001 From: Liam Cervante Date: Mon, 7 Nov 2022 17:39:18 +0100 Subject: [PATCH 2/4] actually commit all the tests --- internal/terraform/eval_variable_test.go | 178 +++++++++++------------ 1 file changed, 89 insertions(+), 89 deletions(-) diff --git a/internal/terraform/eval_variable_test.go b/internal/terraform/eval_variable_test.go index 7ca63d7d247a..702c7a8a31b0 100644 --- a/internal/terraform/eval_variable_test.go +++ b/internal/terraform/eval_variable_test.go @@ -584,46 +584,46 @@ func TestPrepareFinalInputVariableValue(t *testing.T) { }), ``, }, - //{ - // "complex_type_with_empty_default_and_nested_optional", - // cty.ListVal([]cty.Value{ - // cty.ObjectVal(map[string]cty.Value{ - // "name": cty.StringVal("abc"), - // "optional_list": cty.ListVal([]cty.Value{ - // cty.ObjectVal(map[string]cty.Value{ - // "string": cty.StringVal("child"), - // "optional_string": cty.NullVal(cty.String), - // }), - // }), - // }), - // cty.ObjectVal(map[string]cty.Value{ - // "name": cty.StringVal("def"), - // "optional_list": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ - // "string": cty.String, - // "optional_string": cty.String, - // }))), - // }), - // }), - // cty.ListVal([]cty.Value{ - // cty.ObjectVal(map[string]cty.Value{ - // "name": cty.StringVal("abc"), - // "optional_list": cty.ListVal([]cty.Value{ - // cty.ObjectVal(map[string]cty.Value{ - // "string": cty.StringVal("child"), - // "optional_string": cty.NullVal(cty.String), - // }), - // }), - // }), - // cty.ObjectVal(map[string]cty.Value{ - // "name": cty.StringVal("def"), - // "optional_list": cty.ListValEmpty(cty.Object(map[string]cty.Type{ - // "string": cty.String, - // "optional_string": cty.String, - // })), - // }), - // }), - // ``, - //}, + { + "complex_type_with_empty_default_and_nested_optional", + cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "name": cty.StringVal("abc"), + "optional_list": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "string": cty.StringVal("child"), + "optional_string": cty.NullVal(cty.String), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "name": cty.StringVal("def"), + "optional_list": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ + "string": cty.String, + "optional_string": cty.String, + }))), + }), + }), + cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "name": cty.StringVal("abc"), + "optional_list": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "string": cty.StringVal("child"), + "optional_string": cty.NullVal(cty.String), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "name": cty.StringVal("def"), + "optional_list": cty.ListValEmpty(cty.Object(map[string]cty.Type{ + "string": cty.String, + "optional_string": cty.String, + })), + }), + }), + ``, + }, { "object_with_nested_object_with_required_and_optional_attributes", cty.EmptyObjectVal, @@ -665,55 +665,55 @@ func TestPrepareFinalInputVariableValue(t *testing.T) { }), ``, }, - //{ - // "list_with_nested_object_with_required_and_optional_attributes", - // cty.ListVal([]cty.Value{ - // cty.ObjectVal(map[string]cty.Value{ - // "nested_object": cty.ObjectVal(map[string]cty.Value{ - // "string": cty.StringVal("string"), - // "optional_string": cty.NullVal(cty.String), - // }), - // }), - // cty.ObjectVal(map[string]cty.Value{ - // "nested_object": cty.NullVal(cty.Object(map[string]cty.Type{ - // "string": cty.String, - // "optional_string": cty.String, - // })), - // }), - // }), - // cty.ListVal([]cty.Value{ - // cty.ObjectVal(map[string]cty.Value{ - // "nested_object": cty.ObjectVal(map[string]cty.Value{ - // "string": cty.StringVal("string"), - // "optional_string": cty.StringVal("optional"), - // }), - // }), - // cty.ObjectVal(map[string]cty.Value{ - // "nested_object": cty.NullVal(cty.Object(map[string]cty.Type{ - // "string": cty.String, - // "optional_string": cty.String, - // })), - // }), - // }), - // ``, - //}, - //{ - // "list_with_nested_list_of_any", - // cty.NilVal, - // cty.ListVal([]cty.Value{ - // cty.ObjectVal(map[string]cty.Value{ - // "a": cty.StringVal("a"), - // "b": cty.NullVal(cty.List(cty.Number)), - // }), - // cty.ObjectVal(map[string]cty.Value{ - // "a": cty.StringVal("b"), - // "b": cty.ListVal([]cty.Value{ - // cty.NumberIntVal(1), - // }), - // }), - // }), - // ``, - //}, + { + "list_with_nested_object_with_required_and_optional_attributes", + cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "nested_object": cty.ObjectVal(map[string]cty.Value{ + "string": cty.StringVal("string"), + "optional_string": cty.NullVal(cty.String), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "nested_object": cty.NullVal(cty.Object(map[string]cty.Type{ + "string": cty.String, + "optional_string": cty.String, + })), + }), + }), + cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "nested_object": cty.ObjectVal(map[string]cty.Value{ + "string": cty.StringVal("string"), + "optional_string": cty.StringVal("optional"), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "nested_object": cty.NullVal(cty.Object(map[string]cty.Type{ + "string": cty.String, + "optional_string": cty.String, + })), + }), + }), + ``, + }, + { + "list_with_nested_list_of_any", + cty.NilVal, + cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "a": cty.StringVal("a"), + "b": cty.NullVal(cty.List(cty.Number)), + }), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.StringVal("b"), + "b": cty.ListVal([]cty.Value{ + cty.NumberIntVal(1), + }), + }), + }), + ``, + }, // sensitive { From 15080e2ba8c957706c6774b8ed035902db9f47aa Mon Sep 17 00:00:00 2001 From: Liam Cervante Date: Wed, 9 Nov 2022 11:14:32 +0100 Subject: [PATCH 3/4] update go-cty --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 26bec9a4db62..5643f02f82d5 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/tombuildsstuff/giovanni v0.15.1 github.com/xanzy/ssh-agent v0.3.1 github.com/xlab/treeprint v0.0.0-20161029104018-1d6e34225557 - github.com/zclconf/go-cty v1.12.0 + github.com/zclconf/go-cty v1.12.1 github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b github.com/zclconf/go-cty-yaml v1.0.2 golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 diff --git a/go.sum b/go.sum index 611b8429fbac..555a07692495 100644 --- a/go.sum +++ b/go.sum @@ -619,8 +619,8 @@ github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.12.0 h1:F5E/vbilcrCtat9sYcEjlwwg1mDqbRTjyXR57nnx5sc= -github.com/zclconf/go-cty v1.12.0/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= +github.com/zclconf/go-cty v1.12.1 h1:PcupnljUm9EIvbgSHQnHhUr3fO6oFmkOrvs2BAFNXXY= +github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= github.com/zclconf/go-cty-yaml v1.0.2 h1:dNyg4QLTrv2IfJpm7Wtxi55ed5gLGOlPrZ6kMd51hY0= From 55712ab99094fe6cf5c19c064c12d86d3d331507 Mon Sep 17 00:00:00 2001 From: Liam Cervante Date: Thu, 10 Nov 2022 11:12:43 +0000 Subject: [PATCH 4/4] Update hcl --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5643f02f82d5..0dd496cdb969 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f - github.com/hashicorp/hcl/v2 v2.14.1 + github.com/hashicorp/hcl/v2 v2.15.0 github.com/hashicorp/terraform-config-inspect v0.0.0-20210209133302-4fd17a0faac2 github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 diff --git a/go.sum b/go.sum index 555a07692495..6dde32328e44 100644 --- a/go.sum +++ b/go.sum @@ -387,8 +387,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws= github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90= -github.com/hashicorp/hcl/v2 v2.14.1 h1:x0BpjfZ+CYdbiz+8yZTQ+gdLO7IXvOut7Da+XJayx34= -github.com/hashicorp/hcl/v2 v2.14.1/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0= +github.com/hashicorp/hcl/v2 v2.15.0 h1:CPDXO6+uORPjKflkWCCwoWc9uRp+zSIPcCQ+BrxV7m8= +github.com/hashicorp/hcl/v2 v2.15.0/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng= github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d h1:9ARUJJ1VVynB176G1HCwleORqCaXm/Vx0uUi0dL26I0= github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d/go.mod h1:Yog5+CPEM3c99L1CL2CFCYoSzgWm5vTU58idbRUaLik= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=