github.com/bigkraig/terraform@v0.6.4-0.20151219155159-c90d1b074e31/helper/schema/field_reader_config_test.go (about) 1 package schema 2 3 import ( 4 "reflect" 5 "testing" 6 7 "github.com/hashicorp/terraform/config" 8 "github.com/hashicorp/terraform/config/lang/ast" 9 "github.com/hashicorp/terraform/helper/hashcode" 10 "github.com/hashicorp/terraform/terraform" 11 ) 12 13 func TestConfigFieldReader_impl(t *testing.T) { 14 var _ FieldReader = new(ConfigFieldReader) 15 } 16 17 func TestConfigFieldReader(t *testing.T) { 18 testFieldReader(t, func(s map[string]*Schema) FieldReader { 19 return &ConfigFieldReader{ 20 Schema: s, 21 22 Config: testConfig(t, map[string]interface{}{ 23 "bool": true, 24 "float": 3.1415, 25 "int": 42, 26 "string": "string", 27 28 "list": []interface{}{"foo", "bar"}, 29 30 "listInt": []interface{}{21, 42}, 31 32 "map": map[string]interface{}{ 33 "foo": "bar", 34 "bar": "baz", 35 }, 36 37 "set": []interface{}{10, 50}, 38 "setDeep": []interface{}{ 39 map[string]interface{}{ 40 "index": 10, 41 "value": "foo", 42 }, 43 map[string]interface{}{ 44 "index": 50, 45 "value": "bar", 46 }, 47 }, 48 }), 49 } 50 }) 51 } 52 53 func TestConfigFieldReader_DefaultHandling(t *testing.T) { 54 schema := map[string]*Schema{ 55 "strWithDefault": &Schema{ 56 Type: TypeString, 57 Default: "ImADefault", 58 }, 59 "strWithDefaultFunc": &Schema{ 60 Type: TypeString, 61 DefaultFunc: func() (interface{}, error) { 62 return "FuncDefault", nil 63 }, 64 }, 65 } 66 67 cases := map[string]struct { 68 Addr []string 69 Result FieldReadResult 70 Config *terraform.ResourceConfig 71 Err bool 72 }{ 73 "gets default value when no config set": { 74 []string{"strWithDefault"}, 75 FieldReadResult{ 76 Value: "ImADefault", 77 Exists: true, 78 Computed: false, 79 }, 80 testConfig(t, map[string]interface{}{}), 81 false, 82 }, 83 "config overrides default value": { 84 []string{"strWithDefault"}, 85 FieldReadResult{ 86 Value: "fromConfig", 87 Exists: true, 88 Computed: false, 89 }, 90 testConfig(t, map[string]interface{}{ 91 "strWithDefault": "fromConfig", 92 }), 93 false, 94 }, 95 "gets default from function when no config set": { 96 []string{"strWithDefaultFunc"}, 97 FieldReadResult{ 98 Value: "FuncDefault", 99 Exists: true, 100 Computed: false, 101 }, 102 testConfig(t, map[string]interface{}{}), 103 false, 104 }, 105 "config overrides default function": { 106 []string{"strWithDefaultFunc"}, 107 FieldReadResult{ 108 Value: "fromConfig", 109 Exists: true, 110 Computed: false, 111 }, 112 testConfig(t, map[string]interface{}{ 113 "strWithDefaultFunc": "fromConfig", 114 }), 115 false, 116 }, 117 } 118 119 for name, tc := range cases { 120 r := &ConfigFieldReader{ 121 Schema: schema, 122 Config: tc.Config, 123 } 124 out, err := r.ReadField(tc.Addr) 125 if err != nil != tc.Err { 126 t.Fatalf("%s: err: %s", name, err) 127 } 128 if s, ok := out.Value.(*Set); ok { 129 // If it is a set, convert to a list so its more easily checked. 130 out.Value = s.List() 131 } 132 if !reflect.DeepEqual(tc.Result, out) { 133 t.Fatalf("%s: bad: %#v", name, out) 134 } 135 } 136 } 137 138 func TestConfigFieldReader_ComputedMap(t *testing.T) { 139 schema := map[string]*Schema{ 140 "map": &Schema{ 141 Type: TypeMap, 142 Computed: true, 143 }, 144 } 145 146 cases := map[string]struct { 147 Addr []string 148 Result FieldReadResult 149 Config *terraform.ResourceConfig 150 Err bool 151 }{ 152 "set, normal": { 153 []string{"map"}, 154 FieldReadResult{ 155 Value: map[string]interface{}{ 156 "foo": "bar", 157 }, 158 Exists: true, 159 Computed: false, 160 }, 161 testConfig(t, map[string]interface{}{ 162 "map": map[string]interface{}{ 163 "foo": "bar", 164 }, 165 }), 166 false, 167 }, 168 169 "computed element": { 170 []string{"map"}, 171 FieldReadResult{ 172 Exists: true, 173 Computed: true, 174 }, 175 testConfigInterpolate(t, map[string]interface{}{ 176 "map": map[string]interface{}{ 177 "foo": "${var.foo}", 178 }, 179 }, map[string]ast.Variable{ 180 "var.foo": ast.Variable{ 181 Value: config.UnknownVariableValue, 182 Type: ast.TypeString, 183 }, 184 }), 185 false, 186 }, 187 } 188 189 for name, tc := range cases { 190 r := &ConfigFieldReader{ 191 Schema: schema, 192 Config: tc.Config, 193 } 194 out, err := r.ReadField(tc.Addr) 195 if err != nil != tc.Err { 196 t.Fatalf("%s: err: %s", name, err) 197 } 198 if s, ok := out.Value.(*Set); ok { 199 // If it is a set, convert to the raw map 200 out.Value = s.m 201 if len(s.m) == 0 { 202 out.Value = nil 203 } 204 } 205 if !reflect.DeepEqual(tc.Result, out) { 206 t.Fatalf("%s: bad: %#v", name, out) 207 } 208 } 209 } 210 211 func TestConfigFieldReader_ComputedSet(t *testing.T) { 212 schema := map[string]*Schema{ 213 "strSet": &Schema{ 214 Type: TypeSet, 215 Elem: &Schema{Type: TypeString}, 216 Set: func(v interface{}) int { 217 return hashcode.String(v.(string)) 218 }, 219 }, 220 } 221 222 cases := map[string]struct { 223 Addr []string 224 Result FieldReadResult 225 Config *terraform.ResourceConfig 226 Err bool 227 }{ 228 "set, normal": { 229 []string{"strSet"}, 230 FieldReadResult{ 231 Value: map[string]interface{}{ 232 "2356372769": "foo", 233 }, 234 Exists: true, 235 Computed: false, 236 }, 237 testConfig(t, map[string]interface{}{ 238 "strSet": []interface{}{"foo"}, 239 }), 240 false, 241 }, 242 243 "set, computed element": { 244 []string{"strSet"}, 245 FieldReadResult{ 246 Value: nil, 247 Exists: true, 248 Computed: true, 249 }, 250 testConfigInterpolate(t, map[string]interface{}{ 251 "strSet": []interface{}{"${var.foo}"}, 252 }, map[string]ast.Variable{ 253 "var.foo": ast.Variable{ 254 Value: config.UnknownVariableValue, 255 Type: ast.TypeString, 256 }, 257 }), 258 false, 259 }, 260 261 "set, computed element substring": { 262 []string{"strSet"}, 263 FieldReadResult{ 264 Value: nil, 265 Exists: true, 266 Computed: true, 267 }, 268 testConfigInterpolate(t, map[string]interface{}{ 269 "strSet": []interface{}{"${var.foo}/32"}, 270 }, map[string]ast.Variable{ 271 "var.foo": ast.Variable{ 272 Value: config.UnknownVariableValue, 273 Type: ast.TypeString, 274 }, 275 }), 276 false, 277 }, 278 } 279 280 for name, tc := range cases { 281 r := &ConfigFieldReader{ 282 Schema: schema, 283 Config: tc.Config, 284 } 285 out, err := r.ReadField(tc.Addr) 286 if err != nil != tc.Err { 287 t.Fatalf("%s: err: %s", name, err) 288 } 289 if s, ok := out.Value.(*Set); ok { 290 // If it is a set, convert to the raw map 291 out.Value = s.m 292 if len(s.m) == 0 { 293 out.Value = nil 294 } 295 } 296 if !reflect.DeepEqual(tc.Result, out) { 297 t.Fatalf("%s: bad: %#v", name, out) 298 } 299 } 300 } 301 302 func testConfig( 303 t *testing.T, raw map[string]interface{}) *terraform.ResourceConfig { 304 return testConfigInterpolate(t, raw, nil) 305 } 306 307 func testConfigInterpolate( 308 t *testing.T, 309 raw map[string]interface{}, 310 vs map[string]ast.Variable) *terraform.ResourceConfig { 311 rc, err := config.NewRawConfig(raw) 312 if err != nil { 313 t.Fatalf("err: %s", err) 314 } 315 if len(vs) > 0 { 316 if err := rc.Interpolate(vs); err != nil { 317 t.Fatalf("err: %s", err) 318 } 319 } 320 321 return terraform.NewResourceConfig(rc) 322 }