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