github.com/fcwu/docker@v1.4.2-0.20150115145920-2a69ca89f0df/integration-cli/docker_api_containers_test.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"io"
     7  	"io/ioutil"
     8  	"os"
     9  	"os/exec"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
    14  )
    15  
    16  func TestContainerApiGetAll(t *testing.T) {
    17  	startCount, err := getContainerCount()
    18  	if err != nil {
    19  		t.Fatalf("Cannot query container count: %v", err)
    20  	}
    21  
    22  	name := "getall"
    23  	runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "true")
    24  	out, _, err := runCommandWithOutput(runCmd)
    25  	if err != nil {
    26  		t.Fatalf("Error on container creation: %v, output: %q", err, out)
    27  	}
    28  
    29  	body, err := sockRequest("GET", "/containers/json?all=1", nil)
    30  	if err != nil {
    31  		t.Fatalf("GET all containers sockRequest failed: %v", err)
    32  	}
    33  
    34  	var inspectJSON []struct {
    35  		Names []string
    36  	}
    37  	if err = json.Unmarshal(body, &inspectJSON); err != nil {
    38  		t.Fatalf("unable to unmarshal response body: %v", err)
    39  	}
    40  
    41  	if len(inspectJSON) != startCount+1 {
    42  		t.Fatalf("Expected %d container(s), %d found (started with: %d)", startCount+1, len(inspectJSON), startCount)
    43  	}
    44  
    45  	if actual := inspectJSON[0].Names[0]; actual != "/"+name {
    46  		t.Fatalf("Container Name mismatch. Expected: %q, received: %q\n", "/"+name, actual)
    47  	}
    48  
    49  	deleteAllContainers()
    50  
    51  	logDone("container REST API - check GET json/all=1")
    52  }
    53  
    54  func TestContainerApiGetExport(t *testing.T) {
    55  	name := "exportcontainer"
    56  	runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "touch", "/test")
    57  	out, _, err := runCommandWithOutput(runCmd)
    58  	if err != nil {
    59  		t.Fatalf("Error on container creation: %v, output: %q", err, out)
    60  	}
    61  
    62  	body, err := sockRequest("GET", "/containers/"+name+"/export", nil)
    63  	if err != nil {
    64  		t.Fatalf("GET containers/export sockRequest failed: %v", err)
    65  	}
    66  
    67  	found := false
    68  	for tarReader := tar.NewReader(bytes.NewReader(body)); ; {
    69  		h, err := tarReader.Next()
    70  		if err != nil {
    71  			if err == io.EOF {
    72  				break
    73  			}
    74  			t.Fatal(err)
    75  		}
    76  		if h.Name == "test" {
    77  			found = true
    78  			break
    79  		}
    80  	}
    81  
    82  	if !found {
    83  		t.Fatalf("The created test file has not been found in the exported image")
    84  	}
    85  	deleteAllContainers()
    86  
    87  	logDone("container REST API - check GET containers/export")
    88  }
    89  
    90  func TestContainerApiGetChanges(t *testing.T) {
    91  	name := "changescontainer"
    92  	runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "rm", "/etc/passwd")
    93  	out, _, err := runCommandWithOutput(runCmd)
    94  	if err != nil {
    95  		t.Fatalf("Error on container creation: %v, output: %q", err, out)
    96  	}
    97  
    98  	body, err := sockRequest("GET", "/containers/"+name+"/changes", nil)
    99  	if err != nil {
   100  		t.Fatalf("GET containers/changes sockRequest failed: %v", err)
   101  	}
   102  
   103  	changes := []struct {
   104  		Kind int
   105  		Path string
   106  	}{}
   107  	if err = json.Unmarshal(body, &changes); err != nil {
   108  		t.Fatalf("unable to unmarshal response body: %v", err)
   109  	}
   110  
   111  	// Check the changelog for removal of /etc/passwd
   112  	success := false
   113  	for _, elem := range changes {
   114  		if elem.Path == "/etc/passwd" && elem.Kind == 2 {
   115  			success = true
   116  		}
   117  	}
   118  	if !success {
   119  		t.Fatalf("/etc/passwd has been removed but is not present in the diff")
   120  	}
   121  
   122  	deleteAllContainers()
   123  
   124  	logDone("container REST API - check GET containers/changes")
   125  }
   126  
   127  func TestContainerApiStartVolumeBinds(t *testing.T) {
   128  	defer deleteAllContainers()
   129  	name := "testing"
   130  	config := map[string]interface{}{
   131  		"Image":   "busybox",
   132  		"Volumes": map[string]struct{}{"/tmp": {}},
   133  	}
   134  
   135  	if _, err := sockRequest("POST", "/containers/create?name="+name, config); err != nil && !strings.Contains(err.Error(), "201 Created") {
   136  		t.Fatal(err)
   137  	}
   138  
   139  	bindPath, err := ioutil.TempDir(os.TempDir(), "test")
   140  	if err != nil {
   141  		t.Fatal(err)
   142  	}
   143  
   144  	config = map[string]interface{}{
   145  		"Binds": []string{bindPath + ":/tmp"},
   146  	}
   147  	if _, err := sockRequest("POST", "/containers/"+name+"/start", config); err != nil && !strings.Contains(err.Error(), "204 No Content") {
   148  		t.Fatal(err)
   149  	}
   150  
   151  	pth, err := inspectFieldMap(name, "Volumes", "/tmp")
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  
   156  	if pth != bindPath {
   157  		t.Fatalf("expected volume host path to be %s, got %s", bindPath, pth)
   158  	}
   159  
   160  	logDone("container REST API - check volume binds on start")
   161  }
   162  
   163  func TestContainerApiStartVolumesFrom(t *testing.T) {
   164  	defer deleteAllContainers()
   165  	volName := "voltst"
   166  	volPath := "/tmp"
   167  
   168  	if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", volName, "-v", volPath, "busybox")); err != nil {
   169  		t.Fatal(out, err)
   170  	}
   171  
   172  	name := "testing"
   173  	config := map[string]interface{}{
   174  		"Image":   "busybox",
   175  		"Volumes": map[string]struct{}{volPath: {}},
   176  	}
   177  
   178  	if _, err := sockRequest("POST", "/containers/create?name="+name, config); err != nil && !strings.Contains(err.Error(), "201 Created") {
   179  		t.Fatal(err)
   180  	}
   181  
   182  	config = map[string]interface{}{
   183  		"VolumesFrom": []string{volName},
   184  	}
   185  	if _, err := sockRequest("POST", "/containers/"+name+"/start", config); err != nil && !strings.Contains(err.Error(), "204 No Content") {
   186  		t.Fatal(err)
   187  	}
   188  
   189  	pth, err := inspectFieldMap(name, "Volumes", volPath)
   190  	if err != nil {
   191  		t.Fatal(err)
   192  	}
   193  	pth2, err := inspectFieldMap(volName, "Volumes", volPath)
   194  	if err != nil {
   195  		t.Fatal(err)
   196  	}
   197  
   198  	if pth != pth2 {
   199  		t.Fatalf("expected volume host path to be %s, got %s", pth, pth2)
   200  	}
   201  
   202  	logDone("container REST API - check VolumesFrom on start")
   203  }
   204  
   205  // Ensure that volumes-from has priority over binds/anything else
   206  // This is pretty much the same as TestRunApplyVolumesFromBeforeVolumes, except with passing the VolumesFrom and the bind on start
   207  func TestVolumesFromHasPriority(t *testing.T) {
   208  	defer deleteAllContainers()
   209  	volName := "voltst"
   210  	volPath := "/tmp"
   211  
   212  	if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", volName, "-v", volPath, "busybox")); err != nil {
   213  		t.Fatal(out, err)
   214  	}
   215  
   216  	name := "testing"
   217  	config := map[string]interface{}{
   218  		"Image":   "busybox",
   219  		"Volumes": map[string]struct{}{volPath: {}},
   220  	}
   221  
   222  	if _, err := sockRequest("POST", "/containers/create?name="+name, config); err != nil && !strings.Contains(err.Error(), "201 Created") {
   223  		t.Fatal(err)
   224  	}
   225  
   226  	bindPath, err := ioutil.TempDir(os.TempDir(), "test")
   227  	if err != nil {
   228  		t.Fatal(err)
   229  	}
   230  
   231  	config = map[string]interface{}{
   232  		"VolumesFrom": []string{volName},
   233  		"Binds":       []string{bindPath + ":/tmp"},
   234  	}
   235  	if _, err := sockRequest("POST", "/containers/"+name+"/start", config); err != nil && !strings.Contains(err.Error(), "204 No Content") {
   236  		t.Fatal(err)
   237  	}
   238  
   239  	pth, err := inspectFieldMap(name, "Volumes", volPath)
   240  	if err != nil {
   241  		t.Fatal(err)
   242  	}
   243  	pth2, err := inspectFieldMap(volName, "Volumes", volPath)
   244  	if err != nil {
   245  		t.Fatal(err)
   246  	}
   247  
   248  	if pth != pth2 {
   249  		t.Fatalf("expected volume host path to be %s, got %s", pth, pth2)
   250  	}
   251  
   252  	logDone("container REST API - check VolumesFrom has priority")
   253  }