Skip to content

Commit

Permalink
tftypes: Adjust (tftypes.Value).Equal function to support dynamic v…
Browse files Browse the repository at this point in the history
…alue comparisons (#383)

* add as dynamic

* add safe equal

* remove save equal

* add changelog

* added tests for equal
  • Loading branch information
austinvalle committed Feb 29, 2024
1 parent 01b86e9 commit 570828e
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .changes/unreleased/BUG FIXES-20240228-171104.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: BUG FIXES
body: 'tftypes: Fixed an edge-case where `(Value).Equal` would panic when comparing
two values with underlying `DynamicPseudoType` types and different concrete values.'
time: 2024-02-28T17:11:04.381759-05:00
custom:
Issue: "383"
2 changes: 1 addition & 1 deletion tftypes/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ func (val Value) Equal(o Value) bool {
}
deepEqual, err := val.deepEqual(o)
if err != nil {
panic(err)
return false
}
return deepEqual
}
Expand Down
114 changes: 114 additions & 0 deletions tftypes/value_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,11 @@ func TestValueEqual(t *testing.T) {
val2: NewValue(String, "world"),
equal: false,
},
"stringDiff-wrong-type": {
val1: NewValue(String, "true"),
val2: NewValue(Bool, true),
equal: false,
},
"boolEqual": {
val1: NewValue(Bool, true),
val2: NewValue(Bool, true),
Expand All @@ -753,6 +758,11 @@ func TestValueEqual(t *testing.T) {
val2: NewValue(Bool, true),
equal: false,
},
"boolDiff-wrong-type": {
val1: NewValue(Bool, true),
val2: NewValue(String, "true"),
equal: false,
},
"numberEqual": {
val1: NewValue(Number, big.NewFloat(123)),
val2: NewValue(Number, big.NewFloat(0).SetInt64(123)),
Expand All @@ -763,6 +773,11 @@ func TestValueEqual(t *testing.T) {
val2: NewValue(Number, big.NewFloat(2)),
equal: false,
},
"numberDiff-wrong-type": {
val1: NewValue(Number, big.NewFloat(1)),
val2: NewValue(String, "1"),
equal: false,
},
"unknownEqual": {
val1: NewValue(String, UnknownValue),
val2: NewValue(String, UnknownValue),
Expand Down Expand Up @@ -811,6 +826,19 @@ func TestValueEqual(t *testing.T) {
}),
equal: false,
},
"listDiff-wrong-type": {
val1: NewValue(List{ElementType: String}, []Value{
NewValue(String, "hello"),
NewValue(String, "world"),
NewValue(String, "abc"),
}),
val2: NewValue(Set{ElementType: String}, []Value{
NewValue(String, "hello"),
NewValue(String, "world"),
NewValue(String, "abc"),
}),
equal: false,
},
"setEqual": {
val1: NewValue(Set{ElementType: String}, []Value{
NewValue(String, "hello"),
Expand Down Expand Up @@ -849,6 +877,19 @@ func TestValueEqual(t *testing.T) {
}),
equal: false,
},
"setDiff-wrong-type": {
val1: NewValue(Set{ElementType: String}, []Value{
NewValue(String, "hello"),
NewValue(String, "world"),
NewValue(String, "abc"),
}),
val2: NewValue(List{ElementType: String}, []Value{
NewValue(String, "hello"),
NewValue(String, "world"),
NewValue(String, "abc"),
}),
equal: false,
},
"tupleEqual": {
val1: NewValue(Tuple{ElementTypes: []Type{
String, Bool, Number, List{ElementType: String},
Expand Down Expand Up @@ -981,6 +1022,17 @@ func TestValueEqual(t *testing.T) {
}),
equal: false,
},
"mapDiff-wrong-types": {
val1: NewValue(Map{ElementType: String}, map[string]Value{
"one": NewValue(String, "true"),
"two": NewValue(String, "false"),
}),
val2: NewValue(Map{ElementType: Bool}, map[string]Value{
"one": NewValue(Bool, true),
"two": NewValue(Bool, false),
}),
equal: false,
},
"objectEqual": {
val1: NewValue(Object{AttributeTypes: map[string]Type{
"one": Number,
Expand Down Expand Up @@ -1068,6 +1120,68 @@ func TestValueEqual(t *testing.T) {
}),
equal: false,
},
"DynamicPseudoType-tupleEqual": {
val1: NewValue(Tuple{ElementTypes: []Type{
DynamicPseudoType, DynamicPseudoType,
}}, []Value{
NewValue(Bool, true),
NewValue(List{ElementType: String}, []Value{
NewValue(String, "a"),
NewValue(String, "b"),
NewValue(String, "c"),
}),
}),
val2: NewValue(Tuple{ElementTypes: []Type{
DynamicPseudoType, DynamicPseudoType,
}}, []Value{
NewValue(Bool, true),
NewValue(List{ElementType: String}, []Value{
NewValue(String, "a"),
NewValue(String, "b"),
NewValue(String, "c"),
}),
}),
equal: true,
},
// Previously, different value types with a DynamicPseudoType would cause a panic
// https://github.com/hashicorp/terraform-plugin-go/pull/383
"DynamicPseudoType-tupleDiff-different-value-types": {
val1: NewValue(Tuple{ElementTypes: []Type{DynamicPseudoType}}, []Value{
NewValue(String, "false"),
}),
val2: NewValue(Tuple{ElementTypes: []Type{DynamicPseudoType}}, []Value{
NewValue(Bool, false), // This value type is different than val1
}),
equal: false,
},
"DynamicPseudoType-objectEqual": {
val1: NewValue(Object{AttributeTypes: map[string]Type{
"dyn_val": DynamicPseudoType,
}}, map[string]Value{
"dyn_val": NewValue(String, "hello"),
}),
val2: NewValue(Object{AttributeTypes: map[string]Type{
"dyn_val": DynamicPseudoType,
}}, map[string]Value{
"dyn_val": NewValue(String, "hello"),
}),
equal: true,
},
// Previously, different value types with a DynamicPseudoType would cause a panic
// https://github.com/hashicorp/terraform-plugin-go/pull/383
"DynamicPseudoType-objectDiff-different-value-types": {
val1: NewValue(Object{AttributeTypes: map[string]Type{
"dyn_val": DynamicPseudoType,
}}, map[string]Value{
"dyn_val": NewValue(String, "1"),
}),
val2: NewValue(Object{AttributeTypes: map[string]Type{
"dyn_val": DynamicPseudoType,
}}, map[string]Value{
"dyn_val": NewValue(Number, big.NewFloat(1)), // This value type is different than val1
}),
equal: false,
},
"nullEqual": {
val1: NewValue(String, nil),
val2: NewValue(String, nil),
Expand Down

0 comments on commit 570828e

Please sign in to comment.