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