gopkg.in/docker/docker.v20@v20.10.27/integration-cli/docker_api_swarm_node_test.go (about) 1 //go:build !windows 2 // +build !windows 3 4 package main 5 6 import ( 7 "fmt" 8 "testing" 9 "time" 10 11 "github.com/docker/docker/api/types/swarm" 12 "github.com/docker/docker/integration-cli/checker" 13 "github.com/docker/docker/integration-cli/daemon" 14 "gotest.tools/v3/assert" 15 "gotest.tools/v3/poll" 16 ) 17 18 func (s *DockerSwarmSuite) TestAPISwarmListNodes(c *testing.T) { 19 d1 := s.AddDaemon(c, true, true) 20 d2 := s.AddDaemon(c, true, false) 21 d3 := s.AddDaemon(c, true, false) 22 23 nodes := d1.ListNodes(c) 24 assert.Equal(c, len(nodes), 3, fmt.Sprintf("nodes: %#v", nodes)) 25 26 loop0: 27 for _, n := range nodes { 28 for _, d := range []*daemon.Daemon{d1, d2, d3} { 29 if n.ID == d.NodeID() { 30 continue loop0 31 } 32 } 33 c.Errorf("unknown nodeID %v", n.ID) 34 } 35 } 36 37 func (s *DockerSwarmSuite) TestAPISwarmNodeUpdate(c *testing.T) { 38 d := s.AddDaemon(c, true, true) 39 40 nodes := d.ListNodes(c) 41 42 d.UpdateNode(c, nodes[0].ID, func(n *swarm.Node) { 43 n.Spec.Availability = swarm.NodeAvailabilityPause 44 }) 45 46 n := d.GetNode(c, nodes[0].ID) 47 assert.Equal(c, n.Spec.Availability, swarm.NodeAvailabilityPause) 48 } 49 50 func (s *DockerSwarmSuite) TestAPISwarmNodeRemove(c *testing.T) { 51 testRequires(c, Network) 52 d1 := s.AddDaemon(c, true, true) 53 d2 := s.AddDaemon(c, true, false) 54 _ = s.AddDaemon(c, true, false) 55 56 nodes := d1.ListNodes(c) 57 assert.Equal(c, len(nodes), 3, fmt.Sprintf("nodes: %#v", nodes)) 58 59 // Getting the info so we can take the NodeID 60 d2Info := d2.SwarmInfo(c) 61 62 // forceful removal of d2 should work 63 d1.RemoveNode(c, d2Info.NodeID, true) 64 65 nodes = d1.ListNodes(c) 66 assert.Equal(c, len(nodes), 2, fmt.Sprintf("nodes: %#v", nodes)) 67 68 // Restart the node that was removed 69 d2.RestartNode(c) 70 71 // Give some time for the node to rejoin 72 time.Sleep(1 * time.Second) 73 74 // Make sure the node didn't rejoin 75 nodes = d1.ListNodes(c) 76 assert.Equal(c, len(nodes), 2, fmt.Sprintf("nodes: %#v", nodes)) 77 } 78 79 func (s *DockerSwarmSuite) TestAPISwarmNodeDrainPause(c *testing.T) { 80 d1 := s.AddDaemon(c, true, true) 81 d2 := s.AddDaemon(c, true, false) 82 83 time.Sleep(1 * time.Second) // make sure all daemons are ready to accept tasks 84 85 // start a service, expect balanced distribution 86 instances := 2 87 id := d1.CreateService(c, simpleTestService, setInstances(instances)) 88 89 poll.WaitOn(c, pollCheck(c, d1.CheckActiveContainerCount, checker.GreaterThan(0)), poll.WithTimeout(defaultReconciliationTimeout)) 90 poll.WaitOn(c, pollCheck(c, d2.CheckActiveContainerCount, checker.GreaterThan(0)), poll.WithTimeout(defaultReconciliationTimeout)) 91 poll.WaitOn(c, pollCheck(c, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount), checker.Equals(instances)), poll.WithTimeout(defaultReconciliationTimeout)) 92 93 // drain d2, all containers should move to d1 94 d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) { 95 n.Spec.Availability = swarm.NodeAvailabilityDrain 96 }) 97 poll.WaitOn(c, pollCheck(c, d1.CheckActiveContainerCount, checker.Equals(instances)), poll.WithTimeout(defaultReconciliationTimeout)) 98 poll.WaitOn(c, pollCheck(c, d2.CheckActiveContainerCount, checker.Equals(0)), poll.WithTimeout(defaultReconciliationTimeout)) 99 100 // set d2 back to active 101 d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) { 102 n.Spec.Availability = swarm.NodeAvailabilityActive 103 }) 104 105 instances = 1 106 d1.UpdateService(c, d1.GetService(c, id), setInstances(instances)) 107 poll.WaitOn(c, pollCheck(c, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount), checker.Equals(instances)), poll.WithTimeout(defaultReconciliationTimeout*2)) 108 109 instances = 2 110 d1.UpdateService(c, d1.GetService(c, id), setInstances(instances)) 111 112 // drained node first so we don't get any old containers 113 poll.WaitOn(c, pollCheck(c, d2.CheckActiveContainerCount, checker.GreaterThan(0)), poll.WithTimeout(defaultReconciliationTimeout)) 114 poll.WaitOn(c, pollCheck(c, d1.CheckActiveContainerCount, checker.GreaterThan(0)), poll.WithTimeout(defaultReconciliationTimeout)) 115 poll.WaitOn(c, pollCheck(c, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount), checker.Equals(instances)), poll.WithTimeout(defaultReconciliationTimeout*2)) 116 117 d2ContainerCount := len(d2.ActiveContainers(c)) 118 119 // set d2 to paused, scale service up, only d1 gets new tasks 120 d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) { 121 n.Spec.Availability = swarm.NodeAvailabilityPause 122 }) 123 124 instances = 4 125 d1.UpdateService(c, d1.GetService(c, id), setInstances(instances)) 126 poll.WaitOn(c, pollCheck(c, d1.CheckActiveContainerCount, checker.Equals(instances-d2ContainerCount)), poll.WithTimeout(defaultReconciliationTimeout)) 127 poll.WaitOn(c, pollCheck(c, d2.CheckActiveContainerCount, checker.Equals(d2ContainerCount)), poll.WithTimeout(defaultReconciliationTimeout)) 128 129 }