diff --git a/integration-cli/docker_api_network_test.go b/integration-cli/docker_api_network_test.go index 129ec7ea69..e9fbf0426c 100644 --- a/integration-cli/docker_api_network_test.go +++ b/integration-cli/docker_api_network_test.go @@ -81,6 +81,7 @@ func (s *DockerSuite) TestAPINetworkInspect(c *check.C) { // Inspect default bridge network nr := getNetworkResource(c, "bridge") c.Assert(nr.Name, checker.Equals, "bridge") + connCount := len(nr.Containers) // run a container and attach it to the default bridge network out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top") @@ -94,7 +95,7 @@ func (s *DockerSuite) TestAPINetworkInspect(c *check.C) { c.Assert(nr.Internal, checker.Equals, false) c.Assert(nr.EnableIPv6, checker.Equals, false) c.Assert(nr.IPAM.Driver, checker.Equals, "default") - c.Assert(len(nr.Containers), checker.Equals, 1) + c.Assert(len(nr.Containers), checker.Equals, connCount+1) c.Assert(nr.Containers[containerID], checker.NotNil) ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address) @@ -291,9 +292,16 @@ func getNetworkIDByName(c *check.C, name string) string { nJSON := []types.NetworkResource{} err = json.NewDecoder(body).Decode(&nJSON) c.Assert(err, checker.IsNil) - c.Assert(len(nJSON), checker.Equals, 1) + var res string + for _, n := range nJSON { + // Find exact match + if n.Name == name { + res = n.ID + } + } + c.Assert(res, checker.Not(checker.Equals), "") - return nJSON[0].ID + return res } func getNetworkResource(c *check.C, id string) *types.NetworkResource { diff --git a/integration-cli/docker_cli_authz_plugin_v2_test.go b/integration-cli/docker_cli_authz_plugin_v2_test.go index b8bbcc75e1..025d5aeb7f 100644 --- a/integration-cli/docker_cli_authz_plugin_v2_test.go +++ b/integration-cli/docker_cli_authz_plugin_v2_test.go @@ -47,6 +47,9 @@ func (s *DockerAuthzV2Suite) TearDownTest(c *check.C) { func (s *DockerAuthzV2Suite) TestAuthZPluginAllowNonVolumeRequest(c *check.C) { testRequires(c, DaemonIsLinux, IsAmd64, Network) + + existingContainers := ExistingContainerIDs(c) + // Install authz plugin _, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", authzPluginNameWithTag) c.Assert(err, checker.IsNil) @@ -72,7 +75,7 @@ func (s *DockerAuthzV2Suite) TestAuthZPluginAllowNonVolumeRequest(c *check.C) { out, err = s.d.Cmd("ps") c.Assert(err, check.IsNil) - c.Assert(assertContainerList(out, []string{id}), check.Equals, true) + c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), []string{id}), check.Equals, true) } func (s *DockerAuthzV2Suite) TestAuthZPluginDisable(c *check.C) { diff --git a/integration-cli/docker_cli_authz_unix_test.go b/integration-cli/docker_cli_authz_unix_test.go index f46ab806ca..cf3d88e12a 100644 --- a/integration-cli/docker_cli_authz_unix_test.go +++ b/integration-cli/docker_cli_authz_unix_test.go @@ -204,6 +204,8 @@ func (s *DockerAuthzSuite) TearDownSuite(c *check.C) { } func (s *DockerAuthzSuite) TestAuthZPluginAllowRequest(c *check.C) { + existingContainers := ExistingContainerIDs(c) + // start the daemon and load busybox, --net=none build fails otherwise // cause it needs to pull busybox s.d.Start(c, "--authorization-plugin="+testAuthZPlugin) @@ -221,7 +223,7 @@ func (s *DockerAuthzSuite) TestAuthZPluginAllowRequest(c *check.C) { out, err = s.d.Cmd("ps") c.Assert(err, check.IsNil) - c.Assert(assertContainerList(out, []string{id}), check.Equals, true) + c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), []string{id}), check.Equals, true) c.Assert(s.ctrl.psRequestCnt, check.Equals, 1) c.Assert(s.ctrl.psResponseCnt, check.Equals, 1) } diff --git a/integration-cli/docker_cli_by_digest_test.go b/integration-cli/docker_cli_by_digest_test.go index c7115c88c6..0c682719a4 100644 --- a/integration-cli/docker_cli_by_digest_test.go +++ b/integration-cli/docker_cli_by_digest_test.go @@ -407,6 +407,8 @@ func (s *DockerRegistrySuite) TestInspectImageWithDigests(c *check.C) { } func (s *DockerRegistrySuite) TestPsListContainersFilterAncestorImageByDigest(c *check.C) { + existingContainers := ExistingContainerIDs(c) + digest, err := setupImage(c) c.Assert(err, checker.IsNil, check.Commentf("error setting up image")) @@ -438,7 +440,7 @@ func (s *DockerRegistrySuite) TestPsListContainersFilterAncestorImageByDigest(c // Valid imageReference out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+imageReference) - checkPsAncestorFilterOutput(c, out, imageReference, expectedIDs) + checkPsAncestorFilterOutput(c, RemoveOutputForExistingElements(out, existingContainers), imageReference, expectedIDs) } func (s *DockerRegistrySuite) TestDeleteImageByIDOnlyPulledByDigest(c *check.C) { diff --git a/integration-cli/docker_cli_health_test.go b/integration-cli/docker_cli_health_test.go index 0f78a41d87..f6228075be 100644 --- a/integration-cli/docker_cli_health_test.go +++ b/integration-cli/docker_cli_health_test.go @@ -39,6 +39,8 @@ func getHealth(c *check.C, name string) *types.Health { func (s *DockerSuite) TestHealth(c *check.C) { testRequires(c, DaemonIsLinux) // busybox doesn't work on Windows + existingContainers := ExistingContainerNames(c) + imageName := "testhealth" buildImageSuccessfully(c, imageName, build.WithDockerfile(`FROM busybox RUN echo OK > /status @@ -51,6 +53,7 @@ func (s *DockerSuite) TestHealth(c *check.C) { name := "test_health" dockerCmd(c, "create", "--name", name, imageName) out, _ := dockerCmd(c, "ps", "-a", "--format={{.Status}}") + out = RemoveOutputForExistingElements(out, existingContainers) c.Check(out, checker.Equals, "Created\n") // Inspect the options diff --git a/integration-cli/docker_cli_info_test.go b/integration-cli/docker_cli_info_test.go index d75974dfc9..b6f867373b 100644 --- a/integration-cli/docker_cli_info_test.go +++ b/integration-cli/docker_cli_info_test.go @@ -135,42 +135,48 @@ func (s *DockerSuite) TestInfoDiscoveryAdvertiseInterfaceName(c *check.C) { func (s *DockerSuite) TestInfoDisplaysRunningContainers(c *check.C) { testRequires(c, DaemonIsLinux) + existing := existingContainerStates(c) + dockerCmd(c, "run", "-d", "busybox", "top") out, _ := dockerCmd(c, "info") - c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", 1)) - c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", 1)) - c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", 0)) - c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", 0)) + c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", existing["Containers"]+1)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", existing["ContainersRunning"]+1)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", existing["ContainersPaused"])) + c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", existing["ContainersStopped"])) } func (s *DockerSuite) TestInfoDisplaysPausedContainers(c *check.C) { testRequires(c, IsPausable) + existing := existingContainerStates(c) + out := runSleepingContainer(c, "-d") cleanedContainerID := strings.TrimSpace(out) dockerCmd(c, "pause", cleanedContainerID) out, _ = dockerCmd(c, "info") - c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", 1)) - c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", 0)) - c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", 1)) - c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", 0)) + c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", existing["Containers"]+1)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", existing["ContainersRunning"])) + c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", existing["ContainersPaused"]+1)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", existing["ContainersStopped"])) } func (s *DockerSuite) TestInfoDisplaysStoppedContainers(c *check.C) { testRequires(c, DaemonIsLinux) + existing := existingContainerStates(c) + out, _ := dockerCmd(c, "run", "-d", "busybox", "top") cleanedContainerID := strings.TrimSpace(out) dockerCmd(c, "stop", cleanedContainerID) out, _ = dockerCmd(c, "info") - c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", 1)) - c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", 0)) - c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", 0)) - c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", 1)) + c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", existing["Containers"]+1)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", existing["ContainersRunning"])) + c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", existing["ContainersPaused"])) + c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", existing["ContainersStopped"]+1)) } func (s *DockerSuite) TestInfoDebug(c *check.C) { @@ -237,3 +243,16 @@ func (s *DockerDaemonSuite) TestInfoLabels(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, "WARNING: labels with duplicate keys and conflicting values have been deprecated") } + +func existingContainerStates(c *check.C) map[string]int { + out, _ := dockerCmd(c, "info", "--format", "{{json .}}") + var m map[string]interface{} + err := json.Unmarshal([]byte(out), &m) + c.Assert(err, checker.IsNil) + res := map[string]int{} + res["Containers"] = int(m["Containers"].(float64)) + res["ContainersRunning"] = int(m["ContainersRunning"].(float64)) + res["ContainersPaused"] = int(m["ContainersPaused"].(float64)) + res["ContainersStopped"] = int(m["ContainersStopped"].(float64)) + return res +} diff --git a/integration-cli/docker_cli_port_test.go b/integration-cli/docker_cli_port_test.go index bcb87f5f33..7450dd4837 100644 --- a/integration-cli/docker_cli_port_test.go +++ b/integration-cli/docker_cli_port_test.go @@ -5,6 +5,7 @@ import ( "net" "regexp" "sort" + "strconv" "strings" "github.com/docker/docker/integration-cli/checker" @@ -148,9 +149,7 @@ func (s *DockerSuite) TestPortList(c *check.C) { out, _ = dockerCmd(c, "port", ID) - err = assertPortList(c, out, []string{ - "80/tcp -> 0.0.0.0:8000", - "80/udp -> 0.0.0.0:8000"}) + err = assertPortRange(c, out, []int{8000, 8080}, []int{8000, 8080}) // Port list is not correct c.Assert(err, checker.IsNil) dockerCmd(c, "rm", "-f", ID) @@ -173,6 +172,38 @@ func assertPortList(c *check.C, out string, expected []string) error { return nil } +func assertPortRange(c *check.C, out string, expectedTcp, expectedUdp []int) error { + lines := strings.Split(strings.Trim(out, "\n "), "\n") + + var validTcp, validUdp bool + for _, l := range lines { + // 80/tcp -> 0.0.0.0:8015 + port, err := strconv.Atoi(strings.Split(l, ":")[1]) + if err != nil { + return err + } + if strings.Contains(l, "tcp") && expectedTcp != nil { + if port < expectedTcp[0] || port > expectedTcp[1] { + return fmt.Errorf("tcp port (%d) not in range expected range %d-%d", port, expectedTcp[0], expectedTcp[1]) + } + validTcp = true + } + if strings.Contains(l, "udp") && expectedUdp != nil { + if port < expectedUdp[0] || port > expectedUdp[1] { + return fmt.Errorf("udp port (%d) not in range expected range %d-%d", port, expectedUdp[0], expectedUdp[1]) + } + validUdp = true + } + } + if !validTcp { + return fmt.Errorf("tcp port not found") + } + if !validUdp { + return fmt.Errorf("udp port not found") + } + return nil +} + func stopRemoveContainer(id string, c *check.C) { dockerCmd(c, "rm", "-f", id) } diff --git a/integration-cli/docker_cli_ps_test.go b/integration-cli/docker_cli_ps_test.go index 736103e776..2572535e30 100644 --- a/integration-cli/docker_cli_ps_test.go +++ b/integration-cli/docker_cli_ps_test.go @@ -19,6 +19,8 @@ import ( ) func (s *DockerSuite) TestPsListContainersBase(c *check.C) { + existingContainers := ExistingContainerIDs(c) + out := runSleepingContainer(c, "-d") firstID := strings.TrimSpace(out) @@ -43,79 +45,79 @@ func (s *DockerSuite) TestPsListContainersBase(c *check.C) { // all out, _ = dockerCmd(c, "ps", "-a") - 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)) + 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)) // running out, _ = dockerCmd(c, "ps") - 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)) + 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)) // limit out, _ = dockerCmd(c, "ps", "-n=2", "-a") expected := []string{fourthID, thirdID} - c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("LIMIT & ALL: Container list is not in the correct order: \n%s", out)) + 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)) out, _ = dockerCmd(c, "ps", "-n=2") - c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("LIMIT: Container list is not in the correct order: \n%s", out)) + c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("LIMIT: Container list is not in the correct order: \n%s", out)) // filter since out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-a") expected = []string{fourthID, thirdID, secondID} - c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter & ALL: Container list is not in the correct order: \n%s", out)) + 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)) out, _ = dockerCmd(c, "ps", "-f", "since="+firstID) expected = []string{fourthID, secondID} - c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Container list is not in the correct order: \n%s", out)) + 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)) out, _ = dockerCmd(c, "ps", "-f", "since="+thirdID) expected = []string{fourthID} - c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Container list is not in the correct order: \n%s", out)) + 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)) // filter before out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID, "-a") expected = []string{thirdID, secondID, firstID} - c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter & ALL: Container list is not in the correct order: \n%s", out)) + 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)) out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID) expected = []string{secondID, firstID} - c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter: Container list is not in the correct order: \n%s", out)) + 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)) out, _ = dockerCmd(c, "ps", "-f", "before="+thirdID) expected = []string{secondID, firstID} - c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Container list is not in the correct order: \n%s", out)) + 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)) // filter since & before out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID, "-a") expected = []string{thirdID, secondID} - 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)) + 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)) out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID) expected = []string{secondID} - 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)) + 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)) // filter since & limit out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-n=2", "-a") expected = []string{fourthID, thirdID} - 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)) + 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)) out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-n=2") - c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, LIMIT: Container list is not in the correct order: \n%s", out)) + 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)) // filter before & limit out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID, "-n=1", "-a") expected = []string{thirdID} - 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)) + 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)) out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID, "-n=1") - c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter, LIMIT: Container list is not in the correct order: \n%s", out)) + 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)) // filter since & filter before & limit out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID, "-n=1", "-a") expected = []string{thirdID} - 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)) + 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)) out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID, "-n=1") - 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)) + 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)) } @@ -185,6 +187,8 @@ func (s *DockerSuite) TestPsListContainersSize(c *check.C) { } func (s *DockerSuite) TestPsListContainersFilterStatus(c *check.C) { + existingContainers := ExistingContainerIDs(c) + // start exited container out := cli.DockerCmd(c, "run", "-d", "busybox").Combined() firstID := strings.TrimSpace(out) @@ -199,11 +203,11 @@ func (s *DockerSuite) TestPsListContainersFilterStatus(c *check.C) { // filter containers by exited out = cli.DockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=exited").Combined() containerOut := strings.TrimSpace(out) - c.Assert(containerOut, checker.Equals, firstID) + c.Assert(RemoveOutputForExistingElements(containerOut, existingContainers), checker.Equals, firstID) out = cli.DockerCmd(c, "ps", "-a", "--no-trunc", "-q", "--filter=status=running").Combined() containerOut = strings.TrimSpace(out) - c.Assert(containerOut, checker.Equals, secondID) + c.Assert(RemoveOutputForExistingElements(containerOut, existingContainers), checker.Equals, secondID) result := cli.Docker(cli.Args("ps", "-a", "-q", "--filter=status=rubbish"), cli.WithTimeout(time.Second*60)) result.Assert(c, icmd.Expected{ @@ -222,7 +226,7 @@ func (s *DockerSuite) TestPsListContainersFilterStatus(c *check.C) { out = cli.DockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=paused").Combined() containerOut = strings.TrimSpace(out) - c.Assert(containerOut, checker.Equals, pausedID) + c.Assert(RemoveOutputForExistingElements(containerOut, existingContainers), checker.Equals, pausedID) } } @@ -305,6 +309,8 @@ func (s *DockerSuite) TestPsListContainersFilterName(c *check.C) { // - Run containers for each of those image (busybox, images_ps_filter_test1, images_ps_filter_test2) // - Filter them out :P func (s *DockerSuite) TestPsListContainersFilterAncestorImage(c *check.C) { + existingContainers := ExistingContainerIDs(c) + // Build images imageName1 := "images_ps_filter_test1" buildImageSuccessfully(c, imageName1, build.WithDockerfile(`FROM busybox @@ -367,12 +373,12 @@ func (s *DockerSuite) TestPsListContainersFilterAncestorImage(c *check.C) { var out string for _, filter := range filterTestSuite { out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+filter.filterName) - checkPsAncestorFilterOutput(c, out, filter.filterName, filter.expectedIDs) + checkPsAncestorFilterOutput(c, RemoveOutputForExistingElements(out, existingContainers), filter.filterName, filter.expectedIDs) } // Multiple ancestor filter out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+imageName2, "--filter=ancestor="+imageName1Tagged) - checkPsAncestorFilterOutput(c, out, imageName2+","+imageName1Tagged, []string{fourthID, fifthID}) + checkPsAncestorFilterOutput(c, RemoveOutputForExistingElements(out, existingContainers), imageName2+","+imageName1Tagged, []string{fourthID, fifthID}) } func checkPsAncestorFilterOutput(c *check.C, out string, filterName string, expectedIDs []string) { @@ -469,6 +475,9 @@ func (s *DockerSuite) TestPsListContainersFilterExited(c *check.C) { func (s *DockerSuite) TestPsRightTagName(c *check.C) { // TODO Investigate further why this fails on Windows to Windows CI testRequires(c, DaemonIsLinux) + + existingContainers := ExistingContainerNames(c) + tag := "asybox:shmatest" dockerCmd(c, "tag", "busybox", tag) @@ -490,6 +499,7 @@ func (s *DockerSuite) TestPsRightTagName(c *check.C) { out, _ = dockerCmd(c, "ps", "--no-trunc") lines := strings.Split(strings.TrimSpace(string(out)), "\n") + lines = RemoveLinesForExistingElements(lines, existingContainers) // skip header lines = lines[1:] c.Assert(lines, checker.HasLen, 3, check.Commentf("There should be 3 running container, got %d", len(lines))) @@ -581,12 +591,14 @@ func (s *DockerSuite) TestPsListContainersFilterCreated(c *check.C) { func (s *DockerSuite) TestPsFormatMultiNames(c *check.C) { // Problematic on Windows as it doesn't support link as of Jan 2016 testRequires(c, DaemonIsLinux) + existingContainers := ExistingContainerNames(c) //create 2 containers and link them dockerCmd(c, "run", "--name=child", "-d", "busybox", "top") dockerCmd(c, "run", "--name=parent", "--link=child:linkedone", "-d", "busybox", "top") //use the new format capabilities to only list the names and --no-trunc to get all names out, _ := dockerCmd(c, "ps", "--format", "{{.Names}}", "--no-trunc") + out = RemoveOutputForExistingElements(out, existingContainers) lines := strings.Split(strings.TrimSpace(string(out)), "\n") expected := []string{"parent", "child,parent/linkedone"} var names []string @@ -595,6 +607,7 @@ func (s *DockerSuite) TestPsFormatMultiNames(c *check.C) { //now list without turning off truncation and make sure we only get the non-link names out, _ = dockerCmd(c, "ps", "--format", "{{.Names}}") + out = RemoveOutputForExistingElements(out, existingContainers) lines = strings.Split(strings.TrimSpace(string(out)), "\n") expected = []string{"parent", "child"} var truncNames []string @@ -604,12 +617,14 @@ func (s *DockerSuite) TestPsFormatMultiNames(c *check.C) { // Test for GitHub issue #21772 func (s *DockerSuite) TestPsNamesMultipleTime(c *check.C) { + existingContainers := ExistingContainerNames(c) runSleepingContainer(c, "--name=test1") runSleepingContainer(c, "--name=test2") //use the new format capabilities to list the names twice out, _ := dockerCmd(c, "ps", "--format", "{{.Names}} {{.Names}}") lines := strings.Split(strings.TrimSpace(string(out)), "\n") + lines = RemoveLinesForExistingElements(lines, existingContainers) expected := []string{"test2 test2", "test1 test1"} var names []string names = append(names, lines...) @@ -628,6 +643,7 @@ func (s *DockerSuite) TestPsFormatHeaders(c *check.C) { } func (s *DockerSuite) TestPsDefaultFormatAndQuiet(c *check.C) { + existingContainers := ExistingContainerIDs(c) config := `{ "psFormat": "default {{ .ID }}" }` @@ -642,6 +658,7 @@ func (s *DockerSuite) TestPsDefaultFormatAndQuiet(c *check.C) { id := strings.TrimSpace(out) out, _ = dockerCmd(c, "--config", d, "ps", "-q") + out = RemoveOutputForExistingElements(out, existingContainers) c.Assert(id, checker.HasPrefix, strings.TrimSpace(out), check.Commentf("Expected to print only the container id, got %v\n", out)) } @@ -652,6 +669,8 @@ func (s *DockerSuite) TestPsImageIDAfterUpdate(c *check.C) { originalImageName := "busybox:TestPsImageIDAfterUpdate-original" updatedImageName := "busybox:TestPsImageIDAfterUpdate-updated" + existingContainers := ExistingContainerIDs(c) + icmd.RunCommand(dockerBinary, "tag", "busybox:latest", originalImageName).Assert(c, icmd.Success) originalImageID := getIDByName(c, originalImageName) @@ -664,6 +683,7 @@ func (s *DockerSuite) TestPsImageIDAfterUpdate(c *check.C) { result.Assert(c, icmd.Success) lines := strings.Split(strings.TrimSpace(string(result.Combined())), "\n") + lines = RemoveLinesForExistingElements(lines, existingContainers) // skip header lines = lines[1:] c.Assert(len(lines), checker.Equals, 1) @@ -680,6 +700,7 @@ func (s *DockerSuite) TestPsImageIDAfterUpdate(c *check.C) { result.Assert(c, icmd.Success) lines = strings.Split(strings.TrimSpace(string(result.Combined())), "\n") + lines = RemoveLinesForExistingElements(lines, existingContainers) // skip header lines = lines[1:] c.Assert(len(lines), checker.Equals, 1) @@ -710,6 +731,8 @@ func (s *DockerSuite) TestPsNotShowPortsOfStoppedContainer(c *check.C) { } func (s *DockerSuite) TestPsShowMounts(c *check.C) { + existingContainers := ExistingContainerNames(c) + prefix, slash := getPrefixAndSlashFromDaemonPlatform() mp := prefix + slash + "test" @@ -736,6 +759,7 @@ func (s *DockerSuite) TestPsShowMounts(c *check.C) { out, _ := dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}") lines := strings.Split(strings.TrimSpace(string(out)), "\n") + lines = RemoveLinesForExistingElements(lines, existingContainers) c.Assert(lines, checker.HasLen, 3) fields := strings.Fields(lines[0]) @@ -755,6 +779,7 @@ func (s *DockerSuite) TestPsShowMounts(c *check.C) { out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume=ps-volume-test") lines = strings.Split(strings.TrimSpace(string(out)), "\n") + lines = RemoveLinesForExistingElements(lines, existingContainers) c.Assert(lines, checker.HasLen, 1) fields = strings.Fields(lines[0]) @@ -768,6 +793,7 @@ func (s *DockerSuite) TestPsShowMounts(c *check.C) { out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+mp) lines = strings.Split(strings.TrimSpace(string(out)), "\n") + lines = RemoveLinesForExistingElements(lines, existingContainers) c.Assert(lines, checker.HasLen, 2) fields = strings.Fields(lines[0]) @@ -779,6 +805,7 @@ func (s *DockerSuite) TestPsShowMounts(c *check.C) { out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+bindMountSource) lines = strings.Split(strings.TrimSpace(string(out)), "\n") + lines = RemoveLinesForExistingElements(lines, existingContainers) c.Assert(lines, checker.HasLen, 1) fields = strings.Fields(lines[0]) @@ -790,6 +817,7 @@ func (s *DockerSuite) TestPsShowMounts(c *check.C) { out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+bindMountDestination) lines = strings.Split(strings.TrimSpace(string(out)), "\n") + lines = RemoveLinesForExistingElements(lines, existingContainers) c.Assert(lines, checker.HasLen, 1) fields = strings.Fields(lines[0]) @@ -820,6 +848,8 @@ func (s *DockerSuite) TestPsFormatSize(c *check.C) { } func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) { + existing := ExistingContainerIDs(c) + // TODO default network on Windows is not called "bridge", and creating a // custom network fails on Windows fails with "Error response from daemon: plugin not found") testRequires(c, DaemonIsLinux) @@ -837,7 +867,7 @@ func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) { lines = lines[1:] // ps output should have no containers - c.Assert(lines, checker.HasLen, 0) + c.Assert(RemoveLinesForExistingElements(lines, existing), checker.HasLen, 0) // Filter docker ps on network bridge out, _ = dockerCmd(c, "ps", "--filter", "network=bridge") @@ -849,7 +879,7 @@ func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) { lines = lines[1:] // ps output should have only one container - c.Assert(lines, checker.HasLen, 1) + c.Assert(RemoveLinesForExistingElements(lines, existing), checker.HasLen, 1) // Making sure onbridgenetwork is on the output c.Assert(containerOut, checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on network\n")) @@ -864,7 +894,7 @@ func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) { lines = lines[1:] //ps output should have both the containers - c.Assert(lines, checker.HasLen, 2) + c.Assert(RemoveLinesForExistingElements(lines, existing), checker.HasLen, 2) // Making sure onbridgenetwork and onnonenetwork is on the output c.Assert(containerOut, checker.Contains, "onnonenetwork", check.Commentf("Missing the container on none network\n")) @@ -885,11 +915,12 @@ func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) { containerOut = strings.TrimSpace(string(out)) lines = strings.Split(containerOut, "\n") + // skip header lines = lines[1:] // ps output should have only one container - c.Assert(lines, checker.HasLen, 1) + c.Assert(RemoveLinesForExistingElements(lines, existing), checker.HasLen, 1) // Making sure onbridgenetwork is on the output c.Assert(containerOut, checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on network\n")) @@ -927,8 +958,10 @@ func (s *DockerSuite) TestPsFilterMissingArgErrorCode(c *check.C) { // Test case for 30291 func (s *DockerSuite) TestPsFormatTemplateWithArg(c *check.C) { + existingContainers := ExistingContainerNames(c) runSleepingContainer(c, "-d", "--name", "top", "--label", "some.label=label.foo-bar") out, _ := dockerCmd(c, "ps", "--format", `{{.Names}} {{.Label "some.label"}}`) + out = RemoveOutputForExistingElements(out, existingContainers) c.Assert(strings.TrimSpace(out), checker.Equals, "top label.foo-bar") } @@ -969,11 +1002,14 @@ func (s *DockerSuite) TestPsListContainersFilterPorts(c *check.C) { func (s *DockerSuite) TestPsNotShowLinknamesOfDeletedContainer(c *check.C) { testRequires(c, DaemonIsLinux) + existingContainers := ExistingContainerNames(c) + dockerCmd(c, "create", "--name=aaa", "busybox", "top") dockerCmd(c, "create", "--name=bbb", "--link=aaa", "busybox", "top") out, _ := dockerCmd(c, "ps", "--no-trunc", "-a", "--format", "{{.Names}}") lines := strings.Split(strings.TrimSpace(string(out)), "\n") + lines = RemoveLinesForExistingElements(lines, existingContainers) expected := []string{"bbb", "aaa,bbb/aaa"} var names []string names = append(names, lines...) @@ -982,5 +1018,6 @@ func (s *DockerSuite) TestPsNotShowLinknamesOfDeletedContainer(c *check.C) { dockerCmd(c, "rm", "bbb") out, _ = dockerCmd(c, "ps", "--no-trunc", "-a", "--format", "{{.Names}}") + out = RemoveOutputForExistingElements(out, existingContainers) c.Assert(strings.TrimSpace(out), checker.Equals, "aaa") } diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 03996b3047..485d718f17 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -2813,23 +2813,27 @@ func (s *DockerSuite) TestRunVolumesFromRestartAfterRemoved(c *check.C) { // run container with --rm should remove container if exit code != 0 func (s *DockerSuite) TestRunContainerWithRmFlagExitCodeNotEqualToZero(c *check.C) { + existingContainers := ExistingContainerIDs(c) name := "flowers" cli.Docker(cli.Args("run", "--name", name, "--rm", "busybox", "ls", "/notexists")).Assert(c, icmd.Expected{ ExitCode: 1, }) out := cli.DockerCmd(c, "ps", "-q", "-a").Combined() + out = RemoveOutputForExistingElements(out, existingContainers) if out != "" { c.Fatal("Expected not to have containers", out) } } func (s *DockerSuite) TestRunContainerWithRmFlagCannotStartContainer(c *check.C) { + existingContainers := ExistingContainerIDs(c) name := "sparkles" cli.Docker(cli.Args("run", "--name", name, "--rm", "busybox", "commandNotFound")).Assert(c, icmd.Expected{ ExitCode: 127, }) out := cli.DockerCmd(c, "ps", "-q", "-a").Combined() + out = RemoveOutputForExistingElements(out, existingContainers) if out != "" { c.Fatal("Expected not to have containers", out) } diff --git a/integration-cli/utils_test.go b/integration-cli/utils_test.go index e09fb80643..26b0b3106c 100644 --- a/integration-cli/utils_test.go +++ b/integration-cli/utils_test.go @@ -7,7 +7,10 @@ import ( "path/filepath" "strings" + "github.com/docker/docker/api/types" + "github.com/docker/docker/client" "github.com/docker/docker/pkg/stringutils" + "github.com/go-check/check" "github.com/gotestyourself/gotestyourself/icmd" "github.com/pkg/errors" ) @@ -112,3 +115,71 @@ func RunCommandPipelineWithOutput(cmds ...*exec.Cmd) (output string, err error) out, err := cmds[len(cmds)-1].CombinedOutput() return string(out), err } + +type elementListOptions struct { + element, format string +} + +func existingElements(c *check.C, opts elementListOptions) []string { + args := []string{} + switch opts.element { + case "container": + args = append(args, "ps", "-a") + case "image": + args = append(args, "images", "-a") + case "network": + args = append(args, "network", "ls") + case "plugin": + args = append(args, "plugin", "ls") + case "volume": + args = append(args, "volume", "ls") + } + if opts.format != "" { + args = append(args, "--format", opts.format) + } + out, _ := dockerCmd(c, args...) + lines := []string{} + for _, l := range strings.Split(out, "\n") { + if l != "" { + lines = append(lines, l) + } + } + return lines +} + +// ExistingContainerIDs returns a list of currently existing container IDs. +func ExistingContainerIDs(c *check.C) []string { + return existingElements(c, elementListOptions{element: "container", format: "{{.ID}}"}) +} + +// ExistingContainerNames returns a list of existing container names. +func ExistingContainerNames(c *check.C) []string { + return existingElements(c, elementListOptions{element: "container", format: "{{.Names}}"}) +} + +// RemoveLinesForExistingElements removes existing elements from the output of a +// docker command. +// This function takes an output []string and returns a []string. +func RemoveLinesForExistingElements(output, existing []string) []string { + for _, e := range existing { + index := -1 + for i, line := range output { + if strings.Contains(line, e) { + index = i + break + } + } + if index != -1 { + output = append(output[:index], output[index+1:]...) + } + } + return output +} + +// RemoveOutputForExistingElements removes existing elements from the output of +// a docker command. +// This function takes an output string and returns a string. +func RemoveOutputForExistingElements(output string, existing []string) string { + res := RemoveLinesForExistingElements(strings.Split(output, "\n"), existing) + return strings.Join(res, "\n") +}