github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/terraform/context_input_test.go (about) 1 package terraform 2 3 import ( 4 "reflect" 5 "strings" 6 "sync" 7 "testing" 8 ) 9 10 func TestContext2Input(t *testing.T) { 11 input := new(MockUIInput) 12 m := testModule(t, "input-vars") 13 p := testProvider("aws") 14 p.ApplyFn = testApplyFn 15 p.DiffFn = testDiffFn 16 ctx := testContext2(t, &ContextOpts{ 17 Module: m, 18 Providers: map[string]ResourceProviderFactory{ 19 "aws": testProviderFuncFixed(p), 20 }, 21 Variables: map[string]string{ 22 "foo": "us-west-2", 23 "amis.us-east-1": "override", 24 }, 25 UIInput: input, 26 }) 27 28 input.InputReturnMap = map[string]string{ 29 "var.foo": "us-east-1", 30 } 31 32 if err := ctx.Input(InputModeStd); err != nil { 33 t.Fatalf("err: %s", err) 34 } 35 36 if _, err := ctx.Plan(); err != nil { 37 t.Fatalf("err: %s", err) 38 } 39 40 state, err := ctx.Apply() 41 if err != nil { 42 t.Fatalf("err: %s", err) 43 } 44 45 actual := strings.TrimSpace(state.String()) 46 expected := strings.TrimSpace(testTerraformInputVarsStr) 47 if actual != expected { 48 t.Fatalf("bad: \n%s", actual) 49 } 50 } 51 52 func TestContext2Input_badVarDefault(t *testing.T) { 53 m := testModule(t, "input-bad-var-default") 54 p := testProvider("aws") 55 p.ApplyFn = testApplyFn 56 p.DiffFn = testDiffFn 57 ctx := testContext2(t, &ContextOpts{ 58 Module: m, 59 Providers: map[string]ResourceProviderFactory{ 60 "aws": testProviderFuncFixed(p), 61 }, 62 }) 63 64 p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) { 65 c.Config["foo"] = "bar" 66 return c, nil 67 } 68 69 if err := ctx.Input(InputModeStd); err != nil { 70 t.Fatalf("err: %s", err) 71 } 72 } 73 74 func TestContext2Input_provider(t *testing.T) { 75 m := testModule(t, "input-provider") 76 p := testProvider("aws") 77 p.ApplyFn = testApplyFn 78 p.DiffFn = testDiffFn 79 ctx := testContext2(t, &ContextOpts{ 80 Module: m, 81 Providers: map[string]ResourceProviderFactory{ 82 "aws": testProviderFuncFixed(p), 83 }, 84 }) 85 86 var actual interface{} 87 p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) { 88 c.Config["foo"] = "bar" 89 return c, nil 90 } 91 p.ConfigureFn = func(c *ResourceConfig) error { 92 actual = c.Config["foo"] 93 return nil 94 } 95 p.ValidateFn = func(c *ResourceConfig) ([]string, []error) { 96 return nil, c.CheckSet([]string{"foo"}) 97 } 98 99 if err := ctx.Input(InputModeStd); err != nil { 100 t.Fatalf("err: %s", err) 101 } 102 103 if _, err := ctx.Plan(); err != nil { 104 t.Fatalf("err: %s", err) 105 } 106 107 if _, err := ctx.Apply(); err != nil { 108 t.Fatalf("err: %s", err) 109 } 110 111 if !reflect.DeepEqual(actual, "bar") { 112 t.Fatalf("bad: %#v", actual) 113 } 114 } 115 116 func TestContext2Input_providerMulti(t *testing.T) { 117 m := testModule(t, "input-provider-multi") 118 p := testProvider("aws") 119 p.ApplyFn = testApplyFn 120 p.DiffFn = testDiffFn 121 ctx := testContext2(t, &ContextOpts{ 122 Module: m, 123 Providers: map[string]ResourceProviderFactory{ 124 "aws": testProviderFuncFixed(p), 125 }, 126 }) 127 128 var actual []interface{} 129 var lock sync.Mutex 130 p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) { 131 c.Config["foo"] = "bar" 132 return c, nil 133 } 134 p.ConfigureFn = func(c *ResourceConfig) error { 135 lock.Lock() 136 defer lock.Unlock() 137 actual = append(actual, c.Config["foo"]) 138 return nil 139 } 140 p.ValidateFn = func(c *ResourceConfig) ([]string, []error) { 141 return nil, c.CheckSet([]string{"foo"}) 142 } 143 144 if err := ctx.Input(InputModeStd); err != nil { 145 t.Fatalf("err: %s", err) 146 } 147 148 if _, err := ctx.Plan(); err != nil { 149 t.Fatalf("err: %s", err) 150 } 151 152 if _, err := ctx.Apply(); err != nil { 153 t.Fatalf("err: %s", err) 154 } 155 156 expected := []interface{}{"bar", "bar"} 157 if !reflect.DeepEqual(actual, expected) { 158 t.Fatalf("bad: %#v", actual) 159 } 160 } 161 162 func TestContext2Input_providerOnce(t *testing.T) { 163 m := testModule(t, "input-provider-once") 164 p := testProvider("aws") 165 p.ApplyFn = testApplyFn 166 p.DiffFn = testDiffFn 167 ctx := testContext2(t, &ContextOpts{ 168 Module: m, 169 Providers: map[string]ResourceProviderFactory{ 170 "aws": testProviderFuncFixed(p), 171 }, 172 }) 173 174 count := 0 175 p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) { 176 count++ 177 return nil, nil 178 } 179 180 if err := ctx.Input(InputModeStd); err != nil { 181 t.Fatalf("err: %s", err) 182 } 183 184 if count != 1 { 185 t.Fatalf("should only be called once: %d", count) 186 } 187 } 188 189 func TestContext2Input_providerId(t *testing.T) { 190 input := new(MockUIInput) 191 m := testModule(t, "input-provider") 192 p := testProvider("aws") 193 p.ApplyFn = testApplyFn 194 p.DiffFn = testDiffFn 195 ctx := testContext2(t, &ContextOpts{ 196 Module: m, 197 Providers: map[string]ResourceProviderFactory{ 198 "aws": testProviderFuncFixed(p), 199 }, 200 UIInput: input, 201 }) 202 203 var actual interface{} 204 p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) { 205 v, err := i.Input(&InputOpts{Id: "foo"}) 206 if err != nil { 207 return nil, err 208 } 209 210 c.Config["foo"] = v 211 return c, nil 212 } 213 p.ConfigureFn = func(c *ResourceConfig) error { 214 actual = c.Config["foo"] 215 return nil 216 } 217 218 input.InputReturnMap = map[string]string{ 219 "provider.aws.foo": "bar", 220 } 221 222 if err := ctx.Input(InputModeStd); err != nil { 223 t.Fatalf("err: %s", err) 224 } 225 226 if _, err := ctx.Plan(); err != nil { 227 t.Fatalf("err: %s", err) 228 } 229 230 if _, err := ctx.Apply(); err != nil { 231 t.Fatalf("err: %s", err) 232 } 233 234 if !reflect.DeepEqual(actual, "bar") { 235 t.Fatalf("bad: %#v", actual) 236 } 237 } 238 239 func TestContext2Input_providerOnly(t *testing.T) { 240 input := new(MockUIInput) 241 m := testModule(t, "input-provider-vars") 242 p := testProvider("aws") 243 p.ApplyFn = testApplyFn 244 p.DiffFn = testDiffFn 245 ctx := testContext2(t, &ContextOpts{ 246 Module: m, 247 Providers: map[string]ResourceProviderFactory{ 248 "aws": testProviderFuncFixed(p), 249 }, 250 Variables: map[string]string{ 251 "foo": "us-west-2", 252 }, 253 UIInput: input, 254 }) 255 256 input.InputReturnMap = map[string]string{ 257 "var.foo": "us-east-1", 258 } 259 260 var actual interface{} 261 p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) { 262 c.Config["foo"] = "bar" 263 return c, nil 264 } 265 p.ConfigureFn = func(c *ResourceConfig) error { 266 actual = c.Config["foo"] 267 return nil 268 } 269 270 if err := ctx.Input(InputModeProvider); err != nil { 271 t.Fatalf("err: %s", err) 272 } 273 274 if _, err := ctx.Plan(); err != nil { 275 t.Fatalf("err: %s", err) 276 } 277 278 state, err := ctx.Apply() 279 if err != nil { 280 t.Fatalf("err: %s", err) 281 } 282 283 if !reflect.DeepEqual(actual, "bar") { 284 t.Fatalf("bad: %#v", actual) 285 } 286 287 actualStr := strings.TrimSpace(state.String()) 288 expectedStr := strings.TrimSpace(testTerraformInputProviderOnlyStr) 289 if actualStr != expectedStr { 290 t.Fatalf("bad: \n%s", actualStr) 291 } 292 } 293 294 func TestContext2Input_providerVars(t *testing.T) { 295 input := new(MockUIInput) 296 m := testModule(t, "input-provider-with-vars") 297 p := testProvider("aws") 298 p.ApplyFn = testApplyFn 299 p.DiffFn = testDiffFn 300 ctx := testContext2(t, &ContextOpts{ 301 Module: m, 302 Providers: map[string]ResourceProviderFactory{ 303 "aws": testProviderFuncFixed(p), 304 }, 305 Variables: map[string]string{ 306 "foo": "bar", 307 }, 308 UIInput: input, 309 }) 310 311 input.InputReturnMap = map[string]string{ 312 "var.foo": "bar", 313 } 314 315 var actual interface{} 316 p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) { 317 c.Config["bar"] = "baz" 318 return c, nil 319 } 320 p.ConfigureFn = func(c *ResourceConfig) error { 321 actual, _ = c.Get("foo") 322 return nil 323 } 324 325 if err := ctx.Input(InputModeStd); err != nil { 326 t.Fatalf("err: %s", err) 327 } 328 329 if _, err := ctx.Plan(); err != nil { 330 t.Fatalf("err: %s", err) 331 } 332 333 if _, err := ctx.Apply(); err != nil { 334 t.Fatalf("err: %s", err) 335 } 336 337 if !reflect.DeepEqual(actual, "bar") { 338 t.Fatalf("bad: %#v", actual) 339 } 340 } 341 342 func TestContext2Input_providerVarsModuleInherit(t *testing.T) { 343 input := new(MockUIInput) 344 m := testModule(t, "input-provider-with-vars-and-module") 345 p := testProvider("aws") 346 p.ApplyFn = testApplyFn 347 p.DiffFn = testDiffFn 348 ctx := testContext2(t, &ContextOpts{ 349 Module: m, 350 Providers: map[string]ResourceProviderFactory{ 351 "aws": testProviderFuncFixed(p), 352 }, 353 UIInput: input, 354 }) 355 356 p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) { 357 if errs := c.CheckSet([]string{"access_key"}); len(errs) > 0 { 358 return c, errs[0] 359 } 360 return c, nil 361 } 362 p.ConfigureFn = func(c *ResourceConfig) error { 363 return nil 364 } 365 366 if err := ctx.Input(InputModeStd); err != nil { 367 t.Fatalf("err: %s", err) 368 } 369 } 370 371 func TestContext2Input_varOnly(t *testing.T) { 372 input := new(MockUIInput) 373 m := testModule(t, "input-provider-vars") 374 p := testProvider("aws") 375 p.ApplyFn = testApplyFn 376 p.DiffFn = testDiffFn 377 ctx := testContext2(t, &ContextOpts{ 378 Module: m, 379 Providers: map[string]ResourceProviderFactory{ 380 "aws": testProviderFuncFixed(p), 381 }, 382 Variables: map[string]string{ 383 "foo": "us-west-2", 384 }, 385 UIInput: input, 386 }) 387 388 input.InputReturnMap = map[string]string{ 389 "var.foo": "us-east-1", 390 } 391 392 var actual interface{} 393 p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) { 394 c.Raw["foo"] = "bar" 395 return c, nil 396 } 397 p.ConfigureFn = func(c *ResourceConfig) error { 398 actual = c.Raw["foo"] 399 return nil 400 } 401 402 if err := ctx.Input(InputModeVar); err != nil { 403 t.Fatalf("err: %s", err) 404 } 405 406 if _, err := ctx.Plan(); err != nil { 407 t.Fatalf("err: %s", err) 408 } 409 410 state, err := ctx.Apply() 411 if err != nil { 412 t.Fatalf("err: %s", err) 413 } 414 415 if reflect.DeepEqual(actual, "bar") { 416 t.Fatalf("bad: %#v", actual) 417 } 418 419 actualStr := strings.TrimSpace(state.String()) 420 expectedStr := strings.TrimSpace(testTerraformInputVarOnlyStr) 421 if actualStr != expectedStr { 422 t.Fatalf("bad: \n%s", actualStr) 423 } 424 } 425 426 func TestContext2Input_varOnlyUnset(t *testing.T) { 427 input := new(MockUIInput) 428 m := testModule(t, "input-vars-unset") 429 p := testProvider("aws") 430 p.ApplyFn = testApplyFn 431 p.DiffFn = testDiffFn 432 ctx := testContext2(t, &ContextOpts{ 433 Module: m, 434 Providers: map[string]ResourceProviderFactory{ 435 "aws": testProviderFuncFixed(p), 436 }, 437 Variables: map[string]string{ 438 "foo": "foovalue", 439 }, 440 UIInput: input, 441 }) 442 443 input.InputReturnMap = map[string]string{ 444 "var.foo": "nope", 445 "var.bar": "baz", 446 } 447 448 if err := ctx.Input(InputModeVar | InputModeVarUnset); err != nil { 449 t.Fatalf("err: %s", err) 450 } 451 452 if _, err := ctx.Plan(); err != nil { 453 t.Fatalf("err: %s", err) 454 } 455 456 state, err := ctx.Apply() 457 if err != nil { 458 t.Fatalf("err: %s", err) 459 } 460 461 actualStr := strings.TrimSpace(state.String()) 462 expectedStr := strings.TrimSpace(testTerraformInputVarOnlyUnsetStr) 463 if actualStr != expectedStr { 464 t.Fatalf("bad: \n%s", actualStr) 465 } 466 } 467 468 func TestContext2Input_varWithDefault(t *testing.T) { 469 input := new(MockUIInput) 470 m := testModule(t, "input-var-default") 471 p := testProvider("aws") 472 p.ApplyFn = testApplyFn 473 p.DiffFn = testDiffFn 474 ctx := testContext2(t, &ContextOpts{ 475 Module: m, 476 Providers: map[string]ResourceProviderFactory{ 477 "aws": testProviderFuncFixed(p), 478 }, 479 Variables: map[string]string{}, 480 UIInput: input, 481 }) 482 483 input.InputFn = func(opts *InputOpts) (string, error) { 484 t.Fatalf( 485 "Input should never be called because variable has a default: %#v", opts) 486 return "", nil 487 } 488 489 if err := ctx.Input(InputModeVar | InputModeVarUnset); err != nil { 490 t.Fatalf("err: %s", err) 491 } 492 493 if _, err := ctx.Plan(); err != nil { 494 t.Fatalf("err: %s", err) 495 } 496 497 state, err := ctx.Apply() 498 if err != nil { 499 t.Fatalf("err: %s", err) 500 } 501 502 actualStr := strings.TrimSpace(state.String()) 503 expectedStr := strings.TrimSpace(` 504 aws_instance.foo: 505 ID = foo 506 foo = 123 507 type = aws_instance 508 `) 509 if actualStr != expectedStr { 510 t.Fatalf("expected: \n%s\ngot: \n%s\n", expectedStr, actualStr) 511 } 512 } 513 514 func TestContext2Input_varPartiallyComputed(t *testing.T) { 515 input := new(MockUIInput) 516 m := testModule(t, "input-var-partially-computed") 517 p := testProvider("aws") 518 p.ApplyFn = testApplyFn 519 p.DiffFn = testDiffFn 520 ctx := testContext2(t, &ContextOpts{ 521 Module: m, 522 Providers: map[string]ResourceProviderFactory{ 523 "aws": testProviderFuncFixed(p), 524 }, 525 Variables: map[string]string{ 526 "foo": "foovalue", 527 }, 528 UIInput: input, 529 State: &State{ 530 Modules: []*ModuleState{ 531 &ModuleState{ 532 Path: rootModulePath, 533 Resources: map[string]*ResourceState{ 534 "aws_instance.foo": &ResourceState{ 535 Type: "aws_instance", 536 Primary: &InstanceState{ 537 ID: "i-abc123", 538 Attributes: map[string]string{ 539 "id": "i-abc123", 540 }, 541 }, 542 }, 543 }, 544 }, 545 &ModuleState{ 546 Path: append(rootModulePath, "child"), 547 Resources: map[string]*ResourceState{ 548 "aws_instance.mod": &ResourceState{ 549 Type: "aws_instance", 550 Primary: &InstanceState{ 551 ID: "i-bcd345", 552 Attributes: map[string]string{ 553 "id": "i-bcd345", 554 "value": "one,i-abc123", 555 }, 556 }, 557 }, 558 }, 559 }, 560 }, 561 }, 562 }) 563 564 if err := ctx.Input(InputModeStd); err != nil { 565 t.Fatalf("err: %s", err) 566 } 567 568 if _, err := ctx.Plan(); err != nil { 569 t.Fatalf("err: %s", err) 570 } 571 }