Test rolling update.
Signed-off-by: Dong Chen <dongluo.chen@docker.com>
This commit is contained in:
parent
4498214a2a
commit
d327765a62
|
@ -148,6 +148,39 @@ func (d *SwarmDaemon) getServiceTasks(c *check.C, service string) []swarm.Task {
|
||||||
return tasks
|
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 {
|
func (d *SwarmDaemon) getTask(c *check.C, id string) swarm.Task {
|
||||||
var task 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)
|
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) {
|
func (s *DockerSwarmSuite) TestApiSwarmServicesStateReporting(c *check.C) {
|
||||||
testRequires(c, Network)
|
testRequires(c, Network)
|
||||||
testRequires(c, SameHostDaemon)
|
testRequires(c, SameHostDaemon)
|
||||||
|
@ -779,6 +825,29 @@ func simpleTestService(s *swarm.Service) {
|
||||||
s.Spec.Name = "top"
|
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 {
|
func setInstances(replicas int) serviceConstructor {
|
||||||
ureplicas := uint64(replicas)
|
ureplicas := uint64(replicas)
|
||||||
return func(s *swarm.Service) {
|
return func(s *swarm.Service) {
|
||||||
|
@ -790,6 +859,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) {
|
func setGlobalMode(s *swarm.Service) {
|
||||||
s.Spec.Mode = swarm.ServiceMode{
|
s.Spec.Mode = swarm.ServiceMode{
|
||||||
Global: &swarm.GlobalService{},
|
Global: &swarm.GlobalService{},
|
||||||
|
|
Loading…
Reference in New Issue