2015-03-27 23:33:17 +01:00
package docker
import (
2016-12-05 12:06:34 +01:00
"archive/tar"
"bytes"
2015-03-29 03:45:36 +02:00
"fmt"
2015-03-27 23:33:17 +01:00
"testing"
2015-03-29 03:45:36 +02:00
dc "github.com/fsouza/go-dockerclient"
2015-03-27 23:33:17 +01:00
"github.com/hashicorp/terraform/helper/resource"
2015-03-29 03:45:36 +02:00
"github.com/hashicorp/terraform/terraform"
2015-03-27 23:33:17 +01:00
)
func TestAccDockerContainer_basic ( t * testing . T ) {
2015-10-26 22:24:48 +01:00
var c dc . Container
2015-03-27 23:33:17 +01:00
resource . Test ( t , resource . TestCase {
PreCheck : func ( ) { testAccPreCheck ( t ) } ,
Providers : testAccProviders ,
Steps : [ ] resource . TestStep {
resource . TestStep {
Config : testAccDockerContainerConfig ,
Check : resource . ComposeTestCheckFunc (
2015-10-26 22:24:48 +01:00
testAccContainerRunning ( "docker_container.foo" , & c ) ,
2015-03-27 23:33:17 +01:00
) ,
} ,
} ,
} )
}
2016-01-15 22:59:33 +01:00
func TestAccDockerContainer_volume ( t * testing . T ) {
var c dc . Container
testCheck := func ( * terraform . State ) error {
2016-06-29 10:38:56 +02:00
if len ( c . Mounts ) != 1 {
return fmt . Errorf ( "Incorrect number of mounts: expected 1, got %d" , len ( c . Mounts ) )
2016-01-15 22:59:33 +01:00
}
for _ , v := range c . Mounts {
if v . Name != "testAccDockerContainerVolume_volume" {
continue
}
if v . Destination != "/tmp/volume" {
return fmt . Errorf ( "Bad destination on mount: expected /tmp/volume, got %q" , v . Destination )
}
if v . Mode != "rw" {
return fmt . Errorf ( "Bad mode on mount: expected rw, got %q" , v . Mode )
}
return nil
}
return fmt . Errorf ( "Mount for testAccDockerContainerVolume_volume not found" )
}
resource . Test ( t , resource . TestCase {
PreCheck : func ( ) { testAccPreCheck ( t ) } ,
Providers : testAccProviders ,
Steps : [ ] resource . TestStep {
resource . TestStep {
Config : testAccDockerContainerVolumeConfig ,
Check : resource . ComposeTestCheckFunc (
testAccContainerRunning ( "docker_container.foo" , & c ) ,
testCheck ,
) ,
} ,
} ,
} )
}
2015-10-27 17:08:57 +01:00
func TestAccDockerContainer_customized ( t * testing . T ) {
2015-10-26 22:24:48 +01:00
var c dc . Container
testCheck := func ( * terraform . State ) error {
if len ( c . Config . Entrypoint ) < 3 ||
( c . Config . Entrypoint [ 0 ] != "/bin/bash" &&
c . Config . Entrypoint [ 1 ] != "-c" &&
c . Config . Entrypoint [ 2 ] != "ping localhost" ) {
return fmt . Errorf ( "Container wrong entrypoint: %s" , c . Config . Entrypoint )
}
2015-10-27 17:08:57 +01:00
2016-04-05 04:43:59 +02:00
if c . Config . User != "root:root" {
return fmt . Errorf ( "Container wrong user: %s" , c . Config . User )
}
2015-10-27 17:08:57 +01:00
if c . HostConfig . RestartPolicy . Name == "on-failure" {
if c . HostConfig . RestartPolicy . MaximumRetryCount != 5 {
return fmt . Errorf ( "Container has wrong restart policy max retry count: %d" , c . HostConfig . RestartPolicy . MaximumRetryCount )
}
} else {
return fmt . Errorf ( "Container has wrong restart policy: %s" , c . HostConfig . RestartPolicy . Name )
}
2015-11-04 21:46:24 +01:00
if c . HostConfig . Memory != ( 512 * 1024 * 1024 ) {
2015-10-28 00:53:49 +01:00
return fmt . Errorf ( "Container has wrong memory setting: %d" , c . HostConfig . Memory )
}
2015-11-04 21:46:24 +01:00
if c . HostConfig . MemorySwap != ( 2048 * 1024 * 1024 ) {
2016-06-29 16:48:15 +02:00
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 )
2015-10-28 00:53:49 +01:00
}
2015-11-04 21:46:24 +01:00
if c . HostConfig . CPUShares != 32 {
2015-10-28 00:53:49 +01:00
return fmt . Errorf ( "Container has wrong cpu shares setting: %d" , c . HostConfig . CPUShares )
}
2015-11-03 21:20:58 +01:00
2016-06-29 14:38:46 +02:00
if len ( c . HostConfig . DNS ) != 1 {
return fmt . Errorf ( "Container does not have the correct number of dns entries: %d" , len ( c . HostConfig . DNS ) )
}
if c . HostConfig . DNS [ 0 ] != "8.8.8.8" {
return fmt . Errorf ( "Container has wrong dns setting: %v" , c . HostConfig . DNS [ 0 ] )
}
if len ( c . HostConfig . DNSOptions ) != 1 {
return fmt . Errorf ( "Container does not have the correct number of dns option entries: %d" , len ( c . HostConfig . DNS ) )
}
if c . HostConfig . DNSOptions [ 0 ] != "rotate" {
return fmt . Errorf ( "Container has wrong dns option setting: %v" , c . HostConfig . DNS [ 0 ] )
}
if len ( c . HostConfig . DNSSearch ) != 1 {
return fmt . Errorf ( "Container does not have the correct number of dns search entries: %d" , len ( c . HostConfig . DNS ) )
}
if c . HostConfig . DNSSearch [ 0 ] != "example.com" {
return fmt . Errorf ( "Container has wrong dns search setting: %v" , c . HostConfig . DNS [ 0 ] )
}
2017-03-07 17:48:20 +01:00
if len ( c . HostConfig . CapAdd ) != 1 {
return fmt . Errorf ( "Container does not have the correct number of Capabilities in ADD: %d" , len ( c . HostConfig . CapAdd ) )
}
if c . HostConfig . CapAdd [ 0 ] != "ALL" {
return fmt . Errorf ( "Container has wrong CapAdd setting: %v" , c . HostConfig . CapAdd [ 0 ] )
}
if len ( c . HostConfig . CapDrop ) != 1 {
return fmt . Errorf ( "Container does not have the correct number of Capabilities in Drop: %d" , len ( c . HostConfig . CapDrop ) )
}
if c . HostConfig . CapDrop [ 0 ] != "SYS_ADMIN" {
return fmt . Errorf ( "Container has wrong CapDrop setting: %v" , c . HostConfig . CapDrop [ 0 ] )
}
2016-06-29 14:38:46 +02:00
if c . HostConfig . CPUShares != 32 {
return fmt . Errorf ( "Container has wrong cpu shares setting: %d" , c . HostConfig . CPUShares )
}
if c . HostConfig . CPUShares != 32 {
return fmt . Errorf ( "Container has wrong cpu shares setting: %d" , c . HostConfig . CPUShares )
}
2015-11-03 21:20:58 +01:00
if c . Config . Labels [ "env" ] != "prod" || c . Config . Labels [ "role" ] != "test" {
return fmt . Errorf ( "Container does not have the correct labels" )
}
2015-11-04 18:42:55 +01:00
if c . HostConfig . LogConfig . Type != "json-file" {
return fmt . Errorf ( "Container does not have the correct log config: %s" , c . HostConfig . LogConfig . Type )
}
if c . HostConfig . LogConfig . Config [ "max-size" ] != "10m" {
return fmt . Errorf ( "Container does not have the correct max-size log option: %v" , c . HostConfig . LogConfig . Config [ "max-size" ] )
}
if c . HostConfig . LogConfig . Config [ "max-file" ] != "20" {
return fmt . Errorf ( "Container does not have the correct max-file log option: %v" , c . HostConfig . LogConfig . Config [ "max-file" ] )
}
2016-01-15 03:59:07 +01:00
if len ( c . HostConfig . ExtraHosts ) != 2 {
return fmt . Errorf ( "Container does not have correct number of extra host entries, got %d" , len ( c . HostConfig . ExtraHosts ) )
}
if c . HostConfig . ExtraHosts [ 0 ] != "testhost2:10.0.2.0" {
return fmt . Errorf ( "Container has incorrect extra host string: %q" , c . HostConfig . ExtraHosts [ 0 ] )
}
if c . HostConfig . ExtraHosts [ 1 ] != "testhost:10.0.1.0" {
return fmt . Errorf ( "Container has incorrect extra host string: %q" , c . HostConfig . ExtraHosts [ 1 ] )
}
2015-10-26 22:24:48 +01:00
return nil
}
resource . Test ( t , resource . TestCase {
PreCheck : func ( ) { testAccPreCheck ( t ) } ,
Providers : testAccProviders ,
Steps : [ ] resource . TestStep {
resource . TestStep {
2015-10-27 17:08:57 +01:00
Config : testAccDockerContainerCustomizedConfig ,
2015-10-26 22:24:48 +01:00
Check : resource . ComposeTestCheckFunc (
testAccContainerRunning ( "docker_container.foo" , & c ) ,
testCheck ,
) ,
} ,
} ,
} )
}
2016-12-05 12:06:34 +01:00
func TestAccDockerContainer_upload ( t * testing . T ) {
var c dc . Container
testCheck := func ( * terraform . State ) error {
client := testAccProvider . Meta ( ) . ( * dc . Client )
buf := new ( bytes . Buffer )
opts := dc . DownloadFromContainerOptions {
OutputStream : buf ,
Path : "/terraform/test.txt" ,
}
if err := client . DownloadFromContainer ( c . ID , opts ) ; err != nil {
return fmt . Errorf ( "Unable to download a file from container: %s" , err )
}
r := bytes . NewReader ( buf . Bytes ( ) )
tr := tar . NewReader ( r )
if _ , err := tr . Next ( ) ; err != nil {
return fmt . Errorf ( "Unable to read content of tar archive: %s" , err )
}
fbuf := new ( bytes . Buffer )
fbuf . ReadFrom ( tr )
content := fbuf . String ( )
if content != "foo" {
return fmt . Errorf ( "file content is invalid" )
}
return nil
}
resource . Test ( t , resource . TestCase {
PreCheck : func ( ) { testAccPreCheck ( t ) } ,
Providers : testAccProviders ,
Steps : [ ] resource . TestStep {
resource . TestStep {
Config : testAccDockerContainerUploadConfig ,
Check : resource . ComposeTestCheckFunc (
testAccContainerRunning ( "docker_container.foo" , & c ) ,
testCheck ,
) ,
} ,
} ,
} )
}
2015-10-26 22:24:48 +01:00
func testAccContainerRunning ( n string , container * dc . Container ) resource . TestCheckFunc {
2015-03-29 03:45:36 +02:00
return func ( s * terraform . State ) error {
rs , ok := s . RootModule ( ) . Resources [ n ]
if ! ok {
return fmt . Errorf ( "Not found: %s" , n )
}
if rs . Primary . ID == "" {
return fmt . Errorf ( "No ID is set" )
}
client := testAccProvider . Meta ( ) . ( * dc . Client )
containers , err := client . ListContainers ( dc . ListContainersOptions { } )
if err != nil {
return err
}
for _ , c := range containers {
if c . ID == rs . Primary . ID {
2015-10-26 22:24:48 +01:00
inspected , err := client . InspectContainer ( c . ID )
if err != nil {
return fmt . Errorf ( "Container could not be inspected: %s" , err )
}
* container = * inspected
2015-03-29 03:45:36 +02:00
return nil
}
}
return fmt . Errorf ( "Container not found: %s" , rs . Primary . ID )
}
}
2015-03-27 23:33:17 +01:00
const testAccDockerContainerConfig = `
resource "docker_image" "foo" {
2015-06-29 23:09:05 +02:00
name = "nginx:latest"
2015-03-27 23:33:17 +01:00
}
resource "docker_container" "foo" {
name = "tf-test"
image = "${docker_image.foo.latest}"
}
`
2016-01-15 03:59:07 +01:00
2016-01-15 22:59:33 +01:00
const testAccDockerContainerVolumeConfig = `
resource "docker_image" "foo" {
name = "nginx:latest"
}
resource "docker_volume" "foo" {
name = "testAccDockerContainerVolume_volume"
}
resource "docker_container" "foo" {
name = "tf-test"
image = "${docker_image.foo.latest}"
volumes {
volume_name = "${docker_volume.foo.name}"
container_path = "/tmp/volume"
read_only = false
}
}
`
2015-10-27 17:08:57 +01:00
const testAccDockerContainerCustomizedConfig = `
2015-10-26 22:24:48 +01:00
resource "docker_image" "foo" {
name = "nginx:latest"
}
resource "docker_container" "foo" {
name = "tf-test"
image = "${docker_image.foo.latest}"
2016-01-15 03:59:07 +01:00
entrypoint = [ "/bin/bash" , "-c" , "ping localhost" ]
2016-04-05 04:43:59 +02:00
user = "root:root"
2016-01-15 03:59:07 +01:00
restart = "on-failure"
2016-07-11 17:03:02 +02:00
destroy_grace_seconds = 10
2016-01-15 03:59:07 +01:00
max_retry_count = 5
memory = 512
memory_swap = 2048
cpu_shares = 32
2017-03-07 17:48:20 +01:00
capabilities {
add = [ "ALL" ]
drop = [ "SYS_ADMIN" ]
}
2016-06-29 14:38:46 +02:00
dns = [ "8.8.8.8" ]
dns_opts = [ "rotate" ]
dns_search = [ "example.com" ]
2016-01-15 03:59:07 +01:00
labels {
env = "prod"
role = "test"
}
log_driver = "json-file"
log_opts = {
max - size = "10m"
max - file = 20
2015-11-04 18:42:55 +01:00
}
2016-01-01 09:57:21 +01:00
network_mode = "bridge"
2016-01-15 03:59:07 +01:00
host {
host = "testhost"
ip = "10.0.1.0"
}
host {
host = "testhost2"
ip = "10.0.2.0"
}
2015-10-26 22:24:48 +01:00
}
`
2016-12-05 12:06:34 +01:00
const testAccDockerContainerUploadConfig = `
resource "docker_image" "foo" {
name = "nginx:latest"
}
resource "docker_container" "foo" {
name = "tf-test"
image = "${docker_image.foo.latest}"
upload {
content = "foo"
file = "/terraform/test.txt"
}
}
`