github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/docker/resource_docker_container_test.go (about)

     1  package docker
     2  
     3  import (
     4  	"archive/tar"
     5  	"bytes"
     6  	"fmt"
     7  	"testing"
     8  
     9  	dc "github.com/fsouza/go-dockerclient"
    10  	"github.com/hashicorp/terraform/helper/resource"
    11  	"github.com/hashicorp/terraform/terraform"
    12  )
    13  
    14  func TestAccDockerContainer_basic(t *testing.T) {
    15  	var c dc.Container
    16  	resource.Test(t, resource.TestCase{
    17  		PreCheck:  func() { testAccPreCheck(t) },
    18  		Providers: testAccProviders,
    19  		Steps: []resource.TestStep{
    20  			resource.TestStep{
    21  				Config: testAccDockerContainerConfig,
    22  				Check: resource.ComposeTestCheckFunc(
    23  					testAccContainerRunning("docker_container.foo", &c),
    24  				),
    25  			},
    26  		},
    27  	})
    28  }
    29  
    30  func TestAccDockerContainer_volume(t *testing.T) {
    31  	var c dc.Container
    32  
    33  	testCheck := func(*terraform.State) error {
    34  		if len(c.Mounts) != 1 {
    35  			return fmt.Errorf("Incorrect number of mounts: expected 1, got %d", len(c.Mounts))
    36  		}
    37  
    38  		for _, v := range c.Mounts {
    39  			if v.Name != "testAccDockerContainerVolume_volume" {
    40  				continue
    41  			}
    42  
    43  			if v.Destination != "/tmp/volume" {
    44  				return fmt.Errorf("Bad destination on mount: expected /tmp/volume, got %q", v.Destination)
    45  			}
    46  
    47  			if v.Mode != "rw" {
    48  				return fmt.Errorf("Bad mode on mount: expected rw, got %q", v.Mode)
    49  			}
    50  
    51  			return nil
    52  		}
    53  
    54  		return fmt.Errorf("Mount for testAccDockerContainerVolume_volume not found")
    55  	}
    56  
    57  	resource.Test(t, resource.TestCase{
    58  		PreCheck:  func() { testAccPreCheck(t) },
    59  		Providers: testAccProviders,
    60  		Steps: []resource.TestStep{
    61  			resource.TestStep{
    62  				Config: testAccDockerContainerVolumeConfig,
    63  				Check: resource.ComposeTestCheckFunc(
    64  					testAccContainerRunning("docker_container.foo", &c),
    65  					testCheck,
    66  				),
    67  			},
    68  		},
    69  	})
    70  }
    71  
    72  func TestAccDockerContainer_customized(t *testing.T) {
    73  	var c dc.Container
    74  
    75  	testCheck := func(*terraform.State) error {
    76  		if len(c.Config.Entrypoint) < 3 ||
    77  			(c.Config.Entrypoint[0] != "/bin/bash" &&
    78  				c.Config.Entrypoint[1] != "-c" &&
    79  				c.Config.Entrypoint[2] != "ping localhost") {
    80  			return fmt.Errorf("Container wrong entrypoint: %s", c.Config.Entrypoint)
    81  		}
    82  
    83  		if c.Config.User != "root:root" {
    84  			return fmt.Errorf("Container wrong user: %s", c.Config.User)
    85  		}
    86  
    87  		if c.HostConfig.RestartPolicy.Name == "on-failure" {
    88  			if c.HostConfig.RestartPolicy.MaximumRetryCount != 5 {
    89  				return fmt.Errorf("Container has wrong restart policy max retry count: %d", c.HostConfig.RestartPolicy.MaximumRetryCount)
    90  			}
    91  		} else {
    92  			return fmt.Errorf("Container has wrong restart policy: %s", c.HostConfig.RestartPolicy.Name)
    93  		}
    94  
    95  		if c.HostConfig.Memory != (512 * 1024 * 1024) {
    96  			return fmt.Errorf("Container has wrong memory setting: %d", c.HostConfig.Memory)
    97  		}
    98  
    99  		if c.HostConfig.MemorySwap != (2048 * 1024 * 1024) {
   100  			return fmt.Errorf("Container has wrong memory swap setting: %d\n\r\tPlease check that you machine supports memory swap (you can do that by running 'docker info' command).", c.HostConfig.MemorySwap)
   101  		}
   102  
   103  		if c.HostConfig.CPUShares != 32 {
   104  			return fmt.Errorf("Container has wrong cpu shares setting: %d", c.HostConfig.CPUShares)
   105  		}
   106  
   107  		if len(c.HostConfig.DNS) != 1 {
   108  			return fmt.Errorf("Container does not have the correct number of dns entries: %d", len(c.HostConfig.DNS))
   109  		}
   110  
   111  		if c.HostConfig.DNS[0] != "8.8.8.8" {
   112  			return fmt.Errorf("Container has wrong dns setting: %v", c.HostConfig.DNS[0])
   113  		}
   114  
   115  		if len(c.HostConfig.DNSOptions) != 1 {
   116  			return fmt.Errorf("Container does not have the correct number of dns option entries: %d", len(c.HostConfig.DNS))
   117  		}
   118  
   119  		if c.HostConfig.DNSOptions[0] != "rotate" {
   120  			return fmt.Errorf("Container has wrong dns option setting: %v", c.HostConfig.DNS[0])
   121  		}
   122  
   123  		if len(c.HostConfig.DNSSearch) != 1 {
   124  			return fmt.Errorf("Container does not have the correct number of dns search entries: %d", len(c.HostConfig.DNS))
   125  		}
   126  
   127  		if c.HostConfig.DNSSearch[0] != "example.com" {
   128  			return fmt.Errorf("Container has wrong dns search setting: %v", c.HostConfig.DNS[0])
   129  		}
   130  
   131  		if len(c.HostConfig.CapAdd) != 1 {
   132  			return fmt.Errorf("Container does not have the correct number of Capabilities in ADD: %d", len(c.HostConfig.CapAdd))
   133  		}
   134  
   135  		if c.HostConfig.CapAdd[0] != "ALL" {
   136  			return fmt.Errorf("Container has wrong CapAdd setting: %v", c.HostConfig.CapAdd[0])
   137  		}
   138  
   139  		if len(c.HostConfig.CapDrop) != 1 {
   140  			return fmt.Errorf("Container does not have the correct number of Capabilities in Drop: %d", len(c.HostConfig.CapDrop))
   141  		}
   142  
   143  		if c.HostConfig.CapDrop[0] != "SYS_ADMIN" {
   144  			return fmt.Errorf("Container has wrong CapDrop setting: %v", c.HostConfig.CapDrop[0])
   145  		}
   146  
   147  		if c.HostConfig.CPUShares != 32 {
   148  			return fmt.Errorf("Container has wrong cpu shares setting: %d", c.HostConfig.CPUShares)
   149  		}
   150  
   151  		if c.HostConfig.CPUShares != 32 {
   152  			return fmt.Errorf("Container has wrong cpu shares setting: %d", c.HostConfig.CPUShares)
   153  		}
   154  
   155  		if c.Config.Labels["env"] != "prod" || c.Config.Labels["role"] != "test" {
   156  			return fmt.Errorf("Container does not have the correct labels")
   157  		}
   158  
   159  		if c.HostConfig.LogConfig.Type != "json-file" {
   160  			return fmt.Errorf("Container does not have the correct log config: %s", c.HostConfig.LogConfig.Type)
   161  		}
   162  
   163  		if c.HostConfig.LogConfig.Config["max-size"] != "10m" {
   164  			return fmt.Errorf("Container does not have the correct max-size log option: %v", c.HostConfig.LogConfig.Config["max-size"])
   165  		}
   166  
   167  		if c.HostConfig.LogConfig.Config["max-file"] != "20" {
   168  			return fmt.Errorf("Container does not have the correct max-file log option: %v", c.HostConfig.LogConfig.Config["max-file"])
   169  		}
   170  
   171  		if len(c.HostConfig.ExtraHosts) != 2 {
   172  			return fmt.Errorf("Container does not have correct number of extra host entries, got %d", len(c.HostConfig.ExtraHosts))
   173  		}
   174  
   175  		if c.HostConfig.ExtraHosts[0] != "testhost2:10.0.2.0" {
   176  			return fmt.Errorf("Container has incorrect extra host string: %q", c.HostConfig.ExtraHosts[0])
   177  		}
   178  
   179  		if c.HostConfig.ExtraHosts[1] != "testhost:10.0.1.0" {
   180  			return fmt.Errorf("Container has incorrect extra host string: %q", c.HostConfig.ExtraHosts[1])
   181  		}
   182  
   183  		return nil
   184  	}
   185  
   186  	resource.Test(t, resource.TestCase{
   187  		PreCheck:  func() { testAccPreCheck(t) },
   188  		Providers: testAccProviders,
   189  		Steps: []resource.TestStep{
   190  			resource.TestStep{
   191  				Config: testAccDockerContainerCustomizedConfig,
   192  				Check: resource.ComposeTestCheckFunc(
   193  					testAccContainerRunning("docker_container.foo", &c),
   194  					testCheck,
   195  				),
   196  			},
   197  		},
   198  	})
   199  }
   200  
   201  func TestAccDockerContainer_upload(t *testing.T) {
   202  	var c dc.Container
   203  
   204  	testCheck := func(*terraform.State) error {
   205  		client := testAccProvider.Meta().(*dc.Client)
   206  
   207  		buf := new(bytes.Buffer)
   208  		opts := dc.DownloadFromContainerOptions{
   209  			OutputStream: buf,
   210  			Path:         "/terraform/test.txt",
   211  		}
   212  
   213  		if err := client.DownloadFromContainer(c.ID, opts); err != nil {
   214  			return fmt.Errorf("Unable to download a file from container: %s", err)
   215  		}
   216  
   217  		r := bytes.NewReader(buf.Bytes())
   218  		tr := tar.NewReader(r)
   219  
   220  		if _, err := tr.Next(); err != nil {
   221  			return fmt.Errorf("Unable to read content of tar archive: %s", err)
   222  		}
   223  
   224  		fbuf := new(bytes.Buffer)
   225  		fbuf.ReadFrom(tr)
   226  		content := fbuf.String()
   227  
   228  		if content != "foo" {
   229  			return fmt.Errorf("file content is invalid")
   230  		}
   231  
   232  		return nil
   233  	}
   234  
   235  	resource.Test(t, resource.TestCase{
   236  		PreCheck:  func() { testAccPreCheck(t) },
   237  		Providers: testAccProviders,
   238  		Steps: []resource.TestStep{
   239  			resource.TestStep{
   240  				Config: testAccDockerContainerUploadConfig,
   241  				Check: resource.ComposeTestCheckFunc(
   242  					testAccContainerRunning("docker_container.foo", &c),
   243  					testCheck,
   244  				),
   245  			},
   246  		},
   247  	})
   248  }
   249  
   250  func testAccContainerRunning(n string, container *dc.Container) resource.TestCheckFunc {
   251  	return func(s *terraform.State) error {
   252  		rs, ok := s.RootModule().Resources[n]
   253  		if !ok {
   254  			return fmt.Errorf("Not found: %s", n)
   255  		}
   256  
   257  		if rs.Primary.ID == "" {
   258  			return fmt.Errorf("No ID is set")
   259  		}
   260  
   261  		client := testAccProvider.Meta().(*dc.Client)
   262  		containers, err := client.ListContainers(dc.ListContainersOptions{})
   263  		if err != nil {
   264  			return err
   265  		}
   266  
   267  		for _, c := range containers {
   268  			if c.ID == rs.Primary.ID {
   269  				inspected, err := client.InspectContainer(c.ID)
   270  				if err != nil {
   271  					return fmt.Errorf("Container could not be inspected: %s", err)
   272  				}
   273  				*container = *inspected
   274  				return nil
   275  			}
   276  		}
   277  
   278  		return fmt.Errorf("Container not found: %s", rs.Primary.ID)
   279  	}
   280  }
   281  
   282  const testAccDockerContainerConfig = `
   283  resource "docker_image" "foo" {
   284  	name = "nginx:latest"
   285  }
   286  
   287  resource "docker_container" "foo" {
   288  	name = "tf-test"
   289  	image = "${docker_image.foo.latest}"
   290  }
   291  `
   292  
   293  const testAccDockerContainerVolumeConfig = `
   294  resource "docker_image" "foo" {
   295  	name = "nginx:latest"
   296  }
   297  
   298  resource "docker_volume" "foo" {
   299      name = "testAccDockerContainerVolume_volume"
   300  }
   301  
   302  resource "docker_container" "foo" {
   303  	name = "tf-test"
   304  	image = "${docker_image.foo.latest}"
   305  
   306      volumes {
   307          volume_name = "${docker_volume.foo.name}"
   308          container_path = "/tmp/volume"
   309          read_only = false
   310      }
   311  }
   312  `
   313  
   314  const testAccDockerContainerCustomizedConfig = `
   315  resource "docker_image" "foo" {
   316  	name = "nginx:latest"
   317  }
   318  
   319  resource "docker_container" "foo" {
   320  	name = "tf-test"
   321  	image = "${docker_image.foo.latest}"
   322  	entrypoint = ["/bin/bash", "-c", "ping localhost"]
   323  	user = "root:root"
   324  	restart = "on-failure"
   325  	destroy_grace_seconds = 10
   326  	max_retry_count = 5
   327  	memory = 512
   328  	memory_swap = 2048
   329  	cpu_shares = 32
   330  
   331  	capabilities {
   332  		add= ["ALL"]
   333  		drop = ["SYS_ADMIN"]
   334  	}
   335  
   336  	dns = ["8.8.8.8"]
   337  	dns_opts = ["rotate"]
   338  	dns_search = ["example.com"]
   339  	labels {
   340  		env = "prod"
   341  		role = "test"
   342  	}
   343  	log_driver = "json-file"
   344  	log_opts = {
   345  		max-size = "10m"
   346  		max-file = 20
   347  	}
   348  	network_mode = "bridge"
   349  
   350  	host {
   351  		host = "testhost"
   352  		ip = "10.0.1.0"
   353  	}
   354  
   355  	host {
   356  		host = "testhost2"
   357  		ip = "10.0.2.0"
   358  	}
   359  }
   360  `
   361  
   362  const testAccDockerContainerUploadConfig = `
   363  resource "docker_image" "foo" {
   364  	name = "nginx:latest"
   365  }
   366  
   367  resource "docker_container" "foo" {
   368  	name = "tf-test"
   369  	image = "${docker_image.foo.latest}"
   370  
   371  	upload {
   372  		content = "foo"
   373  		file = "/terraform/test.txt"
   374  	}
   375  }
   376  `