core: fix the tests in variables_test.go
This test required some adaptation for the new variable handling model in the HCL2-oriented codepaths, where more of the handling is now done in the "command" package. The initial reorganization of this test was not correct, so this is a further revision to adapt the original assertions to the new model as much as possible, removing a few tests that no longer make sense in the new world.
This commit is contained in:
parent
60ad24229f
commit
c58bdc6390
|
@ -1,6 +1,8 @@
|
||||||
package terraform
|
package terraform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/configs"
|
"github.com/hashicorp/terraform/configs"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
@ -57,6 +59,18 @@ const (
|
||||||
ValueFromCaller ValueSourceType = 'S'
|
ValueFromCaller ValueSourceType = 'S'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (v *InputValue) GoString() string {
|
||||||
|
if (v.SourceRange != tfdiags.SourceRange{}) {
|
||||||
|
return fmt.Sprintf("&terraform.InputValue{Value: %#v, SourceType: %#v, SourceRange: %#v}", v.Value, v.SourceType, v.SourceRange)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("&terraform.InputValue{Value: %#v, SourceType: %#v}", v.Value, v.SourceType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v ValueSourceType) GoString() string {
|
||||||
|
return fmt.Sprintf("terraform.%s", v)
|
||||||
|
}
|
||||||
|
|
||||||
//go:generate stringer -type ValueSourceType
|
//go:generate stringer -type ValueSourceType
|
||||||
|
|
||||||
// InputValues is a map of InputValue instances.
|
// InputValues is a map of InputValue instances.
|
||||||
|
@ -124,3 +138,84 @@ func DefaultVariableValues(configs map[string]*configs.Variable) InputValues {
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SameValues returns true if the given InputValues has the same values as
|
||||||
|
// the receiever, disregarding the source types and source ranges.
|
||||||
|
//
|
||||||
|
// Values are compared using the cty "RawEquals" method, which means that
|
||||||
|
// unknown values can be considered equal to one another if they are of the
|
||||||
|
// same type.
|
||||||
|
func (vv InputValues) SameValues(other InputValues) bool {
|
||||||
|
if len(vv) != len(other) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range vv {
|
||||||
|
ov, exists := other[k]
|
||||||
|
if !exists {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !v.Value.RawEquals(ov.Value) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasValues returns true if the reciever has the same values as in the given
|
||||||
|
// map, disregarding the source types and source ranges.
|
||||||
|
//
|
||||||
|
// Values are compared using the cty "RawEquals" method, which means that
|
||||||
|
// unknown values can be considered equal to one another if they are of the
|
||||||
|
// same type.
|
||||||
|
func (vv InputValues) HasValues(vals map[string]cty.Value) bool {
|
||||||
|
if len(vv) != len(vals) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range vv {
|
||||||
|
oVal, exists := vals[k]
|
||||||
|
if !exists {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !v.Value.RawEquals(oVal) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identical returns true if the given InputValues has the same values,
|
||||||
|
// source types, and source ranges as the receiver.
|
||||||
|
//
|
||||||
|
// Values are compared using the cty "RawEquals" method, which means that
|
||||||
|
// unknown values can be considered equal to one another if they are of the
|
||||||
|
// same type.
|
||||||
|
//
|
||||||
|
// This method is primarily for testing. For most practical purposes, it's
|
||||||
|
// better to use SameValues or HasValues.
|
||||||
|
func (vv InputValues) Identical(other InputValues) bool {
|
||||||
|
if len(vv) != len(other) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range vv {
|
||||||
|
ov, exists := other[k]
|
||||||
|
if !exists {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !v.Value.RawEquals(ov.Value) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if v.SourceType != ov.SourceType {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if v.SourceRange != ov.SourceRange {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
|
@ -1,25 +1,52 @@
|
||||||
package terraform
|
package terraform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
|
|
||||||
|
"github.com/go-test/deep"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestVariables(t *testing.T) {
|
func TestVariables(t *testing.T) {
|
||||||
cases := map[string]struct {
|
tests := map[string]struct {
|
||||||
Module string
|
Module string
|
||||||
Override map[string]cty.Value
|
Override map[string]cty.Value
|
||||||
Expected map[string]cty.Value
|
Want InputValues
|
||||||
}{
|
}{
|
||||||
"config only": {
|
"config only": {
|
||||||
"vars-basic",
|
"vars-basic",
|
||||||
nil,
|
nil,
|
||||||
map[string]cty.Value{
|
InputValues{
|
||||||
"a": cty.StringVal("foo"),
|
"a": &InputValue{
|
||||||
"b": cty.ListValEmpty(cty.String),
|
Value: cty.StringVal("foo"),
|
||||||
"c": cty.MapValEmpty(cty.String),
|
SourceType: ValueFromConfig,
|
||||||
|
SourceRange: tfdiags.SourceRange{
|
||||||
|
Filename: "test-fixtures/vars-basic/main.tf",
|
||||||
|
Start: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
|
||||||
|
End: tfdiags.SourcePos{Line: 1, Column: 13, Byte: 12},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"b": &InputValue{
|
||||||
|
Value: cty.ListValEmpty(cty.DynamicPseudoType),
|
||||||
|
SourceType: ValueFromConfig,
|
||||||
|
SourceRange: tfdiags.SourceRange{
|
||||||
|
Filename: "test-fixtures/vars-basic/main.tf",
|
||||||
|
Start: tfdiags.SourcePos{Line: 6, Column: 1, Byte: 58},
|
||||||
|
End: tfdiags.SourcePos{Line: 6, Column: 13, Byte: 70},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"c": &InputValue{
|
||||||
|
Value: cty.MapValEmpty(cty.DynamicPseudoType),
|
||||||
|
SourceType: ValueFromConfig,
|
||||||
|
SourceRange: tfdiags.SourceRange{
|
||||||
|
Filename: "test-fixtures/vars-basic/main.tf",
|
||||||
|
Start: tfdiags.SourcePos{Line: 11, Column: 1, Byte: 111},
|
||||||
|
End: tfdiags.SourcePos{Line: 11, Column: 13, Byte: 123},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -35,24 +62,49 @@ func TestVariables(t *testing.T) {
|
||||||
"foo": cty.StringVal("bar"),
|
"foo": cty.StringVal("bar"),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
map[string]cty.Value{
|
InputValues{
|
||||||
"a": cty.StringVal("bar"),
|
"a": &InputValue{
|
||||||
"b": cty.ListVal([]cty.Value{
|
Value: cty.StringVal("bar"),
|
||||||
cty.StringVal("foo"),
|
SourceType: ValueFromCaller,
|
||||||
cty.StringVal("bar"),
|
},
|
||||||
}),
|
"b": &InputValue{
|
||||||
"c": cty.MapVal(map[string]cty.Value{
|
Value: cty.ListVal([]cty.Value{
|
||||||
"foo": cty.StringVal("bar"),
|
cty.StringVal("foo"),
|
||||||
}),
|
cty.StringVal("bar"),
|
||||||
|
}),
|
||||||
|
SourceType: ValueFromCaller,
|
||||||
|
},
|
||||||
|
"c": &InputValue{
|
||||||
|
Value: cty.MapVal(map[string]cty.Value{
|
||||||
|
"foo": cty.StringVal("bar"),
|
||||||
|
}),
|
||||||
|
SourceType: ValueFromCaller,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
"bools: config only": {
|
"bools: config only": {
|
||||||
"vars-basic-bool",
|
"vars-basic-bool",
|
||||||
nil,
|
nil,
|
||||||
map[string]cty.Value{
|
InputValues{
|
||||||
"a": cty.StringVal("1"),
|
"a": &InputValue{
|
||||||
"b": cty.StringVal("0"),
|
Value: cty.True,
|
||||||
|
SourceType: ValueFromConfig,
|
||||||
|
SourceRange: tfdiags.SourceRange{
|
||||||
|
Filename: "test-fixtures/vars-basic-bool/main.tf",
|
||||||
|
Start: tfdiags.SourcePos{Line: 4, Column: 1, Byte: 177},
|
||||||
|
End: tfdiags.SourcePos{Line: 4, Column: 13, Byte: 189},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"b": &InputValue{
|
||||||
|
Value: cty.False,
|
||||||
|
SourceType: ValueFromConfig,
|
||||||
|
SourceRange: tfdiags.SourceRange{
|
||||||
|
Filename: "test-fixtures/vars-basic-bool/main.tf",
|
||||||
|
Start: tfdiags.SourcePos{Line: 8, Column: 1, Byte: 214},
|
||||||
|
End: tfdiags.SourcePos{Line: 8, Column: 13, Byte: 226},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -62,9 +114,15 @@ func TestVariables(t *testing.T) {
|
||||||
"a": cty.StringVal("foo"),
|
"a": cty.StringVal("foo"),
|
||||||
"b": cty.StringVal("bar"),
|
"b": cty.StringVal("bar"),
|
||||||
},
|
},
|
||||||
map[string]cty.Value{
|
InputValues{
|
||||||
"a": cty.StringVal("foo"),
|
"a": &InputValue{
|
||||||
"b": cty.StringVal("bar"),
|
Value: cty.StringVal("foo"),
|
||||||
|
SourceType: ValueFromCaller,
|
||||||
|
},
|
||||||
|
"b": &InputValue{
|
||||||
|
Value: cty.StringVal("bar"),
|
||||||
|
SourceType: ValueFromCaller,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -74,23 +132,32 @@ func TestVariables(t *testing.T) {
|
||||||
"a": cty.False,
|
"a": cty.False,
|
||||||
"b": cty.True,
|
"b": cty.True,
|
||||||
},
|
},
|
||||||
map[string]cty.Value{
|
InputValues{
|
||||||
"a": cty.StringVal("0"),
|
"a": &InputValue{
|
||||||
"b": cty.StringVal("1"),
|
Value: cty.False,
|
||||||
|
SourceType: ValueFromCaller,
|
||||||
|
},
|
||||||
|
"b": &InputValue{
|
||||||
|
Value: cty.True,
|
||||||
|
SourceType: ValueFromCaller,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, tc := range cases {
|
for name, test := range tests {
|
||||||
// Wrapped in a func so we can get defers to work
|
// Wrapped in a func so we can get defers to work
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
m := testModule(t, tc.Module)
|
m := testModule(t, test.Module)
|
||||||
fromConfig := DefaultVariableValues(m.Module.Variables)
|
fromConfig := DefaultVariableValues(m.Module.Variables)
|
||||||
overrides := InputValuesFromCaller(tc.Override)
|
overrides := InputValuesFromCaller(test.Override)
|
||||||
actual := fromConfig.Override(overrides)
|
got := fromConfig.Override(overrides)
|
||||||
|
|
||||||
if !reflect.DeepEqual(actual, tc.Expected) {
|
if !got.Identical(test.Want) {
|
||||||
t.Fatalf("%s\n\nexpected: %#v\n\ngot: %#v", name, tc.Expected, actual)
|
t.Errorf("wrong result\ngot: %swant: %s", spew.Sdump(got), spew.Sdump(test.Want))
|
||||||
|
}
|
||||||
|
for _, problem := range deep.Equal(got, test.Want) {
|
||||||
|
t.Errorf(problem)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue