github.com/IBM-Cloud/terraform@v0.6.4-0.20170726051544-8872b87621df/command/init_test.go (about) 1 package command 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "strings" 8 "testing" 9 10 "github.com/hashicorp/terraform/helper/copy" 11 "github.com/mitchellh/cli" 12 ) 13 14 func TestInit(t *testing.T) { 15 dir := tempDir(t) 16 17 ui := new(cli.MockUi) 18 c := &InitCommand{ 19 Meta: Meta{ 20 ContextOpts: testCtxConfig(testProvider()), 21 Ui: ui, 22 }, 23 } 24 25 args := []string{ 26 testFixturePath("init"), 27 dir, 28 } 29 if code := c.Run(args); code != 0 { 30 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 31 } 32 33 if _, err := os.Stat(filepath.Join(dir, "hello.tf")); err != nil { 34 t.Fatalf("err: %s", err) 35 } 36 } 37 38 func TestInit_cwd(t *testing.T) { 39 dir := tempDir(t) 40 if err := os.MkdirAll(dir, 0755); err != nil { 41 t.Fatalf("err: %s", err) 42 } 43 44 // Change to the temporary directory 45 cwd, err := os.Getwd() 46 if err != nil { 47 t.Fatalf("err: %s", err) 48 } 49 if err := os.Chdir(dir); err != nil { 50 t.Fatalf("err: %s", err) 51 } 52 defer os.Chdir(cwd) 53 54 ui := new(cli.MockUi) 55 c := &InitCommand{ 56 Meta: Meta{ 57 ContextOpts: testCtxConfig(testProvider()), 58 Ui: ui, 59 }, 60 } 61 62 args := []string{ 63 testFixturePath("init"), 64 } 65 if code := c.Run(args); code != 0 { 66 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 67 } 68 69 if _, err := os.Stat("hello.tf"); err != nil { 70 t.Fatalf("err: %s", err) 71 } 72 } 73 74 func TestInit_empty(t *testing.T) { 75 // Create a temporary working directory that is empty 76 td := tempDir(t) 77 os.MkdirAll(td, 0755) 78 defer os.RemoveAll(td) 79 defer testChdir(t, td)() 80 81 ui := new(cli.MockUi) 82 c := &InitCommand{ 83 Meta: Meta{ 84 ContextOpts: testCtxConfig(testProvider()), 85 Ui: ui, 86 }, 87 } 88 89 args := []string{} 90 if code := c.Run(args); code != 0 { 91 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 92 } 93 } 94 95 func TestInit_multipleArgs(t *testing.T) { 96 ui := new(cli.MockUi) 97 c := &InitCommand{ 98 Meta: Meta{ 99 ContextOpts: testCtxConfig(testProvider()), 100 Ui: ui, 101 }, 102 } 103 104 args := []string{ 105 "bad", 106 "bad", 107 } 108 if code := c.Run(args); code != 1 { 109 t.Fatalf("bad: \n%s", ui.OutputWriter.String()) 110 } 111 } 112 113 // https://github.com/hashicorp/terraform/issues/518 114 func TestInit_dstInSrc(t *testing.T) { 115 dir := tempDir(t) 116 if err := os.MkdirAll(dir, 0755); err != nil { 117 t.Fatalf("err: %s", err) 118 } 119 120 // Change to the temporary directory 121 cwd, err := os.Getwd() 122 if err != nil { 123 t.Fatalf("err: %s", err) 124 } 125 if err := os.Chdir(dir); err != nil { 126 t.Fatalf("err: %s", err) 127 } 128 defer os.Chdir(cwd) 129 130 if _, err := os.Create("issue518.tf"); err != nil { 131 t.Fatalf("err: %s", err) 132 } 133 134 ui := new(cli.MockUi) 135 c := &InitCommand{ 136 Meta: Meta{ 137 ContextOpts: testCtxConfig(testProvider()), 138 Ui: ui, 139 }, 140 } 141 142 args := []string{ 143 ".", 144 "foo", 145 } 146 if code := c.Run(args); code != 0 { 147 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 148 } 149 150 if _, err := os.Stat(filepath.Join(dir, "foo", "issue518.tf")); err != nil { 151 t.Fatalf("err: %s", err) 152 } 153 } 154 155 func TestInit_get(t *testing.T) { 156 // Create a temporary working directory that is empty 157 td := tempDir(t) 158 copy.CopyDir(testFixturePath("init-get"), td) 159 defer os.RemoveAll(td) 160 defer testChdir(t, td)() 161 162 ui := new(cli.MockUi) 163 c := &InitCommand{ 164 Meta: Meta{ 165 ContextOpts: testCtxConfig(testProvider()), 166 Ui: ui, 167 }, 168 } 169 170 args := []string{} 171 if code := c.Run(args); code != 0 { 172 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 173 } 174 175 // Check output 176 output := ui.OutputWriter.String() 177 if !strings.Contains(output, "Get: file://") { 178 t.Fatalf("doesn't look like get: %s", output) 179 } 180 } 181 182 func TestInit_copyGet(t *testing.T) { 183 // Create a temporary working directory that is empty 184 td := tempDir(t) 185 os.MkdirAll(td, 0755) 186 defer os.RemoveAll(td) 187 defer testChdir(t, td)() 188 189 ui := new(cli.MockUi) 190 c := &InitCommand{ 191 Meta: Meta{ 192 ContextOpts: testCtxConfig(testProvider()), 193 Ui: ui, 194 }, 195 } 196 197 args := []string{ 198 testFixturePath("init-get"), 199 } 200 if code := c.Run(args); code != 0 { 201 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 202 } 203 204 // Check copy 205 if _, err := os.Stat("main.tf"); err != nil { 206 t.Fatalf("err: %s", err) 207 } 208 209 output := ui.OutputWriter.String() 210 if !strings.Contains(output, "Get: file://") { 211 t.Fatalf("doesn't look like get: %s", output) 212 } 213 } 214 215 func TestInit_backend(t *testing.T) { 216 // Create a temporary working directory that is empty 217 td := tempDir(t) 218 copy.CopyDir(testFixturePath("init-backend"), td) 219 defer os.RemoveAll(td) 220 defer testChdir(t, td)() 221 222 ui := new(cli.MockUi) 223 c := &InitCommand{ 224 Meta: Meta{ 225 ContextOpts: testCtxConfig(testProvider()), 226 Ui: ui, 227 }, 228 } 229 230 args := []string{} 231 if code := c.Run(args); code != 0 { 232 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 233 } 234 235 if _, err := os.Stat(filepath.Join(DefaultDataDir, DefaultStateFilename)); err != nil { 236 t.Fatalf("err: %s", err) 237 } 238 } 239 240 func TestInit_backendUnset(t *testing.T) { 241 // Create a temporary working directory that is empty 242 td := tempDir(t) 243 copy.CopyDir(testFixturePath("init-backend"), td) 244 defer os.RemoveAll(td) 245 defer testChdir(t, td)() 246 247 { 248 ui := new(cli.MockUi) 249 c := &InitCommand{ 250 Meta: Meta{ 251 ContextOpts: testCtxConfig(testProvider()), 252 Ui: ui, 253 }, 254 } 255 256 // Init 257 args := []string{} 258 if code := c.Run(args); code != 0 { 259 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 260 } 261 262 if _, err := os.Stat(filepath.Join(DefaultDataDir, DefaultStateFilename)); err != nil { 263 t.Fatalf("err: %s", err) 264 } 265 } 266 267 { 268 // Unset 269 if err := ioutil.WriteFile("main.tf", []byte(""), 0644); err != nil { 270 t.Fatalf("err: %s", err) 271 } 272 273 ui := new(cli.MockUi) 274 c := &InitCommand{ 275 Meta: Meta{ 276 ContextOpts: testCtxConfig(testProvider()), 277 Ui: ui, 278 }, 279 } 280 281 args := []string{"-force-copy"} 282 if code := c.Run(args); code != 0 { 283 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 284 } 285 286 s := testStateRead(t, filepath.Join( 287 DefaultDataDir, DefaultStateFilename)) 288 if !s.Backend.Empty() { 289 t.Fatal("should not have backend config") 290 } 291 } 292 } 293 294 func TestInit_backendConfigFile(t *testing.T) { 295 // Create a temporary working directory that is empty 296 td := tempDir(t) 297 copy.CopyDir(testFixturePath("init-backend-config-file"), td) 298 defer os.RemoveAll(td) 299 defer testChdir(t, td)() 300 301 ui := new(cli.MockUi) 302 c := &InitCommand{ 303 Meta: Meta{ 304 ContextOpts: testCtxConfig(testProvider()), 305 Ui: ui, 306 }, 307 } 308 309 args := []string{"-backend-config", "input.config"} 310 if code := c.Run(args); code != 0 { 311 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 312 } 313 314 // Read our saved backend config and verify we have our settings 315 state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 316 if v := state.Backend.Config["path"]; v != "hello" { 317 t.Fatalf("bad: %#v", v) 318 } 319 } 320 321 func TestInit_backendConfigFileChange(t *testing.T) { 322 // Create a temporary working directory that is empty 323 td := tempDir(t) 324 copy.CopyDir(testFixturePath("init-backend-config-file-change"), td) 325 defer os.RemoveAll(td) 326 defer testChdir(t, td)() 327 328 // Ask input 329 defer testInputMap(t, map[string]string{ 330 "backend-migrate-to-new": "no", 331 })() 332 333 ui := new(cli.MockUi) 334 c := &InitCommand{ 335 Meta: Meta{ 336 ContextOpts: testCtxConfig(testProvider()), 337 Ui: ui, 338 }, 339 } 340 341 args := []string{"-backend-config", "input.config"} 342 if code := c.Run(args); code != 0 { 343 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 344 } 345 346 // Read our saved backend config and verify we have our settings 347 state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 348 if v := state.Backend.Config["path"]; v != "hello" { 349 t.Fatalf("bad: %#v", v) 350 } 351 } 352 353 func TestInit_backendConfigKV(t *testing.T) { 354 // Create a temporary working directory that is empty 355 td := tempDir(t) 356 copy.CopyDir(testFixturePath("init-backend-config-kv"), td) 357 defer os.RemoveAll(td) 358 defer testChdir(t, td)() 359 360 ui := new(cli.MockUi) 361 c := &InitCommand{ 362 Meta: Meta{ 363 ContextOpts: testCtxConfig(testProvider()), 364 Ui: ui, 365 }, 366 } 367 368 args := []string{"-backend-config", "path=hello"} 369 if code := c.Run(args); code != 0 { 370 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 371 } 372 373 // Read our saved backend config and verify we have our settings 374 state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 375 if v := state.Backend.Config["path"]; v != "hello" { 376 t.Fatalf("bad: %#v", v) 377 } 378 } 379 380 func TestInit_copyBackendDst(t *testing.T) { 381 // Create a temporary working directory that is empty 382 td := tempDir(t) 383 os.MkdirAll(td, 0755) 384 defer os.RemoveAll(td) 385 defer testChdir(t, td)() 386 387 ui := new(cli.MockUi) 388 c := &InitCommand{ 389 Meta: Meta{ 390 ContextOpts: testCtxConfig(testProvider()), 391 Ui: ui, 392 }, 393 } 394 395 args := []string{ 396 testFixturePath("init-backend"), 397 "dst", 398 } 399 if code := c.Run(args); code != 0 { 400 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 401 } 402 403 if _, err := os.Stat(filepath.Join( 404 "dst", DefaultDataDir, DefaultStateFilename)); err != nil { 405 t.Fatalf("err: %s", err) 406 } 407 } 408 409 func TestInit_backendReinitWithExtra(t *testing.T) { 410 td := tempDir(t) 411 copy.CopyDir(testFixturePath("init-backend-empty"), td) 412 defer os.RemoveAll(td) 413 defer testChdir(t, td)() 414 415 m := testMetaBackend(t, nil) 416 opts := &BackendOpts{ 417 ConfigExtra: map[string]interface{}{"path": "hello"}, 418 Init: true, 419 } 420 421 b, err := m.backendConfig(opts) 422 if err != nil { 423 t.Fatal(err) 424 } 425 426 ui := new(cli.MockUi) 427 c := &InitCommand{ 428 Meta: Meta{ 429 ContextOpts: testCtxConfig(testProvider()), 430 Ui: ui, 431 }, 432 } 433 434 args := []string{"-backend-config", "path=hello"} 435 if code := c.Run(args); code != 0 { 436 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 437 } 438 439 // Read our saved backend config and verify we have our settings 440 state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 441 if v := state.Backend.Config["path"]; v != "hello" { 442 t.Fatalf("bad: %#v", v) 443 } 444 445 if state.Backend.Hash != b.Hash { 446 t.Fatal("mismatched state and config backend hashes") 447 } 448 449 if state.Backend.Rehash() != b.Rehash() { 450 t.Fatal("mismatched state and config re-hashes") 451 } 452 453 // init again and make sure nothing changes 454 if code := c.Run(args); code != 0 { 455 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 456 } 457 state = testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 458 if v := state.Backend.Config["path"]; v != "hello" { 459 t.Fatalf("bad: %#v", v) 460 } 461 462 if state.Backend.Hash != b.Hash { 463 t.Fatal("mismatched state and config backend hashes") 464 } 465 } 466 467 // move option from config to -backend-config args 468 func TestInit_backendReinitConfigToExtra(t *testing.T) { 469 td := tempDir(t) 470 copy.CopyDir(testFixturePath("init-backend"), td) 471 defer os.RemoveAll(td) 472 defer testChdir(t, td)() 473 474 ui := new(cli.MockUi) 475 c := &InitCommand{ 476 Meta: Meta{ 477 ContextOpts: testCtxConfig(testProvider()), 478 Ui: ui, 479 }, 480 } 481 482 if code := c.Run([]string{"-input=false"}); code != 0 { 483 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 484 } 485 486 // Read our saved backend config and verify we have our settings 487 state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 488 if v := state.Backend.Config["path"]; v != "foo" { 489 t.Fatalf("bad: %#v", v) 490 } 491 492 backendHash := state.Backend.Hash 493 494 // init again but remove the path option from the config 495 cfg := "terraform {\n backend \"local\" {}\n}\n" 496 if err := ioutil.WriteFile("main.tf", []byte(cfg), 0644); err != nil { 497 t.Fatal(err) 498 } 499 500 args := []string{"-input=false", "-backend-config=path=foo"} 501 if code := c.Run(args); code != 0 { 502 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 503 } 504 state = testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 505 506 if state.Backend.Hash == backendHash { 507 t.Fatal("state.Backend.Hash was not updated") 508 } 509 } 510 511 // make sure inputFalse stops execution on migrate 512 func TestInit_inputFalse(t *testing.T) { 513 td := tempDir(t) 514 copy.CopyDir(testFixturePath("init-backend"), td) 515 defer os.RemoveAll(td) 516 defer testChdir(t, td)() 517 518 ui := new(cli.MockUi) 519 c := &InitCommand{ 520 Meta: Meta{ 521 ContextOpts: testCtxConfig(testProvider()), 522 Ui: ui, 523 }, 524 } 525 526 args := []string{"-input=false", "-backend-config=path=foo"} 527 if code := c.Run([]string{"-input=false"}); code != 0 { 528 t.Fatalf("bad: \n%s", ui.ErrorWriter) 529 } 530 531 args = []string{"-input=false", "-backend-config=path=bar"} 532 if code := c.Run(args); code == 0 { 533 t.Fatal("init should have failed", ui.OutputWriter) 534 } 535 } 536 537 /* 538 func TestInit_remoteState(t *testing.T) { 539 tmp, cwd := testCwd(t) 540 defer testFixCwd(t, tmp, cwd) 541 542 s := terraform.NewState() 543 conf, srv := testRemoteState(t, s, 200) 544 defer srv.Close() 545 546 ui := new(cli.MockUi) 547 c := &InitCommand{ 548 Meta: Meta{ 549 ContextOpts: testCtxConfig(testProvider()), 550 Ui: ui, 551 }, 552 } 553 554 args := []string{ 555 "-backend", "HTTP", 556 "-backend-config", "address=" + conf.Config["address"], 557 testFixturePath("init"), 558 tmp, 559 } 560 if code := c.Run(args); code != 0 { 561 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 562 } 563 564 if _, err := os.Stat(filepath.Join(tmp, "hello.tf")); err != nil { 565 t.Fatalf("err: %s", err) 566 } 567 568 if _, err := os.Stat(filepath.Join(tmp, DefaultDataDir, DefaultStateFilename)); err != nil { 569 t.Fatalf("missing state: %s", err) 570 } 571 } 572 573 func TestInit_remoteStateSubdir(t *testing.T) { 574 tmp, cwd := testCwd(t) 575 defer testFixCwd(t, tmp, cwd) 576 subdir := filepath.Join(tmp, "subdir") 577 578 s := terraform.NewState() 579 conf, srv := testRemoteState(t, s, 200) 580 defer srv.Close() 581 582 ui := new(cli.MockUi) 583 c := &InitCommand{ 584 Meta: Meta{ 585 ContextOpts: testCtxConfig(testProvider()), 586 Ui: ui, 587 }, 588 } 589 590 args := []string{ 591 "-backend", "http", 592 "-backend-config", "address=" + conf.Config["address"], 593 testFixturePath("init"), 594 subdir, 595 } 596 if code := c.Run(args); code != 0 { 597 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 598 } 599 600 if _, err := os.Stat(filepath.Join(subdir, "hello.tf")); err != nil { 601 t.Fatalf("err: %s", err) 602 } 603 604 if _, err := os.Stat(filepath.Join(subdir, DefaultDataDir, DefaultStateFilename)); err != nil { 605 t.Fatalf("missing state: %s", err) 606 } 607 } 608 609 func TestInit_remoteStateWithLocal(t *testing.T) { 610 tmp, cwd := testCwd(t) 611 defer testFixCwd(t, tmp, cwd) 612 613 statePath := filepath.Join(tmp, DefaultStateFilename) 614 615 // Write some state 616 f, err := os.Create(statePath) 617 if err != nil { 618 t.Fatalf("err: %s", err) 619 } 620 err = terraform.WriteState(testState(), f) 621 f.Close() 622 if err != nil { 623 t.Fatalf("err: %s", err) 624 } 625 626 ui := new(cli.MockUi) 627 c := &InitCommand{ 628 Meta: Meta{ 629 ContextOpts: testCtxConfig(testProvider()), 630 Ui: ui, 631 }, 632 } 633 634 args := []string{ 635 "-backend", "http", 636 "-backend-config", "address=http://google.com", 637 testFixturePath("init"), 638 } 639 if code := c.Run(args); code == 0 { 640 t.Fatalf("should have failed: \n%s", ui.OutputWriter.String()) 641 } 642 } 643 644 func TestInit_remoteStateWithRemote(t *testing.T) { 645 tmp, cwd := testCwd(t) 646 defer testFixCwd(t, tmp, cwd) 647 648 statePath := filepath.Join(tmp, DefaultDataDir, DefaultStateFilename) 649 if err := os.MkdirAll(filepath.Dir(statePath), 0755); err != nil { 650 t.Fatalf("err: %s", err) 651 } 652 653 // Write some state 654 f, err := os.Create(statePath) 655 if err != nil { 656 t.Fatalf("err: %s", err) 657 } 658 err = terraform.WriteState(testState(), f) 659 f.Close() 660 if err != nil { 661 t.Fatalf("err: %s", err) 662 } 663 664 ui := new(cli.MockUi) 665 c := &InitCommand{ 666 Meta: Meta{ 667 ContextOpts: testCtxConfig(testProvider()), 668 Ui: ui, 669 }, 670 } 671 672 args := []string{ 673 "-backend", "http", 674 "-backend-config", "address=http://google.com", 675 testFixturePath("init"), 676 } 677 if code := c.Run(args); code == 0 { 678 t.Fatalf("should have failed: \n%s", ui.OutputWriter.String()) 679 } 680 } 681 */