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