github.com/rawahars/moby@v24.0.4+incompatible/integration-cli/daemon/daemon_swarm.go (about)

     1  package daemon // import "github.com/docker/docker/integration-cli/daemon"
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/docker/docker/api/types"
    10  	"github.com/docker/docker/api/types/filters"
    11  	"github.com/docker/docker/api/types/swarm"
    12  	"github.com/docker/docker/client"
    13  	"gotest.tools/v3/assert"
    14  )
    15  
    16  // CheckServiceTasksInState returns the number of tasks with a matching state,
    17  // and optional message substring.
    18  func (d *Daemon) CheckServiceTasksInState(service string, state swarm.TaskState, message string) func(*testing.T) (interface{}, string) {
    19  	return func(c *testing.T) (interface{}, string) {
    20  		tasks := d.GetServiceTasks(c, service)
    21  		var count int
    22  		for _, task := range tasks {
    23  			if task.Status.State == state {
    24  				if message == "" || strings.Contains(task.Status.Message, message) {
    25  					count++
    26  				}
    27  			}
    28  		}
    29  		return count, ""
    30  	}
    31  }
    32  
    33  // CheckServiceTasksInStateWithError returns the number of tasks with a matching state,
    34  // and optional message substring.
    35  func (d *Daemon) CheckServiceTasksInStateWithError(service string, state swarm.TaskState, errorMessage string) func(*testing.T) (interface{}, string) {
    36  	return func(c *testing.T) (interface{}, string) {
    37  		tasks := d.GetServiceTasks(c, service)
    38  		var count int
    39  		for _, task := range tasks {
    40  			if task.Status.State == state {
    41  				if errorMessage == "" || strings.Contains(task.Status.Err, errorMessage) {
    42  					count++
    43  				}
    44  			}
    45  		}
    46  		return count, ""
    47  	}
    48  }
    49  
    50  // CheckServiceRunningTasks returns the number of running tasks for the specified service
    51  func (d *Daemon) CheckServiceRunningTasks(service string) func(*testing.T) (interface{}, string) {
    52  	return d.CheckServiceTasksInState(service, swarm.TaskStateRunning, "")
    53  }
    54  
    55  // CheckServiceUpdateState returns the current update state for the specified service
    56  func (d *Daemon) CheckServiceUpdateState(service string) func(*testing.T) (interface{}, string) {
    57  	return func(c *testing.T) (interface{}, string) {
    58  		service := d.GetService(c, service)
    59  		if service.UpdateStatus == nil {
    60  			return "", ""
    61  		}
    62  		return service.UpdateStatus.State, ""
    63  	}
    64  }
    65  
    66  // CheckPluginRunning returns the runtime state of the plugin
    67  func (d *Daemon) CheckPluginRunning(plugin string) func(c *testing.T) (interface{}, string) {
    68  	return func(c *testing.T) (interface{}, string) {
    69  		apiclient := d.NewClientT(c)
    70  		resp, _, err := apiclient.PluginInspectWithRaw(context.Background(), plugin)
    71  		if client.IsErrNotFound(err) {
    72  			return false, fmt.Sprintf("%v", err)
    73  		}
    74  		assert.NilError(c, err)
    75  		return resp.Enabled, fmt.Sprintf("%+v", resp)
    76  	}
    77  }
    78  
    79  // CheckPluginImage returns the runtime state of the plugin
    80  func (d *Daemon) CheckPluginImage(plugin string) func(c *testing.T) (interface{}, string) {
    81  	return func(c *testing.T) (interface{}, string) {
    82  		apiclient := d.NewClientT(c)
    83  		resp, _, err := apiclient.PluginInspectWithRaw(context.Background(), plugin)
    84  		if client.IsErrNotFound(err) {
    85  			return false, fmt.Sprintf("%v", err)
    86  		}
    87  		assert.NilError(c, err)
    88  		return resp.PluginReference, fmt.Sprintf("%+v", resp)
    89  	}
    90  }
    91  
    92  // CheckServiceTasks returns the number of tasks for the specified service
    93  func (d *Daemon) CheckServiceTasks(service string) func(*testing.T) (interface{}, string) {
    94  	return func(c *testing.T) (interface{}, string) {
    95  		tasks := d.GetServiceTasks(c, service)
    96  		return len(tasks), ""
    97  	}
    98  }
    99  
   100  // CheckRunningTaskNetworks returns the number of times each network is referenced from a task.
   101  func (d *Daemon) CheckRunningTaskNetworks(c *testing.T) (interface{}, string) {
   102  	cli := d.NewClientT(c)
   103  	defer cli.Close()
   104  
   105  	tasks, err := cli.TaskList(context.Background(), types.TaskListOptions{
   106  		Filters: filters.NewArgs(filters.Arg("desired-state", "running")),
   107  	})
   108  	assert.NilError(c, err)
   109  
   110  	result := make(map[string]int)
   111  	for _, task := range tasks {
   112  		for _, network := range task.Spec.Networks {
   113  			result[network.Target]++
   114  		}
   115  	}
   116  	return result, ""
   117  }
   118  
   119  // CheckRunningTaskImages returns the times each image is running as a task.
   120  func (d *Daemon) CheckRunningTaskImages(c *testing.T) (interface{}, string) {
   121  	cli := d.NewClientT(c)
   122  	defer cli.Close()
   123  
   124  	tasks, err := cli.TaskList(context.Background(), types.TaskListOptions{
   125  		Filters: filters.NewArgs(filters.Arg("desired-state", "running")),
   126  	})
   127  	assert.NilError(c, err)
   128  
   129  	result := make(map[string]int)
   130  	for _, task := range tasks {
   131  		if task.Status.State == swarm.TaskStateRunning && task.Spec.ContainerSpec != nil {
   132  			result[task.Spec.ContainerSpec.Image]++
   133  		}
   134  	}
   135  	return result, ""
   136  }
   137  
   138  // CheckNodeReadyCount returns the number of ready node on the swarm
   139  func (d *Daemon) CheckNodeReadyCount(c *testing.T) (interface{}, string) {
   140  	nodes := d.ListNodes(c)
   141  	var readyCount int
   142  	for _, node := range nodes {
   143  		if node.Status.State == swarm.NodeStateReady {
   144  			readyCount++
   145  		}
   146  	}
   147  	return readyCount, ""
   148  }
   149  
   150  // CheckLocalNodeState returns the current swarm node state
   151  func (d *Daemon) CheckLocalNodeState(c *testing.T) (interface{}, string) {
   152  	info := d.SwarmInfo(c)
   153  	return info.LocalNodeState, ""
   154  }
   155  
   156  // CheckControlAvailable returns the current swarm control available
   157  func (d *Daemon) CheckControlAvailable(c *testing.T) (interface{}, string) {
   158  	info := d.SwarmInfo(c)
   159  	assert.Equal(c, info.LocalNodeState, swarm.LocalNodeStateActive)
   160  	return info.ControlAvailable, ""
   161  }
   162  
   163  // CheckLeader returns whether there is a leader on the swarm or not
   164  func (d *Daemon) CheckLeader(c *testing.T) (interface{}, string) {
   165  	cli := d.NewClientT(c)
   166  	defer cli.Close()
   167  
   168  	errList := "could not get node list"
   169  
   170  	ls, err := cli.NodeList(context.Background(), types.NodeListOptions{})
   171  	if err != nil {
   172  		return err, errList
   173  	}
   174  
   175  	for _, node := range ls {
   176  		if node.ManagerStatus != nil && node.ManagerStatus.Leader {
   177  			return nil, ""
   178  		}
   179  	}
   180  	return fmt.Errorf("no leader"), "could not find leader"
   181  }
   182  
   183  // CmdRetryOutOfSequence tries the specified command against the current daemon
   184  // up to 10 times, retrying if it encounters an "update out of sequence" error.
   185  func (d *Daemon) CmdRetryOutOfSequence(args ...string) (string, error) {
   186  	var (
   187  		output string
   188  		err    error
   189  	)
   190  
   191  	for i := 0; i < 10; i++ {
   192  		output, err = d.Cmd(args...)
   193  		// error, no error, whatever. if we don't have "update out of
   194  		// sequence", we don't retry, we just return.
   195  		if !strings.Contains(output, "update out of sequence") {
   196  			return output, err
   197  		}
   198  	}
   199  
   200  	// otherwise, once all of our attempts have been exhausted, just return
   201  	// whatever the last values were.
   202  	return output, err
   203  }