github.com/gabrielperezs/terraform@v0.7.0-rc2.0.20160715084931-f7da2612946f/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-5-8-x32"), 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-5-8-x32" { 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-5-8-x32" { 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 return nil 264 } 265 } 266 267 func testAccCheckDigitalOceanDropletExists(n string, droplet *godo.Droplet) resource.TestCheckFunc { 268 return func(s *terraform.State) error { 269 rs, ok := s.RootModule().Resources[n] 270 if !ok { 271 return fmt.Errorf("Not found: %s", n) 272 } 273 274 if rs.Primary.ID == "" { 275 return fmt.Errorf("No Droplet ID is set") 276 } 277 278 client := testAccProvider.Meta().(*godo.Client) 279 280 id, err := strconv.Atoi(rs.Primary.ID) 281 if err != nil { 282 return err 283 } 284 285 // Try to find the Droplet 286 retrieveDroplet, _, err := client.Droplets.Get(id) 287 288 if err != nil { 289 return err 290 } 291 292 if strconv.Itoa(retrieveDroplet.ID) != rs.Primary.ID { 293 return fmt.Errorf("Droplet not found") 294 } 295 296 *droplet = *retrieveDroplet 297 298 return nil 299 } 300 } 301 302 func testAccCheckDigitalOceanDropletRecreated(t *testing.T, 303 before, after *godo.Droplet) resource.TestCheckFunc { 304 return func(s *terraform.State) error { 305 if before.ID == after.ID { 306 t.Fatalf("Expected change of droplet IDs, but both were %v", before.ID) 307 } 308 return nil 309 } 310 } 311 312 // Not sure if this check should remain here as the underlaying 313 // function is changed and is tested indirectly by almost all 314 // other test already 315 // 316 //func Test_new_droplet_state_refresh_func(t *testing.T) { 317 // droplet := godo.Droplet{ 318 // Name: "foobar", 319 // } 320 // resourceMap, _ := resource_digitalocean_droplet_update_state( 321 // &terraform.InstanceState{Attributes: map[string]string{}}, &droplet) 322 // 323 // // See if we can access our attribute 324 // if _, ok := resourceMap.Attributes["name"]; !ok { 325 // t.Fatalf("bad name: %s", resourceMap.Attributes) 326 // } 327 // 328 //} 329 330 var testAccCheckDigitalOceanDropletConfig_basic = fmt.Sprintf(` 331 resource "digitalocean_ssh_key" "foobar" { 332 name = "foobar" 333 public_key = "%s" 334 } 335 336 resource "digitalocean_droplet" "foobar" { 337 name = "foo" 338 size = "512mb" 339 image = "centos-5-8-x32" 340 region = "nyc3" 341 user_data = "foobar" 342 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 343 } 344 `, testAccValidPublicKey) 345 346 var testAccCheckDigitalOceanDropletConfig_tag_update = fmt.Sprintf(` 347 resource "digitalocean_tag" "barbaz" { 348 name = "barbaz" 349 } 350 351 resource "digitalocean_ssh_key" "foobar" { 352 name = "foobar" 353 public_key = "%s" 354 } 355 356 resource "digitalocean_droplet" "foobar" { 357 name = "foo" 358 size = "512mb" 359 image = "centos-5-8-x32" 360 region = "nyc3" 361 user_data = "foobar" 362 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 363 tags = ["${digitalocean_tag.barbaz.id}"] 364 } 365 `, testAccValidPublicKey) 366 367 var testAccCheckDigitalOceanDropletConfig_userdata_update = fmt.Sprintf(` 368 resource "digitalocean_ssh_key" "foobar" { 369 name = "foobar" 370 public_key = "%s" 371 } 372 373 resource "digitalocean_droplet" "foobar" { 374 name = "foo" 375 size = "512mb" 376 image = "centos-5-8-x32" 377 region = "nyc3" 378 user_data = "foobar foobar" 379 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 380 } 381 `, testAccValidPublicKey) 382 383 var testAccCheckDigitalOceanDropletConfig_RenameAndResize = fmt.Sprintf(` 384 resource "digitalocean_ssh_key" "foobar" { 385 name = "foobar" 386 public_key = "%s" 387 } 388 389 resource "digitalocean_droplet" "foobar" { 390 name = "baz" 391 size = "1gb" 392 image = "centos-5-8-x32" 393 region = "nyc3" 394 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 395 } 396 `, testAccValidPublicKey) 397 398 // IPV6 only in singapore 399 var testAccCheckDigitalOceanDropletConfig_PrivateNetworkingIpv6 = fmt.Sprintf(` 400 resource "digitalocean_ssh_key" "foobar" { 401 name = "foobar" 402 public_key = "%s" 403 } 404 405 resource "digitalocean_droplet" "foobar" { 406 name = "baz" 407 size = "1gb" 408 image = "centos-5-8-x32" 409 region = "sgp1" 410 ipv6 = true 411 private_networking = true 412 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 413 } 414 `, testAccValidPublicKey)