docker_cli_ps_test.go 42 KB

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