github.com/gerbenjacobs/terraform@v0.9.5-0.20170630130047-e6ddd62583d8/command/init_test.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "reflect" 9 "runtime" 10 "sort" 11 "strings" 12 "testing" 13 14 "github.com/hashicorp/terraform/helper/copy" 15 "github.com/hashicorp/terraform/plugin/discovery" 16 "github.com/mitchellh/cli" 17 ) 18 19 func TestInit_empty(t *testing.T) { 20 // Create a temporary working directory that is empty 21 td := tempDir(t) 22 os.MkdirAll(td, 0755) 23 defer os.RemoveAll(td) 24 defer testChdir(t, td)() 25 26 ui := new(cli.MockUi) 27 c := &InitCommand{ 28 Meta: Meta{ 29 testingOverrides: metaOverridesForProvider(testProvider()), 30 Ui: ui, 31 }, 32 } 33 34 args := []string{} 35 if code := c.Run(args); code != 0 { 36 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 37 } 38 } 39 40 func TestInit_multipleArgs(t *testing.T) { 41 ui := new(cli.MockUi) 42 c := &InitCommand{ 43 Meta: Meta{ 44 testingOverrides: metaOverridesForProvider(testProvider()), 45 Ui: ui, 46 }, 47 } 48 49 args := []string{ 50 "bad", 51 "bad", 52 } 53 if code := c.Run(args); code != 1 { 54 t.Fatalf("bad: \n%s", ui.OutputWriter.String()) 55 } 56 } 57 58 func TestInit_get(t *testing.T) { 59 // Create a temporary working directory that is empty 60 td := tempDir(t) 61 copy.CopyDir(testFixturePath("init-get"), td) 62 defer os.RemoveAll(td) 63 defer testChdir(t, td)() 64 65 ui := new(cli.MockUi) 66 c := &InitCommand{ 67 Meta: Meta{ 68 testingOverrides: metaOverridesForProvider(testProvider()), 69 Ui: ui, 70 }, 71 } 72 73 args := []string{} 74 if code := c.Run(args); code != 0 { 75 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 76 } 77 78 // Check output 79 output := ui.OutputWriter.String() 80 if !strings.Contains(output, "Get: file://") { 81 t.Fatalf("doesn't look like get: %s", output) 82 } 83 } 84 85 func TestInit_getUpgradeModules(t *testing.T) { 86 // Create a temporary working directory that is empty 87 td := tempDir(t) 88 os.MkdirAll(td, 0755) 89 // copy.CopyDir(testFixturePath("init-get"), td) 90 defer os.RemoveAll(td) 91 defer testChdir(t, td)() 92 93 ui := new(cli.MockUi) 94 c := &InitCommand{ 95 Meta: Meta{ 96 testingOverrides: metaOverridesForProvider(testProvider()), 97 Ui: ui, 98 }, 99 } 100 101 args := []string{ 102 "-get=true", 103 "-get-plugins=false", 104 "-upgrade", 105 testFixturePath("init-get"), 106 } 107 if code := c.Run(args); code != 0 { 108 t.Fatalf("command did not complete successfully:\n%s", ui.ErrorWriter.String()) 109 } 110 111 // Check output 112 output := ui.OutputWriter.String() 113 if !strings.Contains(output, "(update)") { 114 t.Fatalf("doesn't look like get upgrade: %s", output) 115 } 116 } 117 118 func TestInit_backend(t *testing.T) { 119 // Create a temporary working directory that is empty 120 td := tempDir(t) 121 copy.CopyDir(testFixturePath("init-backend"), td) 122 defer os.RemoveAll(td) 123 defer testChdir(t, td)() 124 125 ui := new(cli.MockUi) 126 c := &InitCommand{ 127 Meta: Meta{ 128 testingOverrides: metaOverridesForProvider(testProvider()), 129 Ui: ui, 130 }, 131 } 132 133 args := []string{} 134 if code := c.Run(args); code != 0 { 135 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 136 } 137 138 if _, err := os.Stat(filepath.Join(DefaultDataDir, DefaultStateFilename)); err != nil { 139 t.Fatalf("err: %s", err) 140 } 141 } 142 143 func TestInit_backendUnset(t *testing.T) { 144 // Create a temporary working directory that is empty 145 td := tempDir(t) 146 copy.CopyDir(testFixturePath("init-backend"), td) 147 defer os.RemoveAll(td) 148 defer testChdir(t, td)() 149 150 { 151 ui := new(cli.MockUi) 152 c := &InitCommand{ 153 Meta: Meta{ 154 testingOverrides: metaOverridesForProvider(testProvider()), 155 Ui: ui, 156 }, 157 } 158 159 // Init 160 args := []string{} 161 if code := c.Run(args); code != 0 { 162 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 163 } 164 165 if _, err := os.Stat(filepath.Join(DefaultDataDir, DefaultStateFilename)); err != nil { 166 t.Fatalf("err: %s", err) 167 } 168 } 169 170 { 171 // Unset 172 if err := ioutil.WriteFile("main.tf", []byte(""), 0644); err != nil { 173 t.Fatalf("err: %s", err) 174 } 175 176 ui := new(cli.MockUi) 177 c := &InitCommand{ 178 Meta: Meta{ 179 testingOverrides: metaOverridesForProvider(testProvider()), 180 Ui: ui, 181 }, 182 } 183 184 args := []string{"-force-copy"} 185 if code := c.Run(args); code != 0 { 186 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 187 } 188 189 s := testStateRead(t, filepath.Join( 190 DefaultDataDir, DefaultStateFilename)) 191 if !s.Backend.Empty() { 192 t.Fatal("should not have backend config") 193 } 194 } 195 } 196 197 func TestInit_backendConfigFile(t *testing.T) { 198 // Create a temporary working directory that is empty 199 td := tempDir(t) 200 copy.CopyDir(testFixturePath("init-backend-config-file"), td) 201 defer os.RemoveAll(td) 202 defer testChdir(t, td)() 203 204 ui := new(cli.MockUi) 205 c := &InitCommand{ 206 Meta: Meta{ 207 testingOverrides: metaOverridesForProvider(testProvider()), 208 Ui: ui, 209 }, 210 } 211 212 args := []string{"-backend-config", "input.config"} 213 if code := c.Run(args); code != 0 { 214 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 215 } 216 217 // Read our saved backend config and verify we have our settings 218 state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 219 if v := state.Backend.Config["path"]; v != "hello" { 220 t.Fatalf("bad: %#v", v) 221 } 222 } 223 224 func TestInit_backendConfigFileChange(t *testing.T) { 225 // Create a temporary working directory that is empty 226 td := tempDir(t) 227 copy.CopyDir(testFixturePath("init-backend-config-file-change"), td) 228 defer os.RemoveAll(td) 229 defer testChdir(t, td)() 230 231 // Ask input 232 defer testInputMap(t, map[string]string{ 233 "backend-migrate-to-new": "no", 234 })() 235 236 ui := new(cli.MockUi) 237 c := &InitCommand{ 238 Meta: Meta{ 239 testingOverrides: metaOverridesForProvider(testProvider()), 240 Ui: ui, 241 }, 242 } 243 244 args := []string{"-backend-config", "input.config"} 245 if code := c.Run(args); code != 0 { 246 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 247 } 248 249 // Read our saved backend config and verify we have our settings 250 state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 251 if v := state.Backend.Config["path"]; v != "hello" { 252 t.Fatalf("bad: %#v", v) 253 } 254 } 255 256 func TestInit_backendConfigKV(t *testing.T) { 257 // Create a temporary working directory that is empty 258 td := tempDir(t) 259 copy.CopyDir(testFixturePath("init-backend-config-kv"), td) 260 defer os.RemoveAll(td) 261 defer testChdir(t, td)() 262 263 ui := new(cli.MockUi) 264 c := &InitCommand{ 265 Meta: Meta{ 266 testingOverrides: metaOverridesForProvider(testProvider()), 267 Ui: ui, 268 }, 269 } 270 271 args := []string{"-backend-config", "path=hello"} 272 if code := c.Run(args); code != 0 { 273 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 274 } 275 276 // Read our saved backend config and verify we have our settings 277 state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 278 if v := state.Backend.Config["path"]; v != "hello" { 279 t.Fatalf("bad: %#v", v) 280 } 281 } 282 283 func TestInit_targetSubdir(t *testing.T) { 284 // Create a temporary working directory that is empty 285 td := tempDir(t) 286 os.MkdirAll(td, 0755) 287 defer os.RemoveAll(td) 288 defer testChdir(t, td)() 289 290 // copy the source into a subdir 291 copy.CopyDir(testFixturePath("init-backend"), filepath.Join(td, "source")) 292 293 ui := new(cli.MockUi) 294 c := &InitCommand{ 295 Meta: Meta{ 296 testingOverrides: metaOverridesForProvider(testProvider()), 297 Ui: ui, 298 }, 299 } 300 301 args := []string{ 302 "source", 303 } 304 if code := c.Run(args); code != 0 { 305 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 306 } 307 308 if _, err := os.Stat(filepath.Join(td, DefaultDataDir, DefaultStateFilename)); err != nil { 309 t.Fatalf("err: %s", err) 310 } 311 312 // a data directory should not have been added to out working dir 313 if _, err := os.Stat(filepath.Join(td, "source", DefaultDataDir)); !os.IsNotExist(err) { 314 t.Fatalf("err: %s", err) 315 } 316 } 317 318 func TestInit_backendReinitWithExtra(t *testing.T) { 319 td := tempDir(t) 320 copy.CopyDir(testFixturePath("init-backend-empty"), td) 321 defer os.RemoveAll(td) 322 defer testChdir(t, td)() 323 324 m := testMetaBackend(t, nil) 325 opts := &BackendOpts{ 326 ConfigExtra: map[string]interface{}{"path": "hello"}, 327 Init: true, 328 } 329 330 b, err := m.backendConfig(opts) 331 if err != nil { 332 t.Fatal(err) 333 } 334 335 ui := new(cli.MockUi) 336 c := &InitCommand{ 337 Meta: Meta{ 338 testingOverrides: metaOverridesForProvider(testProvider()), 339 Ui: ui, 340 }, 341 } 342 343 args := []string{"-backend-config", "path=hello"} 344 if code := c.Run(args); code != 0 { 345 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 346 } 347 348 // Read our saved backend config and verify we have our settings 349 state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 350 if v := state.Backend.Config["path"]; v != "hello" { 351 t.Fatalf("bad: %#v", v) 352 } 353 354 if state.Backend.Hash != b.Hash { 355 t.Fatal("mismatched state and config backend hashes") 356 } 357 358 if state.Backend.Rehash() != b.Rehash() { 359 t.Fatal("mismatched state and config re-hashes") 360 } 361 362 // init again and make sure nothing changes 363 if code := c.Run(args); code != 0 { 364 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 365 } 366 state = testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 367 if v := state.Backend.Config["path"]; v != "hello" { 368 t.Fatalf("bad: %#v", v) 369 } 370 371 if state.Backend.Hash != b.Hash { 372 t.Fatal("mismatched state and config backend hashes") 373 } 374 } 375 376 // move option from config to -backend-config args 377 func TestInit_backendReinitConfigToExtra(t *testing.T) { 378 td := tempDir(t) 379 copy.CopyDir(testFixturePath("init-backend"), td) 380 defer os.RemoveAll(td) 381 defer testChdir(t, td)() 382 383 ui := new(cli.MockUi) 384 c := &InitCommand{ 385 Meta: Meta{ 386 testingOverrides: metaOverridesForProvider(testProvider()), 387 Ui: ui, 388 }, 389 } 390 391 if code := c.Run([]string{"-input=false"}); code != 0 { 392 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 393 } 394 395 // Read our saved backend config and verify we have our settings 396 state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 397 if v := state.Backend.Config["path"]; v != "foo" { 398 t.Fatalf("bad: %#v", v) 399 } 400 401 backendHash := state.Backend.Hash 402 403 // init again but remove the path option from the config 404 cfg := "terraform {\n backend \"local\" {}\n}\n" 405 if err := ioutil.WriteFile("main.tf", []byte(cfg), 0644); err != nil { 406 t.Fatal(err) 407 } 408 409 args := []string{"-input=false", "-backend-config=path=foo"} 410 if code := c.Run(args); code != 0 { 411 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 412 } 413 state = testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) 414 415 if state.Backend.Hash == backendHash { 416 t.Fatal("state.Backend.Hash was not updated") 417 } 418 } 419 420 // make sure inputFalse stops execution on migrate 421 func TestInit_inputFalse(t *testing.T) { 422 td := tempDir(t) 423 copy.CopyDir(testFixturePath("init-backend"), td) 424 defer os.RemoveAll(td) 425 defer testChdir(t, td)() 426 427 ui := new(cli.MockUi) 428 c := &InitCommand{ 429 Meta: Meta{ 430 testingOverrides: metaOverridesForProvider(testProvider()), 431 Ui: ui, 432 }, 433 } 434 435 args := []string{"-input=false", "-backend-config=path=foo"} 436 if code := c.Run([]string{"-input=false"}); code != 0 { 437 t.Fatalf("bad: \n%s", ui.ErrorWriter) 438 } 439 440 args = []string{"-input=false", "-backend-config=path=bar"} 441 if code := c.Run(args); code == 0 { 442 t.Fatal("init should have failed", ui.OutputWriter) 443 } 444 } 445 446 func TestInit_getProvider(t *testing.T) { 447 // Create a temporary working directory that is empty 448 td := tempDir(t) 449 copy.CopyDir(testFixturePath("init-get-providers"), td) 450 defer os.RemoveAll(td) 451 defer testChdir(t, td)() 452 453 ui := new(cli.MockUi) 454 m := Meta{ 455 testingOverrides: metaOverridesForProvider(testProvider()), 456 Ui: ui, 457 } 458 459 installer := &mockProviderInstaller{ 460 Providers: map[string][]string{ 461 // looking for an exact version 462 "exact": []string{"1.2.3"}, 463 // config requires >= 2.3.3 464 "greater_than": []string{"2.3.4", "2.3.3", "2.3.0"}, 465 // config specifies 466 "between": []string{"3.4.5", "2.3.4", "1.2.3"}, 467 }, 468 469 Dir: m.pluginDir(), 470 } 471 472 c := &InitCommand{ 473 Meta: m, 474 providerInstaller: installer, 475 } 476 477 args := []string{ 478 "-backend=false", // should be possible to install plugins without backend init 479 } 480 if code := c.Run(args); code != 0 { 481 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 482 } 483 484 if !installer.PurgeUnusedCalled { 485 t.Errorf("init didn't purge providers, but should have") 486 } 487 488 // check that we got the providers for our config 489 exactPath := filepath.Join(c.pluginDir(), installer.FileName("exact", "1.2.3")) 490 if _, err := os.Stat(exactPath); os.IsNotExist(err) { 491 t.Fatal("provider 'exact' not downloaded") 492 } 493 greaterThanPath := filepath.Join(c.pluginDir(), installer.FileName("greater_than", "2.3.4")) 494 if _, err := os.Stat(greaterThanPath); os.IsNotExist(err) { 495 t.Fatal("provider 'greater_than' not downloaded") 496 } 497 betweenPath := filepath.Join(c.pluginDir(), installer.FileName("between", "2.3.4")) 498 if _, err := os.Stat(betweenPath); os.IsNotExist(err) { 499 t.Fatal("provider 'between' not downloaded") 500 } 501 } 502 503 // make sure we can locate providers in various paths 504 func TestInit_findVendoredProviders(t *testing.T) { 505 // Create a temporary working directory that is empty 506 td := tempDir(t) 507 508 configDirName := "init-get-providers" 509 copy.CopyDir(testFixturePath(configDirName), filepath.Join(td, configDirName)) 510 defer os.RemoveAll(td) 511 defer testChdir(t, td)() 512 513 ui := new(cli.MockUi) 514 m := Meta{ 515 testingOverrides: metaOverridesForProvider(testProvider()), 516 Ui: ui, 517 } 518 519 c := &InitCommand{ 520 Meta: m, 521 providerInstaller: &mockProviderInstaller{}, 522 } 523 524 // make our plugin paths 525 if err := os.MkdirAll(c.pluginDir(), 0755); err != nil { 526 t.Fatal(err) 527 } 528 if err := os.MkdirAll(DefaultPluginVendorDir, 0755); err != nil { 529 t.Fatal(err) 530 } 531 532 // add some dummy providers 533 // the auto plugin directory 534 exactPath := filepath.Join(c.pluginDir(), "terraform-provider-exact_v1.2.3_x4") 535 if err := ioutil.WriteFile(exactPath, []byte("test bin"), 0755); err != nil { 536 t.Fatal(err) 537 } 538 // the vendor path 539 greaterThanPath := filepath.Join(DefaultPluginVendorDir, "terraform-provider-greater_than_v2.3.4_x4") 540 if err := ioutil.WriteFile(greaterThanPath, []byte("test bin"), 0755); err != nil { 541 t.Fatal(err) 542 } 543 // Check the current directory too 544 betweenPath := filepath.Join(".", "terraform-provider-between_v2.3.4_x4") 545 if err := ioutil.WriteFile(betweenPath, []byte("test bin"), 0755); err != nil { 546 t.Fatal(err) 547 } 548 549 args := []string{configDirName} 550 if code := c.Run(args); code != 0 { 551 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 552 } 553 } 554 555 func TestInit_getUpgradePlugins(t *testing.T) { 556 // Create a temporary working directory that is empty 557 td := tempDir(t) 558 copy.CopyDir(testFixturePath("init-get-providers"), td) 559 defer os.RemoveAll(td) 560 defer testChdir(t, td)() 561 562 ui := new(cli.MockUi) 563 m := Meta{ 564 testingOverrides: metaOverridesForProvider(testProvider()), 565 Ui: ui, 566 } 567 568 installer := &mockProviderInstaller{ 569 Providers: map[string][]string{ 570 // looking for an exact version 571 "exact": []string{"1.2.3"}, 572 // config requires >= 2.3.3 573 "greater_than": []string{"2.3.4", "2.3.3", "2.3.0"}, 574 // config specifies 575 "between": []string{"3.4.5", "2.3.4", "1.2.3"}, 576 }, 577 578 Dir: m.pluginDir(), 579 } 580 581 err := os.MkdirAll(m.pluginDir(), os.ModePerm) 582 if err != nil { 583 t.Fatal(err) 584 } 585 exactUnwanted := filepath.Join(m.pluginDir(), installer.FileName("exact", "0.0.1")) 586 err = ioutil.WriteFile(exactUnwanted, []byte{}, os.ModePerm) 587 if err != nil { 588 t.Fatal(err) 589 } 590 greaterThanUnwanted := filepath.Join(m.pluginDir(), installer.FileName("greater_than", "2.3.3")) 591 err = ioutil.WriteFile(greaterThanUnwanted, []byte{}, os.ModePerm) 592 if err != nil { 593 t.Fatal(err) 594 } 595 betweenOverride := installer.FileName("between", "2.3.4") // intentionally directly in cwd, and should override auto-install 596 err = ioutil.WriteFile(betweenOverride, []byte{}, os.ModePerm) 597 if err != nil { 598 t.Fatal(err) 599 } 600 601 c := &InitCommand{ 602 Meta: m, 603 providerInstaller: installer, 604 } 605 606 args := []string{ 607 "-upgrade=true", 608 } 609 if code := c.Run(args); code != 0 { 610 t.Fatalf("command did not complete successfully:\n%s", ui.ErrorWriter.String()) 611 } 612 613 files, err := ioutil.ReadDir(m.pluginDir()) 614 if err != nil { 615 t.Fatal(err) 616 } 617 618 if !installer.PurgeUnusedCalled { 619 t.Errorf("init -upgrade didn't purge providers, but should have") 620 } 621 622 gotFilenames := make([]string, len(files)) 623 for i, info := range files { 624 gotFilenames[i] = info.Name() 625 } 626 sort.Strings(gotFilenames) 627 628 wantFilenames := []string{ 629 "lock.json", 630 631 // no "between" because the file in cwd overrides it 632 633 // The mock PurgeUnused doesn't actually purge anything, so the dir 634 // includes both our old and new versions. 635 "terraform-provider-exact_v0.0.1_x4", 636 "terraform-provider-exact_v1.2.3_x4", 637 "terraform-provider-greater_than_v2.3.3_x4", 638 "terraform-provider-greater_than_v2.3.4_x4", 639 } 640 641 if !reflect.DeepEqual(gotFilenames, wantFilenames) { 642 t.Errorf("wrong directory contents after upgrade\ngot: %#v\nwant: %#v", gotFilenames, wantFilenames) 643 } 644 645 } 646 647 func TestInit_getProviderMissing(t *testing.T) { 648 // Create a temporary working directory that is empty 649 td := tempDir(t) 650 copy.CopyDir(testFixturePath("init-get-providers"), td) 651 defer os.RemoveAll(td) 652 defer testChdir(t, td)() 653 654 ui := new(cli.MockUi) 655 m := Meta{ 656 testingOverrides: metaOverridesForProvider(testProvider()), 657 Ui: ui, 658 } 659 660 installer := &mockProviderInstaller{ 661 Providers: map[string][]string{ 662 // looking for exact version 1.2.3 663 "exact": []string{"1.2.4"}, 664 // config requires >= 2.3.3 665 "greater_than": []string{"2.3.4", "2.3.3", "2.3.0"}, 666 // config specifies 667 "between": []string{"3.4.5", "2.3.4", "1.2.3"}, 668 }, 669 670 Dir: m.pluginDir(), 671 } 672 673 c := &InitCommand{ 674 Meta: m, 675 providerInstaller: installer, 676 } 677 678 args := []string{} 679 if code := c.Run(args); code == 0 { 680 t.Fatalf("expceted error, got output: \n%s", ui.OutputWriter.String()) 681 } 682 683 if !strings.Contains(ui.ErrorWriter.String(), "no suitable version for provider") { 684 t.Fatalf("unexpected error output: %s", ui.ErrorWriter) 685 } 686 } 687 688 func TestInit_getProviderHaveLegacyVersion(t *testing.T) { 689 // Create a temporary working directory that is empty 690 td := tempDir(t) 691 copy.CopyDir(testFixturePath("init-providers-lock"), td) 692 defer os.RemoveAll(td) 693 defer testChdir(t, td)() 694 695 if err := ioutil.WriteFile("terraform-provider-test", []byte("provider bin"), 0755); err != nil { 696 t.Fatal(err) 697 } 698 699 // provider test has a version constraint in the config, which should 700 // trigger the getProvider error below. 701 ui := new(cli.MockUi) 702 c := &InitCommand{ 703 Meta: Meta{ 704 testingOverrides: metaOverridesForProvider(testProvider()), 705 Ui: ui, 706 }, 707 providerInstaller: callbackPluginInstaller(func(provider string, req discovery.Constraints) (discovery.PluginMeta, error) { 708 return discovery.PluginMeta{}, fmt.Errorf("EXPECTED PROVIDER ERROR %s", provider) 709 }), 710 } 711 712 args := []string{} 713 if code := c.Run(args); code == 0 { 714 t.Fatalf("expceted error, got output: \n%s", ui.OutputWriter.String()) 715 } 716 717 if !strings.Contains(ui.ErrorWriter.String(), "EXPECTED PROVIDER ERROR test") { 718 t.Fatalf("unexpected error output: %s", ui.ErrorWriter) 719 } 720 } 721 722 func TestInit_providerLockFile(t *testing.T) { 723 // Create a temporary working directory that is empty 724 td := tempDir(t) 725 copy.CopyDir(testFixturePath("init-provider-lock-file"), td) 726 defer os.RemoveAll(td) 727 defer testChdir(t, td)() 728 729 ui := new(cli.MockUi) 730 m := Meta{ 731 testingOverrides: metaOverridesForProvider(testProvider()), 732 Ui: ui, 733 } 734 735 installer := &mockProviderInstaller{ 736 Providers: map[string][]string{ 737 "test": []string{"1.2.3"}, 738 }, 739 740 Dir: m.pluginDir(), 741 } 742 743 c := &InitCommand{ 744 Meta: m, 745 providerInstaller: installer, 746 } 747 748 args := []string{} 749 if code := c.Run(args); code != 0 { 750 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 751 } 752 753 providersLockFile := fmt.Sprintf( 754 ".terraform/plugins/%s_%s/lock.json", 755 runtime.GOOS, runtime.GOARCH, 756 ) 757 buf, err := ioutil.ReadFile(providersLockFile) 758 if err != nil { 759 t.Fatalf("failed to read providers lock file %s: %s", providersLockFile, err) 760 } 761 // The hash in here is for the empty files that mockGetProvider produces 762 wantLockFile := strings.TrimSpace(` 763 { 764 "test": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" 765 } 766 `) 767 if string(buf) != wantLockFile { 768 t.Errorf("wrong provider lock file contents\ngot: %s\nwant: %s", buf, wantLockFile) 769 } 770 } 771 772 // Test user-supplied -plugin-dir 773 func TestInit_pluginDirProviders(t *testing.T) { 774 td := tempDir(t) 775 copy.CopyDir(testFixturePath("init-get-providers"), td) 776 defer os.RemoveAll(td) 777 defer testChdir(t, td)() 778 779 ui := new(cli.MockUi) 780 m := Meta{ 781 testingOverrides: metaOverridesForProvider(testProvider()), 782 Ui: ui, 783 } 784 785 c := &InitCommand{ 786 Meta: m, 787 providerInstaller: &mockProviderInstaller{}, 788 } 789 790 // make our vendor paths 791 pluginPath := []string{"a", "b", "c"} 792 for _, p := range pluginPath { 793 if err := os.MkdirAll(p, 0755); err != nil { 794 t.Fatal(err) 795 } 796 } 797 798 // add some dummy providers in our plugin dirs 799 for i, name := range []string{ 800 "terraform-provider-exact_v1.2.3_x4", 801 "terraform-provider-greater_than_v2.3.4_x4", 802 "terraform-provider-between_v2.3.4_x4", 803 } { 804 805 if err := ioutil.WriteFile(filepath.Join(pluginPath[i], name), []byte("test bin"), 0755); err != nil { 806 t.Fatal(err) 807 } 808 } 809 810 args := []string{ 811 "-plugin-dir", "a", 812 "-plugin-dir", "b", 813 "-plugin-dir", "c", 814 } 815 if code := c.Run(args); code != 0 { 816 t.Fatalf("bad: \n%s", ui.ErrorWriter) 817 } 818 } 819 820 // Test user-supplied -plugin-dir doesn't allow auto-install 821 func TestInit_pluginDirProvidersDoesNotGet(t *testing.T) { 822 td := tempDir(t) 823 copy.CopyDir(testFixturePath("init-get-providers"), td) 824 defer os.RemoveAll(td) 825 defer testChdir(t, td)() 826 827 ui := new(cli.MockUi) 828 m := Meta{ 829 testingOverrides: metaOverridesForProvider(testProvider()), 830 Ui: ui, 831 } 832 833 c := &InitCommand{ 834 Meta: m, 835 providerInstaller: callbackPluginInstaller(func(provider string, req discovery.Constraints) (discovery.PluginMeta, error) { 836 t.Fatalf("plugin installer should not have been called for %q", provider) 837 return discovery.PluginMeta{}, nil 838 }), 839 } 840 841 // make our vendor paths 842 pluginPath := []string{"a", "b"} 843 for _, p := range pluginPath { 844 if err := os.MkdirAll(p, 0755); err != nil { 845 t.Fatal(err) 846 } 847 } 848 849 // add some dummy providers in our plugin dirs 850 for i, name := range []string{ 851 "terraform-provider-exact_v1.2.3_x4", 852 "terraform-provider-greater_than_v2.3.4_x4", 853 } { 854 855 if err := ioutil.WriteFile(filepath.Join(pluginPath[i], name), []byte("test bin"), 0755); err != nil { 856 t.Fatal(err) 857 } 858 } 859 860 args := []string{ 861 "-plugin-dir", "a", 862 "-plugin-dir", "b", 863 } 864 if code := c.Run(args); code == 0 { 865 // should have been an error 866 t.Fatalf("bad: \n%s", ui.OutputWriter) 867 } 868 }