"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "components/engine/integration-cli/docker_cli_service_health_test.go" between
docker-ce-19.03.2.tar.gz and docker-ce-19.03.3.tar.gz

About: Docker CE is a project to pack, ship and run any application as a lightweight container. Docker containers can run anywhere, on a laptop or at scale, in production, on VMs, bare metal, OpenStack clusters, public clouds and more. Community edition.

docker_cli_service_health_test.go  (docker-ce-19.03.2):docker_cli_service_health_test.go  (docker-ce-19.03.3)
// +build !windows // +build !windows
package main package main
import ( import (
"strconv" "strconv"
"strings" "strings"
"testing"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/daemon/cluster/executor/container" "github.com/docker/docker/daemon/cluster/executor/container"
"github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli"
"github.com/docker/docker/integration-cli/cli/build" "github.com/docker/docker/integration-cli/cli/build"
"github.com/go-check/check"
"gotest.tools/assert" "gotest.tools/assert"
"gotest.tools/icmd" "gotest.tools/icmd"
"gotest.tools/poll"
) )
// start a service, and then make its task unhealthy during running // start a service, and then make its task unhealthy during running
// finally, unhealthy task should be detected and killed // finally, unhealthy task should be detected and killed
func (s *DockerSwarmSuite) TestServiceHealthRun(c *check.C) { func (s *DockerSwarmSuite) TestServiceHealthRun(c *testing.T) {
testRequires(c, DaemonIsLinux) // busybox doesn't work on Windows testRequires(c, DaemonIsLinux) // busybox doesn't work on Windows
d := s.AddDaemon(c, true, true) d := s.AddDaemon(c, true, true)
// build image with health-check // build image with health-check
imageName := "testhealth" imageName := "testhealth"
result := cli.BuildCmd(c, imageName, cli.Daemon(d), result := cli.BuildCmd(c, imageName, cli.Daemon(d),
build.WithDockerfile(`FROM busybox build.WithDockerfile(`FROM busybox
RUN touch /status RUN touch /status
HEALTHCHECK --interval=1s --timeout=1s --retries=1\ HEALTHCHECK --interval=1s --timeout=5s --retries=1\
CMD cat /status`), CMD cat /status`),
) )
result.Assert(c, icmd.Success) result.Assert(c, icmd.Success)
serviceName := "healthServiceRun" serviceName := "healthServiceRun"
out, err := d.Cmd("service", "create", "--no-resolve-image", "--detach=tr ue", "--name", serviceName, imageName, "top") out, err := d.Cmd("service", "create", "--no-resolve-image", "--detach=tr ue", "--name", serviceName, imageName, "top")
assert.NilError(c, err, out) assert.NilError(c, err, out)
id := strings.TrimSpace(out) id := strings.TrimSpace(out)
var tasks []swarm.Task var tasks []swarm.Task
waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interfac e{}, check.CommentInterface) { poll.WaitOn(c, pollCheck(c, func(c *testing.T) (interface{}, string) {
tasks = d.GetServiceTasks(c, id) tasks = d.GetServiceTasks(c, id)
return tasks, nil return tasks, ""
}, checker.HasLen, 1) }, checker.HasLen(1)), poll.WithTimeout(defaultReconciliationTimeout))
task := tasks[0] task := tasks[0]
// wait for task to start // wait for task to start
waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interfac e{}, check.CommentInterface) { poll.WaitOn(c, pollCheck(c, func(c *testing.T) (interface{}, string) {
task = d.GetTask(c, task.ID) task = d.GetTask(c, task.ID)
return task.Status.State, nil return task.Status.State, ""
}, checker.Equals, swarm.TaskStateRunning) }, checker.Equals(swarm.TaskStateRunning)), poll.WithTimeout(defaultRecon
ciliationTimeout))
containerID := task.Status.ContainerStatus.ContainerID containerID := task.Status.ContainerStatus.ContainerID
// wait for container to be healthy // wait for container to be healthy
waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interfac e{}, check.CommentInterface) { poll.WaitOn(c, pollCheck(c, func(c *testing.T) (interface{}, string) {
out, _ := d.Cmd("inspect", "--format={{.State.Health.Status}}", c ontainerID) out, _ := d.Cmd("inspect", "--format={{.State.Health.Status}}", c ontainerID)
return strings.TrimSpace(out), nil return strings.TrimSpace(out), ""
}, checker.Equals, "healthy") }, checker.Equals("healthy")), poll.WithTimeout(defaultReconciliationTime
out))
// make it fail // make it fail
d.Cmd("exec", containerID, "rm", "/status") d.Cmd("exec", containerID, "rm", "/status")
// wait for container to be unhealthy // wait for container to be unhealthy
waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interfac e{}, check.CommentInterface) { poll.WaitOn(c, pollCheck(c, func(c *testing.T) (interface{}, string) {
out, _ := d.Cmd("inspect", "--format={{.State.Health.Status}}", c ontainerID) out, _ := d.Cmd("inspect", "--format={{.State.Health.Status}}", c ontainerID)
return strings.TrimSpace(out), nil return strings.TrimSpace(out), ""
}, checker.Equals, "unhealthy") }, checker.Equals("unhealthy")), poll.WithTimeout(defaultReconciliationTi
meout))
// Task should be terminated // Task should be terminated
waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interfac e{}, check.CommentInterface) { poll.WaitOn(c, pollCheck(c, func(c *testing.T) (interface{}, string) {
task = d.GetTask(c, task.ID) task = d.GetTask(c, task.ID)
return task.Status.State, nil return task.Status.State, ""
}, checker.Equals, swarm.TaskStateFailed) }, checker.Equals(swarm.TaskStateFailed)), poll.WithTimeout(defaultReconc
iliationTimeout))
if !strings.Contains(task.Status.Err, container.ErrContainerUnhealthy.Err or()) { if !strings.Contains(task.Status.Err, container.ErrContainerUnhealthy.Err or()) {
c.Fatal("unhealthy task exits because of other error") c.Fatal("unhealthy task exits because of other error")
} }
} }
// start a service whose task is unhealthy at beginning // start a service whose task is unhealthy at beginning
// its tasks should be blocked in starting stage, until health check is passed // its tasks should be blocked in starting stage, until health check is passed
func (s *DockerSwarmSuite) TestServiceHealthStart(c *check.C) { func (s *DockerSwarmSuite) TestServiceHealthStart(c *testing.T) {
testRequires(c, DaemonIsLinux) // busybox doesn't work on Windows testRequires(c, DaemonIsLinux) // busybox doesn't work on Windows
d := s.AddDaemon(c, true, true) d := s.AddDaemon(c, true, true)
// service started from this image won't pass health check // service started from this image won't pass health check
imageName := "testhealth" imageName := "testhealth"
result := cli.BuildCmd(c, imageName, cli.Daemon(d), result := cli.BuildCmd(c, imageName, cli.Daemon(d),
build.WithDockerfile(`FROM busybox build.WithDockerfile(`FROM busybox
HEALTHCHECK --interval=1s --timeout=1s --retries=1024\ HEALTHCHECK --interval=1s --timeout=1s --retries=1024\
CMD cat /status`), CMD cat /status`),
) )
result.Assert(c, icmd.Success) result.Assert(c, icmd.Success)
serviceName := "healthServiceStart" serviceName := "healthServiceStart"
out, err := d.Cmd("service", "create", "--no-resolve-image", "--detach=tr ue", "--name", serviceName, imageName, "top") out, err := d.Cmd("service", "create", "--no-resolve-image", "--detach=tr ue", "--name", serviceName, imageName, "top")
assert.NilError(c, err, out) assert.NilError(c, err, out)
id := strings.TrimSpace(out) id := strings.TrimSpace(out)
var tasks []swarm.Task var tasks []swarm.Task
waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interfac e{}, check.CommentInterface) { poll.WaitOn(c, pollCheck(c, func(c *testing.T) (interface{}, string) {
tasks = d.GetServiceTasks(c, id) tasks = d.GetServiceTasks(c, id)
return tasks, nil return tasks, ""
}, checker.HasLen, 1) }, checker.HasLen(1)), poll.WithTimeout(defaultReconciliationTimeout))
task := tasks[0] task := tasks[0]
// wait for task to start // wait for task to start
waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interfac e{}, check.CommentInterface) { poll.WaitOn(c, pollCheck(c, func(c *testing.T) (interface{}, string) {
task = d.GetTask(c, task.ID) task = d.GetTask(c, task.ID)
return task.Status.State, nil return task.Status.State, ""
}, checker.Equals, swarm.TaskStateStarting) }, checker.Equals(swarm.TaskStateStarting)), poll.WithTimeout(defaultReco
nciliationTimeout))
containerID := task.Status.ContainerStatus.ContainerID containerID := task.Status.ContainerStatus.ContainerID
// wait for health check to work // wait for health check to work
waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interfac e{}, check.CommentInterface) { poll.WaitOn(c, pollCheck(c, func(c *testing.T) (interface{}, string) {
out, _ := d.Cmd("inspect", "--format={{.State.Health.FailingStrea k}}", containerID) out, _ := d.Cmd("inspect", "--format={{.State.Health.FailingStrea k}}", containerID)
failingStreak, _ := strconv.Atoi(strings.TrimSpace(out)) failingStreak, _ := strconv.Atoi(strings.TrimSpace(out))
return failingStreak, nil return failingStreak, ""
}, checker.GreaterThan, 0) }, checker.GreaterThan(0)), poll.WithTimeout(defaultReconciliationTimeout
))
// task should be blocked at starting status // task should be blocked at starting status
task = d.GetTask(c, task.ID) task = d.GetTask(c, task.ID)
c.Assert(task.Status.State, check.Equals, swarm.TaskStateStarting) assert.Equal(c, task.Status.State, swarm.TaskStateStarting)
// make it healthy // make it healthy
d.Cmd("exec", containerID, "touch", "/status") d.Cmd("exec", containerID, "touch", "/status")
// Task should be at running status // Task should be at running status
waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interfac e{}, check.CommentInterface) { poll.WaitOn(c, pollCheck(c, func(c *testing.T) (interface{}, string) {
task = d.GetTask(c, task.ID) task = d.GetTask(c, task.ID)
return task.Status.State, nil return task.Status.State, ""
}, checker.Equals, swarm.TaskStateRunning) }, checker.Equals(swarm.TaskStateRunning)), poll.WithTimeout(defaultRecon
ciliationTimeout))
} }
 End of changes. 25 change blocks. 
32 lines changed or deleted 42 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)