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