github.com/zollie/terraform@v0.5.4-0.20150831205333-7d142134f257/command/refresh_test.go (about) 1 package command 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "reflect" 8 "strings" 9 "testing" 10 11 "github.com/hashicorp/terraform/terraform" 12 "github.com/mitchellh/cli" 13 ) 14 15 func TestRefresh(t *testing.T) { 16 state := testState() 17 statePath := testStateFile(t, state) 18 19 p := testProvider() 20 ui := new(cli.MockUi) 21 c := &RefreshCommand{ 22 Meta: Meta{ 23 ContextOpts: testCtxConfig(p), 24 Ui: ui, 25 }, 26 } 27 28 p.RefreshFn = nil 29 p.RefreshReturn = &terraform.InstanceState{ID: "yes"} 30 31 args := []string{ 32 "-state", statePath, 33 testFixturePath("refresh"), 34 } 35 if code := c.Run(args); code != 0 { 36 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 37 } 38 39 if !p.RefreshCalled { 40 t.Fatal("refresh should be called") 41 } 42 43 f, err := os.Open(statePath) 44 if err != nil { 45 t.Fatalf("err: %s", err) 46 } 47 48 newState, err := terraform.ReadState(f) 49 f.Close() 50 if err != nil { 51 t.Fatalf("err: %s", err) 52 } 53 54 actual := strings.TrimSpace(newState.String()) 55 expected := strings.TrimSpace(testRefreshStr) 56 if actual != expected { 57 t.Fatalf("bad:\n\n%s", actual) 58 } 59 } 60 61 func TestRefresh_badState(t *testing.T) { 62 p := testProvider() 63 ui := new(cli.MockUi) 64 c := &RefreshCommand{ 65 Meta: Meta{ 66 ContextOpts: testCtxConfig(p), 67 Ui: ui, 68 }, 69 } 70 71 args := []string{ 72 "-state", "i-should-not-exist-ever", 73 testFixturePath("refresh"), 74 } 75 if code := c.Run(args); code != 1 { 76 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 77 } 78 } 79 80 func TestRefresh_cwd(t *testing.T) { 81 cwd, err := os.Getwd() 82 if err != nil { 83 t.Fatalf("err: %s", err) 84 } 85 if err := os.Chdir(testFixturePath("refresh")); err != nil { 86 t.Fatalf("err: %s", err) 87 } 88 defer os.Chdir(cwd) 89 90 state := testState() 91 statePath := testStateFile(t, state) 92 93 p := testProvider() 94 ui := new(cli.MockUi) 95 c := &RefreshCommand{ 96 Meta: Meta{ 97 ContextOpts: testCtxConfig(p), 98 Ui: ui, 99 }, 100 } 101 102 p.RefreshFn = nil 103 p.RefreshReturn = &terraform.InstanceState{ID: "yes"} 104 105 args := []string{ 106 "-state", statePath, 107 } 108 if code := c.Run(args); code != 0 { 109 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 110 } 111 112 if !p.RefreshCalled { 113 t.Fatal("refresh should be called") 114 } 115 116 f, err := os.Open(statePath) 117 if err != nil { 118 t.Fatalf("err: %s", err) 119 } 120 121 newState, err := terraform.ReadState(f) 122 f.Close() 123 if err != nil { 124 t.Fatalf("err: %s", err) 125 } 126 127 actual := strings.TrimSpace(newState.String()) 128 expected := strings.TrimSpace(testRefreshCwdStr) 129 if actual != expected { 130 t.Fatalf("bad:\n\n%s", actual) 131 } 132 } 133 134 func TestRefresh_defaultState(t *testing.T) { 135 originalState := testState() 136 137 // Write the state file in a temporary directory with the 138 // default filename. 139 td, err := ioutil.TempDir("", "tf") 140 if err != nil { 141 t.Fatalf("err: %s", err) 142 } 143 statePath := filepath.Join(td, DefaultStateFilename) 144 145 f, err := os.Create(statePath) 146 if err != nil { 147 t.Fatalf("err: %s", err) 148 } 149 err = terraform.WriteState(originalState, f) 150 f.Close() 151 if err != nil { 152 t.Fatalf("err: %s", err) 153 } 154 155 // Change to that directory 156 cwd, err := os.Getwd() 157 if err != nil { 158 t.Fatalf("err: %s", err) 159 } 160 if err := os.Chdir(filepath.Dir(statePath)); err != nil { 161 t.Fatalf("err: %s", err) 162 } 163 defer os.Chdir(cwd) 164 165 p := testProvider() 166 ui := new(cli.MockUi) 167 c := &RefreshCommand{ 168 Meta: Meta{ 169 ContextOpts: testCtxConfig(p), 170 Ui: ui, 171 }, 172 } 173 174 p.RefreshFn = nil 175 p.RefreshReturn = &terraform.InstanceState{ID: "yes"} 176 177 args := []string{ 178 testFixturePath("refresh"), 179 } 180 if code := c.Run(args); code != 0 { 181 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 182 } 183 184 if !p.RefreshCalled { 185 t.Fatal("refresh should be called") 186 } 187 188 f, err = os.Open(statePath) 189 if err != nil { 190 t.Fatalf("err: %s", err) 191 } 192 193 newState, err := terraform.ReadState(f) 194 f.Close() 195 if err != nil { 196 t.Fatalf("err: %s", err) 197 } 198 199 actual := newState.RootModule().Resources["test_instance.foo"].Primary 200 expected := p.RefreshReturn 201 if !reflect.DeepEqual(actual, expected) { 202 t.Fatalf("bad: %#v", actual) 203 } 204 205 f, err = os.Open(statePath + DefaultBackupExtention) 206 if err != nil { 207 t.Fatalf("err: %s", err) 208 } 209 210 backupState, err := terraform.ReadState(f) 211 f.Close() 212 if err != nil { 213 t.Fatalf("err: %s", err) 214 } 215 216 actual = backupState.RootModule().Resources["test_instance.foo"].Primary 217 expected = originalState.RootModule().Resources["test_instance.foo"].Primary 218 if !reflect.DeepEqual(actual, expected) { 219 t.Fatalf("bad: %#v", actual) 220 } 221 } 222 223 func TestRefresh_outPath(t *testing.T) { 224 state := testState() 225 statePath := testStateFile(t, state) 226 227 // Output path 228 outf, err := ioutil.TempFile("", "tf") 229 if err != nil { 230 t.Fatalf("err: %s", err) 231 } 232 outPath := outf.Name() 233 outf.Close() 234 os.Remove(outPath) 235 236 p := testProvider() 237 ui := new(cli.MockUi) 238 c := &RefreshCommand{ 239 Meta: Meta{ 240 ContextOpts: testCtxConfig(p), 241 Ui: ui, 242 }, 243 } 244 245 p.RefreshFn = nil 246 p.RefreshReturn = &terraform.InstanceState{ID: "yes"} 247 248 args := []string{ 249 "-state", statePath, 250 "-state-out", outPath, 251 testFixturePath("refresh"), 252 } 253 if code := c.Run(args); code != 0 { 254 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 255 } 256 257 f, err := os.Open(statePath) 258 if err != nil { 259 t.Fatalf("err: %s", err) 260 } 261 262 newState, err := terraform.ReadState(f) 263 f.Close() 264 if err != nil { 265 t.Fatalf("err: %s", err) 266 } 267 268 if !reflect.DeepEqual(newState, state) { 269 t.Fatalf("bad: %#v", newState) 270 } 271 272 f, err = os.Open(outPath) 273 if err != nil { 274 t.Fatalf("err: %s", err) 275 } 276 277 newState, err = terraform.ReadState(f) 278 f.Close() 279 if err != nil { 280 t.Fatalf("err: %s", err) 281 } 282 283 actual := newState.RootModule().Resources["test_instance.foo"].Primary 284 expected := p.RefreshReturn 285 if !reflect.DeepEqual(actual, expected) { 286 t.Fatalf("bad: %#v", actual) 287 } 288 289 f, err = os.Open(outPath + DefaultBackupExtention) 290 if err != nil { 291 t.Fatalf("err: %s", err) 292 } 293 294 backupState, err := terraform.ReadState(f) 295 f.Close() 296 if err != nil { 297 t.Fatalf("err: %s", err) 298 } 299 300 actualStr := strings.TrimSpace(backupState.String()) 301 expectedStr := strings.TrimSpace(state.String()) 302 if actualStr != expectedStr { 303 t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr) 304 } 305 } 306 307 func TestRefresh_var(t *testing.T) { 308 state := testState() 309 statePath := testStateFile(t, state) 310 311 p := testProvider() 312 ui := new(cli.MockUi) 313 c := &RefreshCommand{ 314 Meta: Meta{ 315 ContextOpts: testCtxConfig(p), 316 Ui: ui, 317 }, 318 } 319 320 args := []string{ 321 "-var", "foo=bar", 322 "-state", statePath, 323 testFixturePath("refresh-var"), 324 } 325 if code := c.Run(args); code != 0 { 326 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 327 } 328 329 if !p.ConfigureCalled { 330 t.Fatal("configure should be called") 331 } 332 if p.ConfigureConfig.Config["value"].(string) != "bar" { 333 t.Fatalf("bad: %#v", p.ConfigureConfig.Config) 334 } 335 } 336 337 func TestRefresh_varFile(t *testing.T) { 338 state := testState() 339 statePath := testStateFile(t, state) 340 341 p := testProvider() 342 ui := new(cli.MockUi) 343 c := &RefreshCommand{ 344 Meta: Meta{ 345 ContextOpts: testCtxConfig(p), 346 Ui: ui, 347 }, 348 } 349 350 varFilePath := testTempFile(t) 351 if err := ioutil.WriteFile(varFilePath, []byte(refreshVarFile), 0644); err != nil { 352 t.Fatalf("err: %s", err) 353 } 354 355 args := []string{ 356 "-var-file", varFilePath, 357 "-state", statePath, 358 testFixturePath("refresh-var"), 359 } 360 if code := c.Run(args); code != 0 { 361 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 362 } 363 364 if !p.ConfigureCalled { 365 t.Fatal("configure should be called") 366 } 367 if p.ConfigureConfig.Config["value"].(string) != "bar" { 368 t.Fatalf("bad: %#v", p.ConfigureConfig.Config) 369 } 370 } 371 372 func TestRefresh_varFileDefault(t *testing.T) { 373 state := testState() 374 statePath := testStateFile(t, state) 375 376 p := testProvider() 377 ui := new(cli.MockUi) 378 c := &RefreshCommand{ 379 Meta: Meta{ 380 ContextOpts: testCtxConfig(p), 381 Ui: ui, 382 }, 383 } 384 385 varFileDir := testTempDir(t) 386 varFilePath := filepath.Join(varFileDir, "terraform.tfvars") 387 if err := ioutil.WriteFile(varFilePath, []byte(refreshVarFile), 0644); err != nil { 388 t.Fatalf("err: %s", err) 389 } 390 391 cwd, err := os.Getwd() 392 if err != nil { 393 t.Fatalf("err: %s", err) 394 } 395 if err := os.Chdir(varFileDir); err != nil { 396 t.Fatalf("err: %s", err) 397 } 398 defer os.Chdir(cwd) 399 400 args := []string{ 401 "-state", statePath, 402 testFixturePath("refresh-var"), 403 } 404 if code := c.Run(args); code != 0 { 405 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 406 } 407 408 if !p.ConfigureCalled { 409 t.Fatal("configure should be called") 410 } 411 if p.ConfigureConfig.Config["value"].(string) != "bar" { 412 t.Fatalf("bad: %#v", p.ConfigureConfig.Config) 413 } 414 } 415 416 func TestRefresh_backup(t *testing.T) { 417 state := testState() 418 statePath := testStateFile(t, state) 419 420 // Output path 421 outf, err := ioutil.TempFile("", "tf") 422 if err != nil { 423 t.Fatalf("err: %s", err) 424 } 425 outPath := outf.Name() 426 outf.Close() 427 os.Remove(outPath) 428 429 // Backup path 430 backupf, err := ioutil.TempFile("", "tf") 431 if err != nil { 432 t.Fatalf("err: %s", err) 433 } 434 backupPath := backupf.Name() 435 backupf.Close() 436 os.Remove(backupPath) 437 438 p := testProvider() 439 ui := new(cli.MockUi) 440 c := &RefreshCommand{ 441 Meta: Meta{ 442 ContextOpts: testCtxConfig(p), 443 Ui: ui, 444 }, 445 } 446 447 p.RefreshFn = nil 448 p.RefreshReturn = &terraform.InstanceState{ID: "yes"} 449 450 args := []string{ 451 "-state", statePath, 452 "-state-out", outPath, 453 "-backup", backupPath, 454 testFixturePath("refresh"), 455 } 456 if code := c.Run(args); code != 0 { 457 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 458 } 459 460 f, err := os.Open(statePath) 461 if err != nil { 462 t.Fatalf("err: %s", err) 463 } 464 465 newState, err := terraform.ReadState(f) 466 f.Close() 467 if err != nil { 468 t.Fatalf("err: %s", err) 469 } 470 471 if !reflect.DeepEqual(newState, state) { 472 t.Fatalf("bad: %#v", newState) 473 } 474 475 f, err = os.Open(outPath) 476 if err != nil { 477 t.Fatalf("err: %s", err) 478 } 479 480 newState, err = terraform.ReadState(f) 481 f.Close() 482 if err != nil { 483 t.Fatalf("err: %s", err) 484 } 485 486 actual := newState.RootModule().Resources["test_instance.foo"].Primary 487 expected := p.RefreshReturn 488 if !reflect.DeepEqual(actual, expected) { 489 t.Fatalf("bad: %#v", actual) 490 } 491 492 f, err = os.Open(backupPath) 493 if err != nil { 494 t.Fatalf("err: %s", err) 495 } 496 497 backupState, err := terraform.ReadState(f) 498 f.Close() 499 if err != nil { 500 t.Fatalf("err: %s", err) 501 } 502 503 actualStr := strings.TrimSpace(backupState.String()) 504 expectedStr := strings.TrimSpace(state.String()) 505 if actualStr != expectedStr { 506 t.Fatalf("bad:\n\n%s\n\n%s", actualStr, expectedStr) 507 } 508 } 509 510 func TestRefresh_disableBackup(t *testing.T) { 511 state := testState() 512 statePath := testStateFile(t, state) 513 514 // Output path 515 outf, err := ioutil.TempFile("", "tf") 516 if err != nil { 517 t.Fatalf("err: %s", err) 518 } 519 outPath := outf.Name() 520 outf.Close() 521 os.Remove(outPath) 522 523 p := testProvider() 524 ui := new(cli.MockUi) 525 c := &RefreshCommand{ 526 Meta: Meta{ 527 ContextOpts: testCtxConfig(p), 528 Ui: ui, 529 }, 530 } 531 532 p.RefreshFn = nil 533 p.RefreshReturn = &terraform.InstanceState{ID: "yes"} 534 535 args := []string{ 536 "-state", statePath, 537 "-state-out", outPath, 538 "-backup", "-", 539 testFixturePath("refresh"), 540 } 541 if code := c.Run(args); code != 0 { 542 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 543 } 544 545 f, err := os.Open(statePath) 546 if err != nil { 547 t.Fatalf("err: %s", err) 548 } 549 550 newState, err := terraform.ReadState(f) 551 f.Close() 552 if err != nil { 553 t.Fatalf("err: %s", err) 554 } 555 556 if !reflect.DeepEqual(newState, state) { 557 t.Fatalf("bad: %#v", newState) 558 } 559 560 f, err = os.Open(outPath) 561 if err != nil { 562 t.Fatalf("err: %s", err) 563 } 564 565 newState, err = terraform.ReadState(f) 566 f.Close() 567 if err != nil { 568 t.Fatalf("err: %s", err) 569 } 570 571 actual := newState.RootModule().Resources["test_instance.foo"].Primary 572 expected := p.RefreshReturn 573 if !reflect.DeepEqual(actual, expected) { 574 t.Fatalf("bad: %#v", actual) 575 } 576 577 // Ensure there is no backup 578 _, err = os.Stat(outPath + DefaultBackupExtention) 579 if err == nil || !os.IsNotExist(err) { 580 t.Fatalf("backup should not exist") 581 } 582 } 583 584 func TestRefresh_displaysOutputs(t *testing.T) { 585 state := testState() 586 statePath := testStateFile(t, state) 587 588 p := testProvider() 589 ui := new(cli.MockUi) 590 c := &RefreshCommand{ 591 Meta: Meta{ 592 ContextOpts: testCtxConfig(p), 593 Ui: ui, 594 }, 595 } 596 597 args := []string{ 598 "-state", statePath, 599 testFixturePath("refresh-output"), 600 } 601 if code := c.Run(args); code != 0 { 602 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 603 } 604 605 // Test that outputs were displayed 606 outputValue := "foo.example.com" 607 actual := ui.OutputWriter.String() 608 if !strings.Contains(actual, outputValue) { 609 t.Fatalf("Expected:\n%s\n\nTo include: %q", actual, outputValue) 610 } 611 } 612 613 const refreshVarFile = ` 614 foo = "bar" 615 ` 616 617 const testRefreshStr = ` 618 test_instance.foo: 619 ID = yes 620 ` 621 const testRefreshCwdStr = ` 622 test_instance.foo: 623 ID = yes 624 `