github.com/fcwu/docker@v1.4.2-0.20150115145920-2a69ca89f0df/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 }