opentofu/terraform/eval_variable_test.go
Martin Atkins 28d6d913e4 core: basic test of EvalVariableBlock
This previously lacked tests altogether. This new test verifies the
"happy path", ensuring that both literal and computed values pass through
correctly into the VariableValues map.
2017-04-04 12:16:19 -07:00

220 lines
5.1 KiB
Go

package terraform
import (
"reflect"
"testing"
"github.com/hashicorp/terraform/config"
)
func TestCoerceMapVariable(t *testing.T) {
cases := map[string]struct {
Input *EvalCoerceMapVariable
ExpectVars map[string]interface{}
}{
"a valid map is untouched": {
Input: &EvalCoerceMapVariable{
Variables: map[string]interface{}{
"amap": map[string]interface{}{"foo": "bar"},
},
ModulePath: []string{"root"},
ModuleTree: testModuleInline(t, map[string]string{
"main.tf": `
variable "amap" {
type = "map"
}
`,
}),
},
ExpectVars: map[string]interface{}{
"amap": map[string]interface{}{"foo": "bar"},
},
},
"a list w/ a single map element is coerced": {
Input: &EvalCoerceMapVariable{
Variables: map[string]interface{}{
"amap": []interface{}{
map[string]interface{}{"foo": "bar"},
},
},
ModulePath: []string{"root"},
ModuleTree: testModuleInline(t, map[string]string{
"main.tf": `
variable "amap" {
type = "map"
}
`,
}),
},
ExpectVars: map[string]interface{}{
"amap": map[string]interface{}{"foo": "bar"},
},
},
"a list w/ more than one map element is untouched": {
Input: &EvalCoerceMapVariable{
Variables: map[string]interface{}{
"amap": []interface{}{
map[string]interface{}{"foo": "bar"},
map[string]interface{}{"baz": "qux"},
},
},
ModulePath: []string{"root"},
ModuleTree: testModuleInline(t, map[string]string{
"main.tf": `
variable "amap" {
type = "map"
}
`,
}),
},
ExpectVars: map[string]interface{}{
"amap": []interface{}{
map[string]interface{}{"foo": "bar"},
map[string]interface{}{"baz": "qux"},
},
},
},
"list coercion also works in a module": {
Input: &EvalCoerceMapVariable{
Variables: map[string]interface{}{
"amap": []interface{}{
map[string]interface{}{"foo": "bar"},
},
},
ModulePath: []string{"root", "middle", "bottom"},
ModuleTree: testModuleInline(t, map[string]string{
"top.tf": `
module "middle" {
source = "./middle"
}
`,
"middle/mid.tf": `
module "bottom" {
source = "./bottom"
amap {
foo = "bar"
}
}
`,
"middle/bottom/bot.tf": `
variable "amap" {
type = "map"
}
`,
}),
},
ExpectVars: map[string]interface{}{
"amap": map[string]interface{}{"foo": "bar"},
},
},
"coercion only occurs when target var is a map": {
Input: &EvalCoerceMapVariable{
Variables: map[string]interface{}{
"alist": []interface{}{
map[string]interface{}{"foo": "bar"},
},
},
ModulePath: []string{"root"},
ModuleTree: testModuleInline(t, map[string]string{
"main.tf": `
variable "alist" {
type = "list"
}
`,
}),
},
ExpectVars: map[string]interface{}{
"alist": []interface{}{
map[string]interface{}{"foo": "bar"},
},
},
},
}
for tn, tc := range cases {
_, err := tc.Input.Eval(&MockEvalContext{})
if err != nil {
t.Fatalf("%s: Unexpected err: %s", tn, err)
}
if !reflect.DeepEqual(tc.Input.Variables, tc.ExpectVars) {
t.Fatalf("%s: Expected variables:\n\n%#v\n\nGot:\n\n%#v",
tn, tc.ExpectVars, tc.Input.Variables)
}
}
}
func TestEvalVariableBlock(t *testing.T) {
rc, err := config.NewRawConfig(map[string]interface{}{
"known": "foo",
"known_list": []interface{}{"foo"},
"known_map": map[string]interface{}{
"foo": "foo",
},
"known_list_of_maps": []map[string]interface{}{
map[string]interface{}{
"foo": "foo",
},
},
"computed_map": map[string]interface{}{},
"computed_list_of_maps": []map[string]interface{}{
map[string]interface{}{},
},
// No computed_list right now, because that isn't currently supported:
// EvalVariableBlock assumes the final step of the path will always
// be a map.
})
if err != nil {
t.Fatalf("config.NewRawConfig failed: %s", err)
}
cfg := NewResourceConfig(rc)
cfg.ComputedKeys = []string{
"computed",
"computed_map.foo",
"computed_list_of_maps.0.foo",
}
n := &EvalVariableBlock{
VariableValues: map[string]interface{}{
// Should be cleared out on Eval
"should_be_deleted": true,
},
Config: &cfg,
}
ctx := &MockEvalContext{}
val, err := n.Eval(ctx)
if err != nil {
t.Fatalf("n.Eval failed: %s", err)
}
if val != nil {
t.Fatalf("n.Eval returned non-nil result: %#v", val)
}
got := n.VariableValues
want := map[string]interface{}{
"known": "foo",
"known_list": []interface{}{"foo"},
"known_map": map[string]interface{}{
"foo": "foo",
},
"known_list_of_maps": []interface{}{
map[string]interface{}{
"foo": "foo",
},
},
"computed": config.UnknownVariableValue,
"computed_map": map[string]interface{}{
"foo": config.UnknownVariableValue,
},
"computed_list_of_maps": []interface{}{
map[string]interface{}{
"foo": config.UnknownVariableValue,
},
},
}
if !reflect.DeepEqual(got, want) {
t.Errorf("Incorrect variables\ngot: %#v\nwant: %#v", got, want)
}
}