mirror of https://github.com/docker/docs.git
				
				
				
			Test rolling update.
Signed-off-by: Dong Chen <dongluo.chen@docker.com> (cherry picked from commit d327765a62a99dc63e9a8c16ac291861cee066f3) Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
		
							parent
							
								
									05b7fe4170
								
							
						
					
					
						commit
						61936227d0
					
				|  | @ -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 New Issue