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)