github.com/devdivbcp/moby@v17.12.0-ce-rc1.0.20200726071732-2d4bfdc789ad+incompatible/integration-cli/docker_api_swarm_node_test.go (about)

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