From 777ee34b075292e5aee16c4088444508899f8f35 Mon Sep 17 00:00:00 2001 From: Arnaud Porterie Date: Tue, 26 Jan 2016 20:16:36 -0800 Subject: [PATCH] Factorize sleeping containers Add `runSleepingContainer` and `runSleepingContainerInImage` helper functions to factor out the way to run system-specific idle containers. Define a sleeping container as command `top` in image `busybox` for Unix and as command `sleep 60` in image `busybox` for Windows. Provide a single point of code to update those. Signed-off-by: Arnaud Porterie --- integration-cli/docker_api_containers_test.go | 31 +++++++++---------- integration-cli/docker_cli_ps_test.go | 28 +++++++---------- integration-cli/docker_cli_rename_test.go | 14 ++------- integration-cli/docker_cli_rmi_test.go | 12 ++----- integration-cli/docker_utils.go | 16 ++++++++++ integration-cli/test_vars_unix.go | 6 ++++ integration-cli/test_vars_windows.go | 6 ++++ 7 files changed, 60 insertions(+), 53 deletions(-) diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index eb110fa151..ad93574992 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -24,12 +24,6 @@ import ( "github.com/go-check/check" ) -func init() { - if daemonPlatform == "windows" { - sleepCmd = "sleep" - } -} - func (s *DockerSuite) TestContainerApiGetAll(c *check.C) { startCount, err := getContainerCount() c.Assert(err, checker.IsNil, check.Commentf("Cannot query container count")) @@ -96,7 +90,7 @@ func (s *DockerSuite) TestContainerApiPsOmitFields(c *check.C) { testRequires(c, DaemonIsLinux) name := "pstest" port := 80 - dockerCmd(c, "run", "-d", "--name", name, "--expose", strconv.Itoa(port), "busybox", sleepCmd, "60") + runSleepingContainer(c, "--name", name, "--expose", strconv.Itoa(port)) status, body, err := sockRequest("GET", "/containers/json?all=1", nil) c.Assert(err, checker.IsNil) @@ -929,7 +923,7 @@ func (s *DockerSuite) TestContainerApiRename(c *check.C) { func (s *DockerSuite) TestContainerApiKill(c *check.C) { name := "test-api-kill" - dockerCmd(c, "run", "-di", "--name", name, "busybox", sleepCmd, "60") + runSleepingContainer(c, "-i", "--name", name) status, _, err := sockRequest("POST", "/containers/"+name+"/kill", nil) c.Assert(err, checker.IsNil) @@ -970,7 +964,7 @@ func (s *DockerSuite) TestContainerApiStart(c *check.C) { name := "testing-start" config := map[string]interface{}{ "Image": "busybox", - "Cmd": []string{"/bin/sh", "-c", sleepCmd, "60"}, + "Cmd": append([]string{"/bin/sh", "-c"}, defaultSleepCommand...), "OpenStdin": true, } @@ -991,7 +985,7 @@ func (s *DockerSuite) TestContainerApiStart(c *check.C) { func (s *DockerSuite) TestContainerApiStop(c *check.C) { name := "test-api-stop" - dockerCmd(c, "run", "-di", "--name", name, "busybox", sleepCmd, "60") + runSleepingContainer(c, "-i", "--name", name) status, _, err := sockRequest("POST", "/containers/"+name+"/stop?t=30", nil) c.Assert(err, checker.IsNil) @@ -1006,6 +1000,11 @@ func (s *DockerSuite) TestContainerApiStop(c *check.C) { func (s *DockerSuite) TestContainerApiWait(c *check.C) { name := "test-api-wait" + + sleepCmd := "/bin/sleep" + if daemonPlatform == "windows" { + sleepCmd = "sleep" + } dockerCmd(c, "run", "--name", name, "busybox", sleepCmd, "5") status, body, err := sockRequest("POST", "/containers/"+name+"/wait", nil) @@ -1092,7 +1091,7 @@ func (s *DockerSuite) TestContainerApiCopyContainerNotFound(c *check.C) { } func (s *DockerSuite) TestContainerApiDelete(c *check.C) { - out, _ := dockerCmd(c, "run", "-d", "busybox", sleepCmd, "60") + out, _ := runSleepingContainer(c) id := strings.TrimSpace(out) c.Assert(waitRun(id), checker.IsNil) @@ -1112,7 +1111,7 @@ func (s *DockerSuite) TestContainerApiDeleteNotExist(c *check.C) { } func (s *DockerSuite) TestContainerApiDeleteForce(c *check.C) { - out, _ := dockerCmd(c, "run", "-d", "busybox", sleepCmd, "60") + out, _ := runSleepingContainer(c) id := strings.TrimSpace(out) c.Assert(waitRun(id), checker.IsNil) @@ -1149,7 +1148,7 @@ func (s *DockerSuite) TestContainerApiDeleteRemoveLinks(c *check.C) { } func (s *DockerSuite) TestContainerApiDeleteConflict(c *check.C) { - out, _ := dockerCmd(c, "run", "-d", "busybox", sleepCmd, "60") + out, _ := runSleepingContainer(c) id := strings.TrimSpace(out) c.Assert(waitRun(id), checker.IsNil) @@ -1167,7 +1166,7 @@ func (s *DockerSuite) TestContainerApiDeleteRemoveVolume(c *check.C) { vol = `c:\testvolume` } - out, _ := dockerCmd(c, "run", "-d", "-v", vol, "busybox", sleepCmd, "60") + out, _ := runSleepingContainer(c, "-v", vol) id := strings.TrimSpace(out) c.Assert(waitRun(id), checker.IsNil) @@ -1221,7 +1220,7 @@ func (s *DockerSuite) TestContainerApiChunkedEncoding(c *check.C) { } func (s *DockerSuite) TestContainerApiPostContainerStop(c *check.C) { - out, _ := dockerCmd(c, "run", "-d", "busybox", sleepCmd, "60") + out, _ := runSleepingContainer(c) containerID := strings.TrimSpace(out) c.Assert(waitRun(containerID), checker.IsNil) @@ -1307,7 +1306,7 @@ func (s *DockerSuite) TestPostContainersStartWithoutLinksInHostConfig(c *check.C // An alternate test could be written to validate the negative testing aspect of this testRequires(c, DaemonIsLinux) name := "test-host-config-links" - dockerCmd(c, "create", "--name", name, "busybox", sleepCmd, "60") + dockerCmd(c, append([]string{"create", "--name", name, "busybox"}, defaultSleepCommand...)...) hc, err := inspectFieldJSON(name, "HostConfig") c.Assert(err, checker.IsNil) diff --git a/integration-cli/docker_cli_ps_test.go b/integration-cli/docker_cli_ps_test.go index 7f4e7253f4..1c130fe83f 100644 --- a/integration-cli/docker_cli_ps_test.go +++ b/integration-cli/docker_cli_ps_test.go @@ -16,12 +16,6 @@ import ( "github.com/go-check/check" ) -func init() { - if daemonPlatform == "windows" { - sleepCmd = "sleep" - } -} - func (s *DockerSuite) TestPsListContainersBase(c *check.C) { // Problematic on Windows as busybox doesn't support top testRequires(c, DaemonIsLinux) @@ -220,7 +214,7 @@ func (s *DockerSuite) TestPsListContainersFilterID(c *check.C) { firstID := strings.TrimSpace(out) // start another container - dockerCmd(c, "run", "-d", "busybox", sleepCmd, "60") + runSleepingContainer(c) // filter containers by id out, _ = dockerCmd(c, "ps", "-a", "-q", "--filter=id="+firstID) @@ -235,7 +229,7 @@ func (s *DockerSuite) TestPsListContainersFilterName(c *check.C) { firstID := strings.TrimSpace(out) // start another container - dockerCmd(c, "run", "-d", "--name=b_name_to_match", "busybox", sleepCmd, "60") + runSleepingContainer(c, "--name=b_name_to_match") // filter containers by name out, _ = dockerCmd(c, "ps", "-a", "-q", "--filter=name=a_name_to_match") @@ -386,7 +380,7 @@ func (s *DockerSuite) TestPsListContainersFilterLabel(c *check.C) { func (s *DockerSuite) TestPsListContainersFilterExited(c *check.C) { // TODO Windows CI: Enable for TP5. Fails on TP4 testRequires(c, DaemonIsLinux) - dockerCmd(c, "run", "-d", "--name", "sleep", "busybox", sleepCmd, "60") + runSleepingContainer(c, "--name=sleep") dockerCmd(c, "run", "--name", "zero1", "busybox", "true") firstZero, err := getIDByName("zero1") @@ -429,11 +423,11 @@ func (s *DockerSuite) TestPsRightTagName(c *check.C) { dockerCmd(c, "tag", "busybox", tag) var id1 string - out, _ := dockerCmd(c, "run", "-d", "busybox", sleepCmd, "60") + out, _ := runSleepingContainer(c) id1 = strings.TrimSpace(string(out)) var id2 string - out, _ = dockerCmd(c, "run", "-d", tag, sleepCmd, "60") + out, _ = runSleepingContainerInImage(c, tag) id2 = strings.TrimSpace(string(out)) var imageID string @@ -441,7 +435,7 @@ func (s *DockerSuite) TestPsRightTagName(c *check.C) { imageID = strings.TrimSpace(string(out)) var id3 string - out, _ = dockerCmd(c, "run", "-d", imageID, sleepCmd, "60") + out, _ = runSleepingContainerInImage(c, imageID) id3 = strings.TrimSpace(string(out)) out, _ = dockerCmd(c, "ps", "--no-trunc") @@ -467,8 +461,8 @@ 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) - dockerCmd(c, "run", "--name=first", "-d", "busybox", sleepCmd, "60") - dockerCmd(c, "run", "--name=second", "--link=first:first", "-d", "busybox", sleepCmd, "60") + runSleepingContainer(c, "--name=first") + runSleepingContainer(c, "--name=second", "--link=first:first") out, _ := dockerCmd(c, "ps", "--no-trunc") lines := strings.Split(strings.TrimSpace(string(out)), "\n") @@ -569,7 +563,7 @@ func (s *DockerSuite) TestPsFormatHeaders(c *check.C) { 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 - dockerCmd(c, "run", "--name=test", "-d", "busybox", sleepCmd, "60") + 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)) } @@ -585,7 +579,7 @@ func (s *DockerSuite) TestPsDefaultFormatAndQuiet(c *check.C) { err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644) c.Assert(err, checker.IsNil) - out, _ := dockerCmd(c, "run", "--name=test", "-d", "busybox", sleepCmd, "60") + out, _ := runSleepingContainer(c, "--name=test") id := strings.TrimSpace(out) out, _ = dockerCmd(c, "--config", d, "ps", "-q") @@ -606,7 +600,7 @@ func (s *DockerSuite) TestPsImageIDAfterUpdate(c *check.C) { originalImageID, err := getIDByName(originalImageName) c.Assert(err, checker.IsNil) - runCmd = exec.Command(dockerBinary, "run", "-d", originalImageName, sleepCmd, "60") + runCmd = exec.Command(dockerBinary, append([]string{"run", "-d", originalImageName}, defaultSleepCommand...)...) out, _, err = runCommandWithOutput(runCmd) c.Assert(err, checker.IsNil) containerID := strings.TrimSpace(out) diff --git a/integration-cli/docker_cli_rename_test.go b/integration-cli/docker_cli_rename_test.go index d534d1a1fb..efad6ecb4d 100644 --- a/integration-cli/docker_cli_rename_test.go +++ b/integration-cli/docker_cli_rename_test.go @@ -8,14 +8,6 @@ import ( "github.com/go-check/check" ) -var sleepCmd = "/bin/sleep" - -func init() { - if daemonPlatform == "windows" { - sleepCmd = "sleep" - } -} - func (s *DockerSuite) TestRenameStoppedContainer(c *check.C) { out, _ := dockerCmd(c, "run", "--name", "first_name", "-d", "busybox", "sh") @@ -45,7 +37,7 @@ func (s *DockerSuite) TestRenameRunningContainer(c *check.C) { } func (s *DockerSuite) TestRenameRunningContainerAndReuse(c *check.C) { - out, _ := dockerCmd(c, "run", "--name", "first_name", "-d", "busybox", sleepCmd, "60") + out, _ := runSleepingContainer(c, "--name", "first_name") c.Assert(waitRun("first_name"), check.IsNil) newName := "new_name" @@ -56,7 +48,7 @@ func (s *DockerSuite) TestRenameRunningContainerAndReuse(c *check.C) { c.Assert(err, checker.IsNil, check.Commentf("Failed to rename container %s", name)) c.Assert(name, checker.Equals, "/"+newName, check.Commentf("Failed to rename container")) - out, _ = dockerCmd(c, "run", "--name", "first_name", "-d", "busybox", sleepCmd, "60") + out, _ = runSleepingContainer(c, "--name", "first_name") c.Assert(waitRun("first_name"), check.IsNil) newContainerID := strings.TrimSpace(out) name, err = inspectField(newContainerID, "Name") @@ -80,7 +72,7 @@ func (s *DockerSuite) TestRenameCheckNames(c *check.C) { } func (s *DockerSuite) TestRenameInvalidName(c *check.C) { - dockerCmd(c, "run", "--name", "myname", "-d", "busybox", sleepCmd, "60") + runSleepingContainer(c, "--name", "myname") out, _, err := dockerCmdWithError("rename", "myname", "new:invalid") c.Assert(err, checker.NotNil, check.Commentf("Renaming container to invalid name should have failed: %s", out)) diff --git a/integration-cli/docker_cli_rmi_test.go b/integration-cli/docker_cli_rmi_test.go index a6e15302fe..901b1e7e36 100644 --- a/integration-cli/docker_cli_rmi_test.go +++ b/integration-cli/docker_cli_rmi_test.go @@ -11,12 +11,6 @@ import ( "github.com/go-check/check" ) -func init() { - if daemonPlatform == "windows" { - sleepCmd = "sleep" - } -} - func (s *DockerSuite) TestRmiWithContainerFails(c *check.C) { errSubstr := "is using it" @@ -92,7 +86,7 @@ func (s *DockerSuite) TestRmiImgIDMultipleTag(c *check.C) { c.Assert(err, checker.IsNil) // run a container with the image - out, _ = dockerCmd(c, "run", "-d", "busybox-one", sleepCmd, "60") + out, _ = runSleepingContainerInImage(c, "busybox-one") containerID = strings.TrimSpace(out) @@ -160,7 +154,7 @@ func (s *DockerSuite) TestRmiImageIDForceWithRunningContainersAndMultipleTags(c newTag := "newtag" dockerCmd(c, "tag", imgID, newTag) - dockerCmd(c, "run", "-d", imgID, sleepCmd, "60") + runSleepingContainerInImage(c, imgID) out, _, err := dockerCmdWithError("rmi", "-f", imgID) // rmi -f should not delete image with running containers @@ -262,7 +256,7 @@ func (s *DockerSuite) TestRmiContainerImageNotFound(c *check.C) { } // Create a long-running container. - dockerCmd(c, "run", "-d", imageNames[0], sleepCmd, "60") + runSleepingContainerInImage(c, imageNames[0]) // Create a stopped container, and then force remove its image. dockerCmd(c, "run", imageNames[1], "true") diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index 647b2c8df5..b29e6af9b3 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -1707,3 +1707,19 @@ func getInspectBody(c *check.C, version, id string) []byte { c.Assert(status, check.Equals, http.StatusOK) return body } + +// Run a long running idle task in a background container using the +// system-specific default image and command. +func runSleepingContainer(c *check.C, extraArgs ...string) (string, int) { + return runSleepingContainerInImage(c, defaultSleepImage, extraArgs...) +} + +// Run a long running idle task in a background container using the specified +// image and the system-specific command. +func runSleepingContainerInImage(c *check.C, image string, extraArgs ...string) (string, int) { + args := []string{"run", "-d"} + args = append(args, extraArgs...) + args = append(args, image) + args = append(args, defaultSleepCommand...) + return dockerCmd(c, args...) +} diff --git a/integration-cli/test_vars_unix.go b/integration-cli/test_vars_unix.go index 1ab8a5ca48..853889abe7 100644 --- a/integration-cli/test_vars_unix.go +++ b/integration-cli/test_vars_unix.go @@ -7,4 +7,10 @@ const ( isUnixCli = true expectedFileChmod = "-rw-r--r--" + + // On Unix variants, the busybox image comes with the `top` command which + // runs indefinitely while still being interruptible by a signal. + defaultSleepImage = "busybox" ) + +var defaultSleepCommand = []string{"top"} diff --git a/integration-cli/test_vars_windows.go b/integration-cli/test_vars_windows.go index f81ac53cc3..a1b916c181 100644 --- a/integration-cli/test_vars_windows.go +++ b/integration-cli/test_vars_windows.go @@ -8,4 +8,10 @@ const ( // this is the expected file permission set on windows: gh#11395 expectedFileChmod = "-rwxr-xr-x" + + // On Windows, the busybox image doesn't have the `top` command, so we rely + // on `sleep` with a high duration. + defaultSleepImage = "busybox" ) + +var defaultSleepCommand = []string{"sleep", "60"}