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