Add integration test for START_FIRST update order

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
Aaron Lehmann 2017-01-18 14:16:47 -08:00
parent 9b54994a8a
commit 6763641d69
2 changed files with 127 additions and 0 deletions

View File

@ -175,6 +175,115 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesUpdate(c *check.C) {
map[string]int{image1: instances})
}
func (s *DockerSwarmSuite) TestAPISwarmServicesUpdateStartFirst(c *check.C) {
d := s.AddDaemon(c, true, true)
// service image at start
image1 := "busybox:latest"
// target image in update
image2 := "testhealth"
// service started from this image won't pass health check
_, _, err := d.BuildImageWithOut(image2,
`FROM busybox
HEALTHCHECK --interval=1s --timeout=1s --retries=1024\
CMD cat /status`,
true)
c.Check(err, check.IsNil)
// create service
instances := 5
parallelism := 2
rollbackParallelism := 3
id := d.CreateService(c, serviceForUpdate, setInstances(instances), setUpdateOrder(swarm.UpdateOrderStartFirst), setRollbackOrder(swarm.UpdateOrderStartFirst))
checkStartingTasks := func(expected int) []swarm.Task {
var startingTasks []swarm.Task
waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) {
tasks := d.GetServiceTasks(c, id)
startingTasks = nil
for _, t := range tasks {
if t.Status.State == swarm.TaskStateStarting {
startingTasks = append(startingTasks, t)
}
}
return startingTasks, nil
}, checker.HasLen, expected)
return startingTasks
}
makeTasksHealthy := func(tasks []swarm.Task) {
for _, t := range tasks {
containerID := t.Status.ContainerStatus.ContainerID
d.Cmd("exec", containerID, "touch", "/status")
}
}
// wait for tasks ready
waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskImages, checker.DeepEquals,
map[string]int{image1: instances})
// issue service update
service := d.GetService(c, id)
d.UpdateService(c, service, setImage(image2))
// first batch
// The old tasks should be running, and the new ones should be starting.
startingTasks := checkStartingTasks(parallelism)
waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskImages, checker.DeepEquals,
map[string]int{image1: instances})
// make it healthy
makeTasksHealthy(startingTasks)
waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskImages, checker.DeepEquals,
map[string]int{image1: instances - parallelism, image2: parallelism})
// 2nd batch
// The old tasks should be running, and the new ones should be starting.
startingTasks = checkStartingTasks(parallelism)
waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskImages, checker.DeepEquals,
map[string]int{image1: instances - parallelism, image2: parallelism})
// make it healthy
makeTasksHealthy(startingTasks)
waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskImages, checker.DeepEquals,
map[string]int{image1: instances - 2*parallelism, image2: 2 * parallelism})
// 3nd batch
// The old tasks should be running, and the new ones should be starting.
startingTasks = checkStartingTasks(1)
waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskImages, checker.DeepEquals,
map[string]int{image1: instances - 2*parallelism, image2: 2 * parallelism})
// make it healthy
makeTasksHealthy(startingTasks)
waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskImages, checker.DeepEquals,
map[string]int{image2: instances})
// Roll back to the previous version. This uses the CLI because
// rollback is a client-side operation.
out, err := d.Cmd("service", "update", "--rollback", id)
c.Assert(err, checker.IsNil, check.Commentf(out))
// first batch
waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskImages, checker.DeepEquals,
map[string]int{image2: instances - rollbackParallelism, image1: rollbackParallelism})
// 2nd batch
waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskImages, checker.DeepEquals,
map[string]int{image1: instances})
}
func (s *DockerSwarmSuite) TestAPISwarmServicesFailedUpdate(c *check.C) {
const nodeCount = 3
var daemons [nodeCount]*daemon.Swarm

View File

@ -596,6 +596,24 @@ func setInstances(replicas int) daemon.ServiceConstructor {
}
}
func setUpdateOrder(order string) daemon.ServiceConstructor {
return func(s *swarm.Service) {
if s.Spec.UpdateConfig == nil {
s.Spec.UpdateConfig = &swarm.UpdateConfig{}
}
s.Spec.UpdateConfig.Order = order
}
}
func setRollbackOrder(order string) daemon.ServiceConstructor {
return func(s *swarm.Service) {
if s.Spec.RollbackConfig == nil {
s.Spec.RollbackConfig = &swarm.UpdateConfig{}
}
s.Spec.RollbackConfig.Order = order
}
}
func setImage(image string) daemon.ServiceConstructor {
return func(s *swarm.Service) {
s.Spec.TaskTemplate.ContainerSpec.Image = image