github.com/pritambaral/docker@v1.4.2-0.20150120174542-b2fe1b3dd952/integration-cli/docker_cli_links_test.go (about)

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