github.com/skyscape-cloud-services/terraform@v0.9.2-0.20170609144644-7ece028a1747/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.App 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.App 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.App 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.App 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.App 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_SPACES_ORGANIZATION") 211 spaceName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) 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 }, 220 Providers: testAccProviders, 221 CheckDestroy: testAccCheckHerokuAppDestroy, 222 Steps: []resource.TestStep{ 223 { 224 Config: testAccCheckHerokuAppConfig_space(appName, spaceName, org), 225 Check: resource.ComposeTestCheckFunc( 226 testAccCheckHerokuAppExistsOrg("heroku_app.foobar", &app), 227 testAccCheckHerokuAppAttributesOrg(&app, appName, spaceName, org), 228 ), 229 }, 230 }, 231 }) 232 } 233 234 func testAccCheckHerokuAppDestroy(s *terraform.State) error { 235 client := testAccProvider.Meta().(*heroku.Service) 236 237 for _, rs := range s.RootModule().Resources { 238 if rs.Type != "heroku_app" { 239 continue 240 } 241 242 _, err := client.AppInfo(context.TODO(), rs.Primary.ID) 243 244 if err == nil { 245 return fmt.Errorf("App still exists") 246 } 247 } 248 249 return nil 250 } 251 252 func testAccCheckHerokuAppAttributes(app *heroku.App, appName string) resource.TestCheckFunc { 253 return func(s *terraform.State) error { 254 client := testAccProvider.Meta().(*heroku.Service) 255 256 if app.Region.Name != "us" { 257 return fmt.Errorf("Bad region: %s", app.Region.Name) 258 } 259 260 if app.Stack.Name != "heroku-16" { 261 return fmt.Errorf("Bad stack: %s", app.Stack.Name) 262 } 263 264 if app.Name != appName { 265 return fmt.Errorf("Bad name: %s", app.Name) 266 } 267 268 vars, err := client.ConfigVarInfoForApp(context.TODO(), app.Name) 269 if err != nil { 270 return err 271 } 272 273 if vars["FOO"] == nil || *vars["FOO"] != "bar" { 274 return fmt.Errorf("Bad config vars: %v", vars) 275 } 276 277 return nil 278 } 279 } 280 281 func testAccCheckHerokuAppAttributesUpdated(app *heroku.App, appName string) resource.TestCheckFunc { 282 return func(s *terraform.State) error { 283 client := testAccProvider.Meta().(*heroku.Service) 284 285 if app.Name != appName { 286 return fmt.Errorf("Bad name: %s", app.Name) 287 } 288 289 vars, err := client.ConfigVarInfoForApp(context.TODO(), app.Name) 290 if err != nil { 291 return err 292 } 293 294 // Make sure we kept the old one 295 if vars["FOO"] == nil || *vars["FOO"] != "bing" { 296 return fmt.Errorf("Bad config vars: %v", vars) 297 } 298 299 if vars["BAZ"] == nil || *vars["BAZ"] != "bar" { 300 return fmt.Errorf("Bad config vars: %v", vars) 301 } 302 303 return nil 304 305 } 306 } 307 308 func testAccCheckHerokuAppAttributesNoVars(app *heroku.App, appName string) resource.TestCheckFunc { 309 return func(s *terraform.State) error { 310 client := testAccProvider.Meta().(*heroku.Service) 311 312 if app.Name != appName { 313 return fmt.Errorf("Bad name: %s", app.Name) 314 } 315 316 vars, err := client.ConfigVarInfoForApp(context.TODO(), app.Name) 317 if err != nil { 318 return err 319 } 320 321 if len(vars) != 0 { 322 return fmt.Errorf("vars exist: %v", vars) 323 } 324 325 return nil 326 } 327 } 328 329 func testAccCheckHerokuAppBuildpacks(appName string, multi bool) resource.TestCheckFunc { 330 return func(s *terraform.State) error { 331 client := testAccProvider.Meta().(*heroku.Service) 332 333 results, err := client.BuildpackInstallationList(context.TODO(), appName, nil) 334 if err != nil { 335 return err 336 } 337 338 buildpacks := []string{} 339 for _, installation := range results { 340 buildpacks = append(buildpacks, installation.Buildpack.Name) 341 } 342 343 if multi { 344 herokuMulti := "https://github.com/heroku/heroku-buildpack-multi-procfile" 345 if len(buildpacks) != 2 || buildpacks[0] != herokuMulti || buildpacks[1] != "heroku/go" { 346 return fmt.Errorf("Bad buildpacks: %v", buildpacks) 347 } 348 349 return nil 350 } 351 352 if len(buildpacks) != 1 || buildpacks[0] != "heroku/go" { 353 return fmt.Errorf("Bad buildpacks: %v", buildpacks) 354 } 355 356 return nil 357 } 358 } 359 360 func testAccCheckHerokuAppNoBuildpacks(appName string) resource.TestCheckFunc { 361 return func(s *terraform.State) error { 362 client := testAccProvider.Meta().(*heroku.Service) 363 364 results, err := client.BuildpackInstallationList(context.TODO(), appName, nil) 365 if err != nil { 366 return err 367 } 368 369 buildpacks := []string{} 370 for _, installation := range results { 371 buildpacks = append(buildpacks, installation.Buildpack.Name) 372 } 373 374 if len(buildpacks) != 0 { 375 return fmt.Errorf("Bad buildpacks: %v", buildpacks) 376 } 377 378 return nil 379 } 380 } 381 382 func testAccCheckHerokuAppAttributesOrg(app *heroku.OrganizationApp, appName, space, org string) resource.TestCheckFunc { 383 return func(s *terraform.State) error { 384 client := testAccProvider.Meta().(*heroku.Service) 385 386 if app.Region.Name != "us" && app.Region.Name != "virginia" { 387 return fmt.Errorf("Bad region: %s", app.Region.Name) 388 } 389 390 var appSpace string 391 if app.Space != nil { 392 appSpace = app.Space.Name 393 } 394 395 if appSpace != space { 396 return fmt.Errorf("Bad space: %s", appSpace) 397 } 398 399 if app.Stack.Name != "heroku-16" { 400 return fmt.Errorf("Bad stack: %s", app.Stack.Name) 401 } 402 403 if app.Name != appName { 404 return fmt.Errorf("Bad name: %s", app.Name) 405 } 406 407 if app.Organization == nil || app.Organization.Name != org { 408 return fmt.Errorf("Bad org: %v", app.Organization) 409 } 410 411 vars, err := client.ConfigVarInfoForApp(context.TODO(), app.Name) 412 if err != nil { 413 return err 414 } 415 416 if vars["FOO"] == nil || *vars["FOO"] != "bar" { 417 return fmt.Errorf("Bad config vars: %v", vars) 418 } 419 420 return nil 421 } 422 } 423 424 func testAccCheckHerokuAppExists(n string, app *heroku.App) resource.TestCheckFunc { 425 return func(s *terraform.State) error { 426 rs, ok := s.RootModule().Resources[n] 427 428 if !ok { 429 return fmt.Errorf("Not found: %s", n) 430 } 431 432 if rs.Primary.ID == "" { 433 return fmt.Errorf("No App Name is set") 434 } 435 436 client := testAccProvider.Meta().(*heroku.Service) 437 438 foundApp, err := client.AppInfo(context.TODO(), rs.Primary.ID) 439 440 if err != nil { 441 return err 442 } 443 444 if foundApp.Name != rs.Primary.ID { 445 return fmt.Errorf("App not found") 446 } 447 448 *app = *foundApp 449 450 return nil 451 } 452 } 453 454 func testAccCheckHerokuAppExistsOrg(n string, app *heroku.OrganizationApp) resource.TestCheckFunc { 455 return func(s *terraform.State) error { 456 rs, ok := s.RootModule().Resources[n] 457 458 if !ok { 459 return fmt.Errorf("Not found: %s", n) 460 } 461 462 if rs.Primary.ID == "" { 463 return fmt.Errorf("No App Name is set") 464 } 465 466 client := testAccProvider.Meta().(*heroku.Service) 467 468 foundApp, err := client.OrganizationAppInfo(context.TODO(), rs.Primary.ID) 469 470 if err != nil { 471 return err 472 } 473 474 if foundApp.Name != rs.Primary.ID { 475 return fmt.Errorf("App not found") 476 } 477 478 *app = *foundApp 479 480 return nil 481 } 482 } 483 484 func testAccInstallUnconfiguredBuildpack(t *testing.T, appName string) func() { 485 return func() { 486 client := testAccProvider.Meta().(*heroku.Service) 487 488 opts := heroku.BuildpackInstallationUpdateOpts{ 489 Updates: []struct { 490 Buildpack string `json:"buildpack" url:"buildpack,key"` 491 }{ 492 {Buildpack: "heroku/go"}, 493 }, 494 } 495 496 _, err := client.BuildpackInstallationUpdate(context.TODO(), appName, opts) 497 if err != nil { 498 t.Fatalf("Error updating buildpacks: %s", err) 499 } 500 } 501 } 502 503 func testAccCheckHerokuAppConfig_basic(appName string) string { 504 return fmt.Sprintf(` 505 resource "heroku_app" "foobar" { 506 name = "%s" 507 region = "us" 508 509 config_vars { 510 FOO = "bar" 511 } 512 }`, appName) 513 } 514 515 func testAccCheckHerokuAppConfig_go(appName string) string { 516 return fmt.Sprintf(` 517 resource "heroku_app" "foobar" { 518 name = "%s" 519 region = "us" 520 521 buildpacks = ["heroku/go"] 522 }`, appName) 523 } 524 525 func testAccCheckHerokuAppConfig_multi(appName string) string { 526 return fmt.Sprintf(` 527 resource "heroku_app" "foobar" { 528 name = "%s" 529 region = "us" 530 531 buildpacks = [ 532 "https://github.com/heroku/heroku-buildpack-multi-procfile", 533 "heroku/go" 534 ] 535 }`, appName) 536 } 537 538 func testAccCheckHerokuAppConfig_updated(appName string) string { 539 return fmt.Sprintf(` 540 resource "heroku_app" "foobar" { 541 name = "%s" 542 region = "us" 543 544 config_vars { 545 FOO = "bing" 546 BAZ = "bar" 547 } 548 }`, appName) 549 } 550 551 func testAccCheckHerokuAppConfig_no_vars(appName string) string { 552 return fmt.Sprintf(` 553 resource "heroku_app" "foobar" { 554 name = "%s" 555 region = "us" 556 }`, appName) 557 } 558 559 func testAccCheckHerokuAppConfig_organization(appName, org string) string { 560 return fmt.Sprintf(` 561 resource "heroku_app" "foobar" { 562 name = "%s" 563 region = "us" 564 565 organization { 566 name = "%s" 567 } 568 569 config_vars { 570 FOO = "bar" 571 } 572 }`, appName, org) 573 } 574 575 func testAccCheckHerokuAppConfig_space(appName, spaceName, org string) string { 576 return fmt.Sprintf(` 577 resource "heroku_space" "foobar" { 578 name = "%s" 579 organization = "%s" 580 region = "virginia" 581 } 582 resource "heroku_app" "foobar" { 583 name = "%s" 584 space = "${heroku_space.foobar.name}" 585 region = "virginia" 586 587 organization { 588 name = "%s" 589 } 590 591 config_vars { 592 FOO = "bar" 593 } 594 }`, spaceName, org, appName, org) 595 }