github.com/stchris/docker@v1.4.2-0.20150106053530-1510a324dbd5/integration-cli/docker_cli_links_test.go (about)

     1  package main
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"os/exec"
     7  	"reflect"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/docker/docker/pkg/iptables"
    13  )
    14  
    15  func TestLinksEtcHostsRegularFile(t *testing.T) {
    16  	runCmd := exec.Command(dockerBinary, "run", "--net=host", "busybox", "ls", "-la", "/etc/hosts")
    17  	out, _, _, err := runCommandWithStdoutStderr(runCmd)
    18  	if err != nil {
    19  		t.Fatal(out, err)
    20  	}
    21  
    22  	if !strings.HasPrefix(out, "-") {
    23  		t.Errorf("/etc/hosts should be a regular file")
    24  	}
    25  
    26  	deleteAllContainers()
    27  
    28  	logDone("link - /etc/hosts is a regular file")
    29  }
    30  
    31  func TestLinksEtcHostsContentMatch(t *testing.T) {
    32  	runCmd := exec.Command(dockerBinary, "run", "--net=host", "busybox", "cat", "/etc/hosts")
    33  	out, _, _, err := runCommandWithStdoutStderr(runCmd)
    34  	if err != nil {
    35  		t.Fatal(out, err)
    36  	}
    37  
    38  	hosts, err := ioutil.ReadFile("/etc/hosts")
    39  	if os.IsNotExist(err) {
    40  		t.Skip("/etc/hosts does not exist, skip this test")
    41  	}
    42  
    43  	if out != string(hosts) {
    44  		t.Errorf("container")
    45  	}
    46  
    47  	deleteAllContainers()
    48  
    49  	logDone("link - /etc/hosts matches hosts copy")
    50  }
    51  
    52  func TestLinksPingUnlinkedContainers(t *testing.T) {
    53  	runCmd := exec.Command(dockerBinary, "run", "--rm", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1")
    54  	exitCode, err := runCommand(runCmd)
    55  
    56  	if exitCode == 0 {
    57  		t.Fatal("run ping did not fail")
    58  	} else if exitCode != 1 {
    59  		t.Fatalf("run ping failed with errors: %v", err)
    60  	}
    61  
    62  	logDone("links - ping unlinked container")
    63  }
    64  
    65  func TestLinksPingLinkedContainers(t *testing.T) {
    66  	var out string
    67  	out, _, _ = dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10")
    68  	idA := stripTrailingCharacters(out)
    69  	out, _, _ = dockerCmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10")
    70  	idB := stripTrailingCharacters(out)
    71  	dockerCmd(t, "run", "--rm", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1")
    72  	dockerCmd(t, "kill", idA)
    73  	dockerCmd(t, "kill", idB)
    74  	deleteAllContainers()
    75  
    76  	logDone("links - ping linked container")
    77  }
    78  
    79  func TestLinksIpTablesRulesWhenLinkAndUnlink(t *testing.T) {
    80  	dockerCmd(t, "run", "-d", "--name", "child", "--publish", "8080:80", "busybox", "sleep", "10")
    81  	dockerCmd(t, "run", "-d", "--name", "parent", "--link", "child:http", "busybox", "sleep", "10")
    82  
    83  	childIP := findContainerIP(t, "child")
    84  	parentIP := findContainerIP(t, "parent")
    85  
    86  	sourceRule := []string{"DOCKER", "-i", "docker0", "-o", "docker0", "-p", "tcp", "-s", childIP, "--sport", "80", "-d", parentIP, "-j", "ACCEPT"}
    87  	destinationRule := []string{"DOCKER", "-i", "docker0", "-o", "docker0", "-p", "tcp", "-s", parentIP, "--dport", "80", "-d", childIP, "-j", "ACCEPT"}
    88  	if !iptables.Exists(sourceRule...) || !iptables.Exists(destinationRule...) {
    89  		t.Fatal("Iptables rules not found")
    90  	}
    91  
    92  	dockerCmd(t, "rm", "--link", "parent/http")
    93  	if iptables.Exists(sourceRule...) || iptables.Exists(destinationRule...) {
    94  		t.Fatal("Iptables rules should be removed when unlink")
    95  	}
    96  
    97  	dockerCmd(t, "kill", "child")
    98  	dockerCmd(t, "kill", "parent")
    99  	deleteAllContainers()
   100  
   101  	logDone("link - verify iptables when link and unlink")
   102  }
   103  
   104  func TestLinksInspectLinksStarted(t *testing.T) {
   105  	var (
   106  		expected = map[string]struct{}{"/container1:/testinspectlink/alias1": {}, "/container2:/testinspectlink/alias2": {}}
   107  		result   []string
   108  	)
   109  	defer deleteAllContainers()
   110  	dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10")
   111  	dockerCmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10")
   112  	dockerCmd(t, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "sleep", "10")
   113  	links, err := inspectFieldJSON("testinspectlink", "HostConfig.Links")
   114  	if err != nil {
   115  		t.Fatal(err)
   116  	}
   117  
   118  	err = unmarshalJSON([]byte(links), &result)
   119  	if err != nil {
   120  		t.Fatal(err)
   121  	}
   122  
   123  	output := convertSliceOfStringsToMap(result)
   124  
   125  	equal := reflect.DeepEqual(output, expected)
   126  
   127  	if !equal {
   128  		t.Fatalf("Links %s, expected %s", result, expected)
   129  	}
   130  	logDone("link - links in started container inspect")
   131  }
   132  
   133  func TestLinksInspectLinksStopped(t *testing.T) {
   134  	var (
   135  		expected = map[string]struct{}{"/container1:/testinspectlink/alias1": {}, "/container2:/testinspectlink/alias2": {}}
   136  		result   []string
   137  	)
   138  	defer deleteAllContainers()
   139  	dockerCmd(t, "run", "-d", "--name", "container1", "busybox", "sleep", "10")
   140  	dockerCmd(t, "run", "-d", "--name", "container2", "busybox", "sleep", "10")
   141  	dockerCmd(t, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "true")
   142  	links, err := inspectFieldJSON("testinspectlink", "HostConfig.Links")
   143  	if err != nil {
   144  		t.Fatal(err)
   145  	}
   146  
   147  	err = unmarshalJSON([]byte(links), &result)
   148  	if err != nil {
   149  		t.Fatal(err)
   150  	}
   151  
   152  	output := convertSliceOfStringsToMap(result)
   153  
   154  	equal := reflect.DeepEqual(output, expected)
   155  
   156  	if !equal {
   157  		t.Fatalf("Links %s, but expected %s", result, expected)
   158  	}
   159  
   160  	logDone("link - links in stopped container inspect")
   161  }
   162  
   163  func TestLinksNotStartedParentNotFail(t *testing.T) {
   164  	defer deleteAllContainers()
   165  	runCmd := exec.Command(dockerBinary, "create", "--name=first", "busybox", "top")
   166  	out, _, _, err := runCommandWithStdoutStderr(runCmd)
   167  	if err != nil {
   168  		t.Fatal(out, err)
   169  	}
   170  	runCmd = exec.Command(dockerBinary, "create", "--name=second", "--link=first:first", "busybox", "top")
   171  	out, _, _, err = runCommandWithStdoutStderr(runCmd)
   172  	if err != nil {
   173  		t.Fatal(out, err)
   174  	}
   175  	runCmd = exec.Command(dockerBinary, "start", "first")
   176  	out, _, _, err = runCommandWithStdoutStderr(runCmd)
   177  	if err != nil {
   178  		t.Fatal(out, err)
   179  	}
   180  	logDone("link - container start not failing on updating stopped parent links")
   181  }
   182  
   183  func TestLinksHostsFilesInject(t *testing.T) {
   184  	defer deleteAllContainers()
   185  
   186  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-itd", "--name", "one", "busybox", "top"))
   187  	if err != nil {
   188  		t.Fatal(err, out)
   189  	}
   190  
   191  	idOne := strings.TrimSpace(out)
   192  
   193  	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "-itd", "--name", "two", "--link", "one:onetwo", "busybox", "top"))
   194  	if err != nil {
   195  		t.Fatal(err, out)
   196  	}
   197  
   198  	idTwo := strings.TrimSpace(out)
   199  
   200  	time.Sleep(1 * time.Second)
   201  
   202  	contentOne, err := readContainerFile(idOne, "hosts")
   203  	if err != nil {
   204  		t.Fatal(err, string(contentOne))
   205  	}
   206  
   207  	contentTwo, err := readContainerFile(idTwo, "hosts")
   208  	if err != nil {
   209  		t.Fatal(err, string(contentTwo))
   210  	}
   211  
   212  	if !strings.Contains(string(contentTwo), "onetwo") {
   213  		t.Fatal("Host is not present in updated hosts file", string(contentTwo))
   214  	}
   215  
   216  	logDone("link - ensure containers hosts files are updated with the link alias.")
   217  }
   218  
   219  func TestLinksNetworkHostContainer(t *testing.T) {
   220  	defer deleteAllContainers()
   221  
   222  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--net", "host", "--name", "host_container", "busybox", "top"))
   223  	if err != nil {
   224  		t.Fatal(err, out)
   225  	}
   226  
   227  	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "should_fail", "--link", "host_container:tester", "busybox", "true"))
   228  	if err == nil || !strings.Contains(out, "--net=host can't be used with links. This would result in undefined behavior.") {
   229  		t.Fatalf("Running container linking to a container with --net host should have failed: %s", out)
   230  	}
   231  
   232  	logDone("link - error thrown when linking to container with --net host")
   233  }