1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #34805 from chris-crone/containerize-integration-tests

Containerize integration tests
This commit is contained in:
Vincent Demeester 2017-09-18 21:11:06 +02:00 committed by GitHub
commit 9be245f438
38 changed files with 709 additions and 248 deletions

70
Dockerfile.e2e Normal file
View file

@ -0,0 +1,70 @@
## Step 1: Build tests
FROM golang:1.8.3-alpine3.6 as builder
RUN apk add --update \
bash \
build-base \
curl \
lvm2-dev \
jq \
&& rm -rf /var/cache/apk/*
RUN mkdir -p /go/src/github.com/docker/docker/
WORKDIR /go/src/github.com/docker/docker/
# Generate frozen images
COPY contrib/download-frozen-image-v2.sh contrib/download-frozen-image-v2.sh
RUN contrib/download-frozen-image-v2.sh /output/docker-frozen-images \
buildpack-deps:jessie@sha256:85b379ec16065e4fe4127eb1c5fb1bcc03c559bd36dbb2e22ff496de55925fa6 \
busybox:latest@sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f \
debian:jessie@sha256:72f784399fd2719b4cb4e16ef8e369a39dc67f53d978cd3e2e7bf4e502c7b793 \
hello-world:latest@sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
# Download Docker CLI binary
COPY hack/dockerfile hack/dockerfile
RUN hack/dockerfile/install-binaries.sh dockercli
# Set tag and add sources
ARG DOCKER_GITCOMMIT
ENV DOCKER_GITCOMMIT=$DOCKER_GITCOMMIT
ADD . .
# Build DockerSuite.TestBuild* dependency
RUN CGO_ENABLED=0 go build -o /output/httpserver github.com/docker/docker/contrib/httpserver
# Build the integration tests and copy the resulting binaries to /output/tests
RUN hack/make.sh build-integration-test-binary
RUN mkdir -p /output/tests && find . -name test.main -exec cp --parents '{}' /output/tests \;
## Step 2: Generate testing image
FROM alpine:3.6 as runner
# GNU tar is used for generating the emptyfs image
RUN apk add --update \
bash \
ca-certificates \
g++ \
git \
iptables \
tar \
xz \
&& rm -rf /var/cache/apk/*
# Add an unprivileged user to be used for tests which need it
RUN addgroup docker && adduser -D -G docker unprivilegeduser -s /bin/ash
COPY contrib/httpserver/Dockerfile /tests/contrib/httpserver/Dockerfile
COPY contrib/syscall-test /tests/contrib/syscall-test
COPY integration-cli/fixtures /tests/integration-cli/fixtures
COPY hack/test/e2e-run.sh /scripts/run.sh
COPY hack/make/.ensure-emptyfs /scripts/ensure-emptyfs.sh
COPY --from=builder /output/docker-frozen-images /docker-frozen-images
COPY --from=builder /output/httpserver /tests/contrib/httpserver/httpserver
COPY --from=builder /output/tests /tests
COPY --from=builder /usr/local/bin/docker /usr/bin/docker
ENV DOCKER_REMOTE_DAEMON=1 DOCKER_INTEGRATION_DAEMON_DEST=/
ENTRYPOINT ["/scripts/run.sh"]

41
hack/test/e2e-run.sh Executable file
View file

@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -e
TESTFLAGS=${TESTFLAGS:-""}
# Currently only DockerSuite and DockerNetworkSuite have been adapted for E2E testing
TESTFLAGS_LEGACY=${TESTFLAGS_LEGACY:-""}
TIMEOUT=${TIMEOUT:-60m}
SCRIPTDIR="$(dirname ${BASH_SOURCE[0]})"
export DOCKER_ENGINE_GOARCH=${DOCKER_ENGINE_GOARCH:-amd64}
run_test_integration() {
run_test_integration_suites
run_test_integration_legacy_suites
}
run_test_integration_suites() {
local flags="-test.v -test.timeout=${TIMEOUT} $TESTFLAGS"
for dir in /tests/integration/*; do
if ! (
cd $dir
echo "Running $PWD"
./test.main $flags
); then exit 1; fi
done
}
run_test_integration_legacy_suites() {
(
flags="-check.v -check.timeout=${TIMEOUT} -test.timeout=360m $TESTFLAGS_LEGACY"
cd /tests/integration-cli
echo "Running $PWD"
./test.main $flags
)
}
bash $SCRIPTDIR/ensure-emptyfs.sh
echo "Run integration tests"
run_test_integration

View file

@ -67,7 +67,7 @@ func TestMain(m *testing.M) {
func Test(t *testing.T) {
cli.SetTestEnvironment(testEnv)
fakestorage.SetTestEnvironment(&testEnv.Execution)
ienv.ProtectImages(t, &testEnv.Execution)
ienv.ProtectAll(t, &testEnv.Execution)
check.TestingT(t)
}
@ -120,7 +120,7 @@ func (s *DockerRegistrySuite) OnTimeout(c *check.C) {
}
func (s *DockerRegistrySuite) SetUpTest(c *check.C) {
testRequires(c, DaemonIsLinux, registry.Hosting)
testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon)
s.reg = setupRegistry(c, false, "", "")
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
Experimental: testEnv.ExperimentalDaemon(),
@ -154,7 +154,7 @@ func (s *DockerSchema1RegistrySuite) OnTimeout(c *check.C) {
}
func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
testRequires(c, DaemonIsLinux, registry.Hosting, NotArm64)
testRequires(c, DaemonIsLinux, registry.Hosting, NotArm64, SameHostDaemon)
s.reg = setupRegistry(c, true, "", "")
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
Experimental: testEnv.ExperimentalDaemon(),
@ -188,7 +188,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) OnTimeout(c *check.C) {
}
func (s *DockerRegistryAuthHtpasswdSuite) SetUpTest(c *check.C) {
testRequires(c, DaemonIsLinux, registry.Hosting)
testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon)
s.reg = setupRegistry(c, false, "htpasswd", "")
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
Experimental: testEnv.ExperimentalDaemon(),
@ -224,7 +224,7 @@ func (s *DockerRegistryAuthTokenSuite) OnTimeout(c *check.C) {
}
func (s *DockerRegistryAuthTokenSuite) SetUpTest(c *check.C) {
testRequires(c, DaemonIsLinux, registry.Hosting)
testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon)
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
Experimental: testEnv.ExperimentalDaemon(),
})
@ -319,7 +319,7 @@ func (s *DockerSwarmSuite) OnTimeout(c *check.C) {
}
func (s *DockerSwarmSuite) SetUpTest(c *check.C) {
testRequires(c, DaemonIsLinux)
testRequires(c, DaemonIsLinux, SameHostDaemon)
}
func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemon.Swarm {
@ -471,7 +471,7 @@ func (ps *DockerPluginSuite) getPluginRepoWithTag() string {
}
func (ps *DockerPluginSuite) SetUpSuite(c *check.C) {
testRequires(c, DaemonIsLinux)
testRequires(c, DaemonIsLinux, registry.Hosting)
ps.registry = setupRegistry(c, false, "", "")
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)

View file

@ -39,27 +39,34 @@ func ensureHTTPServerImage(t testingT) {
goarch = "amd64"
}
goCmd, lookErr := exec.LookPath("go")
if lookErr != nil {
t.Fatalf("could not build http server: %v", lookErr)
}
cmd := exec.Command(goCmd, "build", "-o", filepath.Join(tmp, "httpserver"), "github.com/docker/docker/contrib/httpserver")
cmd.Env = append(os.Environ(), []string{
"CGO_ENABLED=0",
"GOOS=" + goos,
"GOARCH=" + goarch,
}...)
var out []byte
if out, err = cmd.CombinedOutput(); err != nil {
t.Fatalf("could not build http server: %s", string(out))
}
cpCmd, lookErr := exec.LookPath("cp")
if lookErr != nil {
t.Fatalf("could not build http server: %v", lookErr)
}
if out, err = exec.Command(cpCmd, "../contrib/httpserver/Dockerfile", filepath.Join(tmp, "Dockerfile")).CombinedOutput(); err != nil {
if _, err = os.Stat("../contrib/httpserver/httpserver"); os.IsNotExist(err) {
goCmd, lookErr := exec.LookPath("go")
if lookErr != nil {
t.Fatalf("could not build http server: %v", lookErr)
}
cmd := exec.Command(goCmd, "build", "-o", filepath.Join(tmp, "httpserver"), "github.com/docker/docker/contrib/httpserver")
cmd.Env = append(os.Environ(), []string{
"CGO_ENABLED=0",
"GOOS=" + goos,
"GOARCH=" + goarch,
}...)
var out []byte
if out, err = cmd.CombinedOutput(); err != nil {
t.Fatalf("could not build http server: %s", string(out))
}
} else {
if out, err := exec.Command(cpCmd, "../contrib/httpserver/httpserver", filepath.Join(tmp, "httpserver")).CombinedOutput(); err != nil {
t.Fatalf("could not copy http server: %v", string(out))
}
}
if out, err := exec.Command(cpCmd, "../contrib/httpserver/Dockerfile", filepath.Join(tmp, "Dockerfile")).CombinedOutput(); err != nil {
t.Fatalf("could not build http server: %v", string(out))
}

View file

@ -28,6 +28,7 @@ import (
func (s *DockerSuite) TestBuildAPIDockerFileRemote(c *check.C) {
testRequires(c, NotUserNamespace)
var testD string
if testEnv.DaemonPlatform() == "windows" {
testD = `FROM busybox

View file

@ -71,7 +71,6 @@ func (s *DockerSuite) TestContainerAPIGetJSONNoFieldsOmitted(c *check.C) {
c.Assert(err, checker.IsNil)
c.Assert(containers, checker.HasLen, startCount+1)
actual := fmt.Sprintf("%+v", containers[0])
fmt.Println(actual)
// empty Labels field triggered this bug, make sense to check for everything
// cause even Ports for instance can trigger this bug
@ -1372,8 +1371,7 @@ func (s *DockerSuite) TestContainerAPICreateNoHostConfig118(c *check.C) {
Image: "busybox",
}
var httpClient *http.Client
cli, err := client.NewClient(daemonHost(), "v1.18", httpClient, map[string]string{})
cli, err := request.NewEnvClientWithVersion("v1.18")
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
c.Assert(err, checker.IsNil)
@ -1409,16 +1407,6 @@ func (s *DockerSuite) TestPutContainerArchiveErrSymlinkInVolumeToReadOnlyRootfs(
c.Assert(err.Error(), checker.Contains, "container rootfs is marked read-only")
}
func (s *DockerSuite) TestContainerAPIGetContainersJSONEmpty(c *check.C) {
cli, err := client.NewEnvClient()
c.Assert(err, checker.IsNil)
defer cli.Close()
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true})
c.Assert(err, checker.IsNil)
c.Assert(containers, checker.HasLen, 0)
}
func (s *DockerSuite) TestPostContainersCreateWithWrongCpusetValues(c *check.C) {
// Not supported on Windows
testRequires(c, DaemonIsLinux)

View file

@ -119,7 +119,7 @@ func (s *DockerSuite) TestAPIImagesHistory(c *check.C) {
}
func (s *DockerSuite) TestAPIImagesImportBadSrc(c *check.C) {
testRequires(c, Network)
testRequires(c, Network, SameHostDaemon)
server := httptest.NewServer(http.NewServeMux())
defer server.Close()
@ -179,8 +179,7 @@ func (s *DockerSuite) TestAPIImagesSizeCompatibility(c *check.C) {
Labels map[string]string
}
var httpClient *http.Client
cli, err = client.NewClient(daemonHost(), "v1.24", httpClient, nil)
cli, err = request.NewEnvClientWithVersion("v1.24")
c.Assert(err, checker.IsNil)
defer cli.Close()

View file

@ -4,10 +4,9 @@ package main
import (
"encoding/json"
"net/http"
"github.com/docker/docker/client"
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/request"
"github.com/go-check/check"
"golang.org/x/net/context"
)
@ -19,8 +18,7 @@ func (s *DockerSuite) TestInspectAPICpusetInConfigPre120(c *check.C) {
name := "cpusetinconfig-pre120"
dockerCmd(c, "run", "--name", name, "--cpuset-cpus", "0", "busybox", "true")
var httpClient *http.Client
cli, err := client.NewClient(daemonHost(), "v1.19", httpClient, nil)
cli, err := request.NewEnvClientWithVersion("v1.19")
c.Assert(err, checker.IsNil)
defer cli.Close()
_, body, err := cli.ContainerInspectWithRaw(context.Background(), name, false)

View file

@ -76,7 +76,7 @@ func (s *DockerSuite) TestAPINetworkFilter(c *check.C) {
c.Assert(nr.Name, checker.Equals, "bridge")
}
func (s *DockerSuite) TestAPINetworkInspect(c *check.C) {
func (s *DockerSuite) TestAPINetworkInspectBridge(c *check.C) {
testRequires(c, DaemonIsLinux)
// Inspect default bridge network
nr := getNetworkResource(c, "bridge")
@ -94,13 +94,15 @@ 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(nr.Containers[containerID], checker.NotNil)
ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
c.Assert(err, checker.IsNil)
c.Assert(ip.String(), checker.Equals, containerIP)
}
func (s *DockerSuite) TestAPINetworkInspectUserDefinedNetwork(c *check.C) {
testRequires(c, DaemonIsLinux)
// IPAM configuration inspect
ipam := &network.IPAM{
Driver: "default",
@ -117,7 +119,7 @@ func (s *DockerSuite) TestAPINetworkInspect(c *check.C) {
id0 := createNetwork(c, config, true)
c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, true)
nr = getNetworkResource(c, id0)
nr := getNetworkResource(c, id0)
c.Assert(len(nr.IPAM.Config), checker.Equals, 1)
c.Assert(nr.IPAM.Config[0].Subnet, checker.Equals, "172.28.0.0/16")
c.Assert(nr.IPAM.Config[0].IPRange, checker.Equals, "172.28.5.0/24")
@ -291,9 +293,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 {

View file

@ -16,16 +16,27 @@ import (
func (s *DockerSuite) TestVolumesAPIList(c *check.C) {
prefix, _ := getPrefixAndSlashFromDaemonPlatform()
dockerCmd(c, "run", "-v", prefix+"/foo", "busybox")
cid, _ := dockerCmd(c, "run", "-d", "-v", prefix+"/foo", "busybox")
cli, err := client.NewEnvClient()
c.Assert(err, checker.IsNil)
defer cli.Close()
container, err := cli.ContainerInspect(context.Background(), strings.TrimSpace(cid))
c.Assert(err, checker.IsNil)
vname := container.Mounts[0].Name
volumes, err := cli.VolumeList(context.Background(), filters.Args{})
c.Assert(err, checker.IsNil)
c.Assert(len(volumes.Volumes), checker.Equals, 1, check.Commentf("\n%v", volumes.Volumes))
found := false
for _, vol := range volumes.Volumes {
if vol.Name == vname {
found = true
break
}
}
c.Assert(found, checker.Equals, true)
}
func (s *DockerSuite) TestVolumesAPICreate(c *check.C) {
@ -45,21 +56,21 @@ func (s *DockerSuite) TestVolumesAPICreate(c *check.C) {
func (s *DockerSuite) TestVolumesAPIRemove(c *check.C) {
prefix, _ := getPrefixAndSlashFromDaemonPlatform()
dockerCmd(c, "run", "-v", prefix+"/foo", "--name=test", "busybox")
cid, _ := dockerCmd(c, "run", "-d", "-v", prefix+"/foo", "--name=test", "busybox")
cli, err := client.NewEnvClient()
c.Assert(err, checker.IsNil)
defer cli.Close()
volumes, err := cli.VolumeList(context.Background(), filters.Args{})
container, err := cli.ContainerInspect(context.Background(), strings.TrimSpace(cid))
c.Assert(err, checker.IsNil)
vname := container.Mounts[0].Name
v := volumes.Volumes[0]
err = cli.VolumeRemove(context.Background(), v.Name, false)
err = cli.VolumeRemove(context.Background(), vname, false)
c.Assert(err.Error(), checker.Contains, "volume is in use")
dockerCmd(c, "rm", "-f", "test")
err = cli.VolumeRemove(context.Background(), v.Name, false)
err = cli.VolumeRemove(context.Background(), vname, false)
c.Assert(err, checker.IsNil)
}
@ -78,10 +89,6 @@ func (s *DockerSuite) TestVolumesAPIInspect(c *check.C) {
_, err = cli.VolumeCreate(context.Background(), config)
c.Assert(err, check.IsNil)
volumes, err := cli.VolumeList(context.Background(), filters.Args{})
c.Assert(err, checker.IsNil)
c.Assert(len(volumes.Volumes), checker.Equals, 1, check.Commentf("\n%v", volumes.Volumes))
vol, err := cli.VolumeInspect(context.Background(), config.Name)
c.Assert(err, checker.IsNil)
c.Assert(vol.Name, checker.Equals, config.Name)

View file

@ -173,7 +173,7 @@ func (s *DockerSuite) TestAttachDetach(c *check.C) {
c.Assert(running, checker.Equals, "true", check.Commentf("expected container to still be running"))
go func() {
dockerCmd(c, "kill", id)
dockerCmdWithResult("kill", id)
}()
select {
@ -225,7 +225,7 @@ func (s *DockerSuite) TestAttachDetachTruncatedID(c *check.C) {
c.Assert(running, checker.Equals, "true", check.Commentf("expected container to still be running"))
go func() {
dockerCmd(c, "kill", id)
dockerCmdWithResult("kill", id)
}()
select {

View file

@ -4,7 +4,6 @@ package main
import (
"fmt"
"strings"
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/daemon"
@ -31,7 +30,7 @@ type DockerAuthzV2Suite struct {
}
func (s *DockerAuthzV2Suite) SetUpTest(c *check.C) {
testRequires(c, DaemonIsLinux, Network)
testRequires(c, DaemonIsLinux, Network, SameHostDaemon)
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
Experimental: testEnv.ExperimentalDaemon(),
})
@ -47,6 +46,7 @@ func (s *DockerAuthzV2Suite) TearDownTest(c *check.C) {
func (s *DockerAuthzV2Suite) TestAuthZPluginAllowNonVolumeRequest(c *check.C) {
testRequires(c, DaemonIsLinux, IsAmd64, Network)
// Install authz plugin
_, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", authzPluginNameWithTag)
c.Assert(err, checker.IsNil)
@ -65,14 +65,8 @@ func (s *DockerAuthzV2Suite) TestAuthZPluginAllowNonVolumeRequest(c *check.C) {
}()
// Ensure docker run command and accompanying docker ps are successful
out, err := s.d.Cmd("run", "-d", "busybox", "top")
_, err = s.d.Cmd("run", "-d", "busybox", "top")
c.Assert(err, check.IsNil)
id := strings.TrimSpace(out)
out, err = s.d.Cmd("ps")
c.Assert(err, check.IsNil)
c.Assert(assertContainerList(out, []string{id}), check.Equals, true)
}
func (s *DockerAuthzV2Suite) TestAuthZPluginDisable(c *check.C) {

View file

@ -64,6 +64,7 @@ type authorizationController struct {
}
func (s *DockerAuthzSuite) SetUpTest(c *check.C) {
testRequires(c, SameHostDaemon)
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
Experimental: testEnv.ExperimentalDaemon(),
})
@ -218,12 +219,6 @@ func (s *DockerAuthzSuite) TestAuthZPluginAllowRequest(c *check.C) {
id := strings.TrimSpace(out)
assertURIRecorded(c, s.ctrl.requestsURIs, "/containers/create")
assertURIRecorded(c, s.ctrl.requestsURIs, fmt.Sprintf("/containers/%s/start", id))
out, err = s.d.Cmd("ps")
c.Assert(err, check.IsNil)
c.Assert(assertContainerList(out, []string{id}), check.Equals, true)
c.Assert(s.ctrl.psRequestCnt, check.Equals, 1)
c.Assert(s.ctrl.psResponseCnt, check.Equals, 1)
}
func (s *DockerAuthzSuite) TestAuthZPluginTls(c *check.C) {

View file

@ -27,17 +27,18 @@ import (
func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) {
testRequires(c, cpuCfsQuota)
name := "testbuildresourceconstraints"
buildLabel := "DockerSuite.TestBuildResourceConstraintsAreUsed"
ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(`
FROM hello-world:frozen
RUN ["/hello"]
`))
cli.Docker(
cli.Args("build", "--no-cache", "--rm=false", "--memory=64m", "--memory-swap=-1", "--cpuset-cpus=0", "--cpuset-mems=0", "--cpu-shares=100", "--cpu-quota=8000", "--ulimit", "nofile=42", "-t", name, "."),
cli.Args("build", "--no-cache", "--rm=false", "--memory=64m", "--memory-swap=-1", "--cpuset-cpus=0", "--cpuset-mems=0", "--cpu-shares=100", "--cpu-quota=8000", "--ulimit", "nofile=42", "--label="+buildLabel, "-t", name, "."),
cli.InDir(ctx.Dir),
).Assert(c, icmd.Success)
out := cli.DockerCmd(c, "ps", "-lq").Combined()
out := cli.DockerCmd(c, "ps", "-lq", "--filter", "label="+buildLabel).Combined()
cID := strings.TrimSpace(out)
type hostConfig struct {

View file

@ -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) {

View file

@ -11,6 +11,7 @@ import (
)
func (s *DockerSwarmSuite) TestConfigList(c *check.C) {
testRequires(c, SameHostDaemon)
d := s.AddDaemon(c, true, true)
testName0 := "test0"

View file

@ -50,6 +50,7 @@ type DockerExternalVolumeSuite struct {
}
func (s *DockerExternalVolumeSuite) SetUpTest(c *check.C) {
testRequires(c, SameHostDaemon)
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
Experimental: testEnv.ExperimentalDaemon(),
})

View file

@ -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 := ExistingContainerIDs(c)
imageName := "testhealth"
buildImageSuccessfully(c, imageName, build.WithDockerfile(`FROM busybox
RUN echo OK > /status
@ -49,9 +51,10 @@ func (s *DockerSuite) TestHealth(c *check.C) {
// No health status before starting
name := "test_health"
dockerCmd(c, "create", "--name", name, imageName)
out, _ := dockerCmd(c, "ps", "-a", "--format={{.Status}}")
c.Check(out, checker.Equals, "Created\n")
cid, _ := dockerCmd(c, "create", "--name", name, imageName)
out, _ := dockerCmd(c, "ps", "-a", "--format={{.ID}} {{.Status}}")
out = RemoveOutputForExistingElements(out, existingContainers)
c.Check(out, checker.Equals, cid[:12]+" Created\n")
// Inspect the options
out, _ = dockerCmd(c, "inspect",

View file

@ -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
}

View file

@ -1,13 +1,12 @@
package main
import (
"net/http"
"strings"
"time"
"github.com/docker/docker/client"
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/cli"
"github.com/docker/docker/integration-cli/request"
"github.com/go-check/check"
"github.com/gotestyourself/gotestyourself/icmd"
"golang.org/x/net/context"
@ -131,8 +130,7 @@ func (s *DockerSuite) TestKillStoppedContainerAPIPre120(c *check.C) {
testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later
runSleepingContainer(c, "--name", "docker-kill-test-api", "-d")
dockerCmd(c, "stop", "docker-kill-test-api")
var httpClient *http.Client
cli, err := client.NewClient(daemonHost(), "v1.19", httpClient, nil)
cli, err := request.NewEnvClientWithVersion("v1.19")
c.Assert(err, check.IsNil)
defer cli.Close()
err = cli.ContainerKill(context.Background(), "docker-kill-test-api", "SIGKILL")

View file

@ -10,7 +10,6 @@ import (
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"time"
@ -288,39 +287,6 @@ func (s *DockerNetworkSuite) TestDockerNetworkLsDefault(c *check.C) {
}
}
func (s *DockerSuite) TestNetworkLsFormat(c *check.C) {
testRequires(c, DaemonIsLinux)
out, _ := dockerCmd(c, "network", "ls", "--format", "{{.Name}}")
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
expected := []string{"bridge", "host", "none"}
var names []string
names = append(names, lines...)
c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with truncated names: %v, got: %v", expected, names))
}
func (s *DockerSuite) TestNetworkLsFormatDefaultFormat(c *check.C) {
testRequires(c, DaemonIsLinux)
config := `{
"networksFormat": "{{ .Name }} default"
}`
d, err := ioutil.TempDir("", "integration-cli-")
c.Assert(err, checker.IsNil)
defer os.RemoveAll(d)
err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644)
c.Assert(err, checker.IsNil)
out, _ := dockerCmd(c, "--config", d, "network", "ls")
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
expected := []string{"bridge default", "host default", "none default"}
var names []string
names = append(names, lines...)
c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with truncated names: %v, got: %v", expected, names))
}
func (s *DockerNetworkSuite) TestDockerNetworkCreatePredefined(c *check.C) {
predefined := []string{"bridge", "host", "none", "default"}
for _, net := range predefined {
@ -351,6 +317,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkRmPredefined(c *check.C) {
}
func (s *DockerNetworkSuite) TestDockerNetworkLsFilter(c *check.C) {
testRequires(c, OnlyDefaultNetworks)
testNet := "testnet1"
testLabel := "foo"
testValue := "bar"
@ -624,6 +591,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkConnectDisconnect(c *check.C) {
}
func (s *DockerNetworkSuite) TestDockerNetworkIPAMMultipleNetworks(c *check.C) {
testRequires(c, SameHostDaemon)
// test0 bridge network
dockerCmd(c, "network", "create", "--subnet=192.168.0.0/16", "test1")
assertNwIsAvailable(c, "test1")
@ -664,6 +632,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIPAMMultipleNetworks(c *check.C) {
}
func (s *DockerNetworkSuite) TestDockerNetworkCustomIPAM(c *check.C) {
testRequires(c, SameHostDaemon)
// Create a bridge network using custom ipam driver
dockerCmd(c, "network", "create", "--ipam-driver", dummyIPAMDriver, "br0")
assertNwIsAvailable(c, "br0")
@ -679,6 +648,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkCustomIPAM(c *check.C) {
}
func (s *DockerNetworkSuite) TestDockerNetworkIPAMOptions(c *check.C) {
testRequires(c, SameHostDaemon)
// Create a bridge network using custom ipam driver and options
dockerCmd(c, "network", "create", "--ipam-driver", dummyIPAMDriver, "--ipam-opt", "opt1=drv1", "--ipam-opt", "opt2=drv2", "br0")
assertNwIsAvailable(c, "br0")
@ -691,6 +661,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIPAMOptions(c *check.C) {
}
func (s *DockerNetworkSuite) TestDockerNetworkNullIPAMDriver(c *check.C) {
testRequires(c, SameHostDaemon)
// Create a network with null ipam driver
_, _, err := dockerCmdWithError("network", "create", "-d", dummyNetworkDriver, "--ipam-driver", "null", "test000")
c.Assert(err, check.IsNil)
@ -796,6 +767,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIPAMInvalidCombinations(c *check.C
}
func (s *DockerNetworkSuite) TestDockerNetworkDriverOptions(c *check.C) {
testRequires(c, SameHostDaemon)
dockerCmd(c, "network", "create", "-d", dummyNetworkDriver, "-o", "opt1=drv1", "-o", "opt2=drv2", "testopt")
assertNwIsAvailable(c, "testopt")
gopts := remoteDriverNetworkRequest.Options[netlabel.GenericData]
@ -981,6 +953,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkLinkOnDefaultNetworkOnly(c *check.
}
func (s *DockerNetworkSuite) TestDockerNetworkOverlayPortMapping(c *check.C) {
testRequires(c, SameHostDaemon)
// Verify exposed ports are present in ps output when running a container on
// a network managed by a driver which does not provide the default gateway
// for the container
@ -1007,7 +980,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkOverlayPortMapping(c *check.C) {
}
func (s *DockerNetworkSuite) TestDockerNetworkDriverUngracefulRestart(c *check.C) {
testRequires(c, DaemonIsLinux, NotUserNamespace)
testRequires(c, DaemonIsLinux, NotUserNamespace, SameHostDaemon)
dnd := "dnd"
did := "did"
@ -1048,6 +1021,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkDriverUngracefulRestart(c *check.C
}
func (s *DockerNetworkSuite) TestDockerNetworkMacInspect(c *check.C) {
testRequires(c, SameHostDaemon)
// Verify endpoint MAC address is correctly populated in container's network settings
nwn := "ov"
ctn := "bb"
@ -1113,6 +1087,7 @@ func verifyContainerIsConnectedToNetworks(c *check.C, d *daemon.Daemon, cName st
}
func (s *DockerNetworkSuite) TestDockerNetworkMultipleNetworksGracefulDaemonRestart(c *check.C) {
testRequires(c, SameHostDaemon)
cName := "bb"
nwList := []string{"nw1", "nw2", "nw3"}
@ -1131,6 +1106,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkMultipleNetworksGracefulDaemonRest
}
func (s *DockerNetworkSuite) TestDockerNetworkMultipleNetworksUngracefulDaemonRestart(c *check.C) {
testRequires(c, SameHostDaemon)
cName := "cc"
nwList := []string{"nw1", "nw2", "nw3"}
@ -1157,7 +1133,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkRunNetByID(c *check.C) {
}
func (s *DockerNetworkSuite) TestDockerNetworkHostModeUngracefulDaemonRestart(c *check.C) {
testRequires(c, DaemonIsLinux, NotUserNamespace)
testRequires(c, DaemonIsLinux, NotUserNamespace, SameHostDaemon)
s.d.StartWithBusybox(c)
// Run a few containers on host network
@ -1283,6 +1259,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkRestartWithMultipleNetworks(c *che
}
func (s *DockerNetworkSuite) TestDockerNetworkConnectDisconnectToStoppedContainer(c *check.C) {
testRequires(c, SameHostDaemon)
dockerCmd(c, "network", "create", "test")
dockerCmd(c, "create", "--name=foo", "busybox", "top")
dockerCmd(c, "network", "connect", "test", "foo")
@ -1810,7 +1787,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkDisconnectFromBridge(c *check.C) {
// TestConntrackFlowsLeak covers the failure scenario of ticket: https://github.com/docker/docker/issues/8795
// Validates that conntrack is correctly cleaned once a container is destroyed
func (s *DockerNetworkSuite) TestConntrackFlowsLeak(c *check.C) {
testRequires(c, IsAmd64, DaemonIsLinux, Network)
testRequires(c, IsAmd64, DaemonIsLinux, Network, SameHostDaemon)
// Create a new network
cli.DockerCmd(c, "network", "create", "--subnet=192.168.10.0/24", "--gateway=192.168.10.1", "-o", "com.docker.network.bridge.host_binding_ipv4=192.168.10.1", "testbind")

View file

@ -5,6 +5,7 @@ import (
"net"
"regexp"
"sort"
"strconv"
"strings"
"github.com/docker/docker/integration-cli/checker"
@ -148,9 +149,8 @@ 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"})
// Running this test multiple times causes the TCP port to increment.
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 +173,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)
}

View file

@ -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,11 +226,12 @@ 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)
}
}
func (s *DockerSuite) TestPsListContainersFilterHealth(c *check.C) {
existingContainers := ExistingContainerIDs(c)
// Test legacy no health check
out := runSleepingContainer(c, "--name=none_legacy")
containerID := strings.TrimSpace(out)
@ -264,7 +269,7 @@ func (s *DockerSuite) TestPsListContainersFilterHealth(c *check.C) {
waitForHealthStatus(c, "passing_container", "starting", "healthy")
out = cli.DockerCmd(c, "ps", "-q", "--no-trunc", "--filter=health=healthy").Combined()
containerOut = strings.TrimSpace(out)
containerOut = strings.TrimSpace(RemoveOutputForExistingElements(out, existingContainers))
c.Assert(containerOut, checker.Equals, containerID, check.Commentf("Expected containerID %s, got %s for healthy filter, output: %q", containerID, containerOut, out))
}
@ -305,6 +310,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 +374,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 +476,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 +500,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)))
@ -511,6 +522,7 @@ func (s *DockerSuite) TestPsRightTagName(c *check.C) {
func (s *DockerSuite) TestPsLinkedWithNoTrunc(c *check.C) {
// Problematic on Windows as it doesn't support links as of Jan 2016
testRequires(c, DaemonIsLinux)
existingContainers := ExistingContainerIDs(c)
runSleepingContainer(c, "--name=first")
runSleepingContainer(c, "--name=second", "--link=first:first")
@ -518,6 +530,7 @@ func (s *DockerSuite) TestPsLinkedWithNoTrunc(c *check.C) {
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
// strip header
lines = lines[1:]
lines = RemoveLinesForExistingElements(lines, existingContainers)
expected := []string{"second", "first,second/first"}
var names []string
for _, l := range lines {
@ -581,12 +594,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 +610,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,30 +620,22 @@ 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...)
c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with names displayed twice: %v, got: %v", expected, names))
}
func (s *DockerSuite) TestPsFormatHeaders(c *check.C) {
// make sure no-container "docker ps" still prints the header row
out, _ := dockerCmd(c, "ps", "--format", "table {{.ID}}")
c.Assert(out, checker.Equals, "CONTAINER ID\n", check.Commentf(`Expected 'CONTAINER ID\n', got %v`, out))
// verify that "docker ps" with a container still prints the header row also
runSleepingContainer(c, "--name=test")
out, _ = dockerCmd(c, "ps", "--format", "table {{.Names}}")
c.Assert(out, checker.Equals, "NAMES\ntest\n", check.Commentf(`Expected 'NAMES\ntest\n', got %v`, out))
}
func (s *DockerSuite) TestPsDefaultFormatAndQuiet(c *check.C) {
existingContainers := ExistingContainerIDs(c)
config := `{
"psFormat": "default {{ .ID }}"
}`
@ -642,6 +650,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 +661,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 +675,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 +692,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 +723,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 +751,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 +771,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 +785,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 +797,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 +809,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 +840,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 +859,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 +871,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 +886,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 +907,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,13 +950,16 @@ 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")
}
func (s *DockerSuite) TestPsListContainersFilterPorts(c *check.C) {
testRequires(c, DaemonIsLinux)
existingContainers := ExistingContainerIDs(c)
out, _ := dockerCmd(c, "run", "-d", "--publish=80", "busybox", "top")
id1 := strings.TrimSpace(out)
@ -962,6 +988,7 @@ func (s *DockerSuite) TestPsListContainersFilterPorts(c *check.C) {
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), id2)
out, _ = dockerCmd(c, "ps", "--no-trunc", "-q", "--filter", "expose=8080/tcp")
out = RemoveOutputForExistingElements(out, existingContainers)
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), id1)
c.Assert(strings.TrimSpace(out), checker.Equals, id2)
}
@ -969,11 +996,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 +1012,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")
}

View file

@ -21,6 +21,7 @@ import (
"sync"
"time"
"github.com/docker/docker/client"
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/cli"
"github.com/docker/docker/integration-cli/cli/build"
@ -35,6 +36,7 @@ import (
"github.com/go-check/check"
"github.com/gotestyourself/gotestyourself/icmd"
libcontainerUser "github.com/opencontainers/runc/libcontainer/user"
"golang.org/x/net/context"
)
// "test123" should be printed by docker run
@ -2813,23 +2815,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)
}
@ -3963,29 +3969,44 @@ func (s *DockerSuite) TestRunNamedVolumeNotRemoved(c *check.C) {
dockerCmd(c, "run", "--rm", "-v", "test:"+prefix+"/foo", "-v", prefix+"/bar", "busybox", "true")
dockerCmd(c, "volume", "inspect", "test")
out, _ := dockerCmd(c, "volume", "ls", "-q")
c.Assert(strings.TrimSpace(out), checker.Equals, "test")
c.Assert(strings.TrimSpace(out), checker.Contains, "test")
dockerCmd(c, "run", "--name=test", "-v", "test:"+prefix+"/foo", "-v", prefix+"/bar", "busybox", "true")
dockerCmd(c, "rm", "-fv", "test")
dockerCmd(c, "volume", "inspect", "test")
out, _ = dockerCmd(c, "volume", "ls", "-q")
c.Assert(strings.TrimSpace(out), checker.Equals, "test")
c.Assert(strings.TrimSpace(out), checker.Contains, "test")
}
func (s *DockerSuite) TestRunNamedVolumesFromNotRemoved(c *check.C) {
prefix, _ := getPrefixAndSlashFromDaemonPlatform()
dockerCmd(c, "volume", "create", "test")
dockerCmd(c, "run", "--name=parent", "-v", "test:"+prefix+"/foo", "-v", prefix+"/bar", "busybox", "true")
cid, _ := dockerCmd(c, "run", "-d", "--name=parent", "-v", "test:"+prefix+"/foo", "-v", prefix+"/bar", "busybox", "true")
dockerCmd(c, "run", "--name=child", "--volumes-from=parent", "busybox", "true")
cli, err := client.NewEnvClient()
c.Assert(err, checker.IsNil)
defer cli.Close()
container, err := cli.ContainerInspect(context.Background(), strings.TrimSpace(cid))
c.Assert(err, checker.IsNil)
var vname string
for _, v := range container.Mounts {
if v.Name != "test" {
vname = v.Name
}
}
c.Assert(vname, checker.Not(checker.Equals), "")
// Remove the parent so there are not other references to the volumes
dockerCmd(c, "rm", "-f", "parent")
// now remove the child and ensure the named volume (and only the named volume) still exists
dockerCmd(c, "rm", "-fv", "child")
dockerCmd(c, "volume", "inspect", "test")
out, _ := dockerCmd(c, "volume", "ls", "-q")
c.Assert(strings.TrimSpace(out), checker.Equals, "test")
c.Assert(strings.TrimSpace(out), checker.Contains, "test")
c.Assert(strings.TrimSpace(out), checker.Not(checker.Contains), vname)
}
func (s *DockerSuite) TestRunAttachFailedNoLeak(c *check.C) {
@ -4123,7 +4144,7 @@ func (s *DockerSuite) TestRunRm(c *check.C) {
// Test that auto-remove is performed by the client on API versions that do not support daemon-side api-remove (API < 1.25)
func (s *DockerSuite) TestRunRmPre125Api(c *check.C) {
name := "miss-me-when-im-gone"
envs := appendBaseEnv(false, "DOCKER_API_VERSION=1.24")
envs := appendBaseEnv(os.Getenv("DOCKER_TLS_VERIFY") != "", "DOCKER_API_VERSION=1.24")
cli.Docker(cli.Args("run", "--name="+name, "--rm", "busybox"), cli.WithEnvironmentVariables(envs...)).Assert(c, icmd.Success)
cli.Docker(cli.Inspect(name), cli.Format(".name")).Assert(c, icmd.Expected{

View file

@ -677,7 +677,7 @@ func (s *DockerSuite) TestRunWithSwappinessInvalid(c *check.C) {
}
func (s *DockerSuite) TestRunWithMemoryReservation(c *check.C) {
testRequires(c, memoryReservationSupport)
testRequires(c, SameHostDaemon, memoryReservationSupport)
file := "/sys/fs/cgroup/memory/memory.soft_limit_in_bytes"
out, _ := dockerCmd(c, "run", "--memory-reservation", "200M", "--name", "test", "busybox", "cat", file)
@ -689,7 +689,7 @@ func (s *DockerSuite) TestRunWithMemoryReservation(c *check.C) {
func (s *DockerSuite) TestRunWithMemoryReservationInvalid(c *check.C) {
testRequires(c, memoryLimitSupport)
testRequires(c, memoryReservationSupport)
testRequires(c, SameHostDaemon, memoryReservationSupport)
out, _, err := dockerCmdWithError("run", "-m", "500M", "--memory-reservation", "800M", "busybox", "true")
c.Assert(err, check.NotNil)
expected := "Minimum memory limit can not be less than memory reservation limit"
@ -1401,7 +1401,7 @@ func (s *DockerSuite) TestRunDeviceSymlink(c *check.C) {
// TestRunPIDsLimit makes sure the pids cgroup is set with --pids-limit
func (s *DockerSuite) TestRunPIDsLimit(c *check.C) {
testRequires(c, pidsLimit)
testRequires(c, SameHostDaemon, pidsLimit)
file := "/sys/fs/cgroup/pids/pids.max"
out, _ := dockerCmd(c, "run", "--name", "skittles", "--pids-limit", "4", "busybox", "cat", file)

View file

@ -139,7 +139,7 @@ func (s *DockerSuite) TestUpdateKernelMemory(c *check.C) {
func (s *DockerSuite) TestUpdateKernelMemoryUninitialized(c *check.C) {
testRequires(c, DaemonIsLinux, kernelMemorySupport)
isNewKernel := kernel.CheckKernelVersion(4, 6, 0)
isNewKernel := CheckKernelVersion(4, 6, 0)
name := "test-update-container"
dockerCmd(c, "run", "-d", "--name", name, "busybox", "top")
_, _, err := dockerCmdWithError("update", "--kernel-memory", "100M", name)
@ -171,6 +171,18 @@ func (s *DockerSuite) TestUpdateKernelMemoryUninitialized(c *check.C) {
c.Assert(strings.TrimSpace(out), checker.Equals, "314572800")
}
// GetKernelVersion gets the current kernel version.
func GetKernelVersion() *kernel.VersionInfo {
v, _ := kernel.ParseRelease(testEnv.DaemonInfo.KernelVersion)
return v
}
// CheckKernelVersion checks if current kernel is newer than (or equal to)
// the given version.
func CheckKernelVersion(k, major, minor int) bool {
return kernel.CompareKernelVersion(*GetKernelVersion(), kernel.VersionInfo{Kernel: k, Major: major, Minor: minor}) > 0
}
func (s *DockerSuite) TestUpdateSwapMemoryOnly(c *check.C) {
testRequires(c, DaemonIsLinux)
testRequires(c, memoryLimitSupport)

View file

@ -64,9 +64,6 @@ func (s *DockerSuite) TestVolumeCLIInspectMulti(c *check.C) {
})
out := result.Stdout()
outArr := strings.Split(strings.TrimSpace(out), "\n")
c.Assert(len(outArr), check.Equals, 3, check.Commentf("\n%s", out))
c.Assert(out, checker.Contains, "test1")
c.Assert(out, checker.Contains, "test2")
c.Assert(out, checker.Contains, "test3")
@ -81,11 +78,8 @@ func (s *DockerSuite) TestVolumeCLILs(c *check.C) {
dockerCmd(c, "volume", "create", "soo")
dockerCmd(c, "run", "-v", "soo:"+prefix+"/foo", "busybox", "ls", "/")
out, _ := dockerCmd(c, "volume", "ls")
outArr := strings.Split(strings.TrimSpace(out), "\n")
c.Assert(len(outArr), check.Equals, 4, check.Commentf("\n%s", out))
assertVolList(c, out, []string{"aaa", "soo", "test"})
out, _ := dockerCmd(c, "volume", "ls", "-q")
assertVolumesInList(c, out, []string{"aaa", "soo", "test"})
}
func (s *DockerSuite) TestVolumeLsFormat(c *check.C) {
@ -94,12 +88,7 @@ func (s *DockerSuite) TestVolumeLsFormat(c *check.C) {
dockerCmd(c, "volume", "create", "soo")
out, _ := dockerCmd(c, "volume", "ls", "--format", "{{.Name}}")
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
expected := []string{"aaa", "soo", "test"}
var names []string
names = append(names, lines...)
c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with truncated names: %v, got: %v", expected, names))
assertVolumesInList(c, out, []string{"aaa", "soo", "test"})
}
func (s *DockerSuite) TestVolumeLsFormatDefaultFormat(c *check.C) {
@ -118,12 +107,7 @@ func (s *DockerSuite) TestVolumeLsFormatDefaultFormat(c *check.C) {
c.Assert(err, checker.IsNil)
out, _ := dockerCmd(c, "--config", d, "volume", "ls")
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
expected := []string{"aaa default", "soo default", "test default"}
var names []string
names = append(names, lines...)
c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with truncated names: %v, got: %v", expected, names))
assertVolumesInList(c, out, []string{"aaa default", "soo default", "test default"})
}
// assertVolList checks volume retrieved with ls command
@ -142,6 +126,20 @@ func assertVolList(c *check.C, out string, expectVols []string) {
c.Assert(volList, checker.DeepEquals, expectVols)
}
func assertVolumesInList(c *check.C, out string, expected []string) {
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
for _, expect := range expected {
found := false
for _, v := range lines {
found = v == expect
if found {
break
}
}
c.Assert(found, checker.Equals, true, check.Commentf("Expected volume not found: %v, got: %v", expect, lines))
}
}
func (s *DockerSuite) TestVolumeCLILsFilterDangling(c *check.C) {
prefix, _ := getPrefixAndSlashFromDaemonPlatform()
dockerCmd(c, "volume", "create", "testnotinuse1")
@ -213,10 +211,6 @@ func (s *DockerSuite) TestVolumeCLIRm(c *check.C) {
dockerCmd(c, "volume", "rm", id)
dockerCmd(c, "volume", "rm", "test")
out, _ = dockerCmd(c, "volume", "ls")
outArr := strings.Split(strings.TrimSpace(out), "\n")
c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out))
volumeID := "testing"
dockerCmd(c, "run", "-v", volumeID+":"+prefix+"/foo", "--name=test", "busybox", "sh", "-c", "echo hello > /foo/bar")
@ -407,10 +401,6 @@ func (s *DockerSuite) TestVolumeCLIRmForceUsage(c *check.C) {
dockerCmd(c, "volume", "rm", "-f", id)
dockerCmd(c, "volume", "rm", "--force", "nonexist")
out, _ = dockerCmd(c, "volume", "ls")
outArr := strings.Split(strings.TrimSpace(out), "\n")
c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out))
}
func (s *DockerSuite) TestVolumeCLIRmForce(c *check.C) {

View file

@ -39,7 +39,7 @@ func newDockerHubPullSuite() *DockerHubPullSuite {
// SetUpSuite starts the suite daemon.
func (s *DockerHubPullSuite) SetUpSuite(c *check.C) {
testRequires(c, DaemonIsLinux)
testRequires(c, DaemonIsLinux, SameHostDaemon)
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
Experimental: testEnv.ExperimentalDaemon(),
})

View file

@ -6,7 +6,6 @@ import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"path"
"path/filepath"
@ -373,8 +372,7 @@ func waitInspectWithArgs(name, expr, expected string, timeout time.Duration, arg
}
func getInspectBody(c *check.C, version, id string) []byte {
var httpClient *http.Client
cli, err := client.NewClient(daemonHost(), version, httpClient, nil)
cli, err := request.NewEnvClientWithVersion(version)
c.Assert(err, check.IsNil)
defer cli.Close()
_, body, err := cli.ContainerInspectWithRaw(context.Background(), id, false)

View file

@ -129,7 +129,11 @@ func New(host, endpoint string, modifiers ...func(*http.Request) error) (*http.R
return nil, fmt.Errorf("could not create new request: %v", err)
}
req.URL.Scheme = "http"
if os.Getenv("DOCKER_TLS_VERIFY") != "" {
req.URL.Scheme = "https"
} else {
req.URL.Scheme = "http"
}
req.URL.Host = addr
for _, config := range modifiers {
@ -319,3 +323,35 @@ func DaemonHost() string {
}
return daemonURLStr
}
// NewEnvClientWithVersion returns a docker client with a specified version.
// See: github.com/docker/docker/client `NewEnvClient()`
func NewEnvClientWithVersion(version string) (*dclient.Client, error) {
if version == "" {
return nil, errors.New("version not specified")
}
var httpClient *http.Client
if os.Getenv("DOCKER_CERT_PATH") != "" {
tlsConfig, err := getTLSConfig()
if err != nil {
return nil, err
}
httpClient = &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
},
}
}
host := os.Getenv("DOCKER_HOST")
if host == "" {
host = dclient.DefaultDockerHost
}
cli, err := dclient.NewClient(host, version, httpClient, nil)
if err != nil {
return cli, err
}
return cli, nil
}

View file

@ -1,6 +1,7 @@
package main
import (
"context"
"fmt"
"io/ioutil"
"net/http"
@ -10,6 +11,8 @@ import (
"strings"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/docker/docker/integration-cli/requirement"
)
@ -36,6 +39,18 @@ func DaemonIsLinux() bool {
return testEnv.DaemonInfo.OSType == "linux"
}
func OnlyDefaultNetworks() bool {
cli, err := client.NewEnvClient()
if err != nil {
return false
}
networks, err := cli.NetworkList(context.TODO(), types.NetworkListOptions{})
if err != nil || len(networks) > 0 {
return false
}
return true
}
// Deprecated: use skip.IfCondition(t, !testEnv.DaemonInfo.ExperimentalBuild)
func ExperimentalDaemon() bool {
return testEnv.DaemonInfo.ExperimentalBuild

View file

@ -18,19 +18,19 @@ var (
)
func cpuCfsPeriod() bool {
return SysInfo.CPUCfsPeriod
return testEnv.DaemonInfo.CPUCfsPeriod
}
func cpuCfsQuota() bool {
return SysInfo.CPUCfsQuota
return testEnv.DaemonInfo.CPUCfsQuota
}
func cpuShare() bool {
return SysInfo.CPUShares
return testEnv.DaemonInfo.CPUShares
}
func oomControl() bool {
return SysInfo.OomKillDisable
return testEnv.DaemonInfo.OomKillDisable
}
func pidsLimit() bool {
@ -38,11 +38,11 @@ func pidsLimit() bool {
}
func kernelMemorySupport() bool {
return SysInfo.KernelMemory
return testEnv.DaemonInfo.KernelMemory
}
func memoryLimitSupport() bool {
return SysInfo.MemoryLimit
return testEnv.DaemonInfo.MemoryLimit
}
func memoryReservationSupport() bool {
@ -50,19 +50,19 @@ func memoryReservationSupport() bool {
}
func swapMemorySupport() bool {
return SysInfo.SwapLimit
return testEnv.DaemonInfo.SwapLimit
}
func memorySwappinessSupport() bool {
return SysInfo.MemorySwappiness
return SameHostDaemon() && SysInfo.MemorySwappiness
}
func blkioWeight() bool {
return SysInfo.BlkioWeight
return SameHostDaemon() && SysInfo.BlkioWeight
}
func cgroupCpuset() bool {
return SysInfo.Cpuset
return testEnv.DaemonInfo.CPUSet
}
func seccompEnabled() bool {
@ -111,5 +111,7 @@ func overlay2Supported() bool {
}
func init() {
SysInfo = sysinfo.New(true)
if SameHostDaemon() {
SysInfo = sysinfo.New(true)
}
}

View file

@ -8,6 +8,7 @@ import (
"strings"
"github.com/docker/docker/pkg/stringutils"
"github.com/go-check/check"
"github.com/gotestyourself/gotestyourself/icmd"
"github.com/pkg/errors"
)
@ -112,3 +113,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")
}

View file

@ -23,6 +23,6 @@ func TestMain(m *testing.M) {
}
func setupTest(t *testing.T) func() {
environment.ProtectImages(t, testEnv)
environment.ProtectAll(t, testEnv)
return func() { testEnv.Clean(t) }
}

View file

@ -12,12 +12,14 @@ import (
"github.com/docker/docker/integration-cli/daemon"
"github.com/docker/docker/integration-cli/request"
"github.com/gotestyourself/gotestyourself/poll"
"github.com/gotestyourself/gotestyourself/skip"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func TestInspect(t *testing.T) {
skip.IfCondition(t, !testEnv.IsLocalDaemon())
defer setupTest(t)()
d := newSwarm(t)
defer d.Stop(t)

View file

@ -25,6 +25,6 @@ func TestMain(m *testing.M) {
}
func setupTest(t *testing.T) func() {
environment.ProtectImages(t, testEnv)
environment.ProtectAll(t, testEnv)
return func() { testEnv.Clean(t) }
}

View file

@ -32,12 +32,12 @@ func (e *Execution) Clean(t testingT) {
if (platform != "windows") || (platform == "windows" && e.DaemonInfo.Isolation == "hyperv") {
unpauseAllContainers(t, client)
}
deleteAllContainers(t, client)
deleteAllContainers(t, client, e.protectedElements.containers)
deleteAllImages(t, client, e.protectedElements.images)
deleteAllVolumes(t, client)
deleteAllNetworks(t, client, platform)
deleteAllVolumes(t, client, e.protectedElements.volumes)
deleteAllNetworks(t, client, platform, e.protectedElements.networks)
if platform == "linux" {
deleteAllPlugins(t, client)
deleteAllPlugins(t, client, e.protectedElements.plugins)
}
}
@ -66,7 +66,7 @@ func getPausedContainers(ctx context.Context, t assert.TestingT, client client.C
var alreadyExists = regexp.MustCompile(`Error response from daemon: removal of container (\w+) is already in progress`)
func deleteAllContainers(t assert.TestingT, apiclient client.ContainerAPIClient) {
func deleteAllContainers(t assert.TestingT, apiclient client.ContainerAPIClient, protectedContainers map[string]struct{}) {
ctx := context.Background()
containers := getAllContainers(ctx, t, apiclient)
if len(containers) == 0 {
@ -74,6 +74,9 @@ func deleteAllContainers(t assert.TestingT, apiclient client.ContainerAPIClient)
}
for _, container := range containers {
if _, ok := protectedContainers[container.ID]; ok {
continue
}
err := apiclient.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{
Force: true,
RemoveVolumes: true,
@ -126,17 +129,20 @@ func removeImage(ctx context.Context, t assert.TestingT, apiclient client.ImageA
assert.NoError(t, err, "failed to remove image %s", ref)
}
func deleteAllVolumes(t assert.TestingT, c client.VolumeAPIClient) {
func deleteAllVolumes(t assert.TestingT, c client.VolumeAPIClient, protectedVolumes map[string]struct{}) {
volumes, err := c.VolumeList(context.Background(), filters.Args{})
assert.NoError(t, err, "failed to list volumes")
for _, v := range volumes.Volumes {
if _, ok := protectedVolumes[v.Name]; ok {
continue
}
err := c.VolumeRemove(context.Background(), v.Name, true)
assert.NoError(t, err, "failed to remove volume %s", v.Name)
}
}
func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatform string) {
func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatform string, protectedNetworks map[string]struct{}) {
networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{})
assert.NoError(t, err, "failed to list networks")
@ -144,6 +150,9 @@ func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatf
if n.Name == "bridge" || n.Name == "none" || n.Name == "host" {
continue
}
if _, ok := protectedNetworks[n.ID]; ok {
continue
}
if daemonPlatform == "windows" && strings.ToLower(n.Name) == "nat" {
// nat is a pre-defined network on Windows and cannot be removed
continue
@ -153,11 +162,14 @@ func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatf
}
}
func deleteAllPlugins(t assert.TestingT, c client.PluginAPIClient) {
func deleteAllPlugins(t assert.TestingT, c client.PluginAPIClient, protectedPlugins map[string]struct{}) {
plugins, err := c.PluginList(context.Background(), filters.Args{})
assert.NoError(t, err, "failed to list plugins")
for _, p := range plugins {
if _, ok := protectedPlugins[p.Name]; ok {
continue
}
err := c.PluginRemove(context.Background(), p.Name, types.PluginRemoveOptions{Force: true})
assert.NoError(t, err, "failed to remove plugin %s", p.ID)
}

View file

@ -10,7 +10,63 @@ import (
)
type protectedElements struct {
images map[string]struct{}
containers map[string]struct{}
images map[string]struct{}
networks map[string]struct{}
plugins map[string]struct{}
volumes map[string]struct{}
}
func newProtectedElements() protectedElements {
return protectedElements{
containers: map[string]struct{}{},
images: map[string]struct{}{},
networks: map[string]struct{}{},
plugins: map[string]struct{}{},
volumes: map[string]struct{}{},
}
}
// ProtectAll protects the existing environment (containers, images, networks,
// volumes, and, on Linux, plugins) from being cleaned up at the end of test
// runs
func ProtectAll(t testingT, testEnv *Execution) {
ProtectContainers(t, testEnv)
ProtectImages(t, testEnv)
ProtectNetworks(t, testEnv)
ProtectVolumes(t, testEnv)
if testEnv.DaemonInfo.OSType == "linux" {
ProtectPlugins(t, testEnv)
}
}
// ProtectContainer adds the specified container(s) to be protected in case of
// clean
func (e *Execution) ProtectContainer(t testingT, containers ...string) {
for _, container := range containers {
e.protectedElements.containers[container] = struct{}{}
}
}
// ProtectContainers protects existing containers from being cleaned up at the
// end of test runs
func ProtectContainers(t testingT, testEnv *Execution) {
containers := getExistingContainers(t, testEnv)
testEnv.ProtectContainer(t, containers...)
}
func getExistingContainers(t require.TestingT, testEnv *Execution) []string {
client := testEnv.APIClient()
containerList, err := client.ContainerList(context.Background(), types.ContainerListOptions{
All: true,
})
require.NoError(t, err, "failed to list containers")
containers := []string{}
for _, container := range containerList {
containers = append(containers, container.ID)
}
return containers
}
// ProtectImage adds the specified image(s) to be protected in case of clean
@ -20,12 +76,6 @@ func (e *Execution) ProtectImage(t testingT, images ...string) {
}
}
func newProtectedElements() protectedElements {
return protectedElements{
images: map[string]struct{}{},
}
}
// ProtectImages protects existing images and on linux frozen images from being
// cleaned up at the end of test runs
func ProtectImages(t testingT, testEnv *Execution) {
@ -42,6 +92,7 @@ func getExistingImages(t require.TestingT, testEnv *Execution) []string {
filter := filters.NewArgs()
filter.Add("dangling", "false")
imageList, err := client.ImageList(context.Background(), types.ImageListOptions{
All: true,
Filters: filter,
})
require.NoError(t, err, "failed to list images")
@ -76,3 +127,82 @@ func ensureFrozenImagesLinux(t testingT, testEnv *Execution) []string {
}
return images
}
// ProtectNetwork adds the specified network(s) to be protected in case of
// clean
func (e *Execution) ProtectNetwork(t testingT, networks ...string) {
for _, network := range networks {
e.protectedElements.networks[network] = struct{}{}
}
}
// ProtectNetworks protects existing networks from being cleaned up at the end
// of test runs
func ProtectNetworks(t testingT, testEnv *Execution) {
networks := getExistingNetworks(t, testEnv)
testEnv.ProtectNetwork(t, networks...)
}
func getExistingNetworks(t require.TestingT, testEnv *Execution) []string {
client := testEnv.APIClient()
networkList, err := client.NetworkList(context.Background(), types.NetworkListOptions{})
require.NoError(t, err, "failed to list networks")
networks := []string{}
for _, network := range networkList {
networks = append(networks, network.ID)
}
return networks
}
// ProtectPlugin adds the specified plugin(s) to be protected in case of clean
func (e *Execution) ProtectPlugin(t testingT, plugins ...string) {
for _, plugin := range plugins {
e.protectedElements.plugins[plugin] = struct{}{}
}
}
// ProtectPlugins protects existing plugins from being cleaned up at the end of
// test runs
func ProtectPlugins(t testingT, testEnv *Execution) {
plugins := getExistingPlugins(t, testEnv)
testEnv.ProtectPlugin(t, plugins...)
}
func getExistingPlugins(t require.TestingT, testEnv *Execution) []string {
client := testEnv.APIClient()
pluginList, err := client.PluginList(context.Background(), filters.Args{})
require.NoError(t, err, "failed to list plugins")
plugins := []string{}
for _, plugin := range pluginList {
plugins = append(plugins, plugin.Name)
}
return plugins
}
// ProtectVolume adds the specified volume(s) to be protected in case of clean
func (e *Execution) ProtectVolume(t testingT, volumes ...string) {
for _, volume := range volumes {
e.protectedElements.volumes[volume] = struct{}{}
}
}
// ProtectVolumes protects existing volumes from being cleaned up at the end of
// test runs
func ProtectVolumes(t testingT, testEnv *Execution) {
volumes := getExistingVolumes(t, testEnv)
testEnv.ProtectVolume(t, volumes...)
}
func getExistingVolumes(t require.TestingT, testEnv *Execution) []string {
client := testEnv.APIClient()
volumeList, err := client.VolumeList(context.Background(), filters.Args{})
require.NoError(t, err, "failed to list volumes")
volumes := []string{}
for _, volume := range volumeList.Volumes {
volumes = append(volumes, volume.Name)
}
return volumes
}