github.com/rhatdan/docker@v0.7.7-0.20180119204836-47a0dcbcd20a/integration/service/create_test.go (about) 1 package service 2 3 import ( 4 "runtime" 5 "testing" 6 "time" 7 8 "github.com/docker/docker/api/types" 9 "github.com/docker/docker/api/types/filters" 10 "github.com/docker/docker/api/types/swarm" 11 "github.com/docker/docker/client" 12 "github.com/docker/docker/integration-cli/request" 13 "github.com/gotestyourself/gotestyourself/poll" 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 "golang.org/x/net/context" 17 ) 18 19 func TestCreateServiceMultipleTimes(t *testing.T) { 20 defer setupTest(t)() 21 d := newSwarm(t) 22 defer d.Stop(t) 23 client, err := request.NewClientForHost(d.Sock()) 24 require.NoError(t, err) 25 26 overlayName := "overlay1" 27 networkCreate := types.NetworkCreate{ 28 CheckDuplicate: true, 29 Driver: "overlay", 30 } 31 32 netResp, err := client.NetworkCreate(context.Background(), overlayName, networkCreate) 33 require.NoError(t, err) 34 overlayID := netResp.ID 35 36 var instances uint64 = 4 37 serviceSpec := swarmServiceSpec("TestService", instances) 38 serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarm.NetworkAttachmentConfig{Target: overlayName}) 39 40 serviceResp, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ 41 QueryRegistry: false, 42 }) 43 require.NoError(t, err) 44 45 pollSettings := func(config *poll.Settings) { 46 // It takes about ~25s to finish the multi services creation in this case per the pratical observation on arm64/arm platform 47 if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { 48 config.Timeout = 30 * time.Second 49 config.Delay = 100 * time.Millisecond 50 } 51 } 52 53 serviceID := serviceResp.ID 54 poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances), pollSettings) 55 56 _, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{}) 57 require.NoError(t, err) 58 59 err = client.ServiceRemove(context.Background(), serviceID) 60 require.NoError(t, err) 61 62 poll.WaitOn(t, serviceIsRemoved(client, serviceID), pollSettings) 63 poll.WaitOn(t, noTasks(client), pollSettings) 64 65 serviceResp, err = client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ 66 QueryRegistry: false, 67 }) 68 require.NoError(t, err) 69 70 serviceID2 := serviceResp.ID 71 poll.WaitOn(t, serviceRunningTasksCount(client, serviceID2, instances), pollSettings) 72 73 err = client.ServiceRemove(context.Background(), serviceID2) 74 require.NoError(t, err) 75 76 poll.WaitOn(t, serviceIsRemoved(client, serviceID2), pollSettings) 77 poll.WaitOn(t, noTasks(client), pollSettings) 78 79 err = client.NetworkRemove(context.Background(), overlayID) 80 require.NoError(t, err) 81 82 poll.WaitOn(t, networkIsRemoved(client, overlayID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) 83 } 84 85 func TestCreateWithDuplicateNetworkNames(t *testing.T) { 86 defer setupTest(t)() 87 d := newSwarm(t) 88 defer d.Stop(t) 89 client, err := request.NewClientForHost(d.Sock()) 90 require.NoError(t, err) 91 92 name := "foo" 93 networkCreate := types.NetworkCreate{ 94 CheckDuplicate: false, 95 Driver: "bridge", 96 } 97 98 n1, err := client.NetworkCreate(context.Background(), name, networkCreate) 99 require.NoError(t, err) 100 101 n2, err := client.NetworkCreate(context.Background(), name, networkCreate) 102 require.NoError(t, err) 103 104 // Dupliates with name but with different driver 105 networkCreate.Driver = "overlay" 106 n3, err := client.NetworkCreate(context.Background(), name, networkCreate) 107 require.NoError(t, err) 108 109 // Create Service with the same name 110 var instances uint64 = 1 111 serviceSpec := swarmServiceSpec("top", instances) 112 113 serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarm.NetworkAttachmentConfig{Target: name}) 114 115 service, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{}) 116 require.NoError(t, err) 117 118 poll.WaitOn(t, serviceRunningTasksCount(client, service.ID, instances)) 119 120 resp, _, err := client.ServiceInspectWithRaw(context.Background(), service.ID, types.ServiceInspectOptions{}) 121 require.NoError(t, err) 122 assert.Equal(t, n3.ID, resp.Spec.TaskTemplate.Networks[0].Target) 123 124 // Remove Service 125 err = client.ServiceRemove(context.Background(), service.ID) 126 require.NoError(t, err) 127 128 // Make sure task has been destroyed. 129 poll.WaitOn(t, serviceIsRemoved(client, service.ID)) 130 131 // Remove networks 132 err = client.NetworkRemove(context.Background(), n3.ID) 133 require.NoError(t, err) 134 135 err = client.NetworkRemove(context.Background(), n2.ID) 136 require.NoError(t, err) 137 138 err = client.NetworkRemove(context.Background(), n1.ID) 139 require.NoError(t, err) 140 141 // Make sure networks have been destroyed. 142 poll.WaitOn(t, networkIsRemoved(client, n3.ID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) 143 poll.WaitOn(t, networkIsRemoved(client, n2.ID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) 144 poll.WaitOn(t, networkIsRemoved(client, n1.ID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) 145 } 146 147 func swarmServiceSpec(name string, replicas uint64) swarm.ServiceSpec { 148 return swarm.ServiceSpec{ 149 Annotations: swarm.Annotations{ 150 Name: name, 151 }, 152 TaskTemplate: swarm.TaskSpec{ 153 ContainerSpec: &swarm.ContainerSpec{ 154 Image: "busybox:latest", 155 Command: []string{"/bin/top"}, 156 }, 157 }, 158 Mode: swarm.ServiceMode{ 159 Replicated: &swarm.ReplicatedService{ 160 Replicas: &replicas, 161 }, 162 }, 163 } 164 } 165 166 func serviceRunningTasksCount(client client.ServiceAPIClient, serviceID string, instances uint64) func(log poll.LogT) poll.Result { 167 return func(log poll.LogT) poll.Result { 168 filter := filters.NewArgs() 169 filter.Add("service", serviceID) 170 tasks, err := client.TaskList(context.Background(), types.TaskListOptions{ 171 Filters: filter, 172 }) 173 switch { 174 case err != nil: 175 return poll.Error(err) 176 case len(tasks) == int(instances): 177 for _, task := range tasks { 178 if task.Status.State != swarm.TaskStateRunning { 179 return poll.Continue("waiting for tasks to enter run state") 180 } 181 } 182 return poll.Success() 183 default: 184 return poll.Continue("task count at %d waiting for %d", len(tasks), instances) 185 } 186 } 187 } 188 189 func noTasks(client client.ServiceAPIClient) func(log poll.LogT) poll.Result { 190 return func(log poll.LogT) poll.Result { 191 filter := filters.NewArgs() 192 tasks, err := client.TaskList(context.Background(), types.TaskListOptions{ 193 Filters: filter, 194 }) 195 switch { 196 case err != nil: 197 return poll.Error(err) 198 case len(tasks) == 0: 199 return poll.Success() 200 default: 201 return poll.Continue("task count at %d waiting for 0", len(tasks)) 202 } 203 } 204 } 205 206 func serviceIsRemoved(client client.ServiceAPIClient, serviceID string) func(log poll.LogT) poll.Result { 207 return func(log poll.LogT) poll.Result { 208 filter := filters.NewArgs() 209 filter.Add("service", serviceID) 210 _, err := client.TaskList(context.Background(), types.TaskListOptions{ 211 Filters: filter, 212 }) 213 if err == nil { 214 return poll.Continue("waiting for service %s to be deleted", serviceID) 215 } 216 return poll.Success() 217 } 218 } 219 220 func networkIsRemoved(client client.NetworkAPIClient, networkID string) func(log poll.LogT) poll.Result { 221 return func(log poll.LogT) poll.Result { 222 _, err := client.NetworkInspect(context.Background(), networkID, types.NetworkInspectOptions{}) 223 if err == nil { 224 return poll.Continue("waiting for network %s to be removed", networkID) 225 } 226 return poll.Success() 227 } 228 }