github.com/noxiouz/docker@v0.7.3-0.20160629055221-3d231c78e8c5/integration-cli/docker_cli_port_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "net" 6 "regexp" 7 "sort" 8 "strings" 9 10 "github.com/docker/docker/pkg/integration/checker" 11 "github.com/go-check/check" 12 ) 13 14 func (s *DockerSuite) TestPortList(c *check.C) { 15 testRequires(c, DaemonIsLinux) 16 // one port 17 out, _ := dockerCmd(c, "run", "-d", "-p", "9876:80", "busybox", "top") 18 firstID := strings.TrimSpace(out) 19 20 out, _ = dockerCmd(c, "port", firstID, "80") 21 22 err := assertPortList(c, out, []string{"0.0.0.0:9876"}) 23 // Port list is not correct 24 c.Assert(err, checker.IsNil) 25 26 out, _ = dockerCmd(c, "port", firstID) 27 28 err = assertPortList(c, out, []string{"80/tcp -> 0.0.0.0:9876"}) 29 // Port list is not correct 30 c.Assert(err, checker.IsNil) 31 32 dockerCmd(c, "rm", "-f", firstID) 33 34 // three port 35 out, _ = dockerCmd(c, "run", "-d", 36 "-p", "9876:80", 37 "-p", "9877:81", 38 "-p", "9878:82", 39 "busybox", "top") 40 ID := strings.TrimSpace(out) 41 42 out, _ = dockerCmd(c, "port", ID, "80") 43 44 err = assertPortList(c, out, []string{"0.0.0.0:9876"}) 45 // Port list is not correct 46 c.Assert(err, checker.IsNil) 47 48 out, _ = dockerCmd(c, "port", ID) 49 50 err = assertPortList(c, out, []string{ 51 "80/tcp -> 0.0.0.0:9876", 52 "81/tcp -> 0.0.0.0:9877", 53 "82/tcp -> 0.0.0.0:9878"}) 54 // Port list is not correct 55 c.Assert(err, checker.IsNil) 56 57 dockerCmd(c, "rm", "-f", ID) 58 59 // more and one port mapped to the same container port 60 out, _ = dockerCmd(c, "run", "-d", 61 "-p", "9876:80", 62 "-p", "9999:80", 63 "-p", "9877:81", 64 "-p", "9878:82", 65 "busybox", "top") 66 ID = strings.TrimSpace(out) 67 68 out, _ = dockerCmd(c, "port", ID, "80") 69 70 err = assertPortList(c, out, []string{"0.0.0.0:9876", "0.0.0.0:9999"}) 71 // Port list is not correct 72 c.Assert(err, checker.IsNil) 73 74 out, _ = dockerCmd(c, "port", ID) 75 76 err = assertPortList(c, out, []string{ 77 "80/tcp -> 0.0.0.0:9876", 78 "80/tcp -> 0.0.0.0:9999", 79 "81/tcp -> 0.0.0.0:9877", 80 "82/tcp -> 0.0.0.0:9878"}) 81 // Port list is not correct 82 c.Assert(err, checker.IsNil) 83 dockerCmd(c, "rm", "-f", ID) 84 85 testRange := func() { 86 // host port ranges used 87 IDs := make([]string, 3) 88 for i := 0; i < 3; i++ { 89 out, _ = dockerCmd(c, "run", "-d", 90 "-p", "9090-9092:80", 91 "busybox", "top") 92 IDs[i] = strings.TrimSpace(out) 93 94 out, _ = dockerCmd(c, "port", IDs[i]) 95 96 err = assertPortList(c, out, []string{fmt.Sprintf("80/tcp -> 0.0.0.0:%d", 9090+i)}) 97 // Port list is not correct 98 c.Assert(err, checker.IsNil) 99 } 100 101 // test port range exhaustion 102 out, _, err = dockerCmdWithError("run", "-d", 103 "-p", "9090-9092:80", 104 "busybox", "top") 105 // Exhausted port range did not return an error 106 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 107 108 for i := 0; i < 3; i++ { 109 dockerCmd(c, "rm", "-f", IDs[i]) 110 } 111 } 112 testRange() 113 // Verify we ran re-use port ranges after they are no longer in use. 114 testRange() 115 116 // test invalid port ranges 117 for _, invalidRange := range []string{"9090-9089:80", "9090-:80", "-9090:80"} { 118 out, _, err = dockerCmdWithError("run", "-d", 119 "-p", invalidRange, 120 "busybox", "top") 121 // Port range should have returned an error 122 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 123 } 124 125 // test host range:container range spec. 126 out, _ = dockerCmd(c, "run", "-d", 127 "-p", "9800-9803:80-83", 128 "busybox", "top") 129 ID = strings.TrimSpace(out) 130 131 out, _ = dockerCmd(c, "port", ID) 132 133 err = assertPortList(c, out, []string{ 134 "80/tcp -> 0.0.0.0:9800", 135 "81/tcp -> 0.0.0.0:9801", 136 "82/tcp -> 0.0.0.0:9802", 137 "83/tcp -> 0.0.0.0:9803"}) 138 // Port list is not correct 139 c.Assert(err, checker.IsNil) 140 dockerCmd(c, "rm", "-f", ID) 141 142 // test mixing protocols in same port range 143 out, _ = dockerCmd(c, "run", "-d", 144 "-p", "8000-8080:80", 145 "-p", "8000-8080:80/udp", 146 "busybox", "top") 147 ID = strings.TrimSpace(out) 148 149 out, _ = dockerCmd(c, "port", ID) 150 151 err = assertPortList(c, out, []string{ 152 "80/tcp -> 0.0.0.0:8000", 153 "80/udp -> 0.0.0.0:8000"}) 154 // Port list is not correct 155 c.Assert(err, checker.IsNil) 156 dockerCmd(c, "rm", "-f", ID) 157 } 158 159 func assertPortList(c *check.C, out string, expected []string) error { 160 lines := strings.Split(strings.Trim(out, "\n "), "\n") 161 if len(lines) != len(expected) { 162 return fmt.Errorf("different size lists %s, %d, %d", out, len(lines), len(expected)) 163 } 164 sort.Strings(lines) 165 sort.Strings(expected) 166 167 for i := 0; i < len(expected); i++ { 168 if lines[i] != expected[i] { 169 return fmt.Errorf("|" + lines[i] + "!=" + expected[i] + "|") 170 } 171 } 172 173 return nil 174 } 175 176 func stopRemoveContainer(id string, c *check.C) { 177 dockerCmd(c, "rm", "-f", id) 178 } 179 180 func (s *DockerSuite) TestUnpublishedPortsInPsOutput(c *check.C) { 181 testRequires(c, DaemonIsLinux) 182 // Run busybox with command line expose (equivalent to EXPOSE in image's Dockerfile) for the following ports 183 port1 := 80 184 port2 := 443 185 expose1 := fmt.Sprintf("--expose=%d", port1) 186 expose2 := fmt.Sprintf("--expose=%d", port2) 187 dockerCmd(c, "run", "-d", expose1, expose2, "busybox", "sleep", "5") 188 189 // Check docker ps o/p for last created container reports the unpublished ports 190 unpPort1 := fmt.Sprintf("%d/tcp", port1) 191 unpPort2 := fmt.Sprintf("%d/tcp", port2) 192 out, _ := dockerCmd(c, "ps", "-n=1") 193 // Missing unpublished ports in docker ps output 194 c.Assert(out, checker.Contains, unpPort1) 195 // Missing unpublished ports in docker ps output 196 c.Assert(out, checker.Contains, unpPort2) 197 198 // Run the container forcing to publish the exposed ports 199 dockerCmd(c, "run", "-d", "-P", expose1, expose2, "busybox", "sleep", "5") 200 201 // Check docker ps o/p for last created container reports the exposed ports in the port bindings 202 expBndRegx1 := regexp.MustCompile(`0.0.0.0:\d\d\d\d\d->` + unpPort1) 203 expBndRegx2 := regexp.MustCompile(`0.0.0.0:\d\d\d\d\d->` + unpPort2) 204 out, _ = dockerCmd(c, "ps", "-n=1") 205 // Cannot find expected port binding port (0.0.0.0:xxxxx->unpPort1) in docker ps output 206 c.Assert(expBndRegx1.MatchString(out), checker.Equals, true, check.Commentf("out: %s; unpPort1: %s", out, unpPort1)) 207 // Cannot find expected port binding port (0.0.0.0:xxxxx->unpPort2) in docker ps output 208 c.Assert(expBndRegx2.MatchString(out), checker.Equals, true, check.Commentf("out: %s; unpPort2: %s", out, unpPort2)) 209 210 // Run the container specifying explicit port bindings for the exposed ports 211 offset := 10000 212 pFlag1 := fmt.Sprintf("%d:%d", offset+port1, port1) 213 pFlag2 := fmt.Sprintf("%d:%d", offset+port2, port2) 214 out, _ = dockerCmd(c, "run", "-d", "-p", pFlag1, "-p", pFlag2, expose1, expose2, "busybox", "sleep", "5") 215 id := strings.TrimSpace(out) 216 217 // Check docker ps o/p for last created container reports the specified port mappings 218 expBnd1 := fmt.Sprintf("0.0.0.0:%d->%s", offset+port1, unpPort1) 219 expBnd2 := fmt.Sprintf("0.0.0.0:%d->%s", offset+port2, unpPort2) 220 out, _ = dockerCmd(c, "ps", "-n=1") 221 // Cannot find expected port binding (expBnd1) in docker ps output 222 c.Assert(out, checker.Contains, expBnd1) 223 // Cannot find expected port binding (expBnd2) in docker ps output 224 c.Assert(out, checker.Contains, expBnd2) 225 226 // Remove container now otherwise it will interfere with next test 227 stopRemoveContainer(id, c) 228 229 // Run the container with explicit port bindings and no exposed ports 230 out, _ = dockerCmd(c, "run", "-d", "-p", pFlag1, "-p", pFlag2, "busybox", "sleep", "5") 231 id = strings.TrimSpace(out) 232 233 // Check docker ps o/p for last created container reports the specified port mappings 234 out, _ = dockerCmd(c, "ps", "-n=1") 235 // Cannot find expected port binding (expBnd1) in docker ps output 236 c.Assert(out, checker.Contains, expBnd1) 237 // Cannot find expected port binding (expBnd2) in docker ps output 238 c.Assert(out, checker.Contains, expBnd2) 239 // Remove container now otherwise it will interfere with next test 240 stopRemoveContainer(id, c) 241 242 // Run the container with one unpublished exposed port and one explicit port binding 243 dockerCmd(c, "run", "-d", expose1, "-p", pFlag2, "busybox", "sleep", "5") 244 245 // Check docker ps o/p for last created container reports the specified unpublished port and port mapping 246 out, _ = dockerCmd(c, "ps", "-n=1") 247 // Missing unpublished exposed ports (unpPort1) in docker ps output 248 c.Assert(out, checker.Contains, unpPort1) 249 // Missing port binding (expBnd2) in docker ps output 250 c.Assert(out, checker.Contains, expBnd2) 251 } 252 253 func (s *DockerSuite) TestPortHostBinding(c *check.C) { 254 testRequires(c, DaemonIsLinux, NotUserNamespace) 255 out, _ := dockerCmd(c, "run", "-d", "-p", "9876:80", "busybox", 256 "nc", "-l", "-p", "80") 257 firstID := strings.TrimSpace(out) 258 259 out, _ = dockerCmd(c, "port", firstID, "80") 260 261 err := assertPortList(c, out, []string{"0.0.0.0:9876"}) 262 // Port list is not correct 263 c.Assert(err, checker.IsNil) 264 265 dockerCmd(c, "run", "--net=host", "busybox", 266 "nc", "localhost", "9876") 267 268 dockerCmd(c, "rm", "-f", firstID) 269 270 out, _, err = dockerCmdWithError("run", "--net=host", "busybox", "nc", "localhost", "9876") 271 // Port is still bound after the Container is removed 272 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 273 } 274 275 func (s *DockerSuite) TestPortExposeHostBinding(c *check.C) { 276 testRequires(c, DaemonIsLinux, NotUserNamespace) 277 out, _ := dockerCmd(c, "run", "-d", "-P", "--expose", "80", "busybox", 278 "nc", "-l", "-p", "80") 279 firstID := strings.TrimSpace(out) 280 281 out, _ = dockerCmd(c, "port", firstID, "80") 282 283 _, exposedPort, err := net.SplitHostPort(out) 284 c.Assert(err, checker.IsNil, check.Commentf("out: %s", out)) 285 286 dockerCmd(c, "run", "--net=host", "busybox", 287 "nc", "localhost", strings.TrimSpace(exposedPort)) 288 289 dockerCmd(c, "rm", "-f", firstID) 290 291 out, _, err = dockerCmdWithError("run", "--net=host", "busybox", 292 "nc", "localhost", strings.TrimSpace(exposedPort)) 293 // Port is still bound after the Container is removed 294 c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) 295 } 296 297 func (s *DockerSuite) TestPortBindingOnSandbox(c *check.C) { 298 testRequires(c, DaemonIsLinux, NotUserNamespace) 299 dockerCmd(c, "network", "create", "--internal", "-d", "bridge", "internal-net") 300 nr := getNetworkResource(c, "internal-net") 301 c.Assert(nr.Internal, checker.Equals, true) 302 303 dockerCmd(c, "run", "--net", "internal-net", "-d", "--name", "c1", 304 "-p", "8080:8080", "busybox", "nc", "-l", "-p", "8080") 305 c.Assert(waitRun("c1"), check.IsNil) 306 307 _, _, err := dockerCmdWithError("run", "--net=host", "busybox", "nc", "localhost", "8080") 308 c.Assert(err, check.NotNil, 309 check.Commentf("Port mapping on internal network is expected to fail")) 310 311 // Connect container to another normal bridge network 312 dockerCmd(c, "network", "create", "-d", "bridge", "foo-net") 313 dockerCmd(c, "network", "connect", "foo-net", "c1") 314 315 _, _, err = dockerCmdWithError("run", "--net=host", "busybox", "nc", "localhost", "8080") 316 c.Assert(err, check.IsNil, 317 check.Commentf("Port mapping on the new network is expected to succeed")) 318 319 }