github.com/bradfeehan/terraform@v0.7.0-rc3.0.20170529055808-34b45c5ad841/builtin/providers/heroku/resource_heroku_cert_test.go (about) 1 package heroku 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "regexp" 9 "strings" 10 "testing" 11 "time" 12 13 "github.com/cyberdelia/heroku-go/v3" 14 "github.com/hashicorp/terraform/helper/acctest" 15 "github.com/hashicorp/terraform/helper/resource" 16 "github.com/hashicorp/terraform/terraform" 17 ) 18 19 // We break apart testing for EU and US because at present, Heroku deals with 20 // each a bit differently and the setup/teardown of separate tests seems to 21 // help them to perform more consistently. 22 // https://devcenter.heroku.com/articles/ssl-endpoint#add-certificate-and-intermediaries 23 // 24 // We also have a time.Sleep() set for the update step (step 2 of 2) in each 25 // region's tests. This is somewhat kludgy, but the Heroku API SSL Endpoint 26 // handles parts of the create and update requests asynchronously, and if you 27 // add a cert+key then immediately update it, and then delete it (end of test), 28 // there are scenarios where the operations get out of order. For now, sleeping 29 // on update seems to allow the test to run smoothly; in real life, this test 30 // case is definitely an extreme edge case. 31 func TestAccHerokuCert_EU(t *testing.T) { 32 var endpoint heroku.SSLEndpoint 33 appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) 34 35 wd, _ := os.Getwd() 36 certFile := wd + "/test-fixtures/terraform.cert" 37 certFile2 := wd + "/test-fixtures/terraform2.cert" 38 keyFile := wd + "/test-fixtures/terraform.key" 39 keyFile2 := wd + "/test-fixtures/terraform2.key" 40 41 certificateChainBytes, _ := ioutil.ReadFile(certFile) 42 certificateChain := string(certificateChainBytes) 43 certificateChain2Bytes, _ := ioutil.ReadFile(certFile2) 44 certificateChain2 := string(certificateChain2Bytes) 45 46 resource.Test(t, resource.TestCase{ 47 PreCheck: func() { testAccPreCheck(t) }, 48 Providers: testAccProviders, 49 CheckDestroy: testAccCheckHerokuCertDestroy, 50 Steps: []resource.TestStep{ 51 { 52 Config: testAccCheckHerokuCertEUConfig(appName, certFile, keyFile), 53 Check: resource.ComposeTestCheckFunc( 54 testAccCheckHerokuCertExists("heroku_cert.ssl_certificate", &endpoint), 55 testAccCheckHerokuCertificateChain(&endpoint, certificateChain), 56 resource.TestCheckResourceAttr( 57 "heroku_cert.ssl_certificate", 58 "cname", fmt.Sprintf("%s.herokuapp.com", appName)), 59 ), 60 }, 61 { 62 PreConfig: sleep(t, 15), 63 Config: testAccCheckHerokuCertEUConfig(appName, certFile2, keyFile2), 64 Check: resource.ComposeTestCheckFunc( 65 testAccCheckHerokuCertExists("heroku_cert.ssl_certificate", &endpoint), 66 testAccCheckHerokuCertificateChain(&endpoint, certificateChain2), 67 resource.TestCheckResourceAttr( 68 "heroku_cert.ssl_certificate", 69 "cname", fmt.Sprintf("%s.herokuapp.com", appName)), 70 ), 71 }, 72 }, 73 }) 74 } 75 76 func TestAccHerokuCert_US(t *testing.T) { 77 var endpoint heroku.SSLEndpoint 78 appName := fmt.Sprintf("tftest-%s", acctest.RandString(10)) 79 80 wd, _ := os.Getwd() 81 certFile := wd + "/test-fixtures/terraform.cert" 82 certFile2 := wd + "/test-fixtures/terraform2.cert" 83 keyFile := wd + "/test-fixtures/terraform.key" 84 keyFile2 := wd + "/test-fixtures/terraform2.key" 85 86 certificateChainBytes, _ := ioutil.ReadFile(certFile) 87 certificateChain := string(certificateChainBytes) 88 certificateChain2Bytes, _ := ioutil.ReadFile(certFile2) 89 certificateChain2 := string(certificateChain2Bytes) 90 91 resource.Test(t, resource.TestCase{ 92 PreCheck: func() { testAccPreCheck(t) }, 93 Providers: testAccProviders, 94 CheckDestroy: testAccCheckHerokuCertDestroy, 95 Steps: []resource.TestStep{ 96 { 97 Config: testAccCheckHerokuCertUSConfig(appName, certFile2, keyFile2), 98 Check: resource.ComposeTestCheckFunc( 99 testAccCheckHerokuCertExists("heroku_cert.ssl_certificate", &endpoint), 100 testAccCheckHerokuCertificateChain(&endpoint, certificateChain2), 101 resource.TestMatchResourceAttr( 102 "heroku_cert.ssl_certificate", 103 "cname", regexp.MustCompile(`herokussl`)), 104 ), 105 }, 106 { 107 PreConfig: sleep(t, 15), 108 Config: testAccCheckHerokuCertUSConfig(appName, certFile, keyFile), 109 Check: resource.ComposeTestCheckFunc( 110 testAccCheckHerokuCertExists("heroku_cert.ssl_certificate", &endpoint), 111 testAccCheckHerokuCertificateChain(&endpoint, certificateChain), 112 resource.TestMatchResourceAttr( 113 "heroku_cert.ssl_certificate", 114 "cname", regexp.MustCompile(`herokussl`)), 115 ), 116 }, 117 }, 118 }) 119 } 120 121 func testAccCheckHerokuCertEUConfig(appName, certFile, keyFile string) string { 122 return strings.TrimSpace(fmt.Sprintf(` 123 resource "heroku_app" "foobar" { 124 name = "%s" 125 region = "eu" 126 } 127 128 resource "heroku_addon" "ssl" { 129 app = "${heroku_app.foobar.name}" 130 plan = "ssl:endpoint" 131 } 132 133 resource "heroku_cert" "ssl_certificate" { 134 app = "${heroku_app.foobar.name}" 135 depends_on = ["heroku_addon.ssl"] 136 certificate_chain="${file("%s")}" 137 private_key="${file("%s")}" 138 }`, appName, certFile, keyFile)) 139 } 140 141 func testAccCheckHerokuCertUSConfig(appName, certFile, keyFile string) string { 142 return strings.TrimSpace(fmt.Sprintf(` 143 resource "heroku_app" "foobar" { 144 name = "%s" 145 region = "us" 146 } 147 148 resource "heroku_addon" "ssl" { 149 app = "${heroku_app.foobar.name}" 150 plan = "ssl:endpoint" 151 } 152 153 resource "heroku_cert" "ssl_certificate" { 154 app = "${heroku_app.foobar.name}" 155 depends_on = ["heroku_addon.ssl"] 156 certificate_chain="${file("%s")}" 157 private_key="${file("%s")}" 158 }`, appName, certFile, keyFile)) 159 } 160 161 func sleep(t *testing.T, amount time.Duration) func() { 162 return func() { 163 time.Sleep(amount * time.Second) 164 } 165 } 166 167 func testAccCheckHerokuCertDestroy(s *terraform.State) error { 168 client := testAccProvider.Meta().(*heroku.Service) 169 170 for _, rs := range s.RootModule().Resources { 171 if rs.Type != "heroku_cert" { 172 continue 173 } 174 175 _, err := client.SSLEndpointInfo(context.TODO(), rs.Primary.Attributes["app"], rs.Primary.ID) 176 177 if err == nil { 178 return fmt.Errorf("Cerfificate still exists") 179 } 180 } 181 182 return nil 183 } 184 185 func testAccCheckHerokuCertificateChain(endpoint *heroku.SSLEndpoint, chain string) resource.TestCheckFunc { 186 return func(s *terraform.State) error { 187 188 if endpoint.CertificateChain != chain { 189 return fmt.Errorf("Bad certificate chain: %s", endpoint.CertificateChain) 190 } 191 192 return nil 193 } 194 } 195 196 func testAccCheckHerokuCertExists(n string, endpoint *heroku.SSLEndpoint) resource.TestCheckFunc { 197 return func(s *terraform.State) error { 198 rs, ok := s.RootModule().Resources[n] 199 200 if !ok { 201 return fmt.Errorf("Not found: %s", n) 202 } 203 204 if rs.Primary.ID == "" { 205 return fmt.Errorf("No SSL endpoint ID is set") 206 } 207 208 client := testAccProvider.Meta().(*heroku.Service) 209 210 foundEndpoint, err := client.SSLEndpointInfo(context.TODO(), rs.Primary.Attributes["app"], rs.Primary.ID) 211 212 if err != nil { 213 return err 214 } 215 216 if foundEndpoint.ID != rs.Primary.ID { 217 return fmt.Errorf("SSL endpoint not found") 218 } 219 220 *endpoint = *foundEndpoint 221 222 return nil 223 } 224 }