github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/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/integration-cli/checker"
    15  	"github.com/docker/docker/pkg/stringid"
    16  	icmd "github.com/docker/docker/pkg/testutil/cmd"
    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 testEnv.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  	icmd.RunCommand(dockerBinary, "tag", "busybox:latest", originalImageName).Assert(c, icmd.Success)
   673  
   674  	originalImageID, err := getIDByName(originalImageName)
   675  	c.Assert(err, checker.IsNil)
   676  
   677  	result := icmd.RunCommand(dockerBinary, append([]string{"run", "-d", originalImageName}, sleepCommandForDaemonPlatform()...)...)
   678  	result.Assert(c, icmd.Success)
   679  	containerID := strings.TrimSpace(result.Combined())
   680  
   681  	result = icmd.RunCommand(dockerBinary, "ps", "--no-trunc")
   682  	result.Assert(c, icmd.Success)
   683  
   684  	lines := strings.Split(strings.TrimSpace(string(result.Combined())), "\n")
   685  	// skip header
   686  	lines = lines[1:]
   687  	c.Assert(len(lines), checker.Equals, 1)
   688  
   689  	for _, line := range lines {
   690  		f := strings.Fields(line)
   691  		c.Assert(f[1], checker.Equals, originalImageName)
   692  	}
   693  
   694  	icmd.RunCommand(dockerBinary, "commit", containerID, updatedImageName).Assert(c, icmd.Success)
   695  	icmd.RunCommand(dockerBinary, "tag", updatedImageName, originalImageName).Assert(c, icmd.Success)
   696  
   697  	result = icmd.RunCommand(dockerBinary, "ps", "--no-trunc")
   698  	result.Assert(c, icmd.Success)
   699  
   700  	lines = strings.Split(strings.TrimSpace(string(result.Combined())), "\n")
   701  	// skip header
   702  	lines = lines[1:]
   703  	c.Assert(len(lines), checker.Equals, 1)
   704  
   705  	for _, line := range lines {
   706  		f := strings.Fields(line)
   707  		c.Assert(f[1], checker.Equals, originalImageID)
   708  	}
   709  
   710  }
   711  
   712  func (s *DockerSuite) TestPsNotShowPortsOfStoppedContainer(c *check.C) {
   713  	testRequires(c, DaemonIsLinux)
   714  	dockerCmd(c, "run", "--name=foo", "-d", "-p", "5000:5000", "busybox", "top")
   715  	c.Assert(waitRun("foo"), checker.IsNil)
   716  	out, _ := dockerCmd(c, "ps")
   717  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   718  	expected := "0.0.0.0:5000->5000/tcp"
   719  	fields := strings.Fields(lines[1])
   720  	c.Assert(fields[len(fields)-2], checker.Equals, expected, check.Commentf("Expected: %v, got: %v", expected, fields[len(fields)-2]))
   721  
   722  	dockerCmd(c, "kill", "foo")
   723  	dockerCmd(c, "wait", "foo")
   724  	out, _ = dockerCmd(c, "ps", "-l")
   725  	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
   726  	fields = strings.Fields(lines[1])
   727  	c.Assert(fields[len(fields)-2], checker.Not(checker.Equals), expected, check.Commentf("Should not got %v", expected))
   728  }
   729  
   730  func (s *DockerSuite) TestPsShowMounts(c *check.C) {
   731  	prefix, slash := getPrefixAndSlashFromDaemonPlatform()
   732  
   733  	mp := prefix + slash + "test"
   734  
   735  	dockerCmd(c, "volume", "create", "ps-volume-test")
   736  	// volume mount containers
   737  	runSleepingContainer(c, "--name=volume-test-1", "--volume", "ps-volume-test:"+mp)
   738  	c.Assert(waitRun("volume-test-1"), checker.IsNil)
   739  	runSleepingContainer(c, "--name=volume-test-2", "--volume", mp)
   740  	c.Assert(waitRun("volume-test-2"), checker.IsNil)
   741  	// bind mount container
   742  	var bindMountSource string
   743  	var bindMountDestination string
   744  	if DaemonIsWindows() {
   745  		bindMountSource = "c:\\"
   746  		bindMountDestination = "c:\\t"
   747  	} else {
   748  		bindMountSource = "/tmp"
   749  		bindMountDestination = "/t"
   750  	}
   751  	runSleepingContainer(c, "--name=bind-mount-test", "-v", bindMountSource+":"+bindMountDestination)
   752  	c.Assert(waitRun("bind-mount-test"), checker.IsNil)
   753  
   754  	out, _ := dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}")
   755  
   756  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   757  	c.Assert(lines, checker.HasLen, 3)
   758  
   759  	fields := strings.Fields(lines[0])
   760  	c.Assert(fields, checker.HasLen, 2)
   761  	c.Assert(fields[0], checker.Equals, "bind-mount-test")
   762  	c.Assert(fields[1], checker.Equals, bindMountSource)
   763  
   764  	fields = strings.Fields(lines[1])
   765  	c.Assert(fields, checker.HasLen, 2)
   766  
   767  	annonymounsVolumeID := fields[1]
   768  
   769  	fields = strings.Fields(lines[2])
   770  	c.Assert(fields[1], checker.Equals, "ps-volume-test")
   771  
   772  	// filter by volume name
   773  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume=ps-volume-test")
   774  
   775  	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
   776  	c.Assert(lines, checker.HasLen, 1)
   777  
   778  	fields = strings.Fields(lines[0])
   779  	c.Assert(fields[1], checker.Equals, "ps-volume-test")
   780  
   781  	// empty results filtering by unknown volume
   782  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume=this-volume-should-not-exist")
   783  	c.Assert(strings.TrimSpace(string(out)), checker.HasLen, 0)
   784  
   785  	// filter by mount destination
   786  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+mp)
   787  
   788  	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
   789  	c.Assert(lines, checker.HasLen, 2)
   790  
   791  	fields = strings.Fields(lines[0])
   792  	c.Assert(fields[1], checker.Equals, annonymounsVolumeID)
   793  	fields = strings.Fields(lines[1])
   794  	c.Assert(fields[1], checker.Equals, "ps-volume-test")
   795  
   796  	// filter by bind mount source
   797  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+bindMountSource)
   798  
   799  	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
   800  	c.Assert(lines, checker.HasLen, 1)
   801  
   802  	fields = strings.Fields(lines[0])
   803  	c.Assert(fields, checker.HasLen, 2)
   804  	c.Assert(fields[0], checker.Equals, "bind-mount-test")
   805  	c.Assert(fields[1], checker.Equals, bindMountSource)
   806  
   807  	// filter by bind mount destination
   808  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+bindMountDestination)
   809  
   810  	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
   811  	c.Assert(lines, checker.HasLen, 1)
   812  
   813  	fields = strings.Fields(lines[0])
   814  	c.Assert(fields, checker.HasLen, 2)
   815  	c.Assert(fields[0], checker.Equals, "bind-mount-test")
   816  	c.Assert(fields[1], checker.Equals, bindMountSource)
   817  
   818  	// empty results filtering by unknown mount point
   819  	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+prefix+slash+"this-path-was-never-mounted")
   820  	c.Assert(strings.TrimSpace(string(out)), checker.HasLen, 0)
   821  }
   822  
   823  func (s *DockerSuite) TestPsFormatSize(c *check.C) {
   824  	testRequires(c, DaemonIsLinux)
   825  	runSleepingContainer(c)
   826  
   827  	out, _ := dockerCmd(c, "ps", "--format", "table {{.Size}}")
   828  	lines := strings.Split(out, "\n")
   829  	c.Assert(lines[1], checker.Not(checker.Equals), "0 B", check.Commentf("Should not display a size of 0 B"))
   830  
   831  	out, _ = dockerCmd(c, "ps", "--size", "--format", "table {{.Size}}")
   832  	lines = strings.Split(out, "\n")
   833  	c.Assert(lines[0], checker.Equals, "SIZE", check.Commentf("Should only have one size column"))
   834  
   835  	out, _ = dockerCmd(c, "ps", "--size", "--format", "raw")
   836  	lines = strings.Split(out, "\n")
   837  	c.Assert(lines[8], checker.HasPrefix, "size:", check.Commentf("Size should be appended on a newline"))
   838  }
   839  
   840  func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) {
   841  	// TODO default network on Windows is not called "bridge", and creating a
   842  	// custom network fails on Windows fails with "Error response from daemon: plugin not found")
   843  	testRequires(c, DaemonIsLinux)
   844  
   845  	// create some containers
   846  	runSleepingContainer(c, "--net=bridge", "--name=onbridgenetwork")
   847  	runSleepingContainer(c, "--net=none", "--name=onnonenetwork")
   848  
   849  	// Filter docker ps on non existing network
   850  	out, _ := dockerCmd(c, "ps", "--filter", "network=doesnotexist")
   851  	containerOut := strings.TrimSpace(string(out))
   852  	lines := strings.Split(containerOut, "\n")
   853  
   854  	// skip header
   855  	lines = lines[1:]
   856  
   857  	// ps output should have no containers
   858  	c.Assert(lines, checker.HasLen, 0)
   859  
   860  	// Filter docker ps on network bridge
   861  	out, _ = dockerCmd(c, "ps", "--filter", "network=bridge")
   862  	containerOut = strings.TrimSpace(string(out))
   863  
   864  	lines = strings.Split(containerOut, "\n")
   865  
   866  	// skip header
   867  	lines = lines[1:]
   868  
   869  	// ps output should have only one container
   870  	c.Assert(lines, checker.HasLen, 1)
   871  
   872  	// Making sure onbridgenetwork is on the output
   873  	c.Assert(containerOut, checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on network\n"))
   874  
   875  	// Filter docker ps on networks bridge and none
   876  	out, _ = dockerCmd(c, "ps", "--filter", "network=bridge", "--filter", "network=none")
   877  	containerOut = strings.TrimSpace(string(out))
   878  
   879  	lines = strings.Split(containerOut, "\n")
   880  
   881  	// skip header
   882  	lines = lines[1:]
   883  
   884  	//ps output should have both the containers
   885  	c.Assert(lines, checker.HasLen, 2)
   886  
   887  	// Making sure onbridgenetwork and onnonenetwork is on the output
   888  	c.Assert(containerOut, checker.Contains, "onnonenetwork", check.Commentf("Missing the container on none network\n"))
   889  	c.Assert(containerOut, checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on bridge network\n"))
   890  
   891  	nwID, _ := dockerCmd(c, "network", "inspect", "--format", "{{.ID}}", "bridge")
   892  
   893  	// Filter by network ID
   894  	out, _ = dockerCmd(c, "ps", "--filter", "network="+nwID)
   895  	containerOut = strings.TrimSpace(string(out))
   896  
   897  	c.Assert(containerOut, checker.Contains, "onbridgenetwork")
   898  }
   899  
   900  func (s *DockerSuite) TestPsByOrder(c *check.C) {
   901  	name1 := "xyz-abc"
   902  	out, err := runSleepingContainer(c, "--name", name1)
   903  	c.Assert(err, checker.NotNil)
   904  	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
   905  	container1 := strings.TrimSpace(out)
   906  
   907  	name2 := "xyz-123"
   908  	out, err = runSleepingContainer(c, "--name", name2)
   909  	c.Assert(err, checker.NotNil)
   910  	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
   911  	container2 := strings.TrimSpace(out)
   912  
   913  	name3 := "789-abc"
   914  	out, err = runSleepingContainer(c, "--name", name3)
   915  	c.Assert(err, checker.NotNil)
   916  	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
   917  
   918  	name4 := "789-123"
   919  	out, err = runSleepingContainer(c, "--name", name4)
   920  	c.Assert(err, checker.NotNil)
   921  	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
   922  
   923  	// Run multiple time should have the same result
   924  	out, err = dockerCmd(c, "ps", "--no-trunc", "-q", "-f", "name=xyz")
   925  	c.Assert(err, checker.NotNil)
   926  	c.Assert(strings.TrimSpace(out), checker.Equals, fmt.Sprintf("%s\n%s", container2, container1))
   927  
   928  	// Run multiple time should have the same result
   929  	out, err = dockerCmd(c, "ps", "--no-trunc", "-q", "-f", "name=xyz")
   930  	c.Assert(err, checker.NotNil)
   931  	c.Assert(strings.TrimSpace(out), checker.Equals, fmt.Sprintf("%s\n%s", container2, container1))
   932  }
   933  
   934  func (s *DockerSuite) TestPsFilterMissingArgErrorCode(c *check.C) {
   935  	_, errCode, _ := dockerCmdWithError("ps", "--filter")
   936  	c.Assert(errCode, checker.Equals, 125)
   937  }