package config import ( "fmt" "testing" "github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/terraform" ) func TestValidator(t *testing.T) { v := &Validator{ Required: []string{"foo"}, Optional: []string{"bar"}, } var c *terraform.ResourceConfig // Valid c = testConfig(t, map[string]interface{}{ "foo": "bar", }) testValid(v, c) // Valid + optional c = testConfig(t, map[string]interface{}{ "foo": "bar", "bar": "baz", }) testValid(v, c) // Missing required c = testConfig(t, map[string]interface{}{ "bar": "baz", }) testInvalid(v, c) // Unknown key c = testConfig(t, map[string]interface{}{ "foo": "bar", "what": "what", }) testInvalid(v, c) } func TestValidator_array(t *testing.T) { v := &Validator{ Required: []string{ "foo", "nested.*", }, } var c *terraform.ResourceConfig // Valid c = testConfig(t, map[string]interface{}{ "foo": "bar", "nested": []interface{}{"foo", "bar"}, }) testValid(v, c) // Not a nested structure c = testConfig(t, map[string]interface{}{ "foo": "bar", "nested": "baa", }) testInvalid(v, c) } func TestValidator_complex(t *testing.T) { v := &Validator{ Required: []string{ "foo", "nested.*", }, } var c *terraform.ResourceConfig // Valid c = testConfig(t, map[string]interface{}{ "foo": "bar", "nested": []map[string]interface{}{ map[string]interface{}{"foo": "bar"}, }, }) testValid(v, c) // Not a nested structure c = testConfig(t, map[string]interface{}{ "foo": "bar", "nested": "baa", }) testInvalid(v, c) } func TestValidator_complexNested(t *testing.T) { v := &Validator{ Required: []string{ "ingress.*", "ingress.*.from_port", }, Optional: []string{ "ingress.*.cidr_blocks.*", }, } var c *terraform.ResourceConfig // Valid c = testConfig(t, map[string]interface{}{ "ingress": []map[string]interface{}{ map[string]interface{}{ "from_port": "80", }, }, }) testValid(v, c) // Valid c = testConfig(t, map[string]interface{}{ "ingress": []map[string]interface{}{ map[string]interface{}{ "from_port": "80", "cidr_blocks": []interface{}{"foo"}, }, }, }) testValid(v, c) } func TestValidator_complexDeepRequired(t *testing.T) { v := &Validator{ Required: []string{ "foo", "nested.*.foo", }, } var c *terraform.ResourceConfig // Valid c = testConfig(t, map[string]interface{}{ "foo": "bar", "nested": []map[string]interface{}{ map[string]interface{}{"foo": "bar"}, }, }) testValid(v, c) // Valid c = testConfig(t, map[string]interface{}{ "foo": "bar", }) testInvalid(v, c) // Not a nested structure c = testConfig(t, map[string]interface{}{ "foo": "bar", "nested": "baa", }) testInvalid(v, c) } func testConfig( t *testing.T, c map[string]interface{}) *terraform.ResourceConfig { r, err := config.NewRawConfig(c) if err != nil { t.Fatalf("bad: %s", err) } return terraform.NewResourceConfig(r) } func testInvalid(v *Validator, c *terraform.ResourceConfig) { ws, es := v.Validate(c) if len(ws) > 0 { panic(fmt.Sprintf("bad: %#v", ws)) } if len(es) == 0 { panic(fmt.Sprintf("bad: %#v", es)) } } func testValid(v *Validator, c *terraform.ResourceConfig) { ws, es := v.Validate(c) if len(ws) > 0 { panic(fmt.Sprintf("bad: %#v", ws)) } if len(es) > 0 { estrs := make([]string, len(es)) for i, e := range es { estrs[i] = e.Error() } panic(fmt.Sprintf("bad: %#v", estrs)) } }