github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/heroku/resource_heroku_app_test.go (about) 1 package heroku 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "testing" 8 9 "github.com/cyberdelia/heroku-go/v3" 10 "github.com/hashicorp/terraform/helper/acctest" 11 "github.com/hashicorp/terraform/helper/resource" 12 "github.com/hashicorp/terraform/terraform" 13 ) 14 15 func TestAccHerokuApp_Basic(t *testing.T) { 16 var app heroku.AppInfoResult 17 appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) 18 19 resource.Test(t, resource.TestCase{ 20 PreCheck: func() { testAccPreCheck(t) }, 21 Providers: testAccProviders, 22 CheckDestroy: testAccCheckHerokuAppDestroy, 23 Steps: []resource.TestStep{ 24 { 25 Config: testAccCheckHerokuAppConfig_basic(appName), 26 Check: resource.ComposeTestCheckFunc( 27 testAccCheckHerokuAppExists("heroku_app.foobar", &app), 28 testAccCheckHerokuAppAttributes(&app, appName), 29 resource.TestCheckResourceAttr( 30 "heroku_app.foobar", "name", appName), 31 resource.TestCheckResourceAttr( 32 "heroku_app.foobar", "config_vars.0.FOO", "bar"), 33 ), 34 }, 35 }, 36 }) 37 } 38 39 func TestAccHerokuApp_NameChange(t *testing.T) { 40 var app heroku.AppInfoResult 41 appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) 42 appName2 := fmt.Sprintf("%s-v2", appName) 43 44 resource.Test(t, resource.TestCase{ 45 PreCheck: func() { testAccPreCheck(t) }, 46 Providers: testAccProviders, 47 CheckDestroy: testAccCheckHerokuAppDestroy, 48 Steps: []resource.TestStep{ 49 { 50 Config: testAccCheckHerokuAppConfig_basic(appName), 51 Check: resource.ComposeTestCheckFunc( 52 testAccCheckHerokuAppExists("heroku_app.foobar", &app), 53 testAccCheckHerokuAppAttributes(&app, appName), 54 resource.TestCheckResourceAttr( 55 "heroku_app.foobar", "name", appName), 56 resource.TestCheckResourceAttr( 57 "heroku_app.foobar", "config_vars.0.FOO", "bar"), 58 ), 59 }, 60 { 61 Config: testAccCheckHerokuAppConfig_updated(appName2), 62 Check: resource.ComposeTestCheckFunc( 63 testAccCheckHerokuAppExists("heroku_app.foobar", &app), 64 testAccCheckHerokuAppAttributesUpdated(&app, appName2), 65 resource.TestCheckResourceAttr( 66 "heroku_app.foobar", "name", appName2), 67 resource.TestCheckResourceAttr( 68 "heroku_app.foobar", "config_vars.0.FOO", "bing"), 69 resource.TestCheckResourceAttr( 70 "heroku_app.foobar", "config_vars.0.BAZ", "bar"), 71 ), 72 }, 73 }, 74 }) 75 } 76 77 func TestAccHerokuApp_NukeVars(t *testing.T) { 78 var app heroku.AppInfoResult 79 appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) 80 81 resource.Test(t, resource.TestCase{ 82 PreCheck: func() { testAccPreCheck(t) }, 83 Providers: testAccProviders, 84 CheckDestroy: testAccCheckHerokuAppDestroy, 85 Steps: []resource.TestStep{ 86 { 87 Config: testAccCheckHerokuAppConfig_basic(appName), 88 Check: resource.ComposeTestCheckFunc( 89 testAccCheckHerokuAppExists("heroku_app.foobar", &app), 90 testAccCheckHerokuAppAttributes(&app, appName), 91 resource.TestCheckResourceAttr( 92 "heroku_app.foobar", "name", appName), 93 resource.TestCheckResourceAttr( 94 "heroku_app.foobar", "config_vars.0.FOO", "bar"), 95 ), 96 }, 97 { 98 Config: testAccCheckHerokuAppConfig_no_vars(appName), 99 Check: resource.ComposeTestCheckFunc( 100 testAccCheckHerokuAppExists("heroku_app.foobar", &app), 101 testAccCheckHerokuAppAttributesNoVars(&app, appName), 102 resource.TestCheckResourceAttr( 103 "heroku_app.foobar", "name", appName), 104 resource.TestCheckNoResourceAttr( 105 "heroku_app.foobar", "config_vars.0.FOO"), 106 ), 107 }, 108 }, 109 }) 110 } 111 112 func TestAccHerokuApp_Buildpacks(t *testing.T) { 113 var app heroku.AppInfoResult 114 appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) 115 116 resource.Test(t, resource.TestCase{ 117 PreCheck: func() { testAccPreCheck(t) }, 118 Providers: testAccProviders, 119 CheckDestroy: testAccCheckHerokuAppDestroy, 120 Steps: []resource.TestStep{ 121 { 122 Config: testAccCheckHerokuAppConfig_go(appName), 123 Check: resource.ComposeTestCheckFunc( 124 testAccCheckHerokuAppExists("heroku_app.foobar", &app), 125 testAccCheckHerokuAppBuildpacks(appName, false), 126 resource.TestCheckResourceAttr("heroku_app.foobar", "buildpacks.0", "heroku/go"), 127 ), 128 }, 129 { 130 Config: testAccCheckHerokuAppConfig_multi(appName), 131 Check: resource.ComposeTestCheckFunc( 132 testAccCheckHerokuAppExists("heroku_app.foobar", &app), 133 testAccCheckHerokuAppBuildpacks(appName, true), 134 resource.TestCheckResourceAttr( 135 "heroku_app.foobar", "buildpacks.0", "https://github.com/heroku/heroku-buildpack-multi-procfile"), 136 resource.TestCheckResourceAttr("heroku_app.foobar", "buildpacks.1", "heroku/go"), 137 ), 138 }, 139 { 140 Config: testAccCheckHerokuAppConfig_no_vars(appName), 141 Check: resource.ComposeTestCheckFunc( 142 testAccCheckHerokuAppExists("heroku_app.foobar", &app), 143 testAccCheckHerokuAppNoBuildpacks(appName), 144 resource.TestCheckNoResourceAttr("heroku_app.foobar", "buildpacks.0"), 145 ), 146 }, 147 }, 148 }) 149 } 150 151 func TestAccHerokuApp_ExternallySetBuildpacks(t *testing.T) { 152 var app heroku.AppInfoResult 153 appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) 154 155 resource.Test(t, resource.TestCase{ 156 PreCheck: func() { testAccPreCheck(t) }, 157 Providers: testAccProviders, 158 CheckDestroy: testAccCheckHerokuAppDestroy, 159 Steps: []resource.TestStep{ 160 { 161 Config: testAccCheckHerokuAppConfig_no_vars(appName), 162 Check: resource.ComposeTestCheckFunc( 163 testAccCheckHerokuAppExists("heroku_app.foobar", &app), 164 testAccCheckHerokuAppNoBuildpacks(appName), 165 resource.TestCheckNoResourceAttr("heroku_app.foobar", "buildpacks.0"), 166 ), 167 }, 168 { 169 PreConfig: testAccInstallUnconfiguredBuildpack(t, appName), 170 Config: testAccCheckHerokuAppConfig_no_vars(appName), 171 Check: resource.ComposeTestCheckFunc( 172 testAccCheckHerokuAppExists("heroku_app.foobar", &app), 173 testAccCheckHerokuAppBuildpacks(appName, false), 174 resource.TestCheckNoResourceAttr("heroku_app.foobar", "buildpacks.0"), 175 ), 176 }, 177 }, 178 }) 179 } 180 181 func TestAccHerokuApp_Organization(t *testing.T) { 182 var app heroku.OrganizationApp 183 appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) 184 org := os.Getenv("HEROKU_ORGANIZATION") 185 186 resource.Test(t, resource.TestCase{ 187 PreCheck: func() { 188 testAccPreCheck(t) 189 if org == "" { 190 t.Skip("HEROKU_ORGANIZATION is not set; skipping test.") 191 } 192 }, 193 Providers: testAccProviders, 194 CheckDestroy: testAccCheckHerokuAppDestroy, 195 Steps: []resource.TestStep{ 196 { 197 Config: testAccCheckHerokuAppConfig_organization(appName, org), 198 Check: resource.ComposeTestCheckFunc( 199 testAccCheckHerokuAppExistsOrg("heroku_app.foobar", &app), 200 testAccCheckHerokuAppAttributesOrg(&app, appName, "", org), 201 ), 202 }, 203 }, 204 }) 205 } 206 207 func TestAccHerokuApp_Space(t *testing.T) { 208 var app heroku.OrganizationApp 209 appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) 210 org := os.Getenv("HEROKU_ORGANIZATION") 211 space := os.Getenv("HEROKU_SPACE") 212 213 resource.Test(t, resource.TestCase{ 214 PreCheck: func() { 215 testAccPreCheck(t) 216 if org == "" { 217 t.Skip("HEROKU_ORGANIZATION is not set; skipping test.") 218 } 219 if space == "" { 220 t.Skip("HEROKU_SPACE is not set; skipping test.") 221 } 222 }, 223 Providers: testAccProviders, 224 CheckDestroy: testAccCheckHerokuAppDestroy, 225 Steps: []resource.TestStep{ 226 { 227 Config: testAccCheckHerokuAppConfig_space(appName, space, org), 228 Check: resource.ComposeTestCheckFunc( 229 testAccCheckHerokuAppExistsOrg("heroku_app.foobar", &app), 230 testAccCheckHerokuAppAttributesOrg(&app, appName, space, org), 231 ), 232 }, 233 }, 234 }) 235 } 236 237 func testAccCheckHerokuAppDestroy(s *terraform.State) error { 238 client := testAccProvider.Meta().(*heroku.Service) 239 240 for _, rs := range s.RootModule().Resources { 241 if rs.Type != "heroku_app" { 242 continue 243 } 244 245 _, err := client.AppInfo(context.TODO(), rs.Primary.ID) 246 247 if err == nil { 248 return fmt.Errorf("App still exists") 249 } 250 } 251 252 return nil 253 } 254 255 func testAccCheckHerokuAppAttributes(app *heroku.AppInfoResult, appName string) resource.TestCheckFunc { 256 return func(s *terraform.State) error { 257 client := testAccProvider.Meta().(*heroku.Service) 258 259 if app.Region.Name != "us" { 260 return fmt.Errorf("Bad region: %s", app.Region.Name) 261 } 262 263 if app.Stack.Name != "cedar-14" { 264 return fmt.Errorf("Bad stack: %s", app.Stack.Name) 265 } 266 267 if app.Name != appName { 268 return fmt.Errorf("Bad name: %s", app.Name) 269 } 270 271 vars, err := client.ConfigVarInfoForApp(context.TODO(), app.Name) 272 if err != nil { 273 return err 274 } 275 276 if vars["FOO"] == nil || *vars["FOO"] != "bar" { 277 return fmt.Errorf("Bad config vars: %v", vars) 278 } 279 280 return nil 281 } 282 } 283 284 func testAccCheckHerokuAppAttributesUpdated(app *heroku.AppInfoResult, appName string) resource.TestCheckFunc { 285 return func(s *terraform.State) error { 286 client := testAccProvider.Meta().(*heroku.Service) 287 288 if app.Name != appName { 289 return fmt.Errorf("Bad name: %s", app.Name) 290 } 291 292 vars, err := client.ConfigVarInfoForApp(context.TODO(), app.Name) 293 if err != nil { 294 return err 295 } 296 297 // Make sure we kept the old one 298 if vars["FOO"] == nil || *vars["FOO"] != "bing" { 299 return fmt.Errorf("Bad config vars: %v", vars) 300 } 301 302 if vars["BAZ"] == nil || *vars["BAZ"] != "bar" { 303 return fmt.Errorf("Bad config vars: %v", vars) 304 } 305 306 return nil 307 308 } 309 } 310 311 func testAccCheckHerokuAppAttributesNoVars(app *heroku.AppInfoResult, appName string) resource.TestCheckFunc { 312 return func(s *terraform.State) error { 313 client := testAccProvider.Meta().(*heroku.Service) 314 315 if app.Name != appName { 316 return fmt.Errorf("Bad name: %s", app.Name) 317 } 318 319 vars, err := client.ConfigVarInfoForApp(context.TODO(), app.Name) 320 if err != nil { 321 return err 322 } 323 324 if len(vars) != 0 { 325 return fmt.Errorf("vars exist: %v", vars) 326 } 327 328 return nil 329 } 330 } 331 332 func testAccCheckHerokuAppBuildpacks(appName string, multi bool) resource.TestCheckFunc { 333 return func(s *terraform.State) error { 334 client := testAccProvider.Meta().(*heroku.Service) 335 336 results, err := client.BuildpackInstallationList(context.TODO(), appName, nil) 337 if err != nil { 338 return err 339 } 340 341 buildpacks := []string{} 342 for _, installation := range results { 343 buildpacks = append(buildpacks, installation.Buildpack.Name) 344 } 345 346 if multi { 347 herokuMulti := "https://github.com/heroku/heroku-buildpack-multi-procfile" 348 if len(buildpacks) != 2 || buildpacks[0] != herokuMulti || buildpacks[1] != "heroku/go" { 349 return fmt.Errorf("Bad buildpacks: %v", buildpacks) 350 } 351 352 return nil 353 } 354 355 if len(buildpacks) != 1 || buildpacks[0] != "heroku/go" { 356 return fmt.Errorf("Bad buildpacks: %v", buildpacks) 357 } 358 359 return nil 360 } 361 } 362 363 func testAccCheckHerokuAppNoBuildpacks(appName string) resource.TestCheckFunc { 364 return func(s *terraform.State) error { 365 client := testAccProvider.Meta().(*heroku.Service) 366 367 results, err := client.BuildpackInstallationList(context.TODO(), appName, nil) 368 if err != nil { 369 return err 370 } 371 372 buildpacks := []string{} 373 for _, installation := range results { 374 buildpacks = append(buildpacks, installation.Buildpack.Name) 375 } 376 377 if len(buildpacks) != 0 { 378 return fmt.Errorf("Bad buildpacks: %v", buildpacks) 379 } 380 381 return nil 382 } 383 } 384 385 func testAccCheckHerokuAppAttributesOrg(app *heroku.OrganizationApp, appName, space, org string) resource.TestCheckFunc { 386 return func(s *terraform.State) error { 387 client := testAccProvider.Meta().(*heroku.Service) 388 389 if app.Region.Name != "us" && app.Region.Name != "virginia" { 390 return fmt.Errorf("Bad region: %s", app.Region.Name) 391 } 392 393 var appSpace string 394 if app.Space != nil { 395 appSpace = app.Space.Name 396 } 397 398 if appSpace != space { 399 return fmt.Errorf("Bad space: %s", appSpace) 400 } 401 402 if app.Stack.Name != "cedar-14" { 403 return fmt.Errorf("Bad stack: %s", app.Stack.Name) 404 } 405 406 if app.Name != appName { 407 return fmt.Errorf("Bad name: %s", app.Name) 408 } 409 410 if app.Organization == nil || app.Organization.Name != org { 411 return fmt.Errorf("Bad org: %v", app.Organization) 412 } 413 414 vars, err := client.ConfigVarInfoForApp(context.TODO(), app.Name) 415 if err != nil { 416 return err 417 } 418 419 if vars["FOO"] == nil || *vars["FOO"] != "bar" { 420 return fmt.Errorf("Bad config vars: %v", vars) 421 } 422 423 return nil 424 } 425 } 426 427 func testAccCheckHerokuAppExists(n string, app *heroku.AppInfoResult) resource.TestCheckFunc { 428 return func(s *terraform.State) error { 429 rs, ok := s.RootModule().Resources[n] 430 431 if !ok { 432 return fmt.Errorf("Not found: %s", n) 433 } 434 435 if rs.Primary.ID == "" { 436 return fmt.Errorf("No App Name is set") 437 } 438 439 client := testAccProvider.Meta().(*heroku.Service) 440 441 foundApp, err := client.AppInfo(context.TODO(), rs.Primary.ID) 442 443 if err != nil { 444 return err 445 } 446 447 if foundApp.Name != rs.Primary.ID { 448 return fmt.Errorf("App not found") 449 } 450 451 *app = *foundApp 452 453 return nil 454 } 455 } 456 457 func testAccCheckHerokuAppExistsOrg(n string, app *heroku.OrganizationApp) resource.TestCheckFunc { 458 return func(s *terraform.State) error { 459 rs, ok := s.RootModule().Resources[n] 460 461 if !ok { 462 return fmt.Errorf("Not found: %s", n) 463 } 464 465 if rs.Primary.ID == "" { 466 return fmt.Errorf("No App Name is set") 467 } 468 469 client := testAccProvider.Meta().(*heroku.Service) 470 471 foundApp, err := client.OrganizationAppInfo(context.TODO(), rs.Primary.ID) 472 473 if err != nil { 474 return err 475 } 476 477 if foundApp.Name != rs.Primary.ID { 478 return fmt.Errorf("App not found") 479 } 480 481 *app = *foundApp 482 483 return nil 484 } 485 } 486 487 func testAccInstallUnconfiguredBuildpack(t *testing.T, appName string) func() { 488 return func() { 489 client := testAccProvider.Meta().(*heroku.Service) 490 491 opts := heroku.BuildpackInstallationUpdateOpts{ 492 Updates: []struct { 493 Buildpack string `json:"buildpack" url:"buildpack,key"` 494 }{ 495 {Buildpack: "heroku/go"}, 496 }, 497 } 498 499 _, err := client.BuildpackInstallationUpdate(context.TODO(), appName, opts) 500 if err != nil { 501 t.Fatalf("Error updating buildpacks: %s", err) 502 } 503 } 504 } 505 506 func testAccCheckHerokuAppConfig_basic(appName string) string { 507 return fmt.Sprintf(` 508 resource "heroku_app" "foobar" { 509 name = "%s" 510 region = "us" 511 512 config_vars { 513 FOO = "bar" 514 } 515 }`, appName) 516 } 517 518 func testAccCheckHerokuAppConfig_go(appName string) string { 519 return fmt.Sprintf(` 520 resource "heroku_app" "foobar" { 521 name = "%s" 522 region = "us" 523 524 buildpacks = ["heroku/go"] 525 }`, appName) 526 } 527 528 func testAccCheckHerokuAppConfig_multi(appName string) string { 529 return fmt.Sprintf(` 530 resource "heroku_app" "foobar" { 531 name = "%s" 532 region = "us" 533 534 buildpacks = [ 535 "https://github.com/heroku/heroku-buildpack-multi-procfile", 536 "heroku/go" 537 ] 538 }`, appName) 539 } 540 541 func testAccCheckHerokuAppConfig_updated(appName string) string { 542 return fmt.Sprintf(` 543 resource "heroku_app" "foobar" { 544 name = "%s" 545 region = "us" 546 547 config_vars { 548 FOO = "bing" 549 BAZ = "bar" 550 } 551 }`, appName) 552 } 553 554 func testAccCheckHerokuAppConfig_no_vars(appName string) string { 555 return fmt.Sprintf(` 556 resource "heroku_app" "foobar" { 557 name = "%s" 558 region = "us" 559 }`, appName) 560 } 561 562 func testAccCheckHerokuAppConfig_organization(appName, org string) string { 563 return fmt.Sprintf(` 564 resource "heroku_app" "foobar" { 565 name = "%s" 566 region = "us" 567 568 organization { 569 name = "%s" 570 } 571 572 config_vars { 573 FOO = "bar" 574 } 575 }`, appName, org) 576 } 577 578 func testAccCheckHerokuAppConfig_space(appName, space, org string) string { 579 return fmt.Sprintf(` 580 resource "heroku_app" "foobar" { 581 name = "%s" 582 space = "%s" 583 region = "virginia" 584 585 organization { 586 name = "%s" 587 } 588 589 config_vars { 590 FOO = "bar" 591 } 592 }`, appName, space, org) 593 }