github.com/jandre/docker@v1.7.0/integration-cli/docker_cli_port_test.go (about)

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