github.com/richardbowden/terraform@v0.6.12-0.20160901200758-30ea22c25211/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go (about) 1 package digitalocean 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 "testing" 8 9 "github.com/digitalocean/godo" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/terraform" 12 ) 13 14 func TestAccDigitalOceanDroplet_Basic(t *testing.T) { 15 var droplet godo.Droplet 16 17 resource.Test(t, resource.TestCase{ 18 PreCheck: func() { testAccPreCheck(t) }, 19 Providers: testAccProviders, 20 CheckDestroy: testAccCheckDigitalOceanDropletDestroy, 21 Steps: []resource.TestStep{ 22 resource.TestStep{ 23 Config: testAccCheckDigitalOceanDropletConfig_basic, 24 Check: resource.ComposeTestCheckFunc( 25 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), 26 testAccCheckDigitalOceanDropletAttributes(&droplet), 27 resource.TestCheckResourceAttr( 28 "digitalocean_droplet.foobar", "name", "foo"), 29 resource.TestCheckResourceAttr( 30 "digitalocean_droplet.foobar", "size", "512mb"), 31 resource.TestCheckResourceAttr( 32 "digitalocean_droplet.foobar", "image", "centos-7-x64"), 33 resource.TestCheckResourceAttr( 34 "digitalocean_droplet.foobar", "region", "nyc3"), 35 resource.TestCheckResourceAttr( 36 "digitalocean_droplet.foobar", "user_data", "foobar"), 37 ), 38 }, 39 }, 40 }) 41 } 42 43 func TestAccDigitalOceanDroplet_Update(t *testing.T) { 44 var droplet godo.Droplet 45 46 resource.Test(t, resource.TestCase{ 47 PreCheck: func() { testAccPreCheck(t) }, 48 Providers: testAccProviders, 49 CheckDestroy: testAccCheckDigitalOceanDropletDestroy, 50 Steps: []resource.TestStep{ 51 resource.TestStep{ 52 Config: testAccCheckDigitalOceanDropletConfig_basic, 53 Check: resource.ComposeTestCheckFunc( 54 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), 55 testAccCheckDigitalOceanDropletAttributes(&droplet), 56 ), 57 }, 58 59 resource.TestStep{ 60 Config: testAccCheckDigitalOceanDropletConfig_RenameAndResize, 61 Check: resource.ComposeTestCheckFunc( 62 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), 63 testAccCheckDigitalOceanDropletRenamedAndResized(&droplet), 64 resource.TestCheckResourceAttr( 65 "digitalocean_droplet.foobar", "name", "baz"), 66 resource.TestCheckResourceAttr( 67 "digitalocean_droplet.foobar", "size", "1gb"), 68 ), 69 }, 70 }, 71 }) 72 } 73 74 func TestAccDigitalOceanDroplet_UpdateUserData(t *testing.T) { 75 var afterCreate, afterUpdate godo.Droplet 76 77 resource.Test(t, resource.TestCase{ 78 PreCheck: func() { testAccPreCheck(t) }, 79 Providers: testAccProviders, 80 CheckDestroy: testAccCheckDigitalOceanDropletDestroy, 81 Steps: []resource.TestStep{ 82 resource.TestStep{ 83 Config: testAccCheckDigitalOceanDropletConfig_basic, 84 Check: resource.ComposeTestCheckFunc( 85 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &afterCreate), 86 testAccCheckDigitalOceanDropletAttributes(&afterCreate), 87 ), 88 }, 89 90 resource.TestStep{ 91 Config: testAccCheckDigitalOceanDropletConfig_userdata_update, 92 Check: resource.ComposeTestCheckFunc( 93 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &afterUpdate), 94 resource.TestCheckResourceAttr( 95 "digitalocean_droplet.foobar", 96 "user_data", 97 "foobar foobar"), 98 testAccCheckDigitalOceanDropletRecreated( 99 t, &afterCreate, &afterUpdate), 100 ), 101 }, 102 }, 103 }) 104 } 105 106 func TestAccDigitalOceanDroplet_UpdateTags(t *testing.T) { 107 var afterCreate, afterUpdate godo.Droplet 108 109 resource.Test(t, resource.TestCase{ 110 PreCheck: func() { testAccPreCheck(t) }, 111 Providers: testAccProviders, 112 CheckDestroy: testAccCheckDigitalOceanDropletDestroy, 113 Steps: []resource.TestStep{ 114 resource.TestStep{ 115 Config: testAccCheckDigitalOceanDropletConfig_basic, 116 Check: resource.ComposeTestCheckFunc( 117 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &afterCreate), 118 testAccCheckDigitalOceanDropletAttributes(&afterCreate), 119 ), 120 }, 121 122 resource.TestStep{ 123 Config: testAccCheckDigitalOceanDropletConfig_tag_update, 124 Check: resource.ComposeTestCheckFunc( 125 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &afterUpdate), 126 resource.TestCheckResourceAttr( 127 "digitalocean_droplet.foobar", 128 "tags.#", 129 "1"), 130 resource.TestCheckResourceAttr( 131 "digitalocean_droplet.foobar", 132 "tags.0", 133 "barbaz"), 134 ), 135 }, 136 }, 137 }) 138 } 139 140 func TestAccDigitalOceanDroplet_PrivateNetworkingIpv6(t *testing.T) { 141 var droplet godo.Droplet 142 143 resource.Test(t, resource.TestCase{ 144 PreCheck: func() { testAccPreCheck(t) }, 145 Providers: testAccProviders, 146 CheckDestroy: testAccCheckDigitalOceanDropletDestroy, 147 Steps: []resource.TestStep{ 148 resource.TestStep{ 149 Config: testAccCheckDigitalOceanDropletConfig_PrivateNetworkingIpv6, 150 Check: resource.ComposeTestCheckFunc( 151 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), 152 testAccCheckDigitalOceanDropletAttributes_PrivateNetworkingIpv6(&droplet), 153 resource.TestCheckResourceAttr( 154 "digitalocean_droplet.foobar", "private_networking", "true"), 155 resource.TestCheckResourceAttr( 156 "digitalocean_droplet.foobar", "ipv6", "true"), 157 ), 158 }, 159 }, 160 }) 161 } 162 163 func testAccCheckDigitalOceanDropletDestroy(s *terraform.State) error { 164 client := testAccProvider.Meta().(*godo.Client) 165 166 for _, rs := range s.RootModule().Resources { 167 if rs.Type != "digitalocean_droplet" { 168 continue 169 } 170 171 id, err := strconv.Atoi(rs.Primary.ID) 172 if err != nil { 173 return err 174 } 175 176 // Try to find the Droplet 177 _, _, err = client.Droplets.Get(id) 178 179 // Wait 180 181 if err != nil && !strings.Contains(err.Error(), "404") { 182 return fmt.Errorf( 183 "Error waiting for droplet (%s) to be destroyed: %s", 184 rs.Primary.ID, err) 185 } 186 } 187 188 return nil 189 } 190 191 func testAccCheckDigitalOceanDropletAttributes(droplet *godo.Droplet) resource.TestCheckFunc { 192 return func(s *terraform.State) error { 193 194 if droplet.Image.Slug != "centos-7-x64" { 195 return fmt.Errorf("Bad image_slug: %s", droplet.Image.Slug) 196 } 197 198 if droplet.Size.Slug != "512mb" { 199 return fmt.Errorf("Bad size_slug: %s", droplet.Size.Slug) 200 } 201 202 if droplet.Region.Slug != "nyc3" { 203 return fmt.Errorf("Bad region_slug: %s", droplet.Region.Slug) 204 } 205 206 if droplet.Name != "foo" { 207 return fmt.Errorf("Bad name: %s", droplet.Name) 208 } 209 return nil 210 } 211 } 212 213 func testAccCheckDigitalOceanDropletRenamedAndResized(droplet *godo.Droplet) resource.TestCheckFunc { 214 return func(s *terraform.State) error { 215 216 if droplet.Size.Slug != "1gb" { 217 return fmt.Errorf("Bad size_slug: %s", droplet.SizeSlug) 218 } 219 220 if droplet.Name != "baz" { 221 return fmt.Errorf("Bad name: %s", droplet.Name) 222 } 223 224 return nil 225 } 226 } 227 228 func testAccCheckDigitalOceanDropletAttributes_PrivateNetworkingIpv6(droplet *godo.Droplet) resource.TestCheckFunc { 229 return func(s *terraform.State) error { 230 231 if droplet.Image.Slug != "centos-7-x64" { 232 return fmt.Errorf("Bad image_slug: %s", droplet.Image.Slug) 233 } 234 235 if droplet.Size.Slug != "1gb" { 236 return fmt.Errorf("Bad size_slug: %s", droplet.Size.Slug) 237 } 238 239 if droplet.Region.Slug != "sgp1" { 240 return fmt.Errorf("Bad region_slug: %s", droplet.Region.Slug) 241 } 242 243 if droplet.Name != "baz" { 244 return fmt.Errorf("Bad name: %s", droplet.Name) 245 } 246 247 if findIPv4AddrByType(droplet, "private") == "" { 248 return fmt.Errorf("No ipv4 private: %s", findIPv4AddrByType(droplet, "private")) 249 } 250 251 // if droplet.IPV6Address("private") == "" { 252 // return fmt.Errorf("No ipv6 private: %s", droplet.IPV6Address("private")) 253 // } 254 255 if findIPv4AddrByType(droplet, "public") == "" { 256 return fmt.Errorf("No ipv4 public: %s", findIPv4AddrByType(droplet, "public")) 257 } 258 259 if findIPv6AddrByType(droplet, "public") == "" { 260 return fmt.Errorf("No ipv6 public: %s", findIPv6AddrByType(droplet, "public")) 261 } 262 263 for _, rs := range s.RootModule().Resources { 264 if rs.Type != "digitalocean_droplet" { 265 continue 266 } 267 if rs.Primary.Attributes["ipv6_address"] != strings.ToLower(findIPv6AddrByType(droplet, "public")) { 268 return fmt.Errorf("IPV6 Address should be lowercase") 269 } 270 271 } 272 273 return nil 274 } 275 } 276 277 func testAccCheckDigitalOceanDropletExists(n string, droplet *godo.Droplet) resource.TestCheckFunc { 278 return func(s *terraform.State) error { 279 rs, ok := s.RootModule().Resources[n] 280 if !ok { 281 return fmt.Errorf("Not found: %s", n) 282 } 283 284 if rs.Primary.ID == "" { 285 return fmt.Errorf("No Droplet ID is set") 286 } 287 288 client := testAccProvider.Meta().(*godo.Client) 289 290 id, err := strconv.Atoi(rs.Primary.ID) 291 if err != nil { 292 return err 293 } 294 295 // Try to find the Droplet 296 retrieveDroplet, _, err := client.Droplets.Get(id) 297 298 if err != nil { 299 return err 300 } 301 302 if strconv.Itoa(retrieveDroplet.ID) != rs.Primary.ID { 303 return fmt.Errorf("Droplet not found") 304 } 305 306 *droplet = *retrieveDroplet 307 308 return nil 309 } 310 } 311 312 func testAccCheckDigitalOceanDropletRecreated(t *testing.T, 313 before, after *godo.Droplet) resource.TestCheckFunc { 314 return func(s *terraform.State) error { 315 if before.ID == after.ID { 316 t.Fatalf("Expected change of droplet IDs, but both were %v", before.ID) 317 } 318 return nil 319 } 320 } 321 322 // Not sure if this check should remain here as the underlaying 323 // function is changed and is tested indirectly by almost all 324 // other test already 325 // 326 //func Test_new_droplet_state_refresh_func(t *testing.T) { 327 // droplet := godo.Droplet{ 328 // Name: "foobar", 329 // } 330 // resourceMap, _ := resource_digitalocean_droplet_update_state( 331 // &terraform.InstanceState{Attributes: map[string]string{}}, &droplet) 332 // 333 // // See if we can access our attribute 334 // if _, ok := resourceMap.Attributes["name"]; !ok { 335 // t.Fatalf("bad name: %s", resourceMap.Attributes) 336 // } 337 // 338 //} 339 340 var testAccCheckDigitalOceanDropletConfig_basic = fmt.Sprintf(` 341 resource "digitalocean_ssh_key" "foobar" { 342 name = "foobar" 343 public_key = "%s" 344 } 345 346 resource "digitalocean_droplet" "foobar" { 347 name = "foo" 348 size = "512mb" 349 image = "centos-7-x64" 350 region = "nyc3" 351 user_data = "foobar" 352 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 353 } 354 `, testAccValidPublicKey) 355 356 var testAccCheckDigitalOceanDropletConfig_tag_update = fmt.Sprintf(` 357 resource "digitalocean_tag" "barbaz" { 358 name = "barbaz" 359 } 360 361 resource "digitalocean_ssh_key" "foobar" { 362 name = "foobar" 363 public_key = "%s" 364 } 365 366 resource "digitalocean_droplet" "foobar" { 367 name = "foo" 368 size = "512mb" 369 image = "centos-7-x64" 370 region = "nyc3" 371 user_data = "foobar" 372 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 373 tags = ["${digitalocean_tag.barbaz.id}"] 374 } 375 `, testAccValidPublicKey) 376 377 var testAccCheckDigitalOceanDropletConfig_userdata_update = fmt.Sprintf(` 378 resource "digitalocean_ssh_key" "foobar" { 379 name = "foobar" 380 public_key = "%s" 381 } 382 383 resource "digitalocean_droplet" "foobar" { 384 name = "foo" 385 size = "512mb" 386 image = "centos-7-x64" 387 region = "nyc3" 388 user_data = "foobar foobar" 389 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 390 } 391 `, testAccValidPublicKey) 392 393 var testAccCheckDigitalOceanDropletConfig_RenameAndResize = fmt.Sprintf(` 394 resource "digitalocean_ssh_key" "foobar" { 395 name = "foobar" 396 public_key = "%s" 397 } 398 399 resource "digitalocean_droplet" "foobar" { 400 name = "baz" 401 size = "1gb" 402 image = "centos-7-x64" 403 region = "nyc3" 404 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 405 } 406 `, testAccValidPublicKey) 407 408 // IPV6 only in singapore 409 var testAccCheckDigitalOceanDropletConfig_PrivateNetworkingIpv6 = fmt.Sprintf(` 410 resource "digitalocean_ssh_key" "foobar" { 411 name = "foobar" 412 public_key = "%s" 413 } 414 415 resource "digitalocean_droplet" "foobar" { 416 name = "baz" 417 size = "1gb" 418 image = "centos-7-x64" 419 region = "sgp1" 420 ipv6 = true 421 private_networking = true 422 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 423 } 424 `, testAccValidPublicKey)