github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/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 resource.TestCheckResourceAttr( 69 "digitalocean_droplet.foobar", "disk", "30"), 70 ), 71 }, 72 }, 73 }) 74 } 75 76 func TestAccDigitalOceanDroplet_ResizeWithOutDisk(t *testing.T) { 77 var droplet godo.Droplet 78 79 resource.Test(t, resource.TestCase{ 80 PreCheck: func() { testAccPreCheck(t) }, 81 Providers: testAccProviders, 82 CheckDestroy: testAccCheckDigitalOceanDropletDestroy, 83 Steps: []resource.TestStep{ 84 resource.TestStep{ 85 Config: testAccCheckDigitalOceanDropletConfig_basic, 86 Check: resource.ComposeTestCheckFunc( 87 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), 88 testAccCheckDigitalOceanDropletAttributes(&droplet), 89 ), 90 }, 91 92 resource.TestStep{ 93 Config: testAccCheckDigitalOceanDropletConfig_resize_without_disk, 94 Check: resource.ComposeTestCheckFunc( 95 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), 96 testAccCheckDigitalOceanDropletResizeWithOutDisk(&droplet), 97 resource.TestCheckResourceAttr( 98 "digitalocean_droplet.foobar", "size", "1gb"), 99 resource.TestCheckResourceAttr( 100 "digitalocean_droplet.foobar", "disk", "20"), 101 ), 102 }, 103 }, 104 }) 105 } 106 107 func TestAccDigitalOceanDroplet_UpdateUserData(t *testing.T) { 108 var afterCreate, afterUpdate godo.Droplet 109 110 resource.Test(t, resource.TestCase{ 111 PreCheck: func() { testAccPreCheck(t) }, 112 Providers: testAccProviders, 113 CheckDestroy: testAccCheckDigitalOceanDropletDestroy, 114 Steps: []resource.TestStep{ 115 resource.TestStep{ 116 Config: testAccCheckDigitalOceanDropletConfig_basic, 117 Check: resource.ComposeTestCheckFunc( 118 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &afterCreate), 119 testAccCheckDigitalOceanDropletAttributes(&afterCreate), 120 ), 121 }, 122 123 resource.TestStep{ 124 Config: testAccCheckDigitalOceanDropletConfig_userdata_update, 125 Check: resource.ComposeTestCheckFunc( 126 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &afterUpdate), 127 resource.TestCheckResourceAttr( 128 "digitalocean_droplet.foobar", 129 "user_data", 130 "foobar foobar"), 131 testAccCheckDigitalOceanDropletRecreated( 132 t, &afterCreate, &afterUpdate), 133 ), 134 }, 135 }, 136 }) 137 } 138 139 func TestAccDigitalOceanDroplet_UpdateTags(t *testing.T) { 140 var afterCreate, afterUpdate godo.Droplet 141 142 resource.Test(t, resource.TestCase{ 143 PreCheck: func() { testAccPreCheck(t) }, 144 Providers: testAccProviders, 145 CheckDestroy: testAccCheckDigitalOceanDropletDestroy, 146 Steps: []resource.TestStep{ 147 resource.TestStep{ 148 Config: testAccCheckDigitalOceanDropletConfig_basic, 149 Check: resource.ComposeTestCheckFunc( 150 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &afterCreate), 151 testAccCheckDigitalOceanDropletAttributes(&afterCreate), 152 ), 153 }, 154 155 resource.TestStep{ 156 Config: testAccCheckDigitalOceanDropletConfig_tag_update, 157 Check: resource.ComposeTestCheckFunc( 158 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &afterUpdate), 159 resource.TestCheckResourceAttr( 160 "digitalocean_droplet.foobar", 161 "tags.#", 162 "1"), 163 resource.TestCheckResourceAttr( 164 "digitalocean_droplet.foobar", 165 "tags.0", 166 "barbaz"), 167 ), 168 }, 169 }, 170 }) 171 } 172 173 func TestAccDigitalOceanDroplet_PrivateNetworkingIpv6(t *testing.T) { 174 var droplet godo.Droplet 175 176 resource.Test(t, resource.TestCase{ 177 PreCheck: func() { testAccPreCheck(t) }, 178 Providers: testAccProviders, 179 CheckDestroy: testAccCheckDigitalOceanDropletDestroy, 180 Steps: []resource.TestStep{ 181 resource.TestStep{ 182 Config: testAccCheckDigitalOceanDropletConfig_PrivateNetworkingIpv6, 183 Check: resource.ComposeTestCheckFunc( 184 testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), 185 testAccCheckDigitalOceanDropletAttributes_PrivateNetworkingIpv6(&droplet), 186 resource.TestCheckResourceAttr( 187 "digitalocean_droplet.foobar", "private_networking", "true"), 188 resource.TestCheckResourceAttr( 189 "digitalocean_droplet.foobar", "ipv6", "true"), 190 ), 191 }, 192 }, 193 }) 194 } 195 196 func testAccCheckDigitalOceanDropletDestroy(s *terraform.State) error { 197 client := testAccProvider.Meta().(*godo.Client) 198 199 for _, rs := range s.RootModule().Resources { 200 if rs.Type != "digitalocean_droplet" { 201 continue 202 } 203 204 id, err := strconv.Atoi(rs.Primary.ID) 205 if err != nil { 206 return err 207 } 208 209 // Try to find the Droplet 210 _, _, err = client.Droplets.Get(id) 211 212 // Wait 213 214 if err != nil && !strings.Contains(err.Error(), "404") { 215 return fmt.Errorf( 216 "Error waiting for droplet (%s) to be destroyed: %s", 217 rs.Primary.ID, err) 218 } 219 } 220 221 return nil 222 } 223 224 func testAccCheckDigitalOceanDropletAttributes(droplet *godo.Droplet) resource.TestCheckFunc { 225 return func(s *terraform.State) error { 226 227 if droplet.Image.Slug != "centos-7-x64" { 228 return fmt.Errorf("Bad image_slug: %s", droplet.Image.Slug) 229 } 230 231 if droplet.Size.Slug != "512mb" { 232 return fmt.Errorf("Bad size_slug: %s", droplet.Size.Slug) 233 } 234 235 if droplet.Region.Slug != "nyc3" { 236 return fmt.Errorf("Bad region_slug: %s", droplet.Region.Slug) 237 } 238 239 if droplet.Name != "foo" { 240 return fmt.Errorf("Bad name: %s", droplet.Name) 241 } 242 return nil 243 } 244 } 245 246 func testAccCheckDigitalOceanDropletRenamedAndResized(droplet *godo.Droplet) resource.TestCheckFunc { 247 return func(s *terraform.State) error { 248 249 if droplet.Size.Slug != "1gb" { 250 return fmt.Errorf("Bad size_slug: %s", droplet.SizeSlug) 251 } 252 253 if droplet.Name != "baz" { 254 return fmt.Errorf("Bad name: %s", droplet.Name) 255 } 256 257 if droplet.Disk != 30 { 258 return fmt.Errorf("Bad disk: %s", droplet.Disk) 259 } 260 261 return nil 262 } 263 } 264 265 func testAccCheckDigitalOceanDropletResizeWithOutDisk(droplet *godo.Droplet) resource.TestCheckFunc { 266 return func(s *terraform.State) error { 267 268 if droplet.Size.Slug != "1gb" { 269 return fmt.Errorf("Bad size_slug: %s", droplet.SizeSlug) 270 } 271 272 if droplet.Disk != 20 { 273 return fmt.Errorf("Bad disk: %s", droplet.Disk) 274 } 275 276 return nil 277 } 278 } 279 280 func testAccCheckDigitalOceanDropletAttributes_PrivateNetworkingIpv6(droplet *godo.Droplet) resource.TestCheckFunc { 281 return func(s *terraform.State) error { 282 283 if droplet.Image.Slug != "centos-7-x64" { 284 return fmt.Errorf("Bad image_slug: %s", droplet.Image.Slug) 285 } 286 287 if droplet.Size.Slug != "1gb" { 288 return fmt.Errorf("Bad size_slug: %s", droplet.Size.Slug) 289 } 290 291 if droplet.Region.Slug != "sgp1" { 292 return fmt.Errorf("Bad region_slug: %s", droplet.Region.Slug) 293 } 294 295 if droplet.Name != "baz" { 296 return fmt.Errorf("Bad name: %s", droplet.Name) 297 } 298 299 if findIPv4AddrByType(droplet, "private") == "" { 300 return fmt.Errorf("No ipv4 private: %s", findIPv4AddrByType(droplet, "private")) 301 } 302 303 // if droplet.IPV6Address("private") == "" { 304 // return fmt.Errorf("No ipv6 private: %s", droplet.IPV6Address("private")) 305 // } 306 307 if findIPv4AddrByType(droplet, "public") == "" { 308 return fmt.Errorf("No ipv4 public: %s", findIPv4AddrByType(droplet, "public")) 309 } 310 311 if findIPv6AddrByType(droplet, "public") == "" { 312 return fmt.Errorf("No ipv6 public: %s", findIPv6AddrByType(droplet, "public")) 313 } 314 315 for _, rs := range s.RootModule().Resources { 316 if rs.Type != "digitalocean_droplet" { 317 continue 318 } 319 if rs.Primary.Attributes["ipv6_address"] != strings.ToLower(findIPv6AddrByType(droplet, "public")) { 320 return fmt.Errorf("IPV6 Address should be lowercase") 321 } 322 323 } 324 325 return nil 326 } 327 } 328 329 func testAccCheckDigitalOceanDropletExists(n string, droplet *godo.Droplet) resource.TestCheckFunc { 330 return func(s *terraform.State) error { 331 rs, ok := s.RootModule().Resources[n] 332 if !ok { 333 return fmt.Errorf("Not found: %s", n) 334 } 335 336 if rs.Primary.ID == "" { 337 return fmt.Errorf("No Droplet ID is set") 338 } 339 340 client := testAccProvider.Meta().(*godo.Client) 341 342 id, err := strconv.Atoi(rs.Primary.ID) 343 if err != nil { 344 return err 345 } 346 347 // Try to find the Droplet 348 retrieveDroplet, _, err := client.Droplets.Get(id) 349 350 if err != nil { 351 return err 352 } 353 354 if strconv.Itoa(retrieveDroplet.ID) != rs.Primary.ID { 355 return fmt.Errorf("Droplet not found") 356 } 357 358 *droplet = *retrieveDroplet 359 360 return nil 361 } 362 } 363 364 func testAccCheckDigitalOceanDropletRecreated(t *testing.T, 365 before, after *godo.Droplet) resource.TestCheckFunc { 366 return func(s *terraform.State) error { 367 if before.ID == after.ID { 368 t.Fatalf("Expected change of droplet IDs, but both were %v", before.ID) 369 } 370 return nil 371 } 372 } 373 374 // Not sure if this check should remain here as the underlaying 375 // function is changed and is tested indirectly by almost all 376 // other test already 377 // 378 //func Test_new_droplet_state_refresh_func(t *testing.T) { 379 // droplet := godo.Droplet{ 380 // Name: "foobar", 381 // } 382 // resourceMap, _ := resource_digitalocean_droplet_update_state( 383 // &terraform.InstanceState{Attributes: map[string]string{}}, &droplet) 384 // 385 // // See if we can access our attribute 386 // if _, ok := resourceMap.Attributes["name"]; !ok { 387 // t.Fatalf("bad name: %s", resourceMap.Attributes) 388 // } 389 // 390 //} 391 392 var testAccCheckDigitalOceanDropletConfig_basic = fmt.Sprintf(` 393 resource "digitalocean_ssh_key" "foobar" { 394 name = "foobar" 395 public_key = "%s" 396 } 397 398 resource "digitalocean_droplet" "foobar" { 399 name = "foo" 400 size = "512mb" 401 image = "centos-7-x64" 402 region = "nyc3" 403 user_data = "foobar" 404 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 405 } 406 `, testAccValidPublicKey) 407 408 var testAccCheckDigitalOceanDropletConfig_tag_update = fmt.Sprintf(` 409 resource "digitalocean_tag" "barbaz" { 410 name = "barbaz" 411 } 412 413 resource "digitalocean_ssh_key" "foobar" { 414 name = "foobar" 415 public_key = "%s" 416 } 417 418 resource "digitalocean_droplet" "foobar" { 419 name = "foo" 420 size = "512mb" 421 image = "centos-7-x64" 422 region = "nyc3" 423 user_data = "foobar" 424 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 425 tags = ["${digitalocean_tag.barbaz.id}"] 426 } 427 `, testAccValidPublicKey) 428 429 var testAccCheckDigitalOceanDropletConfig_userdata_update = fmt.Sprintf(` 430 resource "digitalocean_ssh_key" "foobar" { 431 name = "foobar" 432 public_key = "%s" 433 } 434 435 resource "digitalocean_droplet" "foobar" { 436 name = "foo" 437 size = "512mb" 438 image = "centos-7-x64" 439 region = "nyc3" 440 user_data = "foobar foobar" 441 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 442 } 443 `, testAccValidPublicKey) 444 445 var testAccCheckDigitalOceanDropletConfig_RenameAndResize = fmt.Sprintf(` 446 resource "digitalocean_ssh_key" "foobar" { 447 name = "foobar" 448 public_key = "%s" 449 } 450 451 resource "digitalocean_droplet" "foobar" { 452 name = "baz" 453 size = "1gb" 454 image = "centos-7-x64" 455 region = "nyc3" 456 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 457 } 458 `, testAccValidPublicKey) 459 460 var testAccCheckDigitalOceanDropletConfig_resize_without_disk = fmt.Sprintf(` 461 resource "digitalocean_ssh_key" "foobar" { 462 name = "foobar" 463 public_key = "%s" 464 } 465 466 resource "digitalocean_droplet" "foobar" { 467 name = "foo" 468 size = "1gb" 469 image = "centos-7-x64" 470 region = "nyc3" 471 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 472 resize_disk = false 473 } 474 `, testAccValidPublicKey) 475 476 // IPV6 only in singapore 477 var testAccCheckDigitalOceanDropletConfig_PrivateNetworkingIpv6 = fmt.Sprintf(` 478 resource "digitalocean_ssh_key" "foobar" { 479 name = "foobar" 480 public_key = "%s" 481 } 482 483 resource "digitalocean_droplet" "foobar" { 484 name = "baz" 485 size = "1gb" 486 image = "centos-7-x64" 487 region = "sgp1" 488 ipv6 = true 489 private_networking = true 490 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 491 } 492 `, testAccValidPublicKey)