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 `