github.com/samwhited/moby@v1.13.1/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  	icmd "github.com/docker/docker/pkg/integration/cmd"
    16  	"github.com/docker/docker/pkg/stringid"
    17  	"github.com/go-check/check"
    18  )
    19  
    20  func (s *DockerSuite) TestPsListContainersBase(c *check.C) {
    21  	out, _ := runSleepingContainer(c, "-d")
    22  	firstID := strings.TrimSpace(out)
    23  
    24  	out, _ = runSleepingContainer(c, "-d")
    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, _ = runSleepingContainer(c, "-d")
    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  	// limit
    52  	out, _ = dockerCmd(c, "ps", "-n=2", "-a")
    53  	expected := []string{fourthID, thirdID}
    54  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("LIMIT & ALL: Container list is not in the correct order: \n%s", out))
    55  
    56  	out, _ = dockerCmd(c, "ps", "-n=2")
    57  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("LIMIT: Container list is not in the correct order: \n%s", out))
    58  
    59  	// filter since
    60  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-a")
    61  	expected = []string{fourthID, thirdID, secondID}
    62  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter & ALL: Container list is not in the correct order: \n%s", out))
    63  
    64  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID)
    65  	expected = []string{fourthID, secondID}
    66  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Container list is not in the correct order: \n%s", out))
    67  
    68  	out, _ = dockerCmd(c, "ps", "-f", "since="+thirdID)
    69  	expected = []string{fourthID}
    70  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Container list is not in the correct order: \n%s", out))
    71  
    72  	// filter before
    73  	out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID, "-a")
    74  	expected = []string{thirdID, secondID, firstID}
    75  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter & ALL: Container list is not in the correct order: \n%s", out))
    76  
    77  	out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID)
    78  	expected = []string{secondID, firstID}
    79  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter: Container list is not in the correct order: \n%s", out))
    80  
    81  	out, _ = dockerCmd(c, "ps", "-f", "before="+thirdID)
    82  	expected = []string{secondID, firstID}
    83  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Container list is not in the correct order: \n%s", out))
    84  
    85  	// filter since & before
    86  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID, "-a")
    87  	expected = []string{thirdID, secondID}
    88  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, BEFORE filter & ALL: Container list is not in the correct order: \n%s", out))
    89  
    90  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID)
    91  	expected = []string{secondID}
    92  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, BEFORE filter: Container list is not in the correct order: \n%s", out))
    93  
    94  	// filter since & limit
    95  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-n=2", "-a")
    96  	expected = []string{fourthID, thirdID}
    97  
    98  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, LIMIT & ALL: Container list is not in the correct order: \n%s", out))
    99  
   100  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-n=2")
   101  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, LIMIT: Container list is not in the correct order: \n%s", out))
   102  
   103  	// filter before & limit
   104  	out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID, "-n=1", "-a")
   105  	expected = []string{thirdID}
   106  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter, LIMIT & ALL: Container list is not in the correct order: \n%s", out))
   107  
   108  	out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID, "-n=1")
   109  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter, LIMIT: Container list is not in the correct order: \n%s", out))
   110  
   111  	// filter since & filter before & limit
   112  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID, "-n=1", "-a")
   113  	expected = []string{thirdID}
   114  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, BEFORE filter, LIMIT & ALL: Container list is not in the correct order: \n%s", out))
   115  
   116  	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID, "-n=1")
   117  	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, BEFORE filter, LIMIT: Container list is not in the correct order: \n%s", out))
   118  
   119  }
   120  
   121  func assertContainerList(out string, expected []string) bool {
   122  	lines := strings.Split(strings.Trim(out, "\n "), "\n")
   123  
   124  	if len(lines)-1 != len(expected) {
   125  		return false
   126  	}
   127  
   128  	containerIDIndex := strings.Index(lines[0], "CONTAINER ID")
   129  	for i := 0; i < len(expected); i++ {
   130  		foundID := lines[i+1][containerIDIndex : containerIDIndex+12]
   131  		if foundID != expected[i][:12] {
   132  			return false
   133  		}
   134  	}
   135  
   136  	return true
   137  }
   138  
   139  // FIXME(vdemeester) Move this into a unit test in daemon package
   140  func (s *DockerSuite) TestPsListContainersInvalidFilterName(c *check.C) {
   141  	out, _, err := dockerCmdWithError("ps", "-f", "invalidFilter=test")
   142  	c.Assert(err, checker.NotNil)
   143  	c.Assert(out, checker.Contains, "Invalid filter")
   144  }
   145  
   146  func (s *DockerSuite) TestPsListContainersSize(c *check.C) {
   147  	// Problematic on Windows as it doesn't report the size correctly @swernli
   148  	testRequires(c, DaemonIsLinux)
   149  	dockerCmd(c, "run", "-d", "busybox")
   150  
   151  	baseOut, _ := dockerCmd(c, "ps", "-s", "-n=1")
   152  	baseLines := strings.Split(strings.Trim(baseOut, "\n "), "\n")
   153  	baseSizeIndex := strings.Index(baseLines[0], "SIZE")
   154  	baseFoundsize := baseLines[1][baseSizeIndex:]
   155  	baseBytes, err := strconv.Atoi(strings.Split(baseFoundsize, " ")[0])
   156  	c.Assert(err, checker.IsNil)
   157  
   158  	name := "test_size"
   159  	dockerCmd(c, "run", "--name", name, "busybox", "sh", "-c", "echo 1 > test")
   160  	id, err := getIDByName(name)
   161  	c.Assert(err, checker.IsNil)
   162  
   163  	runCmd := exec.Command(dockerBinary, "ps", "-s", "-n=1")
   164  	var out string
   165  
   166  	wait := make(chan struct{})
   167  	go func() {
   168  		out, _, err = runCommandWithOutput(runCmd)
   169  		close(wait)
   170  	}()
   171  	select {
   172  	case <-wait:
   173  	case <-time.After(3 * time.Second):
   174  		c.Fatalf("Calling \"docker ps -s\" timed out!")
   175  	}
   176  	c.Assert(err, checker.IsNil)
   177  	lines := strings.Split(strings.Trim(out, "\n "), "\n")
   178  	c.Assert(lines, checker.HasLen, 2, check.Commentf("Expected 2 lines for 'ps -s -n=1' output, got %d", len(lines)))
   179  	sizeIndex := strings.Index(lines[0], "SIZE")
   180  	idIndex := strings.Index(lines[0], "CONTAINER ID")
   181  	foundID := lines[1][idIndex : idIndex+12]
   182  	c.Assert(foundID, checker.Equals, id[:12], check.Commentf("Expected id %s, got %s", id[:12], foundID))
   183  	expectedSize := fmt.Sprintf("%d B", (2 + baseBytes))
   184  	foundSize := lines[1][sizeIndex:]
   185  	c.Assert(foundSize, checker.Contains, expectedSize, check.Commentf("Expected size %q, got %q", expectedSize, foundSize))
   186  }
   187  
   188  func (s *DockerSuite) TestPsListContainersFilterStatus(c *check.C) {
   189  	// start exited container
   190  	out, _ := dockerCmd(c, "run", "-d", "busybox")
   191  	firstID := strings.TrimSpace(out)
   192  
   193  	// make sure the exited container is not running
   194  	dockerCmd(c, "wait", firstID)
   195  
   196  	// start running container
   197  	out, _ = dockerCmd(c, "run", "-itd", "busybox")
   198  	secondID := strings.TrimSpace(out)
   199  
   200  	// filter containers by exited
   201  	out, _ = dockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=exited")
   202  	containerOut := strings.TrimSpace(out)
   203  	c.Assert(containerOut, checker.Equals, firstID)
   204  
   205  	out, _ = dockerCmd(c, "ps", "-a", "--no-trunc", "-q", "--filter=status=running")
   206  	containerOut = strings.TrimSpace(out)
   207  	c.Assert(containerOut, checker.Equals, secondID)
   208  
   209  	result := dockerCmdWithTimeout(time.Second*60, "ps", "-a", "-q", "--filter=status=rubbish")
   210  	c.Assert(result, icmd.Matches, icmd.Expected{
   211  		ExitCode: 1,
   212  		Err:      "Unrecognised filter value for status",
   213  	})
   214  
   215  	// Windows doesn't support pausing of containers
   216  	if daemonPlatform != "windows" {
   217  		// pause running container
   218  		out, _ = dockerCmd(c, "run", "-itd", "busybox")
   219  		pausedID := strings.TrimSpace(out)
   220  		dockerCmd(c, "pause", pausedID)
   221  		// make sure the container is unpaused to let the daemon stop it properly
   222  		defer func() { dockerCmd(c, "unpause", pausedID) }()
   223  
   224  		out, _ = dockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=paused")
   225  		containerOut = strings.TrimSpace(out)
   226  		c.Assert(containerOut, checker.Equals, pausedID)
   227  	}
   228  }
   229  
   230  func (s *DockerSuite) TestPsListContainersFilterHealth(c *check.C) {
   231  	// Test legacy no health check
   232  	out, _ := runSleepingContainer(c, "--name=none_legacy")
   233  	containerID := strings.TrimSpace(out)
   234  
   235  	waitForContainer(containerID)
   236  
   237  	out, _ = dockerCmd(c, "ps", "-q", "-l", "--no-trunc", "--filter=health=none")
   238  	containerOut := strings.TrimSpace(out)
   239  	c.Assert(containerOut, checker.Equals, containerID, check.Commentf("Expected id %s, got %s for legacy none filter, output: %q", containerID, containerOut, out))
   240  
   241  	// Test no health check specified explicitly
   242  	out, _ = runSleepingContainer(c, "--name=none", "--no-healthcheck")
   243  	containerID = strings.TrimSpace(out)
   244  
   245  	waitForContainer(containerID)
   246  
   247  	out, _ = dockerCmd(c, "ps", "-q", "-l", "--no-trunc", "--filter=health=none")
   248  	containerOut = strings.TrimSpace(out)
   249  	c.Assert(containerOut, checker.Equals, containerID, check.Commentf("Expected id %s, got %s for none filter, output: %q", containerID, containerOut, out))
   250  
   251  	// Test failing health check
   252  	out, _ = runSleepingContainer(c, "--name=failing_container", "--health-cmd=exit 1", "--health-interval=1s")
   253  	containerID = strings.TrimSpace(out)
   254  
   255  	waitForHealthStatus(c, "failing_container", "starting", "unhealthy")
   256  
   257  	out, _ = dockerCmd(c, "ps", "-q", "--no-trunc", "--filter=health=unhealthy")
   258  	containerOut = strings.TrimSpace(out)
   259  	c.Assert(containerOut, checker.Equals, containerID, check.Commentf("Expected containerID %s, got %s for unhealthy filter, output: %q", containerID, containerOut, out))
   260  
   261  	// Check passing healthcheck
   262  	out, _ = runSleepingContainer(c, "--name=passing_container", "--health-cmd=exit 0", "--health-interval=1s")
   263  	containerID = strings.TrimSpace(out)
   264  
   265  	waitForHealthStatus(c, "passing_container", "starting", "healthy")
   266  
   267  	out, _ = dockerCmd(c, "ps", "-q", "--no-trunc", "--filter=health=healthy")
   268  	containerOut = strings.TrimSpace(out)
   269  	c.Assert(containerOut, checker.Equals, containerID, check.Commentf("Expected containerID %s, got %s for healthy filter, output: %q", containerID, containerOut, out))
   270  }
   271  
   272  func (s *DockerSuite) TestPsListContainersFilterID(c *check.C) {
   273  	// start container
   274  	out, _ := dockerCmd(c, "run", "-d", "busybox")
   275  	firstID := strings.TrimSpace(out)
   276  
   277  	// start another container
   278  	runSleepingContainer(c)
   279  
   280  	// filter containers by id
   281  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--filter=id="+firstID)
   282  	containerOut := strings.TrimSpace(out)
   283  	c.Assert(containerOut, checker.Equals, firstID[:12], check.Commentf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out))
   284  }
   285  
   286  func (s *DockerSuite) TestPsListContainersFilterName(c *check.C) {
   287  	// start container
   288  	dockerCmd(c, "run", "--name=a_name_to_match", "busybox")
   289  	id, err := getIDByName("a_name_to_match")
   290  	c.Assert(err, check.IsNil)
   291  
   292  	// start another container
   293  	runSleepingContainer(c, "--name=b_name_to_match")
   294  
   295  	// filter containers by name
   296  	out, _ := dockerCmd(c, "ps", "-a", "-q", "--filter=name=a_name_to_match")
   297  	containerOut := strings.TrimSpace(out)
   298  	c.Assert(containerOut, checker.Equals, id[:12], check.Commentf("Expected id %s, got %s for exited filter, output: %q", id[:12], containerOut, out))
   299  }
   300  
   301  // Test for the ancestor filter for ps.
   302  // There is also the same test but with image:tag@digest in docker_cli_by_digest_test.go
   303  //
   304  // What the test setups :
   305  // - Create 2 image based on busybox using the same repository but different tags
   306  // - Create an image based on the previous image (images_ps_filter_test2)
   307  // - Run containers for each of those image (busybox, images_ps_filter_test1, images_ps_filter_test2)
   308  // - Filter them out :P
   309  func (s *DockerSuite) TestPsListContainersFilterAncestorImage(c *check.C) {
   310  	// Build images
   311  	imageName1 := "images_ps_filter_test1"
   312  	imageID1, err := buildImage(imageName1,
   313  		`FROM busybox
   314  		 LABEL match me 1`, true)
   315  	c.Assert(err, checker.IsNil)
   316  
   317  	imageName1Tagged := "images_ps_filter_test1:tag"
   318  	imageID1Tagged, err := buildImage(imageName1Tagged,
   319  		`FROM busybox
   320  		 LABEL match me 1 tagged`, true)
   321  	c.Assert(err, checker.IsNil)
   322  
   323  	imageName2 := "images_ps_filter_test2"
   324  	imageID2, err := buildImage(imageName2,
   325  		fmt.Sprintf(`FROM %s
   326  		 LABEL match me 2`, imageName1), true)
   327  	c.Assert(err, checker.IsNil)
   328  
   329  	// start containers
   330  	dockerCmd(c, "run", "--name=first", "busybox", "echo", "hello")
   331  	firstID, err := getIDByName("first")
   332  	c.Assert(err, check.IsNil)
   333  
   334  	// start another container
   335  	dockerCmd(c, "run", "--name=second", "busybox", "echo", "hello")
   336  	secondID, err := getIDByName("second")
   337  	c.Assert(err, check.IsNil)
   338  
   339  	// start third container
   340  	dockerCmd(c, "run", "--name=third", imageName1, "echo", "hello")
   341  	thirdID, err := getIDByName("third")
   342  	c.Assert(err, check.IsNil)
   343  
   344  	// start fourth container
   345  	dockerCmd(c, "run", "--name=fourth", imageName1Tagged, "echo", "hello")
   346  	fourthID, err := getIDByName("fourth")
   347  	c.Assert(err, check.IsNil)
   348  
   349  	// start fifth container
   350  	dockerCmd(c, "run", "--name=fifth", imageName2, "echo", "hello")
   351  	fifthID, err := getIDByName("fifth")
   352  	c.Assert(err, check.IsNil)
   353  
   354  	var filterTestSuite = []struct {
   355  		filterName  string
   356  		expectedIDs []string
   357  	}{
   358  		// non existent stuff
   359  		{"nonexistent", []string{}},
   360  		{"nonexistent:tag", []string{}},
   361  		// image
   362  		{"busybox", []string{firstID, secondID, thirdID, fourthID, fifthID}},
   363  		{imageName1, []string{thirdID, fifthID}},
   364  		{imageName2, []string{fifthID}},
   365  		// image:tag
   366  		{fmt.Sprintf("%s:latest", imageName1), []string{thirdID, fifthID}},
   367  		{imageName1Tagged, []string{fourthID}},
   368  		// short-id
   369  		{stringid.TruncateID(imageID1), []string{thirdID, fifthID}},
   370  		{stringid.TruncateID(imageID2), []string{fifthID}},
   371  		// full-id
   372  		{imageID1, []string{thirdID, fifthID}},
   373  		{imageID1Tagged, []string{fourthID}},
   374  		{imageID2, []string{fifthID}},
   375  	}
   376  
   377  	var out string
   378  	for _, filter := range filterTestSuite {
   379  		out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+filter.filterName)
   380  		checkPsAncestorFilterOutput(c, out, filter.filterName, filter.expectedIDs)
   381  	}
   382  
   383  	// Multiple ancestor filter
   384  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+imageName2, "--filter=ancestor="+imageName1Tagged)
   385  	checkPsAncestorFilterOutput(c, out, imageName2+","+imageName1Tagged, []string{fourthID, fifthID})
   386  }
   387  
   388  func checkPsAncestorFilterOutput(c *check.C, out string, filterName string, expectedIDs []string) {
   389  	actualIDs := []string{}
   390  	if out != "" {
   391  		actualIDs = strings.Split(out[:len(out)-1], "\n")
   392  	}
   393  	sort.Strings(actualIDs)
   394  	sort.Strings(expectedIDs)
   395  
   396  	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))
   397  	if len(expectedIDs) > 0 {
   398  		same := true
   399  		for i := range expectedIDs {
   400  			if actualIDs[i] != expectedIDs[i] {
   401  				c.Logf("%s, %s", actualIDs[i], expectedIDs[i])
   402  				same = false
   403  				break
   404  			}
   405  		}
   406  		c.Assert(same, checker.Equals, true, check.Commentf("Expected filtered container(s) for %s ancestor filter to be %v, got %v", filterName, expectedIDs, actualIDs))
   407  	}
   408  }
   409  
   410  func (s *DockerSuite) TestPsListContainersFilterLabel(c *check.C) {
   411  	// start container
   412  	dockerCmd(c, "run", "--name=first", "-l", "match=me", "-l", "second=tag", "busybox")
   413  	firstID, err := getIDByName("first")
   414  	c.Assert(err, check.IsNil)
   415  
   416  	// start another container
   417  	dockerCmd(c, "run", "--name=second", "-l", "match=me too", "busybox")
   418  	secondID, err := getIDByName("second")
   419  	c.Assert(err, check.IsNil)
   420  
   421  	// start third container
   422  	dockerCmd(c, "run", "--name=third", "-l", "nomatch=me", "busybox")
   423  	thirdID, err := getIDByName("third")
   424  	c.Assert(err, check.IsNil)
   425  
   426  	// filter containers by exact match
   427  	out, _ := dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me")
   428  	containerOut := strings.TrimSpace(out)
   429  	c.Assert(containerOut, checker.Equals, firstID, check.Commentf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out))
   430  
   431  	// filter containers by two labels
   432  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me", "--filter=label=second=tag")
   433  	containerOut = strings.TrimSpace(out)
   434  	c.Assert(containerOut, checker.Equals, firstID, check.Commentf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out))
   435  
   436  	// filter containers by two labels, but expect not found because of AND behavior
   437  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me", "--filter=label=second=tag-no")
   438  	containerOut = strings.TrimSpace(out)
   439  	c.Assert(containerOut, checker.Equals, "", check.Commentf("Expected nothing, got %s for exited filter, output: %q", containerOut, out))
   440  
   441  	// filter containers by exact key
   442  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match")
   443  	containerOut = strings.TrimSpace(out)
   444  	c.Assert(containerOut, checker.Contains, firstID)
   445  	c.Assert(containerOut, checker.Contains, secondID)
   446  	c.Assert(containerOut, checker.Not(checker.Contains), thirdID)
   447  }
   448  
   449  func (s *DockerSuite) TestPsListContainersFilterExited(c *check.C) {
   450  	runSleepingContainer(c, "--name=sleep")
   451  
   452  	dockerCmd(c, "run", "--name", "zero1", "busybox", "true")
   453  	firstZero, err := getIDByName("zero1")
   454  	c.Assert(err, checker.IsNil)
   455  
   456  	dockerCmd(c, "run", "--name", "zero2", "busybox", "true")
   457  	secondZero, err := getIDByName("zero2")
   458  	c.Assert(err, checker.IsNil)
   459  
   460  	out, _, err := dockerCmdWithError("run", "--name", "nonzero1", "busybox", "false")
   461  	c.Assert(err, checker.NotNil, check.Commentf("Should fail.", out, err))
   462  
   463  	firstNonZero, err := getIDByName("nonzero1")
   464  	c.Assert(err, checker.IsNil)
   465  
   466  	out, _, err = dockerCmdWithError("run", "--name", "nonzero2", "busybox", "false")
   467  	c.Assert(err, checker.NotNil, check.Commentf("Should fail.", out, err))
   468  	secondNonZero, err := getIDByName("nonzero2")
   469  	c.Assert(err, checker.IsNil)
   470  
   471  	// filter containers by exited=0
   472  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=exited=0")
   473  	ids := strings.Split(strings.TrimSpace(out), "\n")
   474  	c.Assert(ids, checker.HasLen, 2, check.Commentf("Should be 2 zero exited containers got %d: %s", len(ids), out))
   475  	c.Assert(ids[0], checker.Equals, secondZero, check.Commentf("First in list should be %q, got %q", secondZero, ids[0]))
   476  	c.Assert(ids[1], checker.Equals, firstZero, check.Commentf("Second in list should be %q, got %q", firstZero, ids[1]))
   477  
   478  	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=exited=1")
   479  	ids = strings.Split(strings.TrimSpace(out), "\n")
   480  	c.Assert(ids, checker.HasLen, 2, check.Commentf("Should be 2 zero exited containers got %d", len(ids)))
   481  	c.Assert(ids[0], checker.Equals, secondNonZero, check.Commentf("First in list should be %q, got %q", secondNonZero, ids[0]))
   482  	c.Assert(ids[1], checker.Equals, firstNonZero, check.Commentf("Second in list should be %q, got %q", firstNonZero, ids[1]))
   483  
   484  }
   485  
   486  func (s *DockerSuite) TestPsRightTagName(c *check.C) {
   487  	// TODO Investigate further why this fails on Windows to Windows CI
   488  	testRequires(c, DaemonIsLinux)
   489  	tag := "asybox:shmatest"
   490  	dockerCmd(c, "tag", "busybox", tag)
   491  
   492  	var id1 string
   493  	out, _ := runSleepingContainer(c)
   494  	id1 = strings.TrimSpace(string(out))
   495  
   496  	var id2 string
   497  	out, _ = runSleepingContainerInImage(c, tag)
   498  	id2 = strings.TrimSpace(string(out))
   499  
   500  	var imageID string
   501  	out = inspectField(c, "busybox", "Id")
   502  	imageID = strings.TrimSpace(string(out))
   503  
   504  	var id3 string
   505  	out, _ = runSleepingContainerInImage(c, imageID)
   506  	id3 = strings.TrimSpace(string(out))
   507  
   508  	out, _ = dockerCmd(c, "ps", "--no-trunc")
   509  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   510  	// skip header
   511  	lines = lines[1:]
   512  	c.Assert(lines, checker.HasLen, 3, check.Commentf("There should be 3 running container, got %d", len(lines)))
   513  	for _, line := range lines {
   514  		f := strings.Fields(line)
   515  		switch f[0] {
   516  		case id1:
   517  			c.Assert(f[1], checker.Equals, "busybox", check.Commentf("Expected %s tag for id %s, got %s", "busybox", id1, f[1]))
   518  		case id2:
   519  			c.Assert(f[1], checker.Equals, tag, check.Commentf("Expected %s tag for id %s, got %s", tag, id2, f[1]))
   520  		case id3:
   521  			c.Assert(f[1], checker.Equals, imageID, check.Commentf("Expected %s imageID for id %s, got %s", tag, id3, f[1]))
   522  		default:
   523  			c.Fatalf("Unexpected id %s, expected %s and %s and %s", f[0], id1, id2, id3)
   524  		}
   525  	}
   526  }
   527  
   528  func (s *DockerSuite) TestPsLinkedWithNoTrunc(c *check.C) {
   529  	// Problematic on Windows as it doesn't support links as of Jan 2016
   530  	testRequires(c, DaemonIsLinux)
   531  	runSleepingContainer(c, "--name=first")
   532  	runSleepingContainer(c, "--name=second", "--link=first:first")
   533  
   534  	out, _ := dockerCmd(c, "ps", "--no-trunc")
   535  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   536  	// strip header
   537  	lines = lines[1:]
   538  	expected := []string{"second", "first,second/first"}
   539  	var names []string
   540  	for _, l := range lines {
   541  		fields := strings.Fields(l)
   542  		names = append(names, fields[len(fields)-1])
   543  	}
   544  	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array: %v, got: %v", expected, names))
   545  }
   546  
   547  func (s *DockerSuite) TestPsGroupPortRange(c *check.C) {
   548  	// Problematic on Windows as it doesn't support port ranges as of Jan 2016
   549  	testRequires(c, DaemonIsLinux)
   550  	portRange := "3850-3900"
   551  	dockerCmd(c, "run", "-d", "--name", "porttest", "-p", portRange+":"+portRange, "busybox", "top")
   552  
   553  	out, _ := dockerCmd(c, "ps")
   554  
   555  	c.Assert(string(out), checker.Contains, portRange, check.Commentf("docker ps output should have had the port range %q: %s", portRange, string(out)))
   556  
   557  }
   558  
   559  func (s *DockerSuite) TestPsWithSize(c *check.C) {
   560  	// Problematic on Windows as it doesn't report the size correctly @swernli
   561  	testRequires(c, DaemonIsLinux)
   562  	dockerCmd(c, "run", "-d", "--name", "sizetest", "busybox", "top")
   563  
   564  	out, _ := dockerCmd(c, "ps", "--size")
   565  	c.Assert(out, checker.Contains, "virtual", check.Commentf("docker ps with --size should show virtual size of container"))
   566  }
   567  
   568  func (s *DockerSuite) TestPsListContainersFilterCreated(c *check.C) {
   569  	// create a container
   570  	out, _ := dockerCmd(c, "create", "busybox")
   571  	cID := strings.TrimSpace(out)
   572  	shortCID := cID[:12]
   573  
   574  	// Make sure it DOESN'T show up w/o a '-a' for normal 'ps'
   575  	out, _ = dockerCmd(c, "ps", "-q")
   576  	c.Assert(out, checker.Not(checker.Contains), shortCID, check.Commentf("Should have not seen '%s' in ps output:\n%s", shortCID, out))
   577  
   578  	// Make sure it DOES show up as 'Created' for 'ps -a'
   579  	out, _ = dockerCmd(c, "ps", "-a")
   580  
   581  	hits := 0
   582  	for _, line := range strings.Split(out, "\n") {
   583  		if !strings.Contains(line, shortCID) {
   584  			continue
   585  		}
   586  		hits++
   587  		c.Assert(line, checker.Contains, "Created", check.Commentf("Missing 'Created' on '%s'", line))
   588  	}
   589  
   590  	c.Assert(hits, checker.Equals, 1, check.Commentf("Should have seen '%s' in ps -a output once:%d\n%s", shortCID, hits, out))
   591  
   592  	// filter containers by 'create' - note, no -a needed
   593  	out, _ = dockerCmd(c, "ps", "-q", "-f", "status=created")
   594  	containerOut := strings.TrimSpace(out)
   595  	c.Assert(cID, checker.HasPrefix, containerOut)
   596  }
   597  
   598  func (s *DockerSuite) TestPsFormatMultiNames(c *check.C) {
   599  	// Problematic on Windows as it doesn't support link as of Jan 2016
   600  	testRequires(c, DaemonIsLinux)
   601  	//create 2 containers and link them
   602  	dockerCmd(c, "run", "--name=child", "-d", "busybox", "top")
   603  	dockerCmd(c, "run", "--name=parent", "--link=child:linkedone", "-d", "busybox", "top")
   604  
   605  	//use the new format capabilities to only list the names and --no-trunc to get all names
   606  	out, _ := dockerCmd(c, "ps", "--format", "{{.Names}}", "--no-trunc")
   607  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   608  	expected := []string{"parent", "child,parent/linkedone"}
   609  	var names []string
   610  	names = append(names, lines...)
   611  	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with non-truncated names: %v, got: %v", expected, names))
   612  
   613  	//now list without turning off truncation and make sure we only get the non-link names
   614  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}}")
   615  	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
   616  	expected = []string{"parent", "child"}
   617  	var truncNames []string
   618  	truncNames = append(truncNames, lines...)
   619  	c.Assert(expected, checker.DeepEquals, truncNames, check.Commentf("Expected array with truncated names: %v, got: %v", expected, truncNames))
   620  }
   621  
   622  // Test for GitHub issue #21772
   623  func (s *DockerSuite) TestPsNamesMultipleTime(c *check.C) {
   624  	runSleepingContainer(c, "--name=test1")
   625  	runSleepingContainer(c, "--name=test2")
   626  
   627  	//use the new format capabilities to list the names twice
   628  	out, _ := dockerCmd(c, "ps", "--format", "{{.Names}} {{.Names}}")
   629  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   630  	expected := []string{"test2 test2", "test1 test1"}
   631  	var names []string
   632  	names = append(names, lines...)
   633  	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with names displayed twice: %v, got: %v", expected, names))
   634  }
   635  
   636  func (s *DockerSuite) TestPsFormatHeaders(c *check.C) {
   637  	// make sure no-container "docker ps" still prints the header row
   638  	out, _ := dockerCmd(c, "ps", "--format", "table {{.ID}}")
   639  	c.Assert(out, checker.Equals, "CONTAINER ID\n", check.Commentf(`Expected 'CONTAINER ID\n', got %v`, out))
   640  
   641  	// verify that "docker ps" with a container still prints the header row also
   642  	runSleepingContainer(c, "--name=test")
   643  	out, _ = dockerCmd(c, "ps", "--format", "table {{.Names}}")
   644  	c.Assert(out, checker.Equals, "NAMES\ntest\n", check.Commentf(`Expected 'NAMES\ntest\n', got %v`, out))
   645  }
   646  
   647  func (s *DockerSuite) TestPsDefaultFormatAndQuiet(c *check.C) {
   648  	config := `{
   649  		"psFormat": "default {{ .ID }}"
   650  }`
   651  	d, err := ioutil.TempDir("", "integration-cli-")
   652  	c.Assert(err, checker.IsNil)
   653  	defer os.RemoveAll(d)
   654  
   655  	err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644)
   656  	c.Assert(err, checker.IsNil)
   657  
   658  	out, _ := runSleepingContainer(c, "--name=test")
   659  	id := strings.TrimSpace(out)
   660  
   661  	out, _ = dockerCmd(c, "--config", d, "ps", "-q")
   662  	c.Assert(id, checker.HasPrefix, strings.TrimSpace(out), check.Commentf("Expected to print only the container id, got %v\n", out))
   663  }
   664  
   665  // Test for GitHub issue #12595
   666  func (s *DockerSuite) TestPsImageIDAfterUpdate(c *check.C) {
   667  	// TODO: Investigate why this fails on Windows to Windows CI further.
   668  	testRequires(c, DaemonIsLinux)
   669  	originalImageName := "busybox:TestPsImageIDAfterUpdate-original"
   670  	updatedImageName := "busybox:TestPsImageIDAfterUpdate-updated"
   671  
   672  	runCmd := exec.Command(dockerBinary, "tag", "busybox:latest", originalImageName)
   673  	out, _, err := runCommandWithOutput(runCmd)
   674  	c.Assert(err, checker.IsNil)
   675  
   676  	originalImageID, err := getIDByName(originalImageName)
   677  	c.Assert(err, checker.IsNil)
   678  
   679  	runCmd = exec.Command(dockerBinary, append([]string{"run", "-d", originalImageName}, sleepCommandForDaemonPlatform()...)...)
   680  	out, _, err = runCommandWithOutput(runCmd)
   681  	c.Assert(err, checker.IsNil)
   682  	containerID := strings.TrimSpace(out)
   683  
   684  	linesOut, err := exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput()
   685  	c.Assert(err, checker.IsNil)
   686  
   687  	lines := strings.Split(strings.TrimSpace(string(linesOut)), "\n")
   688  	// skip header
   689  	lines = lines[1:]
   690  	c.Assert(len(lines), checker.Equals, 1)
   691  
   692  	for _, line := range lines {
   693  		f := strings.Fields(line)
   694  		c.Assert(f[1], checker.Equals, originalImageName)
   695  	}
   696  
   697  	runCmd = exec.Command(dockerBinary, "commit", containerID, updatedImageName)
   698  	out, _, err = runCommandWithOutput(runCmd)
   699  	c.Assert(err, checker.IsNil)
   700  
   701  	runCmd = exec.Command(dockerBinary, "tag", updatedImageName, originalImageName)
   702  	out, _, err = runCommandWithOutput(runCmd)
   703  	c.Assert(err, checker.IsNil)
   704  
   705  	linesOut, err = exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput()
   706  	c.Assert(err, checker.IsNil)
   707  
   708  	lines = strings.Split(strings.TrimSpace(string(linesOut)), "\n")
   709  	// skip header
   710  	lines = lines[1:]
   711  	c.Assert(len(lines), checker.Equals, 1)
   712  
   713  	for _, line := range lines {
   714  		f := strings.Fields(line)
   715  		c.Assert(f[1], checker.Equals, originalImageID)
   716  	}
   717  
   718  }
   719  
   720  func (s *DockerSuite) TestPsNotShowPortsOfStoppedContainer(c *check.C) {
   721  	testRequires(c, DaemonIsLinux)
   722  	dockerCmd(c, "run", "--name=foo", "-d", "-p", "5000:5000", "busybox", "top")
   723  	c.Assert(waitRun("foo"), checker.IsNil)
   724  	out, _ := dockerCmd(c, "ps")
   725  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   726  	expected := "0.0.0.0:5000->5000/tcp"
   727  	fields := strings.Fields(lines[1])
   728  	c.Assert(fields[len(fields)-2], checker.Equals, expected, check.Commentf("Expected: %v, got: %v", expected, fields[len(fields)-2]))
   729  
   730  	dockerCmd(c, "kill", "foo")
   731  	dockerCmd(c, "wait", "foo")
   732  	out, _ = dockerCmd(c, "ps", "-l")
   733  	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
   734  	fields = strings.Fields(lines[1])
   735  	c.Assert(fields[len(fields)-2], checker.Not(checker.Equals), expected, check.Commentf("Should not got %v", expected))
   736  }
   737  
   738  func (s *DockerSuite) TestPsShowMounts(c *check.C) {
   739  	prefix, slash := getPrefixAndSlashFromDaemonPlatform()
   740  
   741  	mp := prefix + slash + "test"
   742  
   743  	dockerCmd(c, "volume", "create", "ps-volume-test")
   744  	// volume mount containers
   745  	runSleepingContainer(c, "--name=volume-test-1", "--volume", "ps-volume-test:"+mp)
   746  	c.Assert(waitRun("volume-test-1"), checker.IsNil)
   747  	runSleepingContainer(c, "--name=volume-test-2", "--volume", mp)
   748  	c.Assert(waitRun("volume-test-2"), checker.IsNil)
   749  	// bind mount container
   750  	var bindMountSource string
   751  	var bindMountDestination string
   752  	if DaemonIsWindows.Condition() {
   753  		bindMountSource = "c:\\"
   754  		bindMountDestination = "c:\\t"
   755  	} else {
   756  		bindMountSource = "/tmp"
   757  		bindMountDestination = "/t"
   758  	}
   759  	runSleepingContainer(c, "--name=bind-mount-test", "-v", bindMountSource+":"+bindMountDestination)
   760  	c.Assert(waitRun("bind-mount-test"), checker.IsNil)
   761  
   762  	out, _ := dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}")
   763  
   764  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   765  	c.Assert(lines, checker.HasLen, 3)
   766  
   767  	fields := strings.Fields(lines[0])
   768  	c.Assert(fields, checker.HasLen, 2)
   769  	c.Assert(fields[0], checker.Equals, "bind-mount-test")
   770  	c.Assert(fields[1], checker.Equals, bindMountSource)
   771  
   772  	fields = strings.Fields(lines[1])
   773  	c.Assert(fields, checker.HasLen, 2)
   774  
   775  	annonymounsVolumeID := fields[1]
   776  
   777  	fields = strings.Fields(lines[2])
   778  	c.Assert(fields[1], checker.Equals, "ps-volume-test")
   779  
   780  	// filter by volume name
   781  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume=ps-volume-test")
   782  
   783  	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
   784  	c.Assert(lines, checker.HasLen, 1)
   785  
   786  	fields = strings.Fields(lines[0])
   787  	c.Assert(fields[1], checker.Equals, "ps-volume-test")
   788  
   789  	// empty results filtering by unknown volume
   790  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume=this-volume-should-not-exist")
   791  	c.Assert(strings.TrimSpace(string(out)), checker.HasLen, 0)
   792  
   793  	// filter by mount destination
   794  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+mp)
   795  
   796  	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
   797  	c.Assert(lines, checker.HasLen, 2)
   798  
   799  	fields = strings.Fields(lines[0])
   800  	c.Assert(fields[1], checker.Equals, annonymounsVolumeID)
   801  	fields = strings.Fields(lines[1])
   802  	c.Assert(fields[1], checker.Equals, "ps-volume-test")
   803  
   804  	// filter by bind mount source
   805  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+bindMountSource)
   806  
   807  	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
   808  	c.Assert(lines, checker.HasLen, 1)
   809  
   810  	fields = strings.Fields(lines[0])
   811  	c.Assert(fields, checker.HasLen, 2)
   812  	c.Assert(fields[0], checker.Equals, "bind-mount-test")
   813  	c.Assert(fields[1], checker.Equals, bindMountSource)
   814  
   815  	// filter by bind mount destination
   816  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+bindMountDestination)
   817  
   818  	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
   819  	c.Assert(lines, checker.HasLen, 1)
   820  
   821  	fields = strings.Fields(lines[0])
   822  	c.Assert(fields, checker.HasLen, 2)
   823  	c.Assert(fields[0], checker.Equals, "bind-mount-test")
   824  	c.Assert(fields[1], checker.Equals, bindMountSource)
   825  
   826  	// empty results filtering by unknown mount point
   827  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+prefix+slash+"this-path-was-never-mounted")
   828  	c.Assert(strings.TrimSpace(string(out)), checker.HasLen, 0)
   829  }
   830  
   831  func (s *DockerSuite) TestPsFormatSize(c *check.C) {
   832  	testRequires(c, DaemonIsLinux)
   833  	runSleepingContainer(c)
   834  
   835  	out, _ := dockerCmd(c, "ps", "--format", "table {{.Size}}")
   836  	lines := strings.Split(out, "\n")
   837  	c.Assert(lines[1], checker.Not(checker.Equals), "0 B", check.Commentf("Should not display a size of 0 B"))
   838  
   839  	out, _ = dockerCmd(c, "ps", "--size", "--format", "table {{.Size}}")
   840  	lines = strings.Split(out, "\n")
   841  	c.Assert(lines[0], checker.Equals, "SIZE", check.Commentf("Should only have one size column"))
   842  
   843  	out, _ = dockerCmd(c, "ps", "--size", "--format", "raw")
   844  	lines = strings.Split(out, "\n")
   845  	c.Assert(lines[8], checker.HasPrefix, "size:", check.Commentf("Size should be appended on a newline"))
   846  }
   847  
   848  func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) {
   849  	// TODO default network on Windows is not called "bridge", and creating a
   850  	// custom network fails on Windows fails with "Error response from daemon: plugin not found")
   851  	testRequires(c, DaemonIsLinux)
   852  
   853  	// create some containers
   854  	runSleepingContainer(c, "--net=bridge", "--name=onbridgenetwork")
   855  	runSleepingContainer(c, "--net=none", "--name=onnonenetwork")
   856  
   857  	// Filter docker ps on non existing network
   858  	out, _ := dockerCmd(c, "ps", "--filter", "network=doesnotexist")
   859  	containerOut := strings.TrimSpace(string(out))
   860  	lines := strings.Split(containerOut, "\n")
   861  
   862  	// skip header
   863  	lines = lines[1:]
   864  
   865  	// ps output should have no containers
   866  	c.Assert(lines, checker.HasLen, 0)
   867  
   868  	// Filter docker ps on network bridge
   869  	out, _ = dockerCmd(c, "ps", "--filter", "network=bridge")
   870  	containerOut = strings.TrimSpace(string(out))
   871  
   872  	lines = strings.Split(containerOut, "\n")
   873  
   874  	// skip header
   875  	lines = lines[1:]
   876  
   877  	// ps output should have only one container
   878  	c.Assert(lines, checker.HasLen, 1)
   879  
   880  	// Making sure onbridgenetwork is on the output
   881  	c.Assert(containerOut, checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on network\n"))
   882  
   883  	// Filter docker ps on networks bridge and none
   884  	out, _ = dockerCmd(c, "ps", "--filter", "network=bridge", "--filter", "network=none")
   885  	containerOut = strings.TrimSpace(string(out))
   886  
   887  	lines = strings.Split(containerOut, "\n")
   888  
   889  	// skip header
   890  	lines = lines[1:]
   891  
   892  	//ps output should have both the containers
   893  	c.Assert(lines, checker.HasLen, 2)
   894  
   895  	// Making sure onbridgenetwork and onnonenetwork is on the output
   896  	c.Assert(containerOut, checker.Contains, "onnonenetwork", check.Commentf("Missing the container on none network\n"))
   897  	c.Assert(containerOut, checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on bridge network\n"))
   898  
   899  	nwID, _ := dockerCmd(c, "network", "inspect", "--format", "{{.ID}}", "bridge")
   900  
   901  	// Filter by network ID
   902  	out, _ = dockerCmd(c, "ps", "--filter", "network="+nwID)
   903  	containerOut = strings.TrimSpace(string(out))
   904  
   905  	c.Assert(containerOut, checker.Contains, "onbridgenetwork")
   906  }
   907  
   908  func (s *DockerSuite) TestPsByOrder(c *check.C) {
   909  	name1 := "xyz-abc"
   910  	out, err := runSleepingContainer(c, "--name", name1)
   911  	c.Assert(err, checker.NotNil)
   912  	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
   913  	container1 := strings.TrimSpace(out)
   914  
   915  	name2 := "xyz-123"
   916  	out, err = runSleepingContainer(c, "--name", name2)
   917  	c.Assert(err, checker.NotNil)
   918  	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
   919  	container2 := strings.TrimSpace(out)
   920  
   921  	name3 := "789-abc"
   922  	out, err = runSleepingContainer(c, "--name", name3)
   923  	c.Assert(err, checker.NotNil)
   924  	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
   925  
   926  	name4 := "789-123"
   927  	out, err = runSleepingContainer(c, "--name", name4)
   928  	c.Assert(err, checker.NotNil)
   929  	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
   930  
   931  	// Run multiple time should have the same result
   932  	out, err = dockerCmd(c, "ps", "--no-trunc", "-q", "-f", "name=xyz")
   933  	c.Assert(err, checker.NotNil)
   934  	c.Assert(strings.TrimSpace(out), checker.Equals, fmt.Sprintf("%s\n%s", container2, container1))
   935  
   936  	// Run multiple time should have the same result
   937  	out, err = dockerCmd(c, "ps", "--no-trunc", "-q", "-f", "name=xyz")
   938  	c.Assert(err, checker.NotNil)
   939  	c.Assert(strings.TrimSpace(out), checker.Equals, fmt.Sprintf("%s\n%s", container2, container1))
   940  }
   941  
   942  func (s *DockerSuite) TestPsFilterMissingArgErrorCode(c *check.C) {
   943  	_, errCode, _ := dockerCmdWithError("ps", "--filter")
   944  	c.Assert(errCode, checker.Equals, 125)
   945  }
   946  
   947  // Test case for 30291
   948  func (s *DockerSuite) TestPsFormatTemplateWithArg(c *check.C) {
   949  	runSleepingContainer(c, "-d", "--name", "top", "--label", "some.label=label.foo-bar")
   950  	out, _ := dockerCmd(c, "ps", "--format", `{{.Names}} {{.Label "some.label"}}`)
   951  	c.Assert(strings.TrimSpace(out), checker.Equals, "top label.foo-bar")
   952  }