Test rolling update.
Signed-off-by: Dong Chen <dongluo.chen@docker.com>
(cherry picked from commit d327765a62
)
Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
parent
05b7fe4170
commit
61936227d0
2 changed files with 108 additions and 0 deletions
|
@ -148,6 +148,39 @@ func (d *SwarmDaemon) getServiceTasks(c *check.C, service string) []swarm.Task {
|
|||
return tasks
|
||||
}
|
||||
|
||||
func (d *SwarmDaemon) checkRunningTaskImages(c *check.C) (interface{}, check.CommentInterface) {
|
||||
var tasks []swarm.Task
|
||||
|
||||
filterArgs := filters.NewArgs()
|
||||
filterArgs.Add("desired-state", "running")
|
||||
filters, err := filters.ToParam(filterArgs)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
status, out, err := d.SockRequest("GET", "/tasks?filters="+filters, nil)
|
||||
c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
|
||||
c.Assert(err, checker.IsNil, check.Commentf(string(out)))
|
||||
c.Assert(json.Unmarshal(out, &tasks), checker.IsNil)
|
||||
|
||||
result := make(map[string]int)
|
||||
for _, task := range tasks {
|
||||
if task.Status.State == swarm.TaskStateRunning {
|
||||
result[task.Spec.ContainerSpec.Image]++
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (d *SwarmDaemon) checkNodeReadyCount(c *check.C) (interface{}, check.CommentInterface) {
|
||||
nodes := d.listNodes(c)
|
||||
var readyCount int
|
||||
for _, node := range nodes {
|
||||
if node.Status.State == swarm.NodeStateReady {
|
||||
readyCount++
|
||||
}
|
||||
}
|
||||
return readyCount, nil
|
||||
}
|
||||
|
||||
func (d *SwarmDaemon) getTask(c *check.C, id string) swarm.Task {
|
||||
var task swarm.Task
|
||||
|
||||
|
|
|
@ -371,6 +371,52 @@ func (s *DockerSwarmSuite) TestApiSwarmServicesCreateGlobal(c *check.C) {
|
|||
waitAndAssert(c, defaultReconciliationTimeout, d5.checkActiveContainerCount, checker.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestApiSwarmServicesUpdate(c *check.C) {
|
||||
const nodeCount = 3
|
||||
var daemons [nodeCount]*SwarmDaemon
|
||||
for i := 0; i < nodeCount; i++ {
|
||||
daemons[i] = s.AddDaemon(c, true, i == 0)
|
||||
}
|
||||
// wait for nodes ready
|
||||
waitAndAssert(c, 5*time.Second, daemons[0].checkNodeReadyCount, checker.Equals, nodeCount)
|
||||
|
||||
// service image at start
|
||||
image1 := "busybox:latest"
|
||||
// target image in update
|
||||
image2 := "busybox:test"
|
||||
|
||||
// create a different tag
|
||||
for _, d := range daemons {
|
||||
out, err := d.Cmd("tag", image1, image2)
|
||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
||||
}
|
||||
|
||||
// create service
|
||||
instances := 5
|
||||
parallelism := 2
|
||||
id := daemons[0].createService(c, serviceForUpdate, setInstances(instances))
|
||||
|
||||
// wait for tasks ready
|
||||
waitAndAssert(c, defaultReconciliationTimeout, daemons[0].checkRunningTaskImages, checker.DeepEquals,
|
||||
map[string]int{image1: instances})
|
||||
|
||||
// issue service update
|
||||
service := daemons[0].getService(c, id)
|
||||
daemons[0].updateService(c, service, setImage(image2))
|
||||
|
||||
// first batch
|
||||
waitAndAssert(c, defaultReconciliationTimeout, daemons[0].checkRunningTaskImages, checker.DeepEquals,
|
||||
map[string]int{image1: instances - parallelism, image2: parallelism})
|
||||
|
||||
// 2nd batch
|
||||
waitAndAssert(c, defaultReconciliationTimeout, daemons[0].checkRunningTaskImages, checker.DeepEquals,
|
||||
map[string]int{image1: instances - 2*parallelism, image2: 2 * parallelism})
|
||||
|
||||
// 3nd batch
|
||||
waitAndAssert(c, defaultReconciliationTimeout, daemons[0].checkRunningTaskImages, checker.DeepEquals,
|
||||
map[string]int{image2: instances})
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestApiSwarmServicesStateReporting(c *check.C) {
|
||||
testRequires(c, Network)
|
||||
testRequires(c, SameHostDaemon)
|
||||
|
@ -754,6 +800,29 @@ func simpleTestService(s *swarm.Service) {
|
|||
s.Spec.Name = "top"
|
||||
}
|
||||
|
||||
func serviceForUpdate(s *swarm.Service) {
|
||||
var ureplicas uint64
|
||||
ureplicas = 1
|
||||
s.Spec = swarm.ServiceSpec{
|
||||
TaskTemplate: swarm.TaskSpec{
|
||||
ContainerSpec: swarm.ContainerSpec{
|
||||
Image: "busybox:latest",
|
||||
Command: []string{"/bin/top"},
|
||||
},
|
||||
},
|
||||
Mode: swarm.ServiceMode{
|
||||
Replicated: &swarm.ReplicatedService{
|
||||
Replicas: &ureplicas,
|
||||
},
|
||||
},
|
||||
UpdateConfig: &swarm.UpdateConfig{
|
||||
Parallelism: 2,
|
||||
Delay: 8 * time.Second,
|
||||
},
|
||||
}
|
||||
s.Spec.Name = "updatetest"
|
||||
}
|
||||
|
||||
func setInstances(replicas int) serviceConstructor {
|
||||
ureplicas := uint64(replicas)
|
||||
return func(s *swarm.Service) {
|
||||
|
@ -765,6 +834,12 @@ func setInstances(replicas int) serviceConstructor {
|
|||
}
|
||||
}
|
||||
|
||||
func setImage(image string) serviceConstructor {
|
||||
return func(s *swarm.Service) {
|
||||
s.Spec.TaskTemplate.ContainerSpec.Image = image
|
||||
}
|
||||
}
|
||||
|
||||
func setGlobalMode(s *swarm.Service) {
|
||||
s.Spec.Mode = swarm.ServiceMode{
|
||||
Global: &swarm.GlobalService{},
|
||||
|
|
Loading…
Reference in a new issue