github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/integration-cli/docker_cli_ps_test.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"os/exec"
     8  	"path/filepath"
     9  	"sort"
    10  	"strconv"
    11  	"strings"
    12  	"time"
    13  
    14  	"github.com/docker/docker/pkg/integration/checker"
    15  	"github.com/docker/docker/pkg/stringid"
    16  	"github.com/go-check/check"
    17  )
    18  
    19  func (s *DockerSuite) TestPsListContainersBase(c *check.C) {
    20  	testRequires(c, DaemonIsLinux)
    21  	out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
    22  	firstID := strings.TrimSpace(out)
    23  
    24  	out, _ = dockerCmd(c, "run", "-d", "busybox", "top")
    25  	secondID := strings.TrimSpace(out)
    26  
    27  	// not long running
    28  	out, _ = dockerCmd(c, "run", "-d", "busybox", "true")
    29  	thirdID := strings.TrimSpace(out)
    30  
    31  	out, _ = dockerCmd(c, "run", "-d", "busybox", "top")
    32  	fourthID := strings.TrimSpace(out)
    33  
    34  	// make sure the second is running
    35  	c.Assert(waitRun(secondID), checker.IsNil)
    36  
    37  	// make sure third one is not running
    38  	dockerCmd(c, "wait", thirdID)
    39  
    40  	// make sure the forth is running
    41  	c.Assert(waitRun(fourthID), checker.IsNil)
    42  
    43  	// all
    44  	out, _ = dockerCmd(c, "ps", "-a")
    45  	c.Assert(assertContainerList(out, []string{fourthID, thirdID, secondID, firstID}), checker.Equals, true, check.Commentf("ALL: Container list is not in the correct order: \n%s", out))
    46  
    47  	// running
    48  	out, _ = dockerCmd(c, "ps")
    49  	c.Assert(assertContainerList(out, []string{fourthID, secondID, firstID}), checker.Equals, true, check.Commentf("RUNNING: Container list is not in the correct order: \n%s", out))
    50  
    51  	// from here all flag '-a' is ignored
    52  
    53  	// limit
    54  	out, _ = dockerCmd(c, "ps", "-n=2", "-a")
    55  	expected := []string{fourthID, thirdID}
    56  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("LIMIT & ALL: Container list is not in the correct order: \n%s", out))
    57  
    58  	out, _ = dockerCmd(c, "ps", "-n=2")
    59  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("LIMIT: Container list is not in the correct order: \n%s", out))
    60  
    61  	// filter since
    62  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-a")
    63  	expected = []string{fourthID, thirdID, secondID}
    64  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE & ALL: Container list is not in the correct order: \n%s", out))
    65  
    66  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID)
    67  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE: Container list is not in the correct order: \n%s", out))
    68  
    69  	// filter before
    70  	out, _ = dockerCmd(c, "ps", "-f", "before="+thirdID, "-a")
    71  	expected = []string{secondID, firstID}
    72  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE & ALL: Container list is not in the correct order: \n%s", out))
    73  
    74  	out, _ = dockerCmd(c, "ps", "-f", "before="+thirdID)
    75  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE: Container list is not in the correct order: \n%s", out))
    76  
    77  	// filter since & before
    78  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID, "-a")
    79  	expected = []string{thirdID, secondID}
    80  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE, BEFORE & ALL: Container list is not in the correct order: \n%s", out))
    81  
    82  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID)
    83  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE, BEFORE: Container list is not in the correct order: \n%s", out))
    84  
    85  	// filter since & limit
    86  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-n=2", "-a")
    87  	expected = []string{fourthID, thirdID}
    88  
    89  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE, LIMIT & ALL: Container list is not in the correct order: \n%s", out))
    90  
    91  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-n=2")
    92  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE, LIMIT: Container list is not in the correct order: \n%s", out))
    93  
    94  	// filter before & limit
    95  	out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID, "-n=1", "-a")
    96  	expected = []string{thirdID}
    97  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE, LIMIT & ALL: Container list is not in the correct order: \n%s", out))
    98  
    99  	out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID, "-n=1")
   100  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE, LIMIT: Container list is not in the correct order: \n%s", out))
   101  
   102  	// filter since & filter before & limit
   103  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID, "-n=1", "-a")
   104  	expected = []string{thirdID}
   105  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE, BEFORE, LIMIT & ALL: Container list is not in the correct order: \n%s", out))
   106  
   107  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID, "-n=1")
   108  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE, BEFORE, LIMIT: Container list is not in the correct order: \n%s", out))
   109  
   110  }
   111  
   112  func assertContainerList(out string, expected []string) bool {
   113  	lines := strings.Split(strings.Trim(out, "\n "), "\n")
   114  	if len(lines)-1 != len(expected) {
   115  		return false
   116  	}
   117  
   118  	containerIDIndex := strings.Index(lines[0], "CONTAINER ID")
   119  	for i := 0; i < len(expected); i++ {
   120  		foundID := lines[i+1][containerIDIndex : containerIDIndex+12]
   121  		if foundID != expected[i][:12] {
   122  			return false
   123  		}
   124  	}
   125  
   126  	return true
   127  }
   128  
   129  func (s *DockerSuite) TestPsListContainersSize(c *check.C) {
   130  	testRequires(c, DaemonIsLinux)
   131  	dockerCmd(c, "run", "-d", "busybox", "echo", "hello")
   132  
   133  	baseOut, _ := dockerCmd(c, "ps", "-s", "-n=1")
   134  	baseLines := strings.Split(strings.Trim(baseOut, "\n "), "\n")
   135  	baseSizeIndex := strings.Index(baseLines[0], "SIZE")
   136  	baseFoundsize := baseLines[1][baseSizeIndex:]
   137  	baseBytes, err := strconv.Atoi(strings.Split(baseFoundsize, " ")[0])
   138  	c.Assert(err, checker.IsNil)
   139  
   140  	name := "test_size"
   141  	out, _ := dockerCmd(c, "run", "--name", name, "busybox", "sh", "-c", "echo 1 > test")
   142  	id, err := getIDByName(name)
   143  	c.Assert(err, checker.IsNil)
   144  
   145  	runCmd := exec.Command(dockerBinary, "ps", "-s", "-n=1")
   146  
   147  	wait := make(chan struct{})
   148  	go func() {
   149  		out, _, err = runCommandWithOutput(runCmd)
   150  		close(wait)
   151  	}()
   152  	select {
   153  	case <-wait:
   154  	case <-time.After(3 * time.Second):
   155  		c.Fatalf("Calling \"docker ps -s\" timed out!")
   156  	}
   157  	c.Assert(err, checker.IsNil)
   158  	lines := strings.Split(strings.Trim(out, "\n "), "\n")
   159  	c.Assert(lines, checker.HasLen, 2, check.Commentf("Expected 2 lines for 'ps -s -n=1' output, got %d", len(lines)))
   160  	sizeIndex := strings.Index(lines[0], "SIZE")
   161  	idIndex := strings.Index(lines[0], "CONTAINER ID")
   162  	foundID := lines[1][idIndex : idIndex+12]
   163  	c.Assert(foundID, checker.Equals, id[:12], check.Commentf("Expected id %s, got %s", id[:12], foundID))
   164  	expectedSize := fmt.Sprintf("%d B", (2 + baseBytes))
   165  	foundSize := lines[1][sizeIndex:]
   166  	c.Assert(foundSize, checker.Contains, expectedSize, check.Commentf("Expected size %q, got %q", expectedSize, foundSize))
   167  
   168  }
   169  
   170  func (s *DockerSuite) TestPsListContainersFilterStatus(c *check.C) {
   171  	testRequires(c, DaemonIsLinux)
   172  
   173  	// start exited container
   174  	out, _ := dockerCmd(c, "run", "-d", "busybox")
   175  	firstID := strings.TrimSpace(out)
   176  
   177  	// make sure the exited container is not running
   178  	dockerCmd(c, "wait", firstID)
   179  
   180  	// start running container
   181  	out, _ = dockerCmd(c, "run", "-itd", "busybox")
   182  	secondID := strings.TrimSpace(out)
   183  
   184  	// filter containers by exited
   185  	out, _ = dockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=exited")
   186  	containerOut := strings.TrimSpace(out)
   187  	c.Assert(containerOut, checker.Equals, firstID)
   188  
   189  	out, _ = dockerCmd(c, "ps", "-a", "--no-trunc", "-q", "--filter=status=running")
   190  	containerOut = strings.TrimSpace(out)
   191  	c.Assert(containerOut, checker.Equals, secondID)
   192  
   193  	out, _, _ = dockerCmdWithTimeout(time.Second*60, "ps", "-a", "-q", "--filter=status=rubbish")
   194  	c.Assert(out, checker.Contains, "Unrecognised filter value for status", check.Commentf("Expected error response due to invalid status filter output: %q", out))
   195  
   196  	// pause running container
   197  	out, _ = dockerCmd(c, "run", "-itd", "busybox")
   198  	pausedID := strings.TrimSpace(out)
   199  	dockerCmd(c, "pause", pausedID)
   200  	// make sure the container is unpaused to let the daemon stop it properly
   201  	defer func() { dockerCmd(c, "unpause", pausedID) }()
   202  
   203  	out, _ = dockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=paused")
   204  	containerOut = strings.TrimSpace(out)
   205  	c.Assert(containerOut, checker.Equals, pausedID)
   206  }
   207  
   208  func (s *DockerSuite) TestPsListContainersFilterID(c *check.C) {
   209  	testRequires(c, DaemonIsLinux)
   210  	// start container
   211  	out, _ := dockerCmd(c, "run", "-d", "busybox")
   212  	firstID := strings.TrimSpace(out)
   213  
   214  	// start another container
   215  	dockerCmd(c, "run", "-d", "busybox", "top")
   216  
   217  	// filter containers by id
   218  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--filter=id="+firstID)
   219  	containerOut := strings.TrimSpace(out)
   220  	c.Assert(containerOut, checker.Equals, firstID[:12], check.Commentf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out))
   221  
   222  }
   223  
   224  func (s *DockerSuite) TestPsListContainersFilterName(c *check.C) {
   225  	testRequires(c, DaemonIsLinux)
   226  	// start container
   227  	out, _ := dockerCmd(c, "run", "-d", "--name=a_name_to_match", "busybox")
   228  	firstID := strings.TrimSpace(out)
   229  
   230  	// start another container
   231  	dockerCmd(c, "run", "-d", "--name=b_name_to_match", "busybox", "top")
   232  
   233  	// filter containers by name
   234  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--filter=name=a_name_to_match")
   235  	containerOut := strings.TrimSpace(out)
   236  	c.Assert(containerOut, checker.Equals, firstID[:12], check.Commentf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out))
   237  
   238  }
   239  
   240  // Test for the ancestor filter for ps.
   241  // There is also the same test but with image:tag@digest in docker_cli_by_digest_test.go
   242  //
   243  // What the test setups :
   244  // - Create 2 image based on busybox using the same repository but different tags
   245  // - Create an image based on the previous image (images_ps_filter_test2)
   246  // - Run containers for each of those image (busybox, images_ps_filter_test1, images_ps_filter_test2)
   247  // - Filter them out :P
   248  func (s *DockerSuite) TestPsListContainersFilterAncestorImage(c *check.C) {
   249  	testRequires(c, DaemonIsLinux)
   250  	// Build images
   251  	imageName1 := "images_ps_filter_test1"
   252  	imageID1, err := buildImage(imageName1,
   253  		`FROM busybox
   254  		 LABEL match me 1`, true)
   255  	c.Assert(err, checker.IsNil)
   256  
   257  	imageName1Tagged := "images_ps_filter_test1:tag"
   258  	imageID1Tagged, err := buildImage(imageName1Tagged,
   259  		`FROM busybox
   260  		 LABEL match me 1 tagged`, true)
   261  	c.Assert(err, checker.IsNil)
   262  
   263  	imageName2 := "images_ps_filter_test2"
   264  	imageID2, err := buildImage(imageName2,
   265  		fmt.Sprintf(`FROM %s
   266  		 LABEL match me 2`, imageName1), true)
   267  	c.Assert(err, checker.IsNil)
   268  
   269  	// start containers
   270  	out, _ := dockerCmd(c, "run", "-d", "busybox", "echo", "hello")
   271  	firstID := strings.TrimSpace(out)
   272  
   273  	// start another container
   274  	out, _ = dockerCmd(c, "run", "-d", "busybox", "echo", "hello")
   275  	secondID := strings.TrimSpace(out)
   276  
   277  	// start third container
   278  	out, _ = dockerCmd(c, "run", "-d", imageName1, "echo", "hello")
   279  	thirdID := strings.TrimSpace(out)
   280  
   281  	// start fourth container
   282  	out, _ = dockerCmd(c, "run", "-d", imageName1Tagged, "echo", "hello")
   283  	fourthID := strings.TrimSpace(out)
   284  
   285  	// start fifth container
   286  	out, _ = dockerCmd(c, "run", "-d", imageName2, "echo", "hello")
   287  	fifthID := strings.TrimSpace(out)
   288  
   289  	var filterTestSuite = []struct {
   290  		filterName  string
   291  		expectedIDs []string
   292  	}{
   293  		// non existent stuff
   294  		{"nonexistent", []string{}},
   295  		{"nonexistent:tag", []string{}},
   296  		// image
   297  		{"busybox", []string{firstID, secondID, thirdID, fourthID, fifthID}},
   298  		{imageName1, []string{thirdID, fifthID}},
   299  		{imageName2, []string{fifthID}},
   300  		// image:tag
   301  		{fmt.Sprintf("%s:latest", imageName1), []string{thirdID, fifthID}},
   302  		{imageName1Tagged, []string{fourthID}},
   303  		// short-id
   304  		{stringid.TruncateID(imageID1), []string{thirdID, fifthID}},
   305  		{stringid.TruncateID(imageID2), []string{fifthID}},
   306  		// full-id
   307  		{imageID1, []string{thirdID, fifthID}},
   308  		{imageID1Tagged, []string{fourthID}},
   309  		{imageID2, []string{fifthID}},
   310  	}
   311  
   312  	for _, filter := range filterTestSuite {
   313  		out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+filter.filterName)
   314  		checkPsAncestorFilterOutput(c, out, filter.filterName, filter.expectedIDs)
   315  	}
   316  
   317  	// Multiple ancestor filter
   318  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+imageName2, "--filter=ancestor="+imageName1Tagged)
   319  	checkPsAncestorFilterOutput(c, out, imageName2+","+imageName1Tagged, []string{fourthID, fifthID})
   320  }
   321  
   322  func checkPsAncestorFilterOutput(c *check.C, out string, filterName string, expectedIDs []string) {
   323  	actualIDs := []string{}
   324  	if out != "" {
   325  		actualIDs = strings.Split(out[:len(out)-1], "\n")
   326  	}
   327  	sort.Strings(actualIDs)
   328  	sort.Strings(expectedIDs)
   329  
   330  	c.Assert(actualIDs, checker.HasLen, len(expectedIDs), check.Commentf("Expected filtered container(s) for %s ancestor filter to be %v:%v, got %v:%v", filterName, len(expectedIDs), expectedIDs, len(actualIDs), actualIDs))
   331  	if len(expectedIDs) > 0 {
   332  		same := true
   333  		for i := range expectedIDs {
   334  			if actualIDs[i] != expectedIDs[i] {
   335  				c.Logf("%s, %s", actualIDs[i], expectedIDs[i])
   336  				same = false
   337  				break
   338  			}
   339  		}
   340  		c.Assert(same, checker.Equals, true, check.Commentf("Expected filtered container(s) for %s ancestor filter to be %v, got %v", filterName, expectedIDs, actualIDs))
   341  	}
   342  }
   343  
   344  func (s *DockerSuite) TestPsListContainersFilterLabel(c *check.C) {
   345  	testRequires(c, DaemonIsLinux)
   346  	// start container
   347  	out, _ := dockerCmd(c, "run", "-d", "-l", "match=me", "-l", "second=tag", "busybox")
   348  	firstID := strings.TrimSpace(out)
   349  
   350  	// start another container
   351  	out, _ = dockerCmd(c, "run", "-d", "-l", "match=me too", "busybox")
   352  	secondID := strings.TrimSpace(out)
   353  
   354  	// start third container
   355  	out, _ = dockerCmd(c, "run", "-d", "-l", "nomatch=me", "busybox")
   356  	thirdID := strings.TrimSpace(out)
   357  
   358  	// filter containers by exact match
   359  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me")
   360  	containerOut := strings.TrimSpace(out)
   361  	c.Assert(containerOut, checker.Equals, firstID, check.Commentf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out))
   362  
   363  	// filter containers by two labels
   364  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me", "--filter=label=second=tag")
   365  	containerOut = strings.TrimSpace(out)
   366  	c.Assert(containerOut, checker.Equals, firstID, check.Commentf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out))
   367  
   368  	// filter containers by two labels, but expect not found because of AND behavior
   369  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me", "--filter=label=second=tag-no")
   370  	containerOut = strings.TrimSpace(out)
   371  	c.Assert(containerOut, checker.Equals, "", check.Commentf("Expected nothing, got %s for exited filter, output: %q", containerOut, out))
   372  
   373  	// filter containers by exact key
   374  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match")
   375  	containerOut = strings.TrimSpace(out)
   376  	c.Assert(containerOut, checker.Contains, firstID)
   377  	c.Assert(containerOut, checker.Contains, secondID)
   378  	c.Assert(containerOut, checker.Not(checker.Contains), thirdID)
   379  }
   380  
   381  func (s *DockerSuite) TestPsListContainersFilterExited(c *check.C) {
   382  	testRequires(c, DaemonIsLinux)
   383  	dockerCmd(c, "run", "-d", "--name", "top", "busybox", "top")
   384  
   385  	dockerCmd(c, "run", "--name", "zero1", "busybox", "true")
   386  	firstZero, err := getIDByName("zero1")
   387  	c.Assert(err, checker.IsNil)
   388  
   389  	dockerCmd(c, "run", "--name", "zero2", "busybox", "true")
   390  	secondZero, err := getIDByName("zero2")
   391  	c.Assert(err, checker.IsNil)
   392  
   393  	out, _, err := dockerCmdWithError("run", "--name", "nonzero1", "busybox", "false")
   394  	c.Assert(err, checker.NotNil, check.Commentf("Should fail.", out, err))
   395  
   396  	firstNonZero, err := getIDByName("nonzero1")
   397  	c.Assert(err, checker.IsNil)
   398  
   399  	out, _, err = dockerCmdWithError("run", "--name", "nonzero2", "busybox", "false")
   400  	c.Assert(err, checker.NotNil, check.Commentf("Should fail.", out, err))
   401  	secondNonZero, err := getIDByName("nonzero2")
   402  	c.Assert(err, checker.IsNil)
   403  
   404  	// filter containers by exited=0
   405  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=exited=0")
   406  	ids := strings.Split(strings.TrimSpace(out), "\n")
   407  	c.Assert(ids, checker.HasLen, 2, check.Commentf("Should be 2 zero exited containers got %d: %s", len(ids), out))
   408  	c.Assert(ids[0], checker.Equals, secondZero, check.Commentf("First in list should be %q, got %q", secondZero, ids[0]))
   409  	c.Assert(ids[1], checker.Equals, firstZero, check.Commentf("Second in list should be %q, got %q", firstZero, ids[1]))
   410  
   411  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=exited=1")
   412  	ids = strings.Split(strings.TrimSpace(out), "\n")
   413  	c.Assert(ids, checker.HasLen, 2, check.Commentf("Should be 2 zero exited containers got %d", len(ids)))
   414  	c.Assert(ids[0], checker.Equals, secondNonZero, check.Commentf("First in list should be %q, got %q", secondNonZero, ids[0]))
   415  	c.Assert(ids[1], checker.Equals, firstNonZero, check.Commentf("Second in list should be %q, got %q", firstNonZero, ids[1]))
   416  
   417  }
   418  
   419  func (s *DockerSuite) TestPsRightTagName(c *check.C) {
   420  	testRequires(c, DaemonIsLinux)
   421  	tag := "asybox:shmatest"
   422  	dockerCmd(c, "tag", "busybox", tag)
   423  
   424  	var id1 string
   425  	out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
   426  	id1 = strings.TrimSpace(string(out))
   427  
   428  	var id2 string
   429  	out, _ = dockerCmd(c, "run", "-d", tag, "top")
   430  	id2 = strings.TrimSpace(string(out))
   431  
   432  	var imageID string
   433  	out, _ = dockerCmd(c, "inspect", "-f", "{{.Id}}", "busybox")
   434  	imageID = strings.TrimSpace(string(out))
   435  
   436  	var id3 string
   437  	out, _ = dockerCmd(c, "run", "-d", imageID, "top")
   438  	id3 = strings.TrimSpace(string(out))
   439  
   440  	out, _ = dockerCmd(c, "ps", "--no-trunc")
   441  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   442  	// skip header
   443  	lines = lines[1:]
   444  	c.Assert(lines, checker.HasLen, 3, check.Commentf("There should be 3 running container, got %d", len(lines)))
   445  	for _, line := range lines {
   446  		f := strings.Fields(line)
   447  		switch f[0] {
   448  		case id1:
   449  			c.Assert(f[1], checker.Equals, "busybox", check.Commentf("Expected %s tag for id %s, got %s", "busybox", id1, f[1]))
   450  		case id2:
   451  			c.Assert(f[1], checker.Equals, tag, check.Commentf("Expected %s tag for id %s, got %s", tag, id2, f[1]))
   452  		case id3:
   453  			c.Assert(f[1], checker.Equals, imageID, check.Commentf("Expected %s imageID for id %s, got %s", tag, id3, f[1]))
   454  		default:
   455  			c.Fatalf("Unexpected id %s, expected %s and %s and %s", f[0], id1, id2, id3)
   456  		}
   457  	}
   458  }
   459  
   460  func (s *DockerSuite) TestPsLinkedWithNoTrunc(c *check.C) {
   461  	testRequires(c, DaemonIsLinux)
   462  	dockerCmd(c, "run", "--name=first", "-d", "busybox", "top")
   463  	dockerCmd(c, "run", "--name=second", "--link=first:first", "-d", "busybox", "top")
   464  
   465  	out, _ := dockerCmd(c, "ps", "--no-trunc")
   466  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   467  	// strip header
   468  	lines = lines[1:]
   469  	expected := []string{"second", "first,second/first"}
   470  	var names []string
   471  	for _, l := range lines {
   472  		fields := strings.Fields(l)
   473  		names = append(names, fields[len(fields)-1])
   474  	}
   475  	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array: %v, got: %v", expected, names))
   476  }
   477  
   478  func (s *DockerSuite) TestPsGroupPortRange(c *check.C) {
   479  	testRequires(c, DaemonIsLinux)
   480  	portRange := "3800-3900"
   481  	dockerCmd(c, "run", "-d", "--name", "porttest", "-p", portRange+":"+portRange, "busybox", "top")
   482  
   483  	out, _ := dockerCmd(c, "ps")
   484  
   485  	c.Assert(string(out), checker.Contains, portRange, check.Commentf("docker ps output should have had the port range %q: %s", portRange, string(out)))
   486  
   487  }
   488  
   489  func (s *DockerSuite) TestPsWithSize(c *check.C) {
   490  	testRequires(c, DaemonIsLinux)
   491  	dockerCmd(c, "run", "-d", "--name", "sizetest", "busybox", "top")
   492  
   493  	out, _ := dockerCmd(c, "ps", "--size")
   494  	c.Assert(out, checker.Contains, "virtual", check.Commentf("docker ps with --size should show virtual size of container"))
   495  }
   496  
   497  func (s *DockerSuite) TestPsListContainersFilterCreated(c *check.C) {
   498  	testRequires(c, DaemonIsLinux)
   499  	// create a container
   500  	out, _ := dockerCmd(c, "create", "busybox")
   501  	cID := strings.TrimSpace(out)
   502  	shortCID := cID[:12]
   503  
   504  	// Make sure it DOESN'T show up w/o a '-a' for normal 'ps'
   505  	out, _ = dockerCmd(c, "ps", "-q")
   506  	c.Assert(out, checker.Not(checker.Contains), shortCID, check.Commentf("Should have not seen '%s' in ps output:\n%s", shortCID, out))
   507  
   508  	// Make sure it DOES show up as 'Created' for 'ps -a'
   509  	out, _ = dockerCmd(c, "ps", "-a")
   510  
   511  	hits := 0
   512  	for _, line := range strings.Split(out, "\n") {
   513  		if !strings.Contains(line, shortCID) {
   514  			continue
   515  		}
   516  		hits++
   517  		c.Assert(line, checker.Contains, "Created", check.Commentf("Missing 'Created' on '%s'", line))
   518  	}
   519  
   520  	c.Assert(hits, checker.Equals, 1, check.Commentf("Should have seen '%s' in ps -a output once:%d\n%s", shortCID, hits, out))
   521  
   522  	// filter containers by 'create' - note, no -a needed
   523  	out, _ = dockerCmd(c, "ps", "-q", "-f", "status=created")
   524  	containerOut := strings.TrimSpace(out)
   525  	c.Assert(cID, checker.HasPrefix, containerOut)
   526  }
   527  
   528  func (s *DockerSuite) TestPsFormatMultiNames(c *check.C) {
   529  	testRequires(c, DaemonIsLinux)
   530  	//create 2 containers and link them
   531  	dockerCmd(c, "run", "--name=child", "-d", "busybox", "top")
   532  	dockerCmd(c, "run", "--name=parent", "--link=child:linkedone", "-d", "busybox", "top")
   533  
   534  	//use the new format capabilities to only list the names and --no-trunc to get all names
   535  	out, _ := dockerCmd(c, "ps", "--format", "{{.Names}}", "--no-trunc")
   536  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   537  	expected := []string{"parent", "child,parent/linkedone"}
   538  	var names []string
   539  	for _, l := range lines {
   540  		names = append(names, l)
   541  	}
   542  	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with non-truncated names: %v, got: %v", expected, names))
   543  
   544  	//now list without turning off truncation and make sure we only get the non-link names
   545  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}}")
   546  	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
   547  	expected = []string{"parent", "child"}
   548  	var truncNames []string
   549  	for _, l := range lines {
   550  		truncNames = append(truncNames, l)
   551  	}
   552  	c.Assert(expected, checker.DeepEquals, truncNames, check.Commentf("Expected array with truncated names: %v, got: %v", expected, truncNames))
   553  
   554  }
   555  
   556  func (s *DockerSuite) TestPsFormatHeaders(c *check.C) {
   557  	testRequires(c, DaemonIsLinux)
   558  	// make sure no-container "docker ps" still prints the header row
   559  	out, _ := dockerCmd(c, "ps", "--format", "table {{.ID}}")
   560  	c.Assert(out, checker.Equals, "CONTAINER ID\n", check.Commentf(`Expected 'CONTAINER ID\n', got %v`, out))
   561  
   562  	// verify that "docker ps" with a container still prints the header row also
   563  	dockerCmd(c, "run", "--name=test", "-d", "busybox", "top")
   564  	out, _ = dockerCmd(c, "ps", "--format", "table {{.Names}}")
   565  	c.Assert(out, checker.Equals, "NAMES\ntest\n", check.Commentf(`Expected 'NAMES\ntest\n', got %v`, out))
   566  }
   567  
   568  func (s *DockerSuite) TestPsDefaultFormatAndQuiet(c *check.C) {
   569  	testRequires(c, DaemonIsLinux)
   570  	config := `{
   571  		"psFormat": "{{ .ID }} default"
   572  }`
   573  	d, err := ioutil.TempDir("", "integration-cli-")
   574  	c.Assert(err, checker.IsNil)
   575  	defer os.RemoveAll(d)
   576  
   577  	err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644)
   578  	c.Assert(err, checker.IsNil)
   579  
   580  	out, _ := dockerCmd(c, "run", "--name=test", "-d", "busybox", "top")
   581  	id := strings.TrimSpace(out)
   582  
   583  	out, _ = dockerCmd(c, "--config", d, "ps", "-q")
   584  	c.Assert(id, checker.HasPrefix, strings.TrimSpace(out), check.Commentf("Expected to print only the container id, got %v\n", out))
   585  }
   586  
   587  // Test for GitHub issue #12595
   588  func (s *DockerSuite) TestPsImageIDAfterUpdate(c *check.C) {
   589  	testRequires(c, DaemonIsLinux)
   590  
   591  	originalImageName := "busybox:TestPsImageIDAfterUpdate-original"
   592  	updatedImageName := "busybox:TestPsImageIDAfterUpdate-updated"
   593  
   594  	runCmd := exec.Command(dockerBinary, "tag", "busybox:latest", originalImageName)
   595  	out, _, err := runCommandWithOutput(runCmd)
   596  	c.Assert(err, checker.IsNil)
   597  
   598  	originalImageID, err := getIDByName(originalImageName)
   599  	c.Assert(err, checker.IsNil)
   600  
   601  	runCmd = exec.Command(dockerBinary, "run", "-d", originalImageName, "top")
   602  	out, _, err = runCommandWithOutput(runCmd)
   603  	c.Assert(err, checker.IsNil)
   604  	containerID := strings.TrimSpace(out)
   605  
   606  	linesOut, err := exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput()
   607  	c.Assert(err, checker.IsNil)
   608  
   609  	lines := strings.Split(strings.TrimSpace(string(linesOut)), "\n")
   610  	// skip header
   611  	lines = lines[1:]
   612  	c.Assert(len(lines), checker.Equals, 1)
   613  
   614  	for _, line := range lines {
   615  		f := strings.Fields(line)
   616  		c.Assert(f[1], checker.Equals, originalImageName)
   617  	}
   618  
   619  	runCmd = exec.Command(dockerBinary, "commit", containerID, updatedImageName)
   620  	out, _, err = runCommandWithOutput(runCmd)
   621  	c.Assert(err, checker.IsNil)
   622  
   623  	runCmd = exec.Command(dockerBinary, "tag", "-f", updatedImageName, originalImageName)
   624  	out, _, err = runCommandWithOutput(runCmd)
   625  	c.Assert(err, checker.IsNil)
   626  
   627  	linesOut, err = exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput()
   628  	c.Assert(err, checker.IsNil)
   629  
   630  	lines = strings.Split(strings.TrimSpace(string(linesOut)), "\n")
   631  	// skip header
   632  	lines = lines[1:]
   633  	c.Assert(len(lines), checker.Equals, 1)
   634  
   635  	for _, line := range lines {
   636  		f := strings.Fields(line)
   637  		c.Assert(f[1], checker.Equals, originalImageID)
   638  	}
   639  
   640  }