github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/integration-cli/daemon/daemon_swarm.go (about)

     1  package daemon // import "github.com/Prakhar-Agarwal-byte/moby/integration-cli/daemon"
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/Prakhar-Agarwal-byte/moby/api/types"
    10  	"github.com/Prakhar-Agarwal-byte/moby/api/types/filters"
    11  	"github.com/Prakhar-Agarwal-byte/moby/api/types/swarm"
    12  	"github.com/Prakhar-Agarwal-byte/moby/errdefs"
    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(ctx context.Context, service string, state swarm.TaskState, message string) func(*testing.T) (interface{}, string) {
    19  	return func(c *testing.T) (interface{}, string) {
    20  		tasks := d.GetServiceTasks(ctx, 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(ctx context.Context, service string, state swarm.TaskState, errorMessage string) func(*testing.T) (interface{}, string) {
    36  	return func(c *testing.T) (interface{}, string) {
    37  		tasks := d.GetServiceTasks(ctx, 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(ctx context.Context, service string) func(*testing.T) (interface{}, string) {
    52  	return d.CheckServiceTasksInState(ctx, service, swarm.TaskStateRunning, "")
    53  }
    54  
    55  // CheckServiceUpdateState returns the current update state for the specified service
    56  func (d *Daemon) CheckServiceUpdateState(ctx context.Context, service string) func(*testing.T) (interface{}, string) {
    57  	return func(c *testing.T) (interface{}, string) {
    58  		service := d.GetService(ctx, 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(ctx context.Context, 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(ctx, plugin)
    71  		if errdefs.IsNotFound(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(ctx context.Context, 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(ctx, plugin)
    84  		if errdefs.IsNotFound(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(ctx context.Context, service string) func(*testing.T) (interface{}, string) {
    94  	return func(c *testing.T) (interface{}, string) {
    95  		tasks := d.GetServiceTasks(ctx, 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(ctx context.Context) func(t *testing.T) (interface{}, string) {
   102  	return func(t *testing.T) (interface{}, string) {
   103  		cli := d.NewClientT(t)
   104  		defer cli.Close()
   105  
   106  		tasks, err := cli.TaskList(ctx, types.TaskListOptions{
   107  			Filters: filters.NewArgs(filters.Arg("desired-state", "running")),
   108  		})
   109  		assert.NilError(t, err)
   110  
   111  		result := make(map[string]int)
   112  		for _, task := range tasks {
   113  			for _, network := range task.Spec.Networks {
   114  				result[network.Target]++
   115  			}
   116  		}
   117  		return result, ""
   118  	}
   119  }
   120  
   121  // CheckRunningTaskImages returns the times each image is running as a task.
   122  func (d *Daemon) CheckRunningTaskImages(ctx context.Context) func(t *testing.T) (interface{}, string) {
   123  	return func(t *testing.T) (interface{}, string) {
   124  		cli := d.NewClientT(t)
   125  		defer cli.Close()
   126  
   127  		tasks, err := cli.TaskList(ctx, types.TaskListOptions{
   128  			Filters: filters.NewArgs(filters.Arg("desired-state", "running")),
   129  		})
   130  		assert.NilError(t, err)
   131  
   132  		result := make(map[string]int)
   133  		for _, task := range tasks {
   134  			if task.Status.State == swarm.TaskStateRunning && task.Spec.ContainerSpec != nil {
   135  				result[task.Spec.ContainerSpec.Image]++
   136  			}
   137  		}
   138  		return result, ""
   139  	}
   140  }
   141  
   142  // CheckNodeReadyCount returns the number of ready node on the swarm
   143  func (d *Daemon) CheckNodeReadyCount(ctx context.Context) func(t *testing.T) (interface{}, string) {
   144  	return func(t *testing.T) (interface{}, string) {
   145  		nodes := d.ListNodes(ctx, t)
   146  		var readyCount int
   147  		for _, node := range nodes {
   148  			if node.Status.State == swarm.NodeStateReady {
   149  				readyCount++
   150  			}
   151  		}
   152  		return readyCount, ""
   153  	}
   154  }
   155  
   156  // CheckLocalNodeState returns the current swarm node state
   157  func (d *Daemon) CheckLocalNodeState(ctx context.Context) func(t *testing.T) (interface{}, string) {
   158  	return func(t *testing.T) (interface{}, string) {
   159  		info := d.SwarmInfo(ctx, t)
   160  		return info.LocalNodeState, ""
   161  	}
   162  }
   163  
   164  // CheckControlAvailable returns the current swarm control available
   165  func (d *Daemon) CheckControlAvailable(ctx context.Context) func(t *testing.T) (interface{}, string) {
   166  	return func(t *testing.T) (interface{}, string) {
   167  		info := d.SwarmInfo(ctx, t)
   168  		assert.Equal(t, info.LocalNodeState, swarm.LocalNodeStateActive)
   169  		return info.ControlAvailable, ""
   170  	}
   171  }
   172  
   173  // CheckLeader returns whether there is a leader on the swarm or not
   174  func (d *Daemon) CheckLeader(ctx context.Context) func(t *testing.T) (interface{}, string) {
   175  	return func(t *testing.T) (interface{}, string) {
   176  		cli := d.NewClientT(t)
   177  		defer cli.Close()
   178  
   179  		errList := "could not get node list"
   180  
   181  		ls, err := cli.NodeList(ctx, types.NodeListOptions{})
   182  		if err != nil {
   183  			return err, errList
   184  		}
   185  
   186  		for _, node := range ls {
   187  			if node.ManagerStatus != nil && node.ManagerStatus.Leader {
   188  				return nil, ""
   189  			}
   190  		}
   191  		return fmt.Errorf("no leader"), "could not find leader"
   192  	}
   193  }
   194  
   195  // CmdRetryOutOfSequence tries the specified command against the current daemon
   196  // up to 10 times, retrying if it encounters an "update out of sequence" error.
   197  func (d *Daemon) CmdRetryOutOfSequence(args ...string) (string, error) {
   198  	var (
   199  		output string
   200  		err    error
   201  	)
   202  
   203  	for i := 0; i < 10; i++ {
   204  		output, err = d.Cmd(args...)
   205  		// error, no error, whatever. if we don't have "update out of
   206  		// sequence", we don't retry, we just return.
   207  		if !strings.Contains(output, "update out of sequence") {
   208  			return output, err
   209  		}
   210  	}
   211  
   212  	// otherwise, once all of our attempts have been exhausted, just return
   213  	// whatever the last values were.
   214  	return output, err
   215  }