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