github.com/IBM-Cloud/terraform@v0.6.4-0.20170726051544-8872b87621df/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 return nil 207 } 208 209 resource.Test(t, resource.TestCase{ 210 PreCheck: func() { testAccPreCheck(t) }, 211 Providers: testAccProviders, 212 Steps: []resource.TestStep{ 213 resource.TestStep{ 214 Config: testAccDockerContainerCustomizedConfig, 215 Check: resource.ComposeTestCheckFunc( 216 testAccContainerRunning("docker_container.foo", &c), 217 testCheck, 218 ), 219 }, 220 }, 221 }) 222 } 223 224 func TestAccDockerContainer_upload(t *testing.T) { 225 var c dc.Container 226 227 testCheck := func(*terraform.State) error { 228 client := testAccProvider.Meta().(*dc.Client) 229 230 buf := new(bytes.Buffer) 231 opts := dc.DownloadFromContainerOptions{ 232 OutputStream: buf, 233 Path: "/terraform/test.txt", 234 } 235 236 if err := client.DownloadFromContainer(c.ID, opts); err != nil { 237 return fmt.Errorf("Unable to download a file from container: %s", err) 238 } 239 240 r := bytes.NewReader(buf.Bytes()) 241 tr := tar.NewReader(r) 242 243 if _, err := tr.Next(); err != nil { 244 return fmt.Errorf("Unable to read content of tar archive: %s", err) 245 } 246 247 fbuf := new(bytes.Buffer) 248 fbuf.ReadFrom(tr) 249 content := fbuf.String() 250 251 if content != "foo" { 252 return fmt.Errorf("file content is invalid") 253 } 254 255 return nil 256 } 257 258 resource.Test(t, resource.TestCase{ 259 PreCheck: func() { testAccPreCheck(t) }, 260 Providers: testAccProviders, 261 Steps: []resource.TestStep{ 262 resource.TestStep{ 263 Config: testAccDockerContainerUploadConfig, 264 Check: resource.ComposeTestCheckFunc( 265 testAccContainerRunning("docker_container.foo", &c), 266 testCheck, 267 ), 268 }, 269 }, 270 }) 271 } 272 273 func testAccContainerRunning(n string, container *dc.Container) resource.TestCheckFunc { 274 return func(s *terraform.State) error { 275 rs, ok := s.RootModule().Resources[n] 276 if !ok { 277 return fmt.Errorf("Not found: %s", n) 278 } 279 280 if rs.Primary.ID == "" { 281 return fmt.Errorf("No ID is set") 282 } 283 284 client := testAccProvider.Meta().(*dc.Client) 285 containers, err := client.ListContainers(dc.ListContainersOptions{}) 286 if err != nil { 287 return err 288 } 289 290 for _, c := range containers { 291 if c.ID == rs.Primary.ID { 292 inspected, err := client.InspectContainer(c.ID) 293 if err != nil { 294 return fmt.Errorf("Container could not be inspected: %s", err) 295 } 296 *container = *inspected 297 return nil 298 } 299 } 300 301 return fmt.Errorf("Container not found: %s", rs.Primary.ID) 302 } 303 } 304 305 const testAccDockerContainerConfig = ` 306 resource "docker_image" "foo" { 307 name = "nginx:latest" 308 } 309 310 resource "docker_container" "foo" { 311 name = "tf-test" 312 image = "${docker_image.foo.latest}" 313 } 314 ` 315 316 const testAccDockerContainerVolumeConfig = ` 317 resource "docker_image" "foo" { 318 name = "nginx:latest" 319 } 320 321 resource "docker_volume" "foo" { 322 name = "testAccDockerContainerVolume_volume" 323 } 324 325 resource "docker_container" "foo" { 326 name = "tf-test" 327 image = "${docker_image.foo.latest}" 328 329 volumes { 330 volume_name = "${docker_volume.foo.name}" 331 container_path = "/tmp/volume" 332 read_only = false 333 } 334 } 335 ` 336 337 const testAccDockerContainerCustomizedConfig = ` 338 resource "docker_image" "foo" { 339 name = "nginx:latest" 340 } 341 342 resource "docker_container" "foo" { 343 name = "tf-test" 344 image = "${docker_image.foo.latest}" 345 entrypoint = ["/bin/bash", "-c", "ping localhost"] 346 user = "root:root" 347 restart = "on-failure" 348 destroy_grace_seconds = 10 349 max_retry_count = 5 350 memory = 512 351 memory_swap = 2048 352 cpu_shares = 32 353 354 capabilities { 355 add= ["ALL"] 356 drop = ["SYS_ADMIN"] 357 } 358 359 dns = ["8.8.8.8"] 360 dns_opts = ["rotate"] 361 dns_search = ["example.com"] 362 labels { 363 env = "prod" 364 role = "test" 365 } 366 log_driver = "json-file" 367 log_opts = { 368 max-size = "10m" 369 max-file = 20 370 } 371 network_mode = "bridge" 372 373 host { 374 host = "testhost" 375 ip = "10.0.1.0" 376 } 377 378 host { 379 host = "testhost2" 380 ip = "10.0.2.0" 381 } 382 } 383 ` 384 385 const testAccDockerContainerUploadConfig = ` 386 resource "docker_image" "foo" { 387 name = "nginx:latest" 388 } 389 390 resource "docker_container" "foo" { 391 name = "tf-test" 392 image = "${docker_image.foo.latest}" 393 394 upload { 395 content = "foo" 396 file = "/terraform/test.txt" 397 } 398 } 399 `