github.com/armen/terraform@v0.5.2-0.20150529052519-caa8117a08f1/config/loader_test.go (about) 1 package config 2 3 import ( 4 "path/filepath" 5 "reflect" 6 "strings" 7 "testing" 8 ) 9 10 func TestIsEmptyDir(t *testing.T) { 11 val, err := IsEmptyDir(fixtureDir) 12 if err != nil { 13 t.Fatalf("err: %s", err) 14 } 15 if val { 16 t.Fatal("should not be empty") 17 } 18 } 19 20 func TestIsEmptyDir_noExist(t *testing.T) { 21 val, err := IsEmptyDir(filepath.Join(fixtureDir, "nopenopenope")) 22 if err != nil { 23 t.Fatalf("err: %s", err) 24 } 25 if !val { 26 t.Fatal("should be empty") 27 } 28 } 29 30 func TestIsEmptyDir_noConfigs(t *testing.T) { 31 val, err := IsEmptyDir(filepath.Join(fixtureDir, "dir-empty")) 32 if err != nil { 33 t.Fatalf("err: %s", err) 34 } 35 if !val { 36 t.Fatal("should be empty") 37 } 38 } 39 40 func TestLoad_badType(t *testing.T) { 41 _, err := Load(filepath.Join(fixtureDir, "bad_type.tf.nope")) 42 if err == nil { 43 t.Fatal("should have error") 44 } 45 } 46 47 func TestLoadBasic(t *testing.T) { 48 c, err := Load(filepath.Join(fixtureDir, "basic.tf")) 49 if err != nil { 50 t.Fatalf("err: %s", err) 51 } 52 53 if c == nil { 54 t.Fatal("config should not be nil") 55 } 56 57 if c.Dir != "" { 58 t.Fatalf("bad: %#v", c.Dir) 59 } 60 61 expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"} 62 if !reflect.DeepEqual(c.Atlas, expectedAtlas) { 63 t.Fatalf("bad: %#v", c.Atlas) 64 } 65 66 actual := variablesStr(c.Variables) 67 if actual != strings.TrimSpace(basicVariablesStr) { 68 t.Fatalf("bad:\n%s", actual) 69 } 70 71 actual = providerConfigsStr(c.ProviderConfigs) 72 if actual != strings.TrimSpace(basicProvidersStr) { 73 t.Fatalf("bad:\n%s", actual) 74 } 75 76 actual = resourcesStr(c.Resources) 77 if actual != strings.TrimSpace(basicResourcesStr) { 78 t.Fatalf("bad:\n%s", actual) 79 } 80 81 actual = outputsStr(c.Outputs) 82 if actual != strings.TrimSpace(basicOutputsStr) { 83 t.Fatalf("bad:\n%s", actual) 84 } 85 } 86 87 func TestLoadBasic_empty(t *testing.T) { 88 c, err := Load(filepath.Join(fixtureDir, "empty.tf")) 89 if err != nil { 90 t.Fatalf("err: %s", err) 91 } 92 93 if c == nil { 94 t.Fatal("config should not be nil") 95 } 96 } 97 98 func TestLoadBasic_import(t *testing.T) { 99 // Skip because we disabled importing 100 t.Skip() 101 102 c, err := Load(filepath.Join(fixtureDir, "import.tf")) 103 if err != nil { 104 t.Fatalf("err: %s", err) 105 } 106 107 if c == nil { 108 t.Fatal("config should not be nil") 109 } 110 111 actual := variablesStr(c.Variables) 112 if actual != strings.TrimSpace(importVariablesStr) { 113 t.Fatalf("bad:\n%s", actual) 114 } 115 116 actual = providerConfigsStr(c.ProviderConfigs) 117 if actual != strings.TrimSpace(importProvidersStr) { 118 t.Fatalf("bad:\n%s", actual) 119 } 120 121 actual = resourcesStr(c.Resources) 122 if actual != strings.TrimSpace(importResourcesStr) { 123 t.Fatalf("bad:\n%s", actual) 124 } 125 } 126 127 func TestLoadBasic_json(t *testing.T) { 128 c, err := Load(filepath.Join(fixtureDir, "basic.tf.json")) 129 if err != nil { 130 t.Fatalf("err: %s", err) 131 } 132 133 if c == nil { 134 t.Fatal("config should not be nil") 135 } 136 137 if c.Dir != "" { 138 t.Fatalf("bad: %#v", c.Dir) 139 } 140 141 expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"} 142 if !reflect.DeepEqual(c.Atlas, expectedAtlas) { 143 t.Fatalf("bad: %#v", c.Atlas) 144 } 145 146 actual := variablesStr(c.Variables) 147 if actual != strings.TrimSpace(basicVariablesStr) { 148 t.Fatalf("bad:\n%s", actual) 149 } 150 151 actual = providerConfigsStr(c.ProviderConfigs) 152 if actual != strings.TrimSpace(basicProvidersStr) { 153 t.Fatalf("bad:\n%s", actual) 154 } 155 156 actual = resourcesStr(c.Resources) 157 if actual != strings.TrimSpace(basicResourcesStr) { 158 t.Fatalf("bad:\n%s", actual) 159 } 160 161 actual = outputsStr(c.Outputs) 162 if actual != strings.TrimSpace(basicOutputsStr) { 163 t.Fatalf("bad:\n%s", actual) 164 } 165 } 166 167 func TestLoadBasic_modules(t *testing.T) { 168 c, err := Load(filepath.Join(fixtureDir, "modules.tf")) 169 if err != nil { 170 t.Fatalf("err: %s", err) 171 } 172 173 if c == nil { 174 t.Fatal("config should not be nil") 175 } 176 177 if c.Dir != "" { 178 t.Fatalf("bad: %#v", c.Dir) 179 } 180 181 actual := modulesStr(c.Modules) 182 if actual != strings.TrimSpace(modulesModulesStr) { 183 t.Fatalf("bad:\n%s", actual) 184 } 185 } 186 187 func TestLoad_variables(t *testing.T) { 188 c, err := Load(filepath.Join(fixtureDir, "variables.tf")) 189 if err != nil { 190 t.Fatalf("err: %s", err) 191 } 192 if c == nil { 193 t.Fatal("config should not be nil") 194 } 195 196 if c.Dir != "" { 197 t.Fatalf("bad: %#v", c.Dir) 198 } 199 200 actual := variablesStr(c.Variables) 201 if actual != strings.TrimSpace(variablesVariablesStr) { 202 t.Fatalf("bad:\n%s", actual) 203 } 204 } 205 206 func TestLoadDir_basic(t *testing.T) { 207 dir := filepath.Join(fixtureDir, "dir-basic") 208 c, err := LoadDir(dir) 209 if err != nil { 210 t.Fatalf("err: %s", err) 211 } 212 213 if c == nil { 214 t.Fatal("config should not be nil") 215 } 216 217 dirAbs, err := filepath.Abs(dir) 218 if err != nil { 219 t.Fatalf("err: %s", err) 220 } 221 if c.Dir != dirAbs { 222 t.Fatalf("bad: %#v", c.Dir) 223 } 224 225 actual := variablesStr(c.Variables) 226 if actual != strings.TrimSpace(dirBasicVariablesStr) { 227 t.Fatalf("bad:\n%s", actual) 228 } 229 230 actual = providerConfigsStr(c.ProviderConfigs) 231 if actual != strings.TrimSpace(dirBasicProvidersStr) { 232 t.Fatalf("bad:\n%s", actual) 233 } 234 235 actual = resourcesStr(c.Resources) 236 if actual != strings.TrimSpace(dirBasicResourcesStr) { 237 t.Fatalf("bad:\n%s", actual) 238 } 239 240 actual = outputsStr(c.Outputs) 241 if actual != strings.TrimSpace(dirBasicOutputsStr) { 242 t.Fatalf("bad:\n%s", actual) 243 } 244 } 245 246 func TestLoadDir_file(t *testing.T) { 247 _, err := LoadDir(filepath.Join(fixtureDir, "variables.tf")) 248 if err == nil { 249 t.Fatal("should error") 250 } 251 } 252 253 func TestLoadDir_noConfigs(t *testing.T) { 254 _, err := LoadDir(filepath.Join(fixtureDir, "dir-empty")) 255 if err == nil { 256 t.Fatal("should error") 257 } 258 } 259 260 func TestLoadDir_noMerge(t *testing.T) { 261 c, err := LoadDir(filepath.Join(fixtureDir, "dir-merge")) 262 if err != nil { 263 t.Fatalf("err: %s", err) 264 } 265 266 if c == nil { 267 t.Fatal("config should not be nil") 268 } 269 270 if err := c.Validate(); err == nil { 271 t.Fatal("should not be valid") 272 } 273 } 274 275 func TestLoadDir_override(t *testing.T) { 276 c, err := LoadDir(filepath.Join(fixtureDir, "dir-override")) 277 if err != nil { 278 t.Fatalf("err: %s", err) 279 } 280 281 if c == nil { 282 t.Fatal("config should not be nil") 283 } 284 285 actual := variablesStr(c.Variables) 286 if actual != strings.TrimSpace(dirOverrideVariablesStr) { 287 t.Fatalf("bad:\n%s", actual) 288 } 289 290 actual = providerConfigsStr(c.ProviderConfigs) 291 if actual != strings.TrimSpace(dirOverrideProvidersStr) { 292 t.Fatalf("bad:\n%s", actual) 293 } 294 295 actual = resourcesStr(c.Resources) 296 if actual != strings.TrimSpace(dirOverrideResourcesStr) { 297 t.Fatalf("bad:\n%s", actual) 298 } 299 300 actual = outputsStr(c.Outputs) 301 if actual != strings.TrimSpace(dirOverrideOutputsStr) { 302 t.Fatalf("bad:\n%s", actual) 303 } 304 } 305 306 func TestLoad_provisioners(t *testing.T) { 307 c, err := Load(filepath.Join(fixtureDir, "provisioners.tf")) 308 if err != nil { 309 t.Fatalf("err: %s", err) 310 } 311 312 if c == nil { 313 t.Fatal("config should not be nil") 314 } 315 316 actual := resourcesStr(c.Resources) 317 if actual != strings.TrimSpace(provisionerResourcesStr) { 318 t.Fatalf("bad:\n%s", actual) 319 } 320 } 321 322 func TestLoad_connections(t *testing.T) { 323 c, err := Load(filepath.Join(fixtureDir, "connection.tf")) 324 if err != nil { 325 t.Fatalf("err: %s", err) 326 } 327 328 if c == nil { 329 t.Fatal("config should not be nil") 330 } 331 332 actual := resourcesStr(c.Resources) 333 if actual != strings.TrimSpace(connectionResourcesStr) { 334 t.Fatalf("bad:\n%s", actual) 335 } 336 337 // Check for the connection info 338 r := c.Resources[0] 339 if r.Name != "web" && r.Type != "aws_instance" { 340 t.Fatalf("Bad: %#v", r) 341 } 342 343 p1 := r.Provisioners[0] 344 if p1.ConnInfo == nil || len(p1.ConnInfo.Raw) != 2 { 345 t.Fatalf("Bad: %#v", p1.ConnInfo) 346 } 347 if p1.ConnInfo.Raw["user"] != "nobody" { 348 t.Fatalf("Bad: %#v", p1.ConnInfo) 349 } 350 351 p2 := r.Provisioners[1] 352 if p2.ConnInfo == nil || len(p2.ConnInfo.Raw) != 2 { 353 t.Fatalf("Bad: %#v", p2.ConnInfo) 354 } 355 if p2.ConnInfo.Raw["user"] != "root" { 356 t.Fatalf("Bad: %#v", p2.ConnInfo) 357 } 358 } 359 360 func TestLoad_createBeforeDestroy(t *testing.T) { 361 c, err := Load(filepath.Join(fixtureDir, "create-before-destroy.tf")) 362 if err != nil { 363 t.Fatalf("err: %s", err) 364 } 365 366 if c == nil { 367 t.Fatal("config should not be nil") 368 } 369 370 actual := resourcesStr(c.Resources) 371 if actual != strings.TrimSpace(createBeforeDestroyResourcesStr) { 372 t.Fatalf("bad:\n%s", actual) 373 } 374 375 // Check for the flag value 376 r := c.Resources[0] 377 if r.Name != "web" && r.Type != "aws_instance" { 378 t.Fatalf("Bad: %#v", r) 379 } 380 381 // Should enable create before destroy 382 if !r.Lifecycle.CreateBeforeDestroy { 383 t.Fatalf("Bad: %#v", r) 384 } 385 386 r = c.Resources[1] 387 if r.Name != "bar" && r.Type != "aws_instance" { 388 t.Fatalf("Bad: %#v", r) 389 } 390 391 // Should not enable create before destroy 392 if r.Lifecycle.CreateBeforeDestroy { 393 t.Fatalf("Bad: %#v", r) 394 } 395 } 396 397 func TestLoad_temporary_files(t *testing.T) { 398 _, err := LoadDir(filepath.Join(fixtureDir, "dir-temporary-files")) 399 if err == nil { 400 t.Fatalf("Expected to see an error stating no config files found") 401 } 402 } 403 404 const basicOutputsStr = ` 405 web_ip 406 vars 407 resource: aws_instance.web.private_ip 408 ` 409 410 const basicProvidersStr = ` 411 aws 412 access_key 413 secret_key 414 do 415 api_key 416 vars 417 user: var.foo 418 ` 419 420 const basicResourcesStr = ` 421 aws_instance[db] (x1) 422 VPC 423 security_groups 424 provisioners 425 file 426 destination 427 source 428 dependsOn 429 aws_instance.web 430 vars 431 resource: aws_security_group.firewall.*.id 432 aws_instance[web] (x1) 433 ami 434 network_interface 435 security_groups 436 provisioners 437 file 438 destination 439 source 440 vars 441 resource: aws_security_group.firewall.foo 442 user: var.foo 443 aws_security_group[firewall] (x5) 444 ` 445 446 const basicVariablesStr = ` 447 foo 448 bar 449 bar 450 ` 451 452 const dirBasicOutputsStr = ` 453 web_ip 454 vars 455 resource: aws_instance.web.private_ip 456 ` 457 458 const dirBasicProvidersStr = ` 459 aws 460 access_key 461 secret_key 462 do 463 api_key 464 vars 465 user: var.foo 466 ` 467 468 const dirBasicResourcesStr = ` 469 aws_instance[db] (x1) 470 security_groups 471 vars 472 resource: aws_security_group.firewall.*.id 473 aws_instance[web] (x1) 474 ami 475 network_interface 476 security_groups 477 vars 478 resource: aws_security_group.firewall.foo 479 user: var.foo 480 aws_security_group[firewall] (x5) 481 ` 482 483 const dirBasicVariablesStr = ` 484 foo 485 bar 486 bar 487 ` 488 489 const dirOverrideOutputsStr = ` 490 web_ip 491 vars 492 resource: aws_instance.web.private_ip 493 ` 494 495 const dirOverrideProvidersStr = ` 496 aws 497 access_key 498 secret_key 499 do 500 api_key 501 vars 502 user: var.foo 503 ` 504 505 const dirOverrideResourcesStr = ` 506 aws_instance[db] (x1) 507 ami 508 security_groups 509 aws_instance[web] (x1) 510 ami 511 foo 512 network_interface 513 security_groups 514 vars 515 resource: aws_security_group.firewall.foo 516 user: var.foo 517 aws_security_group[firewall] (x5) 518 ` 519 520 const dirOverrideVariablesStr = ` 521 foo 522 bar 523 bar 524 ` 525 526 const importProvidersStr = ` 527 aws 528 bar 529 foo 530 ` 531 532 const importResourcesStr = ` 533 aws_security_group[db] (x1) 534 aws_security_group[web] (x1) 535 ` 536 537 const importVariablesStr = ` 538 bar (required) 539 <> 540 <> 541 foo 542 bar 543 bar 544 ` 545 546 const modulesModulesStr = ` 547 bar 548 source = baz 549 memory 550 ` 551 552 const provisionerResourcesStr = ` 553 aws_instance[web] (x1) 554 ami 555 security_groups 556 provisioners 557 shell 558 path 559 vars 560 resource: aws_security_group.firewall.foo 561 user: var.foo 562 ` 563 564 const connectionResourcesStr = ` 565 aws_instance[web] (x1) 566 ami 567 security_groups 568 provisioners 569 shell 570 path 571 shell 572 path 573 vars 574 resource: aws_security_group.firewall.foo 575 user: var.foo 576 ` 577 578 const variablesVariablesStr = ` 579 bar 580 <> 581 <> 582 baz 583 foo 584 <> 585 foo (required) 586 <> 587 <> 588 ` 589 590 const createBeforeDestroyResourcesStr = ` 591 aws_instance[bar] (x1) 592 ami 593 aws_instance[web] (x1) 594 ami 595 `