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)
|
|
}
|
|
}
|