github.com/rita33cool1/iot-system-gateway@v0.0.0-20200911033302-e65bde238cc5/docker-engine/integration/internal/swarm/service.go (about) 1 package swarm 2 3 import ( 4 "context" 5 "runtime" 6 "testing" 7 "time" 8 9 "github.com/docker/docker/api/types" 10 "github.com/docker/docker/api/types/filters" 11 swarmtypes "github.com/docker/docker/api/types/swarm" 12 "github.com/docker/docker/internal/test/daemon" 13 "github.com/docker/docker/internal/test/environment" 14 "github.com/gotestyourself/gotestyourself/assert" 15 "github.com/gotestyourself/gotestyourself/poll" 16 "github.com/gotestyourself/gotestyourself/skip" 17 ) 18 19 // ServicePoll tweaks the pollSettings for `service` 20 func ServicePoll(config *poll.Settings) { 21 // Override the default pollSettings for `service` resource here ... 22 23 if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { 24 config.Timeout = 1 * time.Minute 25 config.Delay = 100 * time.Millisecond 26 } 27 } 28 29 // NetworkPoll tweaks the pollSettings for `network` 30 func NetworkPoll(config *poll.Settings) { 31 // Override the default pollSettings for `network` resource here ... 32 config.Timeout = 30 * time.Second 33 config.Delay = 100 * time.Millisecond 34 35 if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { 36 config.Timeout = 50 * time.Second 37 } 38 } 39 40 // ContainerPoll tweaks the pollSettings for `container` 41 func ContainerPoll(config *poll.Settings) { 42 // Override the default pollSettings for `container` resource here ... 43 44 if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { 45 config.Timeout = 30 * time.Second 46 config.Delay = 100 * time.Millisecond 47 } 48 } 49 50 // NewSwarm creates a swarm daemon for testing 51 func NewSwarm(t *testing.T, testEnv *environment.Execution, ops ...func(*daemon.Daemon)) *daemon.Daemon { 52 skip.IfCondition(t, testEnv.IsRemoteDaemon()) 53 if testEnv.DaemonInfo.ExperimentalBuild { 54 ops = append(ops, daemon.WithExperimental) 55 } 56 d := daemon.New(t, ops...) 57 d.StartAndSwarmInit(t) 58 return d 59 } 60 61 // ServiceSpecOpt is used with `CreateService` to pass in service spec modifiers 62 type ServiceSpecOpt func(*swarmtypes.ServiceSpec) 63 64 // CreateService creates a service on the passed in swarm daemon. 65 func CreateService(t *testing.T, d *daemon.Daemon, opts ...ServiceSpecOpt) string { 66 spec := defaultServiceSpec() 67 for _, o := range opts { 68 o(&spec) 69 } 70 71 client := d.NewClientT(t) 72 defer client.Close() 73 74 resp, err := client.ServiceCreate(context.Background(), spec, types.ServiceCreateOptions{}) 75 assert.NilError(t, err, "error creating service") 76 return resp.ID 77 } 78 79 func defaultServiceSpec() swarmtypes.ServiceSpec { 80 var spec swarmtypes.ServiceSpec 81 ServiceWithImage("busybox:latest")(&spec) 82 ServiceWithCommand([]string{"/bin/top"})(&spec) 83 ServiceWithReplicas(1)(&spec) 84 return spec 85 } 86 87 // ServiceWithImage sets the image to use for the service 88 func ServiceWithImage(image string) func(*swarmtypes.ServiceSpec) { 89 return func(spec *swarmtypes.ServiceSpec) { 90 ensureContainerSpec(spec) 91 spec.TaskTemplate.ContainerSpec.Image = image 92 } 93 } 94 95 // ServiceWithCommand sets the command to use for the service 96 func ServiceWithCommand(cmd []string) ServiceSpecOpt { 97 return func(spec *swarmtypes.ServiceSpec) { 98 ensureContainerSpec(spec) 99 spec.TaskTemplate.ContainerSpec.Command = cmd 100 } 101 } 102 103 // ServiceWithConfig adds the config reference to the service 104 func ServiceWithConfig(configRef *swarmtypes.ConfigReference) ServiceSpecOpt { 105 return func(spec *swarmtypes.ServiceSpec) { 106 ensureContainerSpec(spec) 107 spec.TaskTemplate.ContainerSpec.Configs = append(spec.TaskTemplate.ContainerSpec.Configs, configRef) 108 } 109 } 110 111 // ServiceWithSecret adds the secret reference to the service 112 func ServiceWithSecret(secretRef *swarmtypes.SecretReference) ServiceSpecOpt { 113 return func(spec *swarmtypes.ServiceSpec) { 114 ensureContainerSpec(spec) 115 spec.TaskTemplate.ContainerSpec.Secrets = append(spec.TaskTemplate.ContainerSpec.Secrets, secretRef) 116 } 117 } 118 119 // ServiceWithReplicas sets the replicas for the service 120 func ServiceWithReplicas(n uint64) ServiceSpecOpt { 121 return func(spec *swarmtypes.ServiceSpec) { 122 spec.Mode = swarmtypes.ServiceMode{ 123 Replicated: &swarmtypes.ReplicatedService{ 124 Replicas: &n, 125 }, 126 } 127 } 128 } 129 130 // ServiceWithName sets the name of the service 131 func ServiceWithName(name string) ServiceSpecOpt { 132 return func(spec *swarmtypes.ServiceSpec) { 133 spec.Annotations.Name = name 134 } 135 } 136 137 // GetRunningTasks gets the list of running tasks for a service 138 func GetRunningTasks(t *testing.T, d *daemon.Daemon, serviceID string) []swarmtypes.Task { 139 client := d.NewClientT(t) 140 defer client.Close() 141 142 filterArgs := filters.NewArgs() 143 filterArgs.Add("desired-state", "running") 144 filterArgs.Add("service", serviceID) 145 146 options := types.TaskListOptions{ 147 Filters: filterArgs, 148 } 149 tasks, err := client.TaskList(context.Background(), options) 150 assert.NilError(t, err) 151 return tasks 152 } 153 154 // ExecTask runs the passed in exec config on the given task 155 func ExecTask(t *testing.T, d *daemon.Daemon, task swarmtypes.Task, config types.ExecConfig) types.HijackedResponse { 156 client := d.NewClientT(t) 157 defer client.Close() 158 159 ctx := context.Background() 160 resp, err := client.ContainerExecCreate(ctx, task.Status.ContainerStatus.ContainerID, config) 161 assert.NilError(t, err, "error creating exec") 162 163 startCheck := types.ExecStartCheck{} 164 attach, err := client.ContainerExecAttach(ctx, resp.ID, startCheck) 165 assert.NilError(t, err, "error attaching to exec") 166 return attach 167 } 168 169 func ensureContainerSpec(spec *swarmtypes.ServiceSpec) { 170 if spec.TaskTemplate.ContainerSpec == nil { 171 spec.TaskTemplate.ContainerSpec = &swarmtypes.ContainerSpec{} 172 } 173 }