github.com/hustcat/docker@v1.3.3-0.20160314103604-901c67a8eeab/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) TestPsListContainersSize(c *check.C) { 217 // Problematic on Windows as it doesn't report the size correctly @swernli 218 testRequires(c, DaemonIsLinux) 219 dockerCmd(c, "run", "-d", "busybox") 220 221 baseOut, _ := dockerCmd(c, "ps", "-s", "-n=1") 222 baseLines := strings.Split(strings.Trim(baseOut, "\n "), "\n") 223 baseSizeIndex := strings.Index(baseLines[0], "SIZE") 224 baseFoundsize := baseLines[1][baseSizeIndex:] 225 baseBytes, err := strconv.Atoi(strings.Split(baseFoundsize, " ")[0]) 226 c.Assert(err, checker.IsNil) 227 228 name := "test_size" 229 dockerCmd(c, "run", "--name", name, "busybox", "sh", "-c", "echo 1 > test") 230 id, err := getIDByName(name) 231 c.Assert(err, checker.IsNil) 232 233 runCmd := exec.Command(dockerBinary, "ps", "-s", "-n=1") 234 var out string 235 236 wait := make(chan struct{}) 237 go func() { 238 out, _, err = runCommandWithOutput(runCmd) 239 close(wait) 240 }() 241 select { 242 case <-wait: 243 case <-time.After(3 * time.Second): 244 c.Fatalf("Calling \"docker ps -s\" timed out!") 245 } 246 c.Assert(err, checker.IsNil) 247 lines := strings.Split(strings.Trim(out, "\n "), "\n") 248 c.Assert(lines, checker.HasLen, 2, check.Commentf("Expected 2 lines for 'ps -s -n=1' output, got %d", len(lines))) 249 sizeIndex := strings.Index(lines[0], "SIZE") 250 idIndex := strings.Index(lines[0], "CONTAINER ID") 251 foundID := lines[1][idIndex : idIndex+12] 252 c.Assert(foundID, checker.Equals, id[:12], check.Commentf("Expected id %s, got %s", id[:12], foundID)) 253 expectedSize := fmt.Sprintf("%d B", (2 + baseBytes)) 254 foundSize := lines[1][sizeIndex:] 255 c.Assert(foundSize, checker.Contains, expectedSize, check.Commentf("Expected size %q, got %q", expectedSize, foundSize)) 256 } 257 258 func (s *DockerSuite) TestPsListContainersFilterStatus(c *check.C) { 259 // start exited container 260 out, _ := dockerCmd(c, "run", "-d", "busybox") 261 firstID := strings.TrimSpace(out) 262 263 // make sure the exited container is not running 264 dockerCmd(c, "wait", firstID) 265 266 // start running container 267 out, _ = dockerCmd(c, "run", "-itd", "busybox") 268 secondID := strings.TrimSpace(out) 269 270 // filter containers by exited 271 out, _ = dockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=exited") 272 containerOut := strings.TrimSpace(out) 273 c.Assert(containerOut, checker.Equals, firstID) 274 275 out, _ = dockerCmd(c, "ps", "-a", "--no-trunc", "-q", "--filter=status=running") 276 containerOut = strings.TrimSpace(out) 277 c.Assert(containerOut, checker.Equals, secondID) 278 279 out, _, _ = dockerCmdWithTimeout(time.Second*60, "ps", "-a", "-q", "--filter=status=rubbish") 280 c.Assert(out, checker.Contains, "Unrecognised filter value for status", check.Commentf("Expected error response due to invalid status filter output: %q", out)) 281 282 // Windows doesn't support pausing of containers 283 if daemonPlatform != "windows" { 284 // pause running container 285 out, _ = dockerCmd(c, "run", "-itd", "busybox") 286 pausedID := strings.TrimSpace(out) 287 dockerCmd(c, "pause", pausedID) 288 // make sure the container is unpaused to let the daemon stop it properly 289 defer func() { dockerCmd(c, "unpause", pausedID) }() 290 291 out, _ = dockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=paused") 292 containerOut = strings.TrimSpace(out) 293 c.Assert(containerOut, checker.Equals, pausedID) 294 } 295 } 296 297 func (s *DockerSuite) TestPsListContainersFilterID(c *check.C) { 298 // start container 299 out, _ := dockerCmd(c, "run", "-d", "busybox") 300 firstID := strings.TrimSpace(out) 301 302 // start another container 303 runSleepingContainer(c) 304 305 // filter containers by id 306 out, _ = dockerCmd(c, "ps", "-a", "-q", "--filter=id="+firstID) 307 containerOut := strings.TrimSpace(out) 308 c.Assert(containerOut, checker.Equals, firstID[:12], check.Commentf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)) 309 310 } 311 312 func (s *DockerSuite) TestPsListContainersFilterName(c *check.C) { 313 // start container 314 dockerCmd(c, "run", "--name=a_name_to_match", "busybox") 315 id, err := getIDByName("a_name_to_match") 316 c.Assert(err, check.IsNil) 317 318 // start another container 319 runSleepingContainer(c, "--name=b_name_to_match") 320 321 // filter containers by name 322 out, _ := dockerCmd(c, "ps", "-a", "-q", "--filter=name=a_name_to_match") 323 containerOut := strings.TrimSpace(out) 324 c.Assert(containerOut, checker.Equals, id[:12], check.Commentf("Expected id %s, got %s for exited filter, output: %q", id[:12], containerOut, out)) 325 } 326 327 // Test for the ancestor filter for ps. 328 // There is also the same test but with image:tag@digest in docker_cli_by_digest_test.go 329 // 330 // What the test setups : 331 // - Create 2 image based on busybox using the same repository but different tags 332 // - Create an image based on the previous image (images_ps_filter_test2) 333 // - Run containers for each of those image (busybox, images_ps_filter_test1, images_ps_filter_test2) 334 // - Filter them out :P 335 func (s *DockerSuite) TestPsListContainersFilterAncestorImage(c *check.C) { 336 // Build images 337 imageName1 := "images_ps_filter_test1" 338 imageID1, err := buildImage(imageName1, 339 `FROM busybox 340 LABEL match me 1`, true) 341 c.Assert(err, checker.IsNil) 342 343 imageName1Tagged := "images_ps_filter_test1:tag" 344 imageID1Tagged, err := buildImage(imageName1Tagged, 345 `FROM busybox 346 LABEL match me 1 tagged`, true) 347 c.Assert(err, checker.IsNil) 348 349 imageName2 := "images_ps_filter_test2" 350 imageID2, err := buildImage(imageName2, 351 fmt.Sprintf(`FROM %s 352 LABEL match me 2`, imageName1), true) 353 c.Assert(err, checker.IsNil) 354 355 // start containers 356 dockerCmd(c, "run", "--name=first", "busybox", "echo", "hello") 357 firstID, err := getIDByName("first") 358 c.Assert(err, check.IsNil) 359 360 // start another container 361 dockerCmd(c, "run", "--name=second", "busybox", "echo", "hello") 362 secondID, err := getIDByName("second") 363 c.Assert(err, check.IsNil) 364 365 // start third container 366 dockerCmd(c, "run", "--name=third", imageName1, "echo", "hello") 367 thirdID, err := getIDByName("third") 368 c.Assert(err, check.IsNil) 369 370 // start fourth container 371 dockerCmd(c, "run", "--name=fourth", imageName1Tagged, "echo", "hello") 372 fourthID, err := getIDByName("fourth") 373 c.Assert(err, check.IsNil) 374 375 // start fifth container 376 dockerCmd(c, "run", "--name=fifth", imageName2, "echo", "hello") 377 fifthID, err := getIDByName("fifth") 378 c.Assert(err, check.IsNil) 379 380 var filterTestSuite = []struct { 381 filterName string 382 expectedIDs []string 383 }{ 384 // non existent stuff 385 {"nonexistent", []string{}}, 386 {"nonexistent:tag", []string{}}, 387 // image 388 {"busybox", []string{firstID, secondID, thirdID, fourthID, fifthID}}, 389 {imageName1, []string{thirdID, fifthID}}, 390 {imageName2, []string{fifthID}}, 391 // image:tag 392 {fmt.Sprintf("%s:latest", imageName1), []string{thirdID, fifthID}}, 393 {imageName1Tagged, []string{fourthID}}, 394 // short-id 395 {stringid.TruncateID(imageID1), []string{thirdID, fifthID}}, 396 {stringid.TruncateID(imageID2), []string{fifthID}}, 397 // full-id 398 {imageID1, []string{thirdID, fifthID}}, 399 {imageID1Tagged, []string{fourthID}}, 400 {imageID2, []string{fifthID}}, 401 } 402 403 var out string 404 for _, filter := range filterTestSuite { 405 out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+filter.filterName) 406 checkPsAncestorFilterOutput(c, out, filter.filterName, filter.expectedIDs) 407 } 408 409 // Multiple ancestor filter 410 out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+imageName2, "--filter=ancestor="+imageName1Tagged) 411 checkPsAncestorFilterOutput(c, out, imageName2+","+imageName1Tagged, []string{fourthID, fifthID}) 412 } 413 414 func checkPsAncestorFilterOutput(c *check.C, out string, filterName string, expectedIDs []string) { 415 actualIDs := []string{} 416 if out != "" { 417 actualIDs = strings.Split(out[:len(out)-1], "\n") 418 } 419 sort.Strings(actualIDs) 420 sort.Strings(expectedIDs) 421 422 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)) 423 if len(expectedIDs) > 0 { 424 same := true 425 for i := range expectedIDs { 426 if actualIDs[i] != expectedIDs[i] { 427 c.Logf("%s, %s", actualIDs[i], expectedIDs[i]) 428 same = false 429 break 430 } 431 } 432 c.Assert(same, checker.Equals, true, check.Commentf("Expected filtered container(s) for %s ancestor filter to be %v, got %v", filterName, expectedIDs, actualIDs)) 433 } 434 } 435 436 func (s *DockerSuite) TestPsListContainersFilterLabel(c *check.C) { 437 // start container 438 dockerCmd(c, "run", "--name=first", "-l", "match=me", "-l", "second=tag", "busybox") 439 firstID, err := getIDByName("first") 440 c.Assert(err, check.IsNil) 441 442 // start another container 443 dockerCmd(c, "run", "--name=second", "-l", "match=me too", "busybox") 444 secondID, err := getIDByName("second") 445 c.Assert(err, check.IsNil) 446 447 // start third container 448 dockerCmd(c, "run", "--name=third", "-l", "nomatch=me", "busybox") 449 thirdID, err := getIDByName("third") 450 c.Assert(err, check.IsNil) 451 452 // filter containers by exact match 453 out, _ := dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me") 454 containerOut := strings.TrimSpace(out) 455 c.Assert(containerOut, checker.Equals, firstID, check.Commentf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out)) 456 457 // filter containers by two labels 458 out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me", "--filter=label=second=tag") 459 containerOut = strings.TrimSpace(out) 460 c.Assert(containerOut, checker.Equals, firstID, check.Commentf("Expected id %s, got %s for exited filter, output: %q", firstID, containerOut, out)) 461 462 // filter containers by two labels, but expect not found because of AND behavior 463 out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match=me", "--filter=label=second=tag-no") 464 containerOut = strings.TrimSpace(out) 465 c.Assert(containerOut, checker.Equals, "", check.Commentf("Expected nothing, got %s for exited filter, output: %q", containerOut, out)) 466 467 // filter containers by exact key 468 out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=label=match") 469 containerOut = strings.TrimSpace(out) 470 c.Assert(containerOut, checker.Contains, firstID) 471 c.Assert(containerOut, checker.Contains, secondID) 472 c.Assert(containerOut, checker.Not(checker.Contains), thirdID) 473 } 474 475 func (s *DockerSuite) TestPsListContainersFilterExited(c *check.C) { 476 runSleepingContainer(c, "--name=sleep") 477 478 dockerCmd(c, "run", "--name", "zero1", "busybox", "true") 479 firstZero, err := getIDByName("zero1") 480 c.Assert(err, checker.IsNil) 481 482 dockerCmd(c, "run", "--name", "zero2", "busybox", "true") 483 secondZero, err := getIDByName("zero2") 484 c.Assert(err, checker.IsNil) 485 486 out, _, err := dockerCmdWithError("run", "--name", "nonzero1", "busybox", "false") 487 c.Assert(err, checker.NotNil, check.Commentf("Should fail.", out, err)) 488 489 firstNonZero, err := getIDByName("nonzero1") 490 c.Assert(err, checker.IsNil) 491 492 out, _, err = dockerCmdWithError("run", "--name", "nonzero2", "busybox", "false") 493 c.Assert(err, checker.NotNil, check.Commentf("Should fail.", out, err)) 494 secondNonZero, err := getIDByName("nonzero2") 495 c.Assert(err, checker.IsNil) 496 497 // filter containers by exited=0 498 out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=exited=0") 499 ids := strings.Split(strings.TrimSpace(out), "\n") 500 c.Assert(ids, checker.HasLen, 2, check.Commentf("Should be 2 zero exited containers got %d: %s", len(ids), out)) 501 c.Assert(ids[0], checker.Equals, secondZero, check.Commentf("First in list should be %q, got %q", secondZero, ids[0])) 502 c.Assert(ids[1], checker.Equals, firstZero, check.Commentf("Second in list should be %q, got %q", firstZero, ids[1])) 503 504 out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=exited=1") 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", len(ids))) 507 c.Assert(ids[0], checker.Equals, secondNonZero, check.Commentf("First in list should be %q, got %q", secondNonZero, ids[0])) 508 c.Assert(ids[1], checker.Equals, firstNonZero, check.Commentf("Second in list should be %q, got %q", firstNonZero, ids[1])) 509 510 } 511 512 func (s *DockerSuite) TestPsRightTagName(c *check.C) { 513 // TODO Investigate further why this fails on Windows to Windows CI 514 testRequires(c, DaemonIsLinux) 515 tag := "asybox:shmatest" 516 dockerCmd(c, "tag", "busybox", tag) 517 518 var id1 string 519 out, _ := runSleepingContainer(c) 520 id1 = strings.TrimSpace(string(out)) 521 522 var id2 string 523 out, _ = runSleepingContainerInImage(c, tag) 524 id2 = strings.TrimSpace(string(out)) 525 526 var imageID string 527 out = inspectField(c, "busybox", "Id") 528 imageID = strings.TrimSpace(string(out)) 529 530 var id3 string 531 out, _ = runSleepingContainerInImage(c, imageID) 532 id3 = strings.TrimSpace(string(out)) 533 534 out, _ = dockerCmd(c, "ps", "--no-trunc") 535 lines := strings.Split(strings.TrimSpace(string(out)), "\n") 536 // skip header 537 lines = lines[1:] 538 c.Assert(lines, checker.HasLen, 3, check.Commentf("There should be 3 running container, got %d", len(lines))) 539 for _, line := range lines { 540 f := strings.Fields(line) 541 switch f[0] { 542 case id1: 543 c.Assert(f[1], checker.Equals, "busybox", check.Commentf("Expected %s tag for id %s, got %s", "busybox", id1, f[1])) 544 case id2: 545 c.Assert(f[1], checker.Equals, tag, check.Commentf("Expected %s tag for id %s, got %s", tag, id2, f[1])) 546 case id3: 547 c.Assert(f[1], checker.Equals, imageID, check.Commentf("Expected %s imageID for id %s, got %s", tag, id3, f[1])) 548 default: 549 c.Fatalf("Unexpected id %s, expected %s and %s and %s", f[0], id1, id2, id3) 550 } 551 } 552 } 553 554 func (s *DockerSuite) TestPsLinkedWithNoTrunc(c *check.C) { 555 // Problematic on Windows as it doesn't support links as of Jan 2016 556 testRequires(c, DaemonIsLinux) 557 runSleepingContainer(c, "--name=first") 558 runSleepingContainer(c, "--name=second", "--link=first:first") 559 560 out, _ := dockerCmd(c, "ps", "--no-trunc") 561 lines := strings.Split(strings.TrimSpace(string(out)), "\n") 562 // strip header 563 lines = lines[1:] 564 expected := []string{"second", "first,second/first"} 565 var names []string 566 for _, l := range lines { 567 fields := strings.Fields(l) 568 names = append(names, fields[len(fields)-1]) 569 } 570 c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array: %v, got: %v", expected, names)) 571 } 572 573 func (s *DockerSuite) TestPsGroupPortRange(c *check.C) { 574 // Problematic on Windows as it doesn't support port ranges as of Jan 2016 575 testRequires(c, DaemonIsLinux) 576 portRange := "3800-3900" 577 dockerCmd(c, "run", "-d", "--name", "porttest", "-p", portRange+":"+portRange, "busybox", "top") 578 579 out, _ := dockerCmd(c, "ps") 580 581 c.Assert(string(out), checker.Contains, portRange, check.Commentf("docker ps output should have had the port range %q: %s", portRange, string(out))) 582 583 } 584 585 func (s *DockerSuite) TestPsWithSize(c *check.C) { 586 // Problematic on Windows as it doesn't report the size correctly @swernli 587 testRequires(c, DaemonIsLinux) 588 dockerCmd(c, "run", "-d", "--name", "sizetest", "busybox", "top") 589 590 out, _ := dockerCmd(c, "ps", "--size") 591 c.Assert(out, checker.Contains, "virtual", check.Commentf("docker ps with --size should show virtual size of container")) 592 } 593 594 func (s *DockerSuite) TestPsListContainersFilterCreated(c *check.C) { 595 // create a container 596 out, _ := dockerCmd(c, "create", "busybox") 597 cID := strings.TrimSpace(out) 598 shortCID := cID[:12] 599 600 // Make sure it DOESN'T show up w/o a '-a' for normal 'ps' 601 out, _ = dockerCmd(c, "ps", "-q") 602 c.Assert(out, checker.Not(checker.Contains), shortCID, check.Commentf("Should have not seen '%s' in ps output:\n%s", shortCID, out)) 603 604 // Make sure it DOES show up as 'Created' for 'ps -a' 605 out, _ = dockerCmd(c, "ps", "-a") 606 607 hits := 0 608 for _, line := range strings.Split(out, "\n") { 609 if !strings.Contains(line, shortCID) { 610 continue 611 } 612 hits++ 613 c.Assert(line, checker.Contains, "Created", check.Commentf("Missing 'Created' on '%s'", line)) 614 } 615 616 c.Assert(hits, checker.Equals, 1, check.Commentf("Should have seen '%s' in ps -a output once:%d\n%s", shortCID, hits, out)) 617 618 // filter containers by 'create' - note, no -a needed 619 out, _ = dockerCmd(c, "ps", "-q", "-f", "status=created") 620 containerOut := strings.TrimSpace(out) 621 c.Assert(cID, checker.HasPrefix, containerOut) 622 } 623 624 func (s *DockerSuite) TestPsFormatMultiNames(c *check.C) { 625 // Problematic on Windows as it doesn't support link as of Jan 2016 626 testRequires(c, DaemonIsLinux) 627 //create 2 containers and link them 628 dockerCmd(c, "run", "--name=child", "-d", "busybox", "top") 629 dockerCmd(c, "run", "--name=parent", "--link=child:linkedone", "-d", "busybox", "top") 630 631 //use the new format capabilities to only list the names and --no-trunc to get all names 632 out, _ := dockerCmd(c, "ps", "--format", "{{.Names}}", "--no-trunc") 633 lines := strings.Split(strings.TrimSpace(string(out)), "\n") 634 expected := []string{"parent", "child,parent/linkedone"} 635 var names []string 636 for _, l := range lines { 637 names = append(names, l) 638 } 639 c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with non-truncated names: %v, got: %v", expected, names)) 640 641 //now list without turning off truncation and make sure we only get the non-link names 642 out, _ = dockerCmd(c, "ps", "--format", "{{.Names}}") 643 lines = strings.Split(strings.TrimSpace(string(out)), "\n") 644 expected = []string{"parent", "child"} 645 var truncNames []string 646 for _, l := range lines { 647 truncNames = append(truncNames, l) 648 } 649 c.Assert(expected, checker.DeepEquals, truncNames, check.Commentf("Expected array with truncated names: %v, got: %v", expected, truncNames)) 650 651 } 652 653 func (s *DockerSuite) TestPsFormatHeaders(c *check.C) { 654 // make sure no-container "docker ps" still prints the header row 655 out, _ := dockerCmd(c, "ps", "--format", "table {{.ID}}") 656 c.Assert(out, checker.Equals, "CONTAINER ID\n", check.Commentf(`Expected 'CONTAINER ID\n', got %v`, out)) 657 658 // verify that "docker ps" with a container still prints the header row also 659 runSleepingContainer(c, "--name=test") 660 out, _ = dockerCmd(c, "ps", "--format", "table {{.Names}}") 661 c.Assert(out, checker.Equals, "NAMES\ntest\n", check.Commentf(`Expected 'NAMES\ntest\n', got %v`, out)) 662 } 663 664 func (s *DockerSuite) TestPsDefaultFormatAndQuiet(c *check.C) { 665 config := `{ 666 "psFormat": "default {{ .ID }}" 667 }` 668 d, err := ioutil.TempDir("", "integration-cli-") 669 c.Assert(err, checker.IsNil) 670 defer os.RemoveAll(d) 671 672 err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644) 673 c.Assert(err, checker.IsNil) 674 675 out, _ := runSleepingContainer(c, "--name=test") 676 id := strings.TrimSpace(out) 677 678 out, _ = dockerCmd(c, "--config", d, "ps", "-q") 679 c.Assert(id, checker.HasPrefix, strings.TrimSpace(out), check.Commentf("Expected to print only the container id, got %v\n", out)) 680 } 681 682 // Test for GitHub issue #12595 683 func (s *DockerSuite) TestPsImageIDAfterUpdate(c *check.C) { 684 // TODO: Investigate why this fails on Windows to Windows CI further. 685 testRequires(c, DaemonIsLinux) 686 originalImageName := "busybox:TestPsImageIDAfterUpdate-original" 687 updatedImageName := "busybox:TestPsImageIDAfterUpdate-updated" 688 689 runCmd := exec.Command(dockerBinary, "tag", "busybox:latest", originalImageName) 690 out, _, err := runCommandWithOutput(runCmd) 691 c.Assert(err, checker.IsNil) 692 693 originalImageID, err := getIDByName(originalImageName) 694 c.Assert(err, checker.IsNil) 695 696 runCmd = exec.Command(dockerBinary, append([]string{"run", "-d", originalImageName}, defaultSleepCommand...)...) 697 out, _, err = runCommandWithOutput(runCmd) 698 c.Assert(err, checker.IsNil) 699 containerID := strings.TrimSpace(out) 700 701 linesOut, err := exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput() 702 c.Assert(err, checker.IsNil) 703 704 lines := strings.Split(strings.TrimSpace(string(linesOut)), "\n") 705 // skip header 706 lines = lines[1:] 707 c.Assert(len(lines), checker.Equals, 1) 708 709 for _, line := range lines { 710 f := strings.Fields(line) 711 c.Assert(f[1], checker.Equals, originalImageName) 712 } 713 714 runCmd = exec.Command(dockerBinary, "commit", containerID, updatedImageName) 715 out, _, err = runCommandWithOutput(runCmd) 716 c.Assert(err, checker.IsNil) 717 718 runCmd = exec.Command(dockerBinary, "tag", "-f", updatedImageName, originalImageName) 719 out, _, err = runCommandWithOutput(runCmd) 720 c.Assert(err, checker.IsNil) 721 722 linesOut, err = exec.Command(dockerBinary, "ps", "--no-trunc").CombinedOutput() 723 c.Assert(err, checker.IsNil) 724 725 lines = strings.Split(strings.TrimSpace(string(linesOut)), "\n") 726 // skip header 727 lines = lines[1:] 728 c.Assert(len(lines), checker.Equals, 1) 729 730 for _, line := range lines { 731 f := strings.Fields(line) 732 c.Assert(f[1], checker.Equals, originalImageID) 733 } 734 735 } 736 737 func (s *DockerSuite) TestPsNotShowPortsOfStoppedContainer(c *check.C) { 738 testRequires(c, DaemonIsLinux) 739 dockerCmd(c, "run", "--name=foo", "-d", "-p", "5000:5000", "busybox", "top") 740 c.Assert(waitRun("foo"), checker.IsNil) 741 out, _ := dockerCmd(c, "ps") 742 lines := strings.Split(strings.TrimSpace(string(out)), "\n") 743 expected := "0.0.0.0:5000->5000/tcp" 744 fields := strings.Fields(lines[1]) 745 c.Assert(fields[len(fields)-2], checker.Equals, expected, check.Commentf("Expected: %v, got: %v", expected, fields[len(fields)-2])) 746 747 dockerCmd(c, "kill", "foo") 748 dockerCmd(c, "wait", "foo") 749 out, _ = dockerCmd(c, "ps", "-l") 750 lines = strings.Split(strings.TrimSpace(string(out)), "\n") 751 fields = strings.Fields(lines[1]) 752 c.Assert(fields[len(fields)-2], checker.Not(checker.Equals), expected, check.Commentf("Should not got %v", expected)) 753 } 754 755 func (s *DockerSuite) TestPsShowMounts(c *check.C) { 756 prefix, slash := getPrefixAndSlashFromDaemonPlatform() 757 758 mp := prefix + slash + "test" 759 760 dockerCmd(c, "volume", "create", "--name", "ps-volume-test") 761 runSleepingContainer(c, "--name=volume-test-1", "--volume", "ps-volume-test:"+mp) 762 c.Assert(waitRun("volume-test-1"), checker.IsNil) 763 runSleepingContainer(c, "--name=volume-test-2", "--volume", mp) 764 c.Assert(waitRun("volume-test-2"), checker.IsNil) 765 766 out, _ := dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}") 767 768 lines := strings.Split(strings.TrimSpace(string(out)), "\n") 769 c.Assert(lines, checker.HasLen, 2) 770 771 fields := strings.Fields(lines[0]) 772 c.Assert(fields, checker.HasLen, 2) 773 774 annonymounsVolumeID := fields[1] 775 776 fields = strings.Fields(lines[1]) 777 c.Assert(fields[1], checker.Equals, "ps-volume-test") 778 779 // filter by volume name 780 out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume=ps-volume-test") 781 782 lines = strings.Split(strings.TrimSpace(string(out)), "\n") 783 c.Assert(lines, checker.HasLen, 1) 784 785 fields = strings.Fields(lines[0]) 786 c.Assert(fields[1], checker.Equals, "ps-volume-test") 787 788 // empty results filtering by unknown volume 789 out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume=this-volume-should-not-exist") 790 c.Assert(strings.TrimSpace(string(out)), checker.HasLen, 0) 791 792 // filter by mount destination 793 out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+mp) 794 795 lines = strings.Split(strings.TrimSpace(string(out)), "\n") 796 c.Assert(lines, checker.HasLen, 2) 797 798 fields = strings.Fields(lines[0]) 799 c.Assert(fields[1], checker.Equals, annonymounsVolumeID) 800 fields = strings.Fields(lines[1]) 801 c.Assert(fields[1], checker.Equals, "ps-volume-test") 802 803 // empty results filtering by unknown mount point 804 out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+prefix+slash+"this-path-was-never-mounted") 805 c.Assert(strings.TrimSpace(string(out)), checker.HasLen, 0) 806 }