github.com/afein/docker@v1.8.2/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 ) 16 17 func (s *DockerSuite) TestPsListContainers(c *check.C) { 18 19 out, _ := dockerCmd(c, "run", "-d", "busybox", "top") 20 firstID := strings.TrimSpace(out) 21 22 out, _ = dockerCmd(c, "run", "-d", "busybox", "top") 23 secondID := strings.TrimSpace(out) 24 25 // not long running 26 out, _ = dockerCmd(c, "run", "-d", "busybox", "true") 27 thirdID := strings.TrimSpace(out) 28 29 out, _ = dockerCmd(c, "run", "-d", "busybox", "top") 30 fourthID := strings.TrimSpace(out) 31 32 // make sure the second is running 33 if err := waitRun(secondID); err != nil { 34 c.Fatalf("waiting for container failed: %v", err) 35 } 36 37 // make sure third one is not running 38 dockerCmd(c, "wait", thirdID) 39 40 // make sure the forth is running 41 if err := waitRun(fourthID); err != nil { 42 c.Fatalf("waiting for container failed: %v", err) 43 } 44 45 // all 46 out, _ = dockerCmd(c, "ps", "-a") 47 if !assertContainerList(out, []string{fourthID, thirdID, secondID, firstID}) { 48 c.Errorf("Container list is not in the correct order: %s", out) 49 } 50 51 // running 52 out, _ = dockerCmd(c, "ps") 53 if !assertContainerList(out, []string{fourthID, secondID, firstID}) { 54 c.Errorf("Container list is not in the correct order: %s", out) 55 } 56 57 // from here all flag '-a' is ignored 58 59 // limit 60 out, _ = dockerCmd(c, "ps", "-n=2", "-a") 61 expected := []string{fourthID, thirdID} 62 if !assertContainerList(out, expected) { 63 c.Errorf("Container list is not in the correct order: %s", out) 64 } 65 66 out, _ = dockerCmd(c, "ps", "-n=2") 67 if !assertContainerList(out, expected) { 68 c.Errorf("Container list is not in the correct order: %s", out) 69 } 70 71 // since 72 out, _ = dockerCmd(c, "ps", "--since", firstID, "-a") 73 expected = []string{fourthID, thirdID, secondID} 74 if !assertContainerList(out, expected) { 75 c.Errorf("Container list is not in the correct order: %s", out) 76 } 77 78 out, _ = dockerCmd(c, "ps", "--since", firstID) 79 if !assertContainerList(out, expected) { 80 c.Errorf("Container list is not in the correct order: %s", out) 81 } 82 83 // before 84 out, _ = dockerCmd(c, "ps", "--before", thirdID, "-a") 85 expected = []string{secondID, firstID} 86 if !assertContainerList(out, expected) { 87 c.Errorf("Container list is not in the correct order: %s", out) 88 } 89 90 out, _ = dockerCmd(c, "ps", "--before", thirdID) 91 if !assertContainerList(out, expected) { 92 c.Errorf("Container list is not in the correct order: %s", out) 93 } 94 95 // since & before 96 out, _ = dockerCmd(c, "ps", "--since", firstID, "--before", fourthID, "-a") 97 expected = []string{thirdID, secondID} 98 if !assertContainerList(out, expected) { 99 c.Errorf("Container list is not in the correct order: %s", out) 100 } 101 102 out, _ = dockerCmd(c, "ps", "--since", firstID, "--before", fourthID) 103 if !assertContainerList(out, expected) { 104 c.Errorf("Container list is not in the correct order: %s", out) 105 } 106 107 // since & limit 108 out, _ = dockerCmd(c, "ps", "--since", firstID, "-n=2", "-a") 109 expected = []string{fourthID, thirdID} 110 111 if !assertContainerList(out, expected) { 112 c.Errorf("Container list is not in the correct order: %s", out) 113 } 114 115 out, _ = dockerCmd(c, "ps", "--since", firstID, "-n=2") 116 if !assertContainerList(out, expected) { 117 c.Errorf("Container list is not in the correct order: %s", out) 118 } 119 120 // before & limit 121 out, _ = dockerCmd(c, "ps", "--before", fourthID, "-n=1", "-a") 122 expected = []string{thirdID} 123 if !assertContainerList(out, expected) { 124 c.Errorf("Container list is not in the correct order: %s", out) 125 } 126 127 out, _ = dockerCmd(c, "ps", "--before", fourthID, "-n=1") 128 if !assertContainerList(out, expected) { 129 c.Errorf("Container list is not in the correct order: %s", out) 130 } 131 132 out, _ = dockerCmd(c, "ps", "--since", firstID, "--before", fourthID, "-n=1", "-a") 133 expected = []string{thirdID} 134 if !assertContainerList(out, expected) { 135 c.Errorf("Container list is not in the correct order: %s", out) 136 } 137 138 out, _ = dockerCmd(c, "ps", "--since", firstID, "--before", fourthID, "-n=1") 139 if !assertContainerList(out, expected) { 140 c.Errorf("Container list is not in the correct order: %s", out) 141 } 142 143 } 144 145 func assertContainerList(out string, expected []string) bool { 146 lines := strings.Split(strings.Trim(out, "\n "), "\n") 147 if len(lines)-1 != len(expected) { 148 return false 149 } 150 151 containerIDIndex := strings.Index(lines[0], "CONTAINER ID") 152 for i := 0; i < len(expected); i++ { 153 foundID := lines[i+1][containerIDIndex : containerIDIndex+12] 154 if foundID != expected[i][:12] { 155 return false 156 } 157 } 158 159 return true 160 } 161 162 func (s *DockerSuite) TestPsListContainersSize(c *check.C) { 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 // FIXME: this should test paused, but it makes things hang and its wonky 216 // this is because paused containers can't be controlled by signals 217 218 // start exited container 219 out, _ := dockerCmd(c, "run", "-d", "busybox") 220 firstID := strings.TrimSpace(out) 221 222 // make sure the exited cintainer is not running 223 dockerCmd(c, "wait", firstID) 224 225 // start running container 226 out, _ = dockerCmd(c, "run", "-itd", "busybox") 227 secondID := strings.TrimSpace(out) 228 229 // filter containers by exited 230 out, _ = dockerCmd(c, "ps", "-q", "--filter=status=exited") 231 containerOut := strings.TrimSpace(out) 232 if containerOut != firstID[:12] { 233 c.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out) 234 } 235 236 out, _ = dockerCmd(c, "ps", "-a", "-q", "--filter=status=running") 237 containerOut = strings.TrimSpace(out) 238 if containerOut != secondID[:12] { 239 c.Fatalf("Expected id %s, got %s for running filter, output: %q", secondID[:12], containerOut, out) 240 } 241 242 out, _, _ = dockerCmdWithTimeout(time.Second*60, "ps", "-a", "-q", "--filter=status=rubbish") 243 if !strings.Contains(out, "Unrecognised filter value for status") { 244 c.Fatalf("Expected error response due to invalid status filter output: %q", out) 245 } 246 247 } 248 249 func (s *DockerSuite) TestPsListContainersFilterID(c *check.C) { 250 251 // start container 252 out, _ := dockerCmd(c, "run", "-d", "busybox") 253 firstID := strings.TrimSpace(out) 254 255 // start another container 256 dockerCmd(c, "run", "-d", "busybox", "top") 257 258 // filter containers by id 259 out, _ = dockerCmd(c, "ps", "-a", "-q", "--filter=id="+firstID) 260 containerOut := strings.TrimSpace(out) 261 if containerOut != firstID[:12] { 262 c.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out) 263 } 264 265 } 266 267 func (s *DockerSuite) TestPsListContainersFilterName(c *check.C) { 268 269 // start container 270 out, _ := dockerCmd(c, "run", "-d", "--name=a_name_to_match", "busybox") 271 firstID := strings.TrimSpace(out) 272 273 // start another container 274 dockerCmd(c, "run", "-d", "--name=b_name_to_match", "busybox", "top") 275 276 // filter containers by name 277 out, _ = dockerCmd(c, "ps", "-a", "-q", "--filter=name=a_name_to_match") 278 containerOut := strings.TrimSpace(out) 279 if containerOut != firstID[:12] { 280 c.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out) 281 } 282 283 } 284 285 func (s *DockerSuite) TestPsListContainersFilterLabel(c *check.C) { 286 // start container 287 out, _ := dockerCmd(c, "run", "-d", "-l", "match=me", "-l", "second=tag", "busybox") 288 firstID := strings.TrimSpace(out) 289 290 // start another container 291 out, _ = dockerCmd(c, "run", "-d", "-l", "match=me too", "busybox") 292 secondID := strings.TrimSpace(out) 293 294 // start third container 295 out, _ = dockerCmd(c, "run", "-d", "-l", "nomatch=me", "busybox") 296 thirdID := strings.TrimSpace(out) 297 298 // filter containers by exact match 299 out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me") 300 containerOut := strings.TrimSpace(out) 301 if containerOut != firstID { 302 c.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out) 303 } 304 305 // filter containers by two labels 306 out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me", "--filter=label=second=tag") 307 containerOut = strings.TrimSpace(out) 308 if containerOut != firstID { 309 c.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out) 310 } 311 312 // filter containers by two labels, but expect not found because of AND behavior 313 out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me", "--filter=label=second=tag-no") 314 containerOut = strings.TrimSpace(out) 315 if containerOut != "" { 316 c.Fatalf("Expected nothing, got %s for exited filter, output: %q", containerOut, out) 317 } 318 319 // filter containers by exact key 320 out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match") 321 containerOut = strings.TrimSpace(out) 322 if (!strings.Contains(containerOut, firstID) || !strings.Contains(containerOut, secondID)) || strings.Contains(containerOut, thirdID) { 323 c.Fatalf("Expected ids %s,%s, got %s for exited filter, output: %q", firstID, secondID, containerOut, out) 324 } 325 } 326 327 func (s *DockerSuite) TestPsListContainersFilterExited(c *check.C) { 328 329 dockerCmd(c, "run", "-d", "--name", "top", "busybox", "top") 330 331 dockerCmd(c, "run", "--name", "zero1", "busybox", "true") 332 firstZero, err := getIDByName("zero1") 333 if err != nil { 334 c.Fatal(err) 335 } 336 337 dockerCmd(c, "run", "--name", "zero2", "busybox", "true") 338 secondZero, err := getIDByName("zero2") 339 if err != nil { 340 c.Fatal(err) 341 } 342 343 if out, _, err := dockerCmdWithError(c, "run", "--name", "nonzero1", "busybox", "false"); err == nil { 344 c.Fatal("Should fail.", out, err) 345 } 346 347 firstNonZero, err := getIDByName("nonzero1") 348 if err != nil { 349 c.Fatal(err) 350 } 351 352 if out, _, err := dockerCmdWithError(c, "run", "--name", "nonzero2", "busybox", "false"); err == nil { 353 c.Fatal("Should fail.", out, err) 354 } 355 secondNonZero, err := getIDByName("nonzero2") 356 if err != nil { 357 c.Fatal(err) 358 } 359 360 // filter containers by exited=0 361 out, _ := dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=exited=0") 362 ids := strings.Split(strings.TrimSpace(out), "\n") 363 if len(ids) != 2 { 364 c.Fatalf("Should be 2 zero exited containers got %d: %s", len(ids), out) 365 } 366 if ids[0] != secondZero { 367 c.Fatalf("First in list should be %q, got %q", secondZero, ids[0]) 368 } 369 if ids[1] != firstZero { 370 c.Fatalf("Second in list should be %q, got %q", firstZero, ids[1]) 371 } 372 373 out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=exited=1") 374 ids = strings.Split(strings.TrimSpace(out), "\n") 375 if len(ids) != 2 { 376 c.Fatalf("Should be 2 zero exited containers got %d", len(ids)) 377 } 378 if ids[0] != secondNonZero { 379 c.Fatalf("First in list should be %q, got %q", secondNonZero, ids[0]) 380 } 381 if ids[1] != firstNonZero { 382 c.Fatalf("Second in list should be %q, got %q", firstNonZero, ids[1]) 383 } 384 385 } 386 387 func (s *DockerSuite) TestPsRightTagName(c *check.C) { 388 tag := "asybox:shmatest" 389 dockerCmd(c, "tag", "busybox", tag) 390 391 var id1 string 392 out, _ := dockerCmd(c, "run", "-d", "busybox", "top") 393 id1 = strings.TrimSpace(string(out)) 394 395 var id2 string 396 out, _ = dockerCmd(c, "run", "-d", tag, "top") 397 id2 = strings.TrimSpace(string(out)) 398 399 var imageID string 400 out, _ = dockerCmd(c, "inspect", "-f", "{{.Id}}", "busybox") 401 imageID = strings.TrimSpace(string(out)) 402 403 var id3 string 404 out, _ = dockerCmd(c, "run", "-d", imageID, "top") 405 id3 = strings.TrimSpace(string(out)) 406 407 out, _ = dockerCmd(c, "ps", "--no-trunc") 408 lines := strings.Split(strings.TrimSpace(string(out)), "\n") 409 // skip header 410 lines = lines[1:] 411 if len(lines) != 3 { 412 c.Fatalf("There should be 3 running container, got %d", len(lines)) 413 } 414 for _, line := range lines { 415 f := strings.Fields(line) 416 switch f[0] { 417 case id1: 418 if f[1] != "busybox" { 419 c.Fatalf("Expected %s tag for id %s, got %s", "busybox", id1, f[1]) 420 } 421 case id2: 422 if f[1] != tag { 423 c.Fatalf("Expected %s tag for id %s, got %s", tag, id2, f[1]) 424 } 425 case id3: 426 if f[1] != imageID { 427 c.Fatalf("Expected %s imageID for id %s, got %s", tag, id3, f[1]) 428 } 429 default: 430 c.Fatalf("Unexpected id %s, expected %s and %s and %s", f[0], id1, id2, id3) 431 } 432 } 433 } 434 435 func (s *DockerSuite) TestPsLinkedWithNoTrunc(c *check.C) { 436 dockerCmd(c, "run", "--name=first", "-d", "busybox", "top") 437 dockerCmd(c, "run", "--name=second", "--link=first:first", "-d", "busybox", "top") 438 439 out, _ := dockerCmd(c, "ps", "--no-trunc") 440 lines := strings.Split(strings.TrimSpace(string(out)), "\n") 441 // strip header 442 lines = lines[1:] 443 expected := []string{"second", "first,second/first"} 444 var names []string 445 for _, l := range lines { 446 fields := strings.Fields(l) 447 names = append(names, fields[len(fields)-1]) 448 } 449 if !reflect.DeepEqual(expected, names) { 450 c.Fatalf("Expected array: %v, got: %v", expected, names) 451 } 452 } 453 454 func (s *DockerSuite) TestPsGroupPortRange(c *check.C) { 455 456 portRange := "3800-3900" 457 dockerCmd(c, "run", "-d", "--name", "porttest", "-p", portRange+":"+portRange, "busybox", "top") 458 459 out, _ := dockerCmd(c, "ps") 460 461 // check that the port range is in the output 462 if !strings.Contains(string(out), portRange) { 463 c.Fatalf("docker ps output should have had the port range %q: %s", portRange, string(out)) 464 } 465 466 } 467 468 func (s *DockerSuite) TestPsWithSize(c *check.C) { 469 dockerCmd(c, "run", "-d", "--name", "sizetest", "busybox", "top") 470 471 out, _ := dockerCmd(c, "ps", "--size") 472 if !strings.Contains(out, "virtual") { 473 c.Fatalf("docker ps with --size should show virtual size of container") 474 } 475 } 476 477 func (s *DockerSuite) TestPsListContainersFilterCreated(c *check.C) { 478 // create a container 479 out, _ := dockerCmd(c, "create", "busybox") 480 cID := strings.TrimSpace(out) 481 shortCID := cID[:12] 482 483 // Make sure it DOESN'T show up w/o a '-a' for normal 'ps' 484 out, _ = dockerCmd(c, "ps", "-q") 485 if strings.Contains(out, shortCID) { 486 c.Fatalf("Should have not seen '%s' in ps output:\n%s", shortCID, out) 487 } 488 489 // Make sure it DOES show up as 'Created' for 'ps -a' 490 out, _ = dockerCmd(c, "ps", "-a") 491 492 hits := 0 493 for _, line := range strings.Split(out, "\n") { 494 if !strings.Contains(line, shortCID) { 495 continue 496 } 497 hits++ 498 if !strings.Contains(line, "Created") { 499 c.Fatalf("Missing 'Created' on '%s'", line) 500 } 501 } 502 503 if hits != 1 { 504 c.Fatalf("Should have seen '%s' in ps -a output once:%d\n%s", shortCID, hits, out) 505 } 506 507 // filter containers by 'create' - note, no -a needed 508 out, _ = dockerCmd(c, "ps", "-q", "-f", "status=created") 509 containerOut := strings.TrimSpace(out) 510 if !strings.HasPrefix(cID, containerOut) { 511 c.Fatalf("Expected id %s, got %s for filter, out: %s", cID, containerOut, out) 512 } 513 } 514 515 func (s *DockerSuite) TestPsFormatMultiNames(c *check.C) { 516 //create 2 containers and link them 517 dockerCmd(c, "run", "--name=child", "-d", "busybox", "top") 518 dockerCmd(c, "run", "--name=parent", "--link=child:linkedone", "-d", "busybox", "top") 519 520 //use the new format capabilities to only list the names and --no-trunc to get all names 521 out, _ := dockerCmd(c, "ps", "--format", "{{.Names}}", "--no-trunc") 522 lines := strings.Split(strings.TrimSpace(string(out)), "\n") 523 expected := []string{"parent", "child,parent/linkedone"} 524 var names []string 525 for _, l := range lines { 526 names = append(names, l) 527 } 528 if !reflect.DeepEqual(expected, names) { 529 c.Fatalf("Expected array with non-truncated names: %v, got: %v", expected, names) 530 } 531 532 //now list without turning off truncation and make sure we only get the non-link names 533 out, _ = dockerCmd(c, "ps", "--format", "{{.Names}}") 534 lines = strings.Split(strings.TrimSpace(string(out)), "\n") 535 expected = []string{"parent", "child"} 536 var truncNames []string 537 for _, l := range lines { 538 truncNames = append(truncNames, l) 539 } 540 if !reflect.DeepEqual(expected, truncNames) { 541 c.Fatalf("Expected array with truncated names: %v, got: %v", expected, truncNames) 542 } 543 544 } 545 546 func (s *DockerSuite) TestPsFormatHeaders(c *check.C) { 547 // make sure no-container "docker ps" still prints the header row 548 out, _ := dockerCmd(c, "ps", "--format", "table {{.ID}}") 549 if out != "CONTAINER ID\n" { 550 c.Fatalf(`Expected 'CONTAINER ID\n', got %v`, out) 551 } 552 553 // verify that "docker ps" with a container still prints the header row also 554 dockerCmd(c, "run", "--name=test", "-d", "busybox", "top") 555 out, _ = dockerCmd(c, "ps", "--format", "table {{.Names}}") 556 if out != "NAMES\ntest\n" { 557 c.Fatalf(`Expected 'NAMES\ntest\n', got %v`, out) 558 } 559 } 560 561 func (s *DockerSuite) TestPsDefaultFormatAndQuiet(c *check.C) { 562 config := `{ 563 "psFormat": "{{ .ID }} default" 564 }` 565 d, err := ioutil.TempDir("", "integration-cli-") 566 c.Assert(err, check.IsNil) 567 defer os.RemoveAll(d) 568 569 err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644) 570 c.Assert(err, check.IsNil) 571 572 out, _ := dockerCmd(c, "run", "--name=test", "-d", "busybox", "top") 573 id := strings.TrimSpace(out) 574 575 out, _ = dockerCmd(c, "--config", d, "ps", "-q") 576 if !strings.HasPrefix(id, strings.TrimSpace(out)) { 577 c.Fatalf("Expected to print only the container id, got %v\n", out) 578 } 579 }