github.com/crquan/docker@v1.8.1/integration-cli/docker_cli_links_test.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/go-check/check"
     6  	"reflect"
     7  	"regexp"
     8  	"strings"
     9  	"time"
    10  )
    11  
    12  func (s *DockerSuite) TestLinksPingUnlinkedContainers(c *check.C) {
    13  
    14  	_, exitCode, err := dockerCmdWithError(c, "run", "--rm", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1")
    15  
    16  	if exitCode == 0 {
    17  		c.Fatal("run ping did not fail")
    18  	} else if exitCode != 1 {
    19  		c.Fatalf("run ping failed with errors: %v", err)
    20  	}
    21  
    22  }
    23  
    24  // Test for appropriate error when calling --link with an invalid target container
    25  func (s *DockerSuite) TestLinksInvalidContainerTarget(c *check.C) {
    26  
    27  	out, _, err := dockerCmdWithError(c, "run", "--link", "bogus:alias", "busybox", "true")
    28  
    29  	if err == nil {
    30  		c.Fatal("an invalid container target should produce an error")
    31  	}
    32  	if !strings.Contains(out, "Could not get container") {
    33  		c.Fatalf("error output expected 'Could not get container', but got %q instead; err: %v", out, err)
    34  	}
    35  
    36  }
    37  
    38  func (s *DockerSuite) TestLinksPingLinkedContainers(c *check.C) {
    39  
    40  	dockerCmd(c, "run", "-d", "--name", "container1", "--hostname", "fred", "busybox", "top")
    41  	dockerCmd(c, "run", "-d", "--name", "container2", "--hostname", "wilma", "busybox", "top")
    42  
    43  	runArgs := []string{"run", "--rm", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "sh", "-c"}
    44  	pingCmd := "ping -c 1 %s -W 1 && ping -c 1 %s -W 1"
    45  
    46  	// test ping by alias, ping by name, and ping by hostname
    47  	// 1. Ping by alias
    48  	dockerCmd(c, append(runArgs, fmt.Sprintf(pingCmd, "alias1", "alias2"))...)
    49  	// 2. Ping by container name
    50  	dockerCmd(c, append(runArgs, fmt.Sprintf(pingCmd, "container1", "container2"))...)
    51  	// 3. Ping by hostname
    52  	dockerCmd(c, append(runArgs, fmt.Sprintf(pingCmd, "fred", "wilma"))...)
    53  
    54  }
    55  
    56  func (s *DockerSuite) TestLinksPingLinkedContainersAfterRename(c *check.C) {
    57  
    58  	out, _ := dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top")
    59  	idA := strings.TrimSpace(out)
    60  	out, _ = dockerCmd(c, "run", "-d", "--name", "container2", "busybox", "top")
    61  	idB := strings.TrimSpace(out)
    62  	dockerCmd(c, "rename", "container1", "container_new")
    63  	dockerCmd(c, "run", "--rm", "--link", "container_new:alias1", "--link", "container2:alias2", "busybox", "sh", "-c", "ping -c 1 alias1 -W 1 && ping -c 1 alias2 -W 1")
    64  	dockerCmd(c, "kill", idA)
    65  	dockerCmd(c, "kill", idB)
    66  
    67  }
    68  
    69  func (s *DockerSuite) TestLinksInspectLinksStarted(c *check.C) {
    70  	var (
    71  		expected = map[string]struct{}{"/container1:/testinspectlink/alias1": {}, "/container2:/testinspectlink/alias2": {}}
    72  		result   []string
    73  	)
    74  	dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top")
    75  	dockerCmd(c, "run", "-d", "--name", "container2", "busybox", "top")
    76  	dockerCmd(c, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "top")
    77  	links, err := inspectFieldJSON("testinspectlink", "HostConfig.Links")
    78  	if err != nil {
    79  		c.Fatal(err)
    80  	}
    81  
    82  	err = unmarshalJSON([]byte(links), &result)
    83  	if err != nil {
    84  		c.Fatal(err)
    85  	}
    86  
    87  	output := convertSliceOfStringsToMap(result)
    88  
    89  	equal := reflect.DeepEqual(output, expected)
    90  
    91  	if !equal {
    92  		c.Fatalf("Links %s, expected %s", result, expected)
    93  	}
    94  }
    95  
    96  func (s *DockerSuite) TestLinksInspectLinksStopped(c *check.C) {
    97  	var (
    98  		expected = map[string]struct{}{"/container1:/testinspectlink/alias1": {}, "/container2:/testinspectlink/alias2": {}}
    99  		result   []string
   100  	)
   101  	dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top")
   102  	dockerCmd(c, "run", "-d", "--name", "container2", "busybox", "top")
   103  	dockerCmd(c, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "true")
   104  	links, err := inspectFieldJSON("testinspectlink", "HostConfig.Links")
   105  	if err != nil {
   106  		c.Fatal(err)
   107  	}
   108  
   109  	err = unmarshalJSON([]byte(links), &result)
   110  	if err != nil {
   111  		c.Fatal(err)
   112  	}
   113  
   114  	output := convertSliceOfStringsToMap(result)
   115  
   116  	equal := reflect.DeepEqual(output, expected)
   117  
   118  	if !equal {
   119  		c.Fatalf("Links %s, but expected %s", result, expected)
   120  	}
   121  
   122  }
   123  
   124  func (s *DockerSuite) TestLinksNotStartedParentNotFail(c *check.C) {
   125  
   126  	dockerCmd(c, "create", "--name=first", "busybox", "top")
   127  	dockerCmd(c, "create", "--name=second", "--link=first:first", "busybox", "top")
   128  	dockerCmd(c, "start", "first")
   129  
   130  }
   131  
   132  func (s *DockerSuite) TestLinksHostsFilesInject(c *check.C) {
   133  	testRequires(c, SameHostDaemon, ExecSupport)
   134  
   135  	out, _ := dockerCmd(c, "run", "-itd", "--name", "one", "busybox", "top")
   136  	idOne := strings.TrimSpace(out)
   137  
   138  	out, _ = dockerCmd(c, "run", "-itd", "--name", "two", "--link", "one:onetwo", "busybox", "top")
   139  	idTwo := strings.TrimSpace(out)
   140  
   141  	time.Sleep(1 * time.Second)
   142  
   143  	contentOne, err := readContainerFileWithExec(idOne, "/etc/hosts")
   144  	if err != nil {
   145  		c.Fatal(err, string(contentOne))
   146  	}
   147  
   148  	contentTwo, err := readContainerFileWithExec(idTwo, "/etc/hosts")
   149  	if err != nil {
   150  		c.Fatal(err, string(contentTwo))
   151  	}
   152  
   153  	if !strings.Contains(string(contentTwo), "onetwo") {
   154  		c.Fatal("Host is not present in updated hosts file", string(contentTwo))
   155  	}
   156  
   157  }
   158  
   159  func (s *DockerSuite) TestLinksUpdateOnRestart(c *check.C) {
   160  	testRequires(c, SameHostDaemon, ExecSupport)
   161  	dockerCmd(c, "run", "-d", "--name", "one", "busybox", "top")
   162  	out, _ := dockerCmd(c, "run", "-d", "--name", "two", "--link", "one:onetwo", "--link", "one:one", "busybox", "top")
   163  	id := strings.TrimSpace(string(out))
   164  
   165  	realIP, err := inspectField("one", "NetworkSettings.IPAddress")
   166  	if err != nil {
   167  		c.Fatal(err)
   168  	}
   169  	content, err := readContainerFileWithExec(id, "/etc/hosts")
   170  	if err != nil {
   171  		c.Fatal(err, string(content))
   172  	}
   173  	getIP := func(hosts []byte, hostname string) string {
   174  		re := regexp.MustCompile(fmt.Sprintf(`(\S*)\t%s`, regexp.QuoteMeta(hostname)))
   175  		matches := re.FindSubmatch(hosts)
   176  		if matches == nil {
   177  			c.Fatalf("Hostname %s have no matches in hosts", hostname)
   178  		}
   179  		return string(matches[1])
   180  	}
   181  	if ip := getIP(content, "one"); ip != realIP {
   182  		c.Fatalf("For 'one' alias expected IP: %s, got: %s", realIP, ip)
   183  	}
   184  	if ip := getIP(content, "onetwo"); ip != realIP {
   185  		c.Fatalf("For 'onetwo' alias expected IP: %s, got: %s", realIP, ip)
   186  	}
   187  	dockerCmd(c, "restart", "one")
   188  	realIP, err = inspectField("one", "NetworkSettings.IPAddress")
   189  	if err != nil {
   190  		c.Fatal(err)
   191  	}
   192  	content, err = readContainerFileWithExec(id, "/etc/hosts")
   193  	if err != nil {
   194  		c.Fatal(err, string(content))
   195  	}
   196  	if ip := getIP(content, "one"); ip != realIP {
   197  		c.Fatalf("For 'one' alias expected IP: %s, got: %s", realIP, ip)
   198  	}
   199  	if ip := getIP(content, "onetwo"); ip != realIP {
   200  		c.Fatalf("For 'onetwo' alias expected IP: %s, got: %s", realIP, ip)
   201  	}
   202  }
   203  
   204  func (s *DockerSuite) TestLinksEnvs(c *check.C) {
   205  	dockerCmd(c, "run", "-d", "-e", "e1=", "-e", "e2=v2", "-e", "e3=v3=v3", "--name=first", "busybox", "top")
   206  	out, _ := dockerCmd(c, "run", "--name=second", "--link=first:first", "busybox", "env")
   207  	if !strings.Contains(out, "FIRST_ENV_e1=\n") ||
   208  		!strings.Contains(out, "FIRST_ENV_e2=v2") ||
   209  		!strings.Contains(out, "FIRST_ENV_e3=v3=v3") {
   210  		c.Fatalf("Incorrect output: %s", out)
   211  	}
   212  }
   213  
   214  func (s *DockerSuite) TestLinkShortDefinition(c *check.C) {
   215  	out, _ := dockerCmd(c, "run", "-d", "--name", "shortlinkdef", "busybox", "top")
   216  
   217  	cid := strings.TrimSpace(out)
   218  	c.Assert(waitRun(cid), check.IsNil)
   219  
   220  	out, _ = dockerCmd(c, "run", "-d", "--name", "link2", "--link", "shortlinkdef", "busybox", "top")
   221  
   222  	cid2 := strings.TrimSpace(out)
   223  	c.Assert(waitRun(cid2), check.IsNil)
   224  
   225  	links, err := inspectFieldJSON(cid2, "HostConfig.Links")
   226  	c.Assert(err, check.IsNil)
   227  	c.Assert(links, check.Equals, "[\"/shortlinkdef:/link2/shortlinkdef\"]")
   228  }