github.com/christopherobin/docker@v1.6.2/integration-cli/docker_cli_ps_test.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os/exec"
     6  	"reflect"
     7  	"strconv"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  func TestPsListContainers(t *testing.T) {
    14  	defer deleteAllContainers()
    15  
    16  	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
    17  	out, _, err := runCommandWithOutput(runCmd)
    18  	if err != nil {
    19  		t.Fatal(out, err)
    20  	}
    21  	firstID := stripTrailingCharacters(out)
    22  
    23  	runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "top")
    24  	out, _, err = runCommandWithOutput(runCmd)
    25  	if err != nil {
    26  		t.Fatal(out, err)
    27  	}
    28  	secondID := stripTrailingCharacters(out)
    29  
    30  	// not long running
    31  	runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "true")
    32  	out, _, err = runCommandWithOutput(runCmd)
    33  	if err != nil {
    34  		t.Fatal(out, err)
    35  	}
    36  	thirdID := stripTrailingCharacters(out)
    37  
    38  	runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "top")
    39  	out, _, err = runCommandWithOutput(runCmd)
    40  	if err != nil {
    41  		t.Fatal(out, err)
    42  	}
    43  	fourthID := stripTrailingCharacters(out)
    44  
    45  	// make sure third one is not running
    46  	runCmd = exec.Command(dockerBinary, "wait", thirdID)
    47  	if out, _, err = runCommandWithOutput(runCmd); err != nil {
    48  		t.Fatal(out, err)
    49  	}
    50  
    51  	// all
    52  	runCmd = exec.Command(dockerBinary, "ps", "-a")
    53  	out, _, err = runCommandWithOutput(runCmd)
    54  	if err != nil {
    55  		t.Fatal(out, err)
    56  	}
    57  
    58  	if !assertContainerList(out, []string{fourthID, thirdID, secondID, firstID}) {
    59  		t.Error("Container list is not in the correct order")
    60  	}
    61  
    62  	// running
    63  	runCmd = exec.Command(dockerBinary, "ps")
    64  	out, _, err = runCommandWithOutput(runCmd)
    65  	if err != nil {
    66  		t.Fatal(out, err)
    67  	}
    68  
    69  	if !assertContainerList(out, []string{fourthID, secondID, firstID}) {
    70  		t.Error("Container list is not in the correct order")
    71  	}
    72  
    73  	// from here all flag '-a' is ignored
    74  
    75  	// limit
    76  	runCmd = exec.Command(dockerBinary, "ps", "-n=2", "-a")
    77  	out, _, err = runCommandWithOutput(runCmd)
    78  	if err != nil {
    79  		t.Fatal(out, err)
    80  	}
    81  	expected := []string{fourthID, thirdID}
    82  
    83  	if !assertContainerList(out, expected) {
    84  		t.Error("Container list is not in the correct order")
    85  	}
    86  
    87  	runCmd = exec.Command(dockerBinary, "ps", "-n=2")
    88  	out, _, err = runCommandWithOutput(runCmd)
    89  	if err != nil {
    90  		t.Fatal(out, err)
    91  	}
    92  
    93  	if !assertContainerList(out, expected) {
    94  		t.Error("Container list is not in the correct order")
    95  	}
    96  
    97  	// since
    98  	runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "-a")
    99  	out, _, err = runCommandWithOutput(runCmd)
   100  	if err != nil {
   101  		t.Fatal(out, err)
   102  	}
   103  	expected = []string{fourthID, thirdID, secondID}
   104  
   105  	if !assertContainerList(out, expected) {
   106  		t.Error("Container list is not in the correct order")
   107  	}
   108  
   109  	runCmd = exec.Command(dockerBinary, "ps", "--since", firstID)
   110  	out, _, err = runCommandWithOutput(runCmd)
   111  	if err != nil {
   112  		t.Fatal(out, err)
   113  	}
   114  
   115  	if !assertContainerList(out, expected) {
   116  		t.Error("Container list is not in the correct order")
   117  	}
   118  
   119  	// before
   120  	runCmd = exec.Command(dockerBinary, "ps", "--before", thirdID, "-a")
   121  	out, _, err = runCommandWithOutput(runCmd)
   122  	if err != nil {
   123  		t.Fatal(out, err)
   124  	}
   125  	expected = []string{secondID, firstID}
   126  
   127  	if !assertContainerList(out, expected) {
   128  		t.Error("Container list is not in the correct order")
   129  	}
   130  
   131  	runCmd = exec.Command(dockerBinary, "ps", "--before", thirdID)
   132  	out, _, err = runCommandWithOutput(runCmd)
   133  	if err != nil {
   134  		t.Fatal(out, err)
   135  	}
   136  
   137  	if !assertContainerList(out, expected) {
   138  		t.Error("Container list is not in the correct order")
   139  	}
   140  
   141  	// since & before
   142  	runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "--before", fourthID, "-a")
   143  	out, _, err = runCommandWithOutput(runCmd)
   144  	if err != nil {
   145  		t.Fatal(out, err)
   146  	}
   147  	expected = []string{thirdID, secondID}
   148  
   149  	if !assertContainerList(out, expected) {
   150  		t.Error("Container list is not in the correct order")
   151  	}
   152  
   153  	runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "--before", fourthID)
   154  	out, _, err = runCommandWithOutput(runCmd)
   155  	if err != nil {
   156  		t.Fatal(out, err)
   157  	}
   158  	if !assertContainerList(out, expected) {
   159  		t.Error("Container list is not in the correct order")
   160  	}
   161  
   162  	// since & limit
   163  	runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "-n=2", "-a")
   164  	out, _, err = runCommandWithOutput(runCmd)
   165  	if err != nil {
   166  		t.Fatal(out, err)
   167  	}
   168  	expected = []string{fourthID, thirdID}
   169  
   170  	if !assertContainerList(out, expected) {
   171  		t.Error("Container list is not in the correct order")
   172  	}
   173  
   174  	runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "-n=2")
   175  	out, _, err = runCommandWithOutput(runCmd)
   176  	if err != nil {
   177  		t.Fatal(out, err)
   178  	}
   179  
   180  	if !assertContainerList(out, expected) {
   181  		t.Error("Container list is not in the correct order")
   182  	}
   183  
   184  	// before & limit
   185  	runCmd = exec.Command(dockerBinary, "ps", "--before", fourthID, "-n=1", "-a")
   186  	out, _, err = runCommandWithOutput(runCmd)
   187  	if err != nil {
   188  		t.Fatal(out, err)
   189  	}
   190  	expected = []string{thirdID}
   191  
   192  	if !assertContainerList(out, expected) {
   193  		t.Error("Container list is not in the correct order")
   194  	}
   195  
   196  	runCmd = exec.Command(dockerBinary, "ps", "--before", fourthID, "-n=1")
   197  	out, _, err = runCommandWithOutput(runCmd)
   198  	if err != nil {
   199  		t.Fatal(out, err)
   200  	}
   201  
   202  	if !assertContainerList(out, expected) {
   203  		t.Error("Container list is not in the correct order")
   204  	}
   205  
   206  	// since & before & limit
   207  	runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "--before", fourthID, "-n=1", "-a")
   208  	out, _, err = runCommandWithOutput(runCmd)
   209  	if err != nil {
   210  		t.Fatal(out, err)
   211  	}
   212  	expected = []string{thirdID}
   213  
   214  	if !assertContainerList(out, expected) {
   215  		t.Error("Container list is not in the correct order")
   216  	}
   217  
   218  	runCmd = exec.Command(dockerBinary, "ps", "--since", firstID, "--before", fourthID, "-n=1")
   219  	out, _, err = runCommandWithOutput(runCmd)
   220  	if err != nil {
   221  		t.Fatal(out, err)
   222  	}
   223  
   224  	if !assertContainerList(out, expected) {
   225  		t.Error("Container list is not in the correct order")
   226  	}
   227  
   228  	logDone("ps - test ps options")
   229  }
   230  
   231  func assertContainerList(out string, expected []string) bool {
   232  	lines := strings.Split(strings.Trim(out, "\n "), "\n")
   233  	if len(lines)-1 != len(expected) {
   234  		return false
   235  	}
   236  
   237  	containerIDIndex := strings.Index(lines[0], "CONTAINER ID")
   238  	for i := 0; i < len(expected); i++ {
   239  		foundID := lines[i+1][containerIDIndex : containerIDIndex+12]
   240  		if foundID != expected[i][:12] {
   241  			return false
   242  		}
   243  	}
   244  
   245  	return true
   246  }
   247  
   248  func TestPsListContainersSize(t *testing.T) {
   249  	defer deleteAllContainers()
   250  
   251  	cmd := exec.Command(dockerBinary, "run", "-d", "busybox", "echo", "hello")
   252  	runCommandWithOutput(cmd)
   253  	cmd = exec.Command(dockerBinary, "ps", "-s", "-n=1")
   254  	base_out, _, err := runCommandWithOutput(cmd)
   255  	base_lines := strings.Split(strings.Trim(base_out, "\n "), "\n")
   256  	base_sizeIndex := strings.Index(base_lines[0], "SIZE")
   257  	base_foundSize := base_lines[1][base_sizeIndex:]
   258  	base_bytes, err := strconv.Atoi(strings.Split(base_foundSize, " ")[0])
   259  	if err != nil {
   260  		t.Fatal(err)
   261  	}
   262  
   263  	name := "test_size"
   264  	runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "sh", "-c", "echo 1 > test")
   265  	out, _, err := runCommandWithOutput(runCmd)
   266  	if err != nil {
   267  		t.Fatal(out, err)
   268  	}
   269  	id, err := getIDByName(name)
   270  	if err != nil {
   271  		t.Fatal(err)
   272  	}
   273  
   274  	runCmd = exec.Command(dockerBinary, "ps", "-s", "-n=1")
   275  	wait := make(chan struct{})
   276  	go func() {
   277  		out, _, err = runCommandWithOutput(runCmd)
   278  		close(wait)
   279  	}()
   280  	select {
   281  	case <-wait:
   282  	case <-time.After(3 * time.Second):
   283  		t.Fatalf("Calling \"docker ps -s\" timed out!")
   284  	}
   285  	if err != nil {
   286  		t.Fatal(out, err)
   287  	}
   288  	lines := strings.Split(strings.Trim(out, "\n "), "\n")
   289  	sizeIndex := strings.Index(lines[0], "SIZE")
   290  	idIndex := strings.Index(lines[0], "CONTAINER ID")
   291  	foundID := lines[1][idIndex : idIndex+12]
   292  	if foundID != id[:12] {
   293  		t.Fatalf("Expected id %s, got %s", id[:12], foundID)
   294  	}
   295  	expectedSize := fmt.Sprintf("%d B", (2 + base_bytes))
   296  	foundSize := lines[1][sizeIndex:]
   297  	if foundSize != expectedSize {
   298  		t.Fatalf("Expected size %q, got %q", expectedSize, foundSize)
   299  	}
   300  
   301  	logDone("ps - test ps size")
   302  }
   303  
   304  func TestPsListContainersFilterStatus(t *testing.T) {
   305  	// FIXME: this should test paused, but it makes things hang and its wonky
   306  	// this is because paused containers can't be controlled by signals
   307  	defer deleteAllContainers()
   308  
   309  	// start exited container
   310  	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox")
   311  	out, _, err := runCommandWithOutput(runCmd)
   312  	if err != nil {
   313  		t.Fatal(out, err)
   314  	}
   315  	firstID := stripTrailingCharacters(out)
   316  
   317  	// make sure the exited cintainer is not running
   318  	runCmd = exec.Command(dockerBinary, "wait", firstID)
   319  	if out, _, err = runCommandWithOutput(runCmd); err != nil {
   320  		t.Fatal(out, err)
   321  	}
   322  
   323  	// start running container
   324  	runCmd = exec.Command(dockerBinary, "run", "-itd", "busybox")
   325  	out, _, err = runCommandWithOutput(runCmd)
   326  	if err != nil {
   327  		t.Fatal(out, err)
   328  	}
   329  	secondID := stripTrailingCharacters(out)
   330  
   331  	// filter containers by exited
   332  	runCmd = exec.Command(dockerBinary, "ps", "-q", "--filter=status=exited")
   333  	out, _, err = runCommandWithOutput(runCmd)
   334  	if err != nil {
   335  		t.Fatal(out, err)
   336  	}
   337  	containerOut := strings.TrimSpace(out)
   338  	if containerOut != firstID[:12] {
   339  		t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
   340  	}
   341  
   342  	runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=status=running")
   343  	out, _, err = runCommandWithOutput(runCmd)
   344  	if err != nil {
   345  		t.Fatal(out, err)
   346  	}
   347  	containerOut = strings.TrimSpace(out)
   348  	if containerOut != secondID[:12] {
   349  		t.Fatalf("Expected id %s, got %s for running filter, output: %q", secondID[:12], containerOut, out)
   350  	}
   351  
   352  	logDone("ps - test ps filter status")
   353  }
   354  
   355  func TestPsListContainersFilterID(t *testing.T) {
   356  	defer deleteAllContainers()
   357  
   358  	// start container
   359  	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox")
   360  	out, _, err := runCommandWithOutput(runCmd)
   361  	if err != nil {
   362  		t.Fatal(out, err)
   363  	}
   364  	firstID := stripTrailingCharacters(out)
   365  
   366  	// start another container
   367  	runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 360")
   368  	if out, _, err = runCommandWithOutput(runCmd); err != nil {
   369  		t.Fatal(out, err)
   370  	}
   371  
   372  	// filter containers by id
   373  	runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=id="+firstID)
   374  	if out, _, err = runCommandWithOutput(runCmd); err != nil {
   375  		t.Fatal(out, err)
   376  	}
   377  	containerOut := strings.TrimSpace(out)
   378  	if containerOut != firstID[:12] {
   379  		t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
   380  	}
   381  
   382  	logDone("ps - test ps filter id")
   383  }
   384  
   385  func TestPsListContainersFilterName(t *testing.T) {
   386  	defer deleteAllContainers()
   387  
   388  	// start container
   389  	runCmd := exec.Command(dockerBinary, "run", "-d", "--name=a_name_to_match", "busybox")
   390  	out, _, err := runCommandWithOutput(runCmd)
   391  	if err != nil {
   392  		t.Fatal(out, err)
   393  	}
   394  	firstID := stripTrailingCharacters(out)
   395  
   396  	// start another container
   397  	runCmd = exec.Command(dockerBinary, "run", "-d", "--name=b_name_to_match", "busybox", "sh", "-c", "sleep 360")
   398  	if out, _, err = runCommandWithOutput(runCmd); err != nil {
   399  		t.Fatal(out, err)
   400  	}
   401  
   402  	// filter containers by name
   403  	runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=name=a_name_to_match")
   404  	if out, _, err = runCommandWithOutput(runCmd); err != nil {
   405  		t.Fatal(out, err)
   406  	}
   407  	containerOut := strings.TrimSpace(out)
   408  	if containerOut != firstID[:12] {
   409  		t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
   410  	}
   411  
   412  	logDone("ps - test ps filter name")
   413  }
   414  
   415  func TestPsListContainersFilterLabel(t *testing.T) {
   416  	// start container
   417  	runCmd := exec.Command(dockerBinary, "run", "-d", "-l", "match=me", "-l", "second=tag", "busybox")
   418  	out, _, err := runCommandWithOutput(runCmd)
   419  	if err != nil {
   420  		t.Fatal(out, err)
   421  	}
   422  	firstID := stripTrailingCharacters(out)
   423  
   424  	// start another container
   425  	runCmd = exec.Command(dockerBinary, "run", "-d", "-l", "match=me too", "busybox")
   426  	if out, _, err = runCommandWithOutput(runCmd); err != nil {
   427  		t.Fatal(out, err)
   428  	}
   429  	secondID := stripTrailingCharacters(out)
   430  
   431  	// start third container
   432  	runCmd = exec.Command(dockerBinary, "run", "-d", "-l", "nomatch=me", "busybox")
   433  	if out, _, err = runCommandWithOutput(runCmd); err != nil {
   434  		t.Fatal(out, err)
   435  	}
   436  	thirdID := stripTrailingCharacters(out)
   437  
   438  	// filter containers by exact match
   439  	runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me")
   440  	if out, _, err = runCommandWithOutput(runCmd); err != nil {
   441  		t.Fatal(out, err)
   442  	}
   443  	containerOut := strings.TrimSpace(out)
   444  	if containerOut != firstID {
   445  		t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out)
   446  	}
   447  
   448  	// filter containers by two labels
   449  	runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me", "--filter=label=second=tag")
   450  	if out, _, err = runCommandWithOutput(runCmd); err != nil {
   451  		t.Fatal(out, err)
   452  	}
   453  	containerOut = strings.TrimSpace(out)
   454  	if containerOut != firstID {
   455  		t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out)
   456  	}
   457  
   458  	// filter containers by two labels, but expect not found because of AND behavior
   459  	runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me", "--filter=label=second=tag-no")
   460  	if out, _, err = runCommandWithOutput(runCmd); err != nil {
   461  		t.Fatal(out, err)
   462  	}
   463  	containerOut = strings.TrimSpace(out)
   464  	if containerOut != "" {
   465  		t.Fatalf("Expected nothing, got %s for exited filter, output: %q", containerOut, out)
   466  	}
   467  
   468  	// filter containers by exact key
   469  	runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--no-trunc", "--filter=label=match")
   470  	if out, _, err = runCommandWithOutput(runCmd); err != nil {
   471  		t.Fatal(out, err)
   472  	}
   473  	containerOut = strings.TrimSpace(out)
   474  	if (!strings.Contains(containerOut, firstID) || !strings.Contains(containerOut, secondID)) || strings.Contains(containerOut, thirdID) {
   475  		t.Fatalf("Expected ids %s,%s, got %s for exited filter, output: %q", firstID, secondID, containerOut, out)
   476  	}
   477  
   478  	deleteAllContainers()
   479  
   480  	logDone("ps - test ps filter label")
   481  }
   482  
   483  func TestPsListContainersFilterExited(t *testing.T) {
   484  	defer deleteAllContainers()
   485  
   486  	runCmd := exec.Command(dockerBinary, "run", "-d", "--name", "top", "busybox", "top")
   487  	if out, _, err := runCommandWithOutput(runCmd); err != nil {
   488  		t.Fatal(out, err)
   489  	}
   490  
   491  	runCmd = exec.Command(dockerBinary, "run", "--name", "zero1", "busybox", "true")
   492  	if out, _, err := runCommandWithOutput(runCmd); err != nil {
   493  		t.Fatal(out, err)
   494  	}
   495  	firstZero, err := getIDByName("zero1")
   496  	if err != nil {
   497  		t.Fatal(err)
   498  	}
   499  
   500  	runCmd = exec.Command(dockerBinary, "run", "--name", "zero2", "busybox", "true")
   501  	if out, _, err := runCommandWithOutput(runCmd); err != nil {
   502  		t.Fatal(out, err)
   503  	}
   504  	secondZero, err := getIDByName("zero2")
   505  	if err != nil {
   506  		t.Fatal(err)
   507  	}
   508  
   509  	runCmd = exec.Command(dockerBinary, "run", "--name", "nonzero1", "busybox", "false")
   510  	if out, _, err := runCommandWithOutput(runCmd); err == nil {
   511  		t.Fatal("Should fail.", out, err)
   512  	}
   513  	firstNonZero, err := getIDByName("nonzero1")
   514  	if err != nil {
   515  		t.Fatal(err)
   516  	}
   517  
   518  	runCmd = exec.Command(dockerBinary, "run", "--name", "nonzero2", "busybox", "false")
   519  	if out, _, err := runCommandWithOutput(runCmd); err == nil {
   520  		t.Fatal("Should fail.", out, err)
   521  	}
   522  	secondNonZero, err := getIDByName("nonzero2")
   523  	if err != nil {
   524  		t.Fatal(err)
   525  	}
   526  
   527  	// filter containers by exited=0
   528  	runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--no-trunc", "--filter=exited=0")
   529  	out, _, err := runCommandWithOutput(runCmd)
   530  	if err != nil {
   531  		t.Fatal(out, err)
   532  	}
   533  	ids := strings.Split(strings.TrimSpace(out), "\n")
   534  	if len(ids) != 2 {
   535  		t.Fatalf("Should be 2 zero exited containerst got %d", len(ids))
   536  	}
   537  	if ids[0] != secondZero {
   538  		t.Fatalf("First in list should be %q, got %q", secondZero, ids[0])
   539  	}
   540  	if ids[1] != firstZero {
   541  		t.Fatalf("Second in list should be %q, got %q", firstZero, ids[1])
   542  	}
   543  
   544  	runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--no-trunc", "--filter=exited=1")
   545  	out, _, err = runCommandWithOutput(runCmd)
   546  	if err != nil {
   547  		t.Fatal(out, err)
   548  	}
   549  	ids = strings.Split(strings.TrimSpace(out), "\n")
   550  	if len(ids) != 2 {
   551  		t.Fatalf("Should be 2 zero exited containerst got %d", len(ids))
   552  	}
   553  	if ids[0] != secondNonZero {
   554  		t.Fatalf("First in list should be %q, got %q", secondNonZero, ids[0])
   555  	}
   556  	if ids[1] != firstNonZero {
   557  		t.Fatalf("Second in list should be %q, got %q", firstNonZero, ids[1])
   558  	}
   559  
   560  	logDone("ps - test ps filter exited")
   561  }
   562  
   563  func TestPsRightTagName(t *testing.T) {
   564  	tag := "asybox:shmatest"
   565  	defer deleteAllContainers()
   566  	defer deleteImages(tag)
   567  	if out, err := exec.Command(dockerBinary, "tag", "busybox", tag).CombinedOutput(); err != nil {
   568  		t.Fatalf("Failed to tag image: %s, out: %q", err, out)
   569  	}
   570  
   571  	var id1 string
   572  	if out, err := exec.Command(dockerBinary, "run", "-d", "busybox", "top").CombinedOutput(); err != nil {
   573  		t.Fatalf("Failed to run container: %s, out: %q", err, out)
   574  	} else {
   575  		id1 = strings.TrimSpace(string(out))
   576  	}
   577  
   578  	var id2 string
   579  	if out, err := exec.Command(dockerBinary, "run", "-d", tag, "top").CombinedOutput(); err != nil {
   580  		t.Fatalf("Failed to run container: %s, out: %q", err, out)
   581  	} else {
   582  		id2 = strings.TrimSpace(string(out))
   583  	}
   584  	out, err := exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput()
   585  	if err != nil {
   586  		t.Fatalf("Failed to run 'ps': %s, out: %q", err, out)
   587  	}
   588  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   589  	// skip header
   590  	lines = lines[1:]
   591  	if len(lines) != 2 {
   592  		t.Fatalf("There should be 2 running container, got %d", len(lines))
   593  	}
   594  	for _, line := range lines {
   595  		f := strings.Fields(line)
   596  		switch f[0] {
   597  		case id1:
   598  			if f[1] != "busybox:latest" {
   599  				t.Fatalf("Expected %s tag for id %s, got %s", "busybox", id1, f[1])
   600  			}
   601  		case id2:
   602  			if f[1] != tag {
   603  				t.Fatalf("Expected %s tag for id %s, got %s", tag, id1, f[1])
   604  			}
   605  		default:
   606  			t.Fatalf("Unexpected id %s, expected %s and %s", f[0], id1, id2)
   607  		}
   608  	}
   609  	logDone("ps - right tags for containers")
   610  }
   611  
   612  func TestPsLinkedWithNoTrunc(t *testing.T) {
   613  	defer deleteAllContainers()
   614  	if out, err := exec.Command(dockerBinary, "run", "--name=first", "-d", "busybox", "top").CombinedOutput(); err != nil {
   615  		t.Fatalf("Output: %s, err: %s", out, err)
   616  	}
   617  	if out, err := exec.Command(dockerBinary, "run", "--name=second", "--link=first:first", "-d", "busybox", "top").CombinedOutput(); err != nil {
   618  		t.Fatalf("Output: %s, err: %s", out, err)
   619  	}
   620  	out, err := exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput()
   621  	if err != nil {
   622  		t.Fatalf("Output: %s, err: %s", out, err)
   623  	}
   624  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   625  	// strip header
   626  	lines = lines[1:]
   627  	expected := []string{"second", "first,second/first"}
   628  	var names []string
   629  	for _, l := range lines {
   630  		fields := strings.Fields(l)
   631  		names = append(names, fields[len(fields)-1])
   632  	}
   633  	if !reflect.DeepEqual(expected, names) {
   634  		t.Fatalf("Expected array: %v, got: %v", expected, names)
   635  	}
   636  }
   637  
   638  func TestPsGroupPortRange(t *testing.T) {
   639  	defer deleteAllContainers()
   640  
   641  	portRange := "3300-3900"
   642  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "porttest", "-p", portRange+":"+portRange, "busybox", "top"))
   643  	if err != nil {
   644  		t.Fatal(out, err)
   645  	}
   646  
   647  	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "ps"))
   648  	if err != nil {
   649  		t.Fatal(out, err)
   650  	}
   651  
   652  	// check that the port range is in the output
   653  	if !strings.Contains(string(out), portRange) {
   654  		t.Fatalf("docker ps output should have had the port range %q: %s", portRange, string(out))
   655  	}
   656  
   657  	logDone("ps - port range")
   658  }