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