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