github.com/ns1/terraform@v0.7.10-0.20161109153551-8949419bef40/command/state_mv_test.go (about) 1 package command 2 3 import ( 4 "path/filepath" 5 "testing" 6 7 "github.com/hashicorp/terraform/terraform" 8 "github.com/mitchellh/cli" 9 ) 10 11 func TestStateMv(t *testing.T) { 12 state := &terraform.State{ 13 Modules: []*terraform.ModuleState{ 14 &terraform.ModuleState{ 15 Path: []string{"root"}, 16 Resources: map[string]*terraform.ResourceState{ 17 "test_instance.foo": &terraform.ResourceState{ 18 Type: "test_instance", 19 Primary: &terraform.InstanceState{ 20 ID: "bar", 21 Attributes: map[string]string{ 22 "foo": "value", 23 "bar": "value", 24 }, 25 }, 26 }, 27 28 "test_instance.baz": &terraform.ResourceState{ 29 Type: "test_instance", 30 Primary: &terraform.InstanceState{ 31 ID: "foo", 32 Attributes: map[string]string{ 33 "foo": "value", 34 "bar": "value", 35 }, 36 }, 37 }, 38 }, 39 }, 40 }, 41 } 42 43 statePath := testStateFile(t, state) 44 45 p := testProvider() 46 ui := new(cli.MockUi) 47 c := &StateMvCommand{ 48 Meta: Meta{ 49 ContextOpts: testCtxConfig(p), 50 Ui: ui, 51 }, 52 } 53 54 args := []string{ 55 "-state", statePath, 56 "test_instance.foo", 57 "test_instance.bar", 58 } 59 if code := c.Run(args); code != 0 { 60 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 61 } 62 63 // Test it is correct 64 testStateOutput(t, statePath, testStateMvOutput) 65 66 // Test we have backups 67 backups := testStateBackups(t, filepath.Dir(statePath)) 68 if len(backups) != 1 { 69 t.Fatalf("bad: %#v", backups) 70 } 71 testStateOutput(t, backups[0], testStateMvOutputOriginal) 72 } 73 74 func TestStateMv_stateOutNew(t *testing.T) { 75 state := &terraform.State{ 76 Modules: []*terraform.ModuleState{ 77 &terraform.ModuleState{ 78 Path: []string{"root"}, 79 Resources: map[string]*terraform.ResourceState{ 80 "test_instance.foo": &terraform.ResourceState{ 81 Type: "test_instance", 82 Primary: &terraform.InstanceState{ 83 ID: "bar", 84 Attributes: map[string]string{ 85 "foo": "value", 86 "bar": "value", 87 }, 88 }, 89 }, 90 }, 91 }, 92 }, 93 } 94 95 statePath := testStateFile(t, state) 96 stateOutPath := statePath + ".out" 97 98 p := testProvider() 99 ui := new(cli.MockUi) 100 c := &StateMvCommand{ 101 Meta: Meta{ 102 ContextOpts: testCtxConfig(p), 103 Ui: ui, 104 }, 105 } 106 107 args := []string{ 108 "-state", statePath, 109 "-state-out", stateOutPath, 110 "test_instance.foo", 111 "test_instance.bar", 112 } 113 if code := c.Run(args); code != 0 { 114 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 115 } 116 117 // Test it is correct 118 testStateOutput(t, stateOutPath, testStateMvOutput_stateOut) 119 testStateOutput(t, statePath, testStateMvOutput_stateOutSrc) 120 121 // Test we have backups 122 backups := testStateBackups(t, filepath.Dir(statePath)) 123 if len(backups) != 1 { 124 t.Fatalf("bad: %#v", backups) 125 } 126 testStateOutput(t, backups[0], testStateMvOutput_stateOutOriginal) 127 } 128 129 func TestStateMv_stateOutExisting(t *testing.T) { 130 stateSrc := &terraform.State{ 131 Modules: []*terraform.ModuleState{ 132 &terraform.ModuleState{ 133 Path: []string{"root"}, 134 Resources: map[string]*terraform.ResourceState{ 135 "test_instance.foo": &terraform.ResourceState{ 136 Type: "test_instance", 137 Primary: &terraform.InstanceState{ 138 ID: "bar", 139 Attributes: map[string]string{ 140 "foo": "value", 141 "bar": "value", 142 }, 143 }, 144 }, 145 }, 146 }, 147 }, 148 } 149 150 statePath := testStateFile(t, stateSrc) 151 152 stateDst := &terraform.State{ 153 Modules: []*terraform.ModuleState{ 154 &terraform.ModuleState{ 155 Path: []string{"root"}, 156 Resources: map[string]*terraform.ResourceState{ 157 "test_instance.qux": &terraform.ResourceState{ 158 Type: "test_instance", 159 Primary: &terraform.InstanceState{ 160 ID: "bar", 161 }, 162 }, 163 }, 164 }, 165 }, 166 } 167 168 stateOutPath := testStateFile(t, stateDst) 169 170 p := testProvider() 171 ui := new(cli.MockUi) 172 c := &StateMvCommand{ 173 Meta: Meta{ 174 ContextOpts: testCtxConfig(p), 175 Ui: ui, 176 }, 177 } 178 179 args := []string{ 180 "-state", statePath, 181 "-state-out", stateOutPath, 182 "test_instance.foo", 183 "test_instance.bar", 184 } 185 if code := c.Run(args); code != 0 { 186 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 187 } 188 189 // Test it is correct 190 testStateOutput(t, stateOutPath, testStateMvExisting_stateDst) 191 testStateOutput(t, statePath, testStateMvExisting_stateSrc) 192 193 // Test we have backups 194 backups := testStateBackups(t, filepath.Dir(statePath)) 195 if len(backups) != 1 { 196 t.Fatalf("bad: %#v", backups) 197 } 198 testStateOutput(t, backups[0], testStateMvExisting_stateSrcOriginal) 199 200 backups = testStateBackups(t, filepath.Dir(stateOutPath)) 201 if len(backups) != 1 { 202 t.Fatalf("bad: %#v", backups) 203 } 204 testStateOutput(t, backups[0], testStateMvExisting_stateDstOriginal) 205 } 206 207 func TestStateMv_noState(t *testing.T) { 208 tmp, cwd := testCwd(t) 209 defer testFixCwd(t, tmp, cwd) 210 211 p := testProvider() 212 ui := new(cli.MockUi) 213 c := &StateMvCommand{ 214 Meta: Meta{ 215 ContextOpts: testCtxConfig(p), 216 Ui: ui, 217 }, 218 } 219 220 args := []string{"from", "to"} 221 if code := c.Run(args); code != 1 { 222 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 223 } 224 } 225 226 func TestStateMv_stateOutNew_count(t *testing.T) { 227 state := &terraform.State{ 228 Modules: []*terraform.ModuleState{ 229 &terraform.ModuleState{ 230 Path: []string{"root"}, 231 Resources: map[string]*terraform.ResourceState{ 232 "test_instance.foo.0": &terraform.ResourceState{ 233 Type: "test_instance", 234 Primary: &terraform.InstanceState{ 235 ID: "foo", 236 Attributes: map[string]string{ 237 "foo": "value", 238 "bar": "value", 239 }, 240 }, 241 }, 242 243 "test_instance.foo.1": &terraform.ResourceState{ 244 Type: "test_instance", 245 Primary: &terraform.InstanceState{ 246 ID: "bar", 247 Attributes: map[string]string{ 248 "foo": "value", 249 "bar": "value", 250 }, 251 }, 252 }, 253 254 "test_instance.bar": &terraform.ResourceState{ 255 Type: "test_instance", 256 Primary: &terraform.InstanceState{ 257 ID: "bar", 258 Attributes: map[string]string{ 259 "foo": "value", 260 "bar": "value", 261 }, 262 }, 263 }, 264 }, 265 }, 266 }, 267 } 268 269 statePath := testStateFile(t, state) 270 stateOutPath := statePath + ".out" 271 272 p := testProvider() 273 ui := new(cli.MockUi) 274 c := &StateMvCommand{ 275 Meta: Meta{ 276 ContextOpts: testCtxConfig(p), 277 Ui: ui, 278 }, 279 } 280 281 args := []string{ 282 "-state", statePath, 283 "-state-out", stateOutPath, 284 "test_instance.foo", 285 "test_instance.bar", 286 } 287 if code := c.Run(args); code != 0 { 288 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 289 } 290 291 // Test it is correct 292 testStateOutput(t, stateOutPath, testStateMvCount_stateOut) 293 testStateOutput(t, statePath, testStateMvCount_stateOutSrc) 294 295 // Test we have backups 296 backups := testStateBackups(t, filepath.Dir(statePath)) 297 if len(backups) != 1 { 298 t.Fatalf("bad: %#v", backups) 299 } 300 testStateOutput(t, backups[0], testStateMvCount_stateOutOriginal) 301 } 302 303 func TestStateMv_stateOutNew_nestedModule(t *testing.T) { 304 state := &terraform.State{ 305 Modules: []*terraform.ModuleState{ 306 &terraform.ModuleState{ 307 Path: []string{"root"}, 308 Resources: map[string]*terraform.ResourceState{}, 309 }, 310 311 &terraform.ModuleState{ 312 Path: []string{"root", "foo"}, 313 Resources: map[string]*terraform.ResourceState{}, 314 }, 315 316 &terraform.ModuleState{ 317 Path: []string{"root", "foo", "child1"}, 318 Resources: map[string]*terraform.ResourceState{ 319 "test_instance.foo": &terraform.ResourceState{ 320 Type: "test_instance", 321 Primary: &terraform.InstanceState{ 322 ID: "bar", 323 Attributes: map[string]string{ 324 "foo": "value", 325 "bar": "value", 326 }, 327 }, 328 }, 329 }, 330 }, 331 332 &terraform.ModuleState{ 333 Path: []string{"root", "foo", "child2"}, 334 Resources: map[string]*terraform.ResourceState{ 335 "test_instance.foo": &terraform.ResourceState{ 336 Type: "test_instance", 337 Primary: &terraform.InstanceState{ 338 ID: "bar", 339 Attributes: map[string]string{ 340 "foo": "value", 341 "bar": "value", 342 }, 343 }, 344 }, 345 }, 346 }, 347 }, 348 } 349 350 statePath := testStateFile(t, state) 351 stateOutPath := statePath + ".out" 352 353 p := testProvider() 354 ui := new(cli.MockUi) 355 c := &StateMvCommand{ 356 Meta: Meta{ 357 ContextOpts: testCtxConfig(p), 358 Ui: ui, 359 }, 360 } 361 362 args := []string{ 363 "-state", statePath, 364 "-state-out", stateOutPath, 365 "module.foo", 366 "module.bar", 367 } 368 if code := c.Run(args); code != 0 { 369 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 370 } 371 372 // Test it is correct 373 testStateOutput(t, stateOutPath, testStateMvNestedModule_stateOut) 374 testStateOutput(t, statePath, testStateMvNestedModule_stateOutSrc) 375 376 // Test we have backups 377 backups := testStateBackups(t, filepath.Dir(statePath)) 378 if len(backups) != 1 { 379 t.Fatalf("bad: %#v", backups) 380 } 381 testStateOutput(t, backups[0], testStateMvNestedModule_stateOutOriginal) 382 } 383 384 const testStateMvOutputOriginal = ` 385 test_instance.baz: 386 ID = foo 387 bar = value 388 foo = value 389 test_instance.foo: 390 ID = bar 391 bar = value 392 foo = value 393 ` 394 395 const testStateMvOutput = ` 396 test_instance.bar: 397 ID = bar 398 bar = value 399 foo = value 400 test_instance.baz: 401 ID = foo 402 bar = value 403 foo = value 404 ` 405 406 const testStateMvCount_stateOut = ` 407 test_instance.bar.0: 408 ID = foo 409 bar = value 410 foo = value 411 test_instance.bar.1: 412 ID = bar 413 bar = value 414 foo = value 415 ` 416 417 const testStateMvCount_stateOutSrc = ` 418 test_instance.bar: 419 ID = bar 420 bar = value 421 foo = value 422 ` 423 424 const testStateMvCount_stateOutOriginal = ` 425 test_instance.bar: 426 ID = bar 427 bar = value 428 foo = value 429 test_instance.foo.0: 430 ID = foo 431 bar = value 432 foo = value 433 test_instance.foo.1: 434 ID = bar 435 bar = value 436 foo = value 437 ` 438 439 const testStateMvNestedModule_stateOut = ` 440 <no state> 441 module.bar: 442 <no state> 443 module.bar.child1: 444 test_instance.foo: 445 ID = bar 446 bar = value 447 foo = value 448 module.bar.child2: 449 test_instance.foo: 450 ID = bar 451 bar = value 452 foo = value 453 ` 454 455 const testStateMvNestedModule_stateOutSrc = ` 456 <no state> 457 ` 458 459 const testStateMvNestedModule_stateOutOriginal = ` 460 <no state> 461 module.foo: 462 <no state> 463 module.foo.child1: 464 test_instance.foo: 465 ID = bar 466 bar = value 467 foo = value 468 module.foo.child2: 469 test_instance.foo: 470 ID = bar 471 bar = value 472 foo = value 473 ` 474 475 const testStateMvOutput_stateOut = ` 476 test_instance.bar: 477 ID = bar 478 bar = value 479 foo = value 480 ` 481 482 const testStateMvOutput_stateOutSrc = ` 483 <no state> 484 ` 485 486 const testStateMvOutput_stateOutOriginal = ` 487 test_instance.foo: 488 ID = bar 489 bar = value 490 foo = value 491 ` 492 493 const testStateMvExisting_stateSrc = ` 494 <no state> 495 ` 496 497 const testStateMvExisting_stateDst = ` 498 test_instance.bar: 499 ID = bar 500 bar = value 501 foo = value 502 test_instance.qux: 503 ID = bar 504 ` 505 506 const testStateMvExisting_stateSrcOriginal = ` 507 test_instance.foo: 508 ID = bar 509 bar = value 510 foo = value 511 ` 512 513 const testStateMvExisting_stateDstOriginal = ` 514 test_instance.qux: 515 ID = bar 516 `