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