mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
28d6d913e4
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.
220 lines
5.1 KiB
Go
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)
|
|
}
|
|
}
|