github.com/sams1990/dockerrepo@v17.12.1-ce-rc2+incompatible/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/require" 15 "golang.org/x/net/context" 16 ) 17 18 func TestCreateServiceMultipleTimes(t *testing.T) { 19 defer setupTest(t)() 20 d := newSwarm(t) 21 defer d.Stop(t) 22 client, err := request.NewClientForHost(d.Sock()) 23 require.NoError(t, err) 24 25 overlayName := "overlay1" 26 networkCreate := types.NetworkCreate{ 27 CheckDuplicate: true, 28 Driver: "overlay", 29 } 30 31 netResp, err := client.NetworkCreate(context.Background(), overlayName, networkCreate) 32 require.NoError(t, err) 33 overlayID := netResp.ID 34 35 var instances uint64 = 4 36 serviceSpec := swarmServiceSpec("TestService", instances) 37 serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarm.NetworkAttachmentConfig{Target: overlayName}) 38 39 serviceResp, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ 40 QueryRegistry: false, 41 }) 42 require.NoError(t, err) 43 44 pollSettings := func(config *poll.Settings) { 45 if runtime.GOARCH == "arm" { 46 config.Timeout = 30 * time.Second 47 config.Delay = 100 * time.Millisecond 48 } 49 } 50 51 serviceID := serviceResp.ID 52 poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances), pollSettings) 53 54 _, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{}) 55 require.NoError(t, err) 56 57 err = client.ServiceRemove(context.Background(), serviceID) 58 require.NoError(t, err) 59 60 poll.WaitOn(t, serviceIsRemoved(client, serviceID), pollSettings) 61 poll.WaitOn(t, noTasks(client), pollSettings) 62 63 serviceResp, err = client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ 64 QueryRegistry: false, 65 }) 66 require.NoError(t, err) 67 68 serviceID2 := serviceResp.ID 69 poll.WaitOn(t, serviceRunningTasksCount(client, serviceID2, instances), pollSettings) 70 71 err = client.ServiceRemove(context.Background(), serviceID2) 72 require.NoError(t, err) 73 74 poll.WaitOn(t, serviceIsRemoved(client, serviceID2), pollSettings) 75 poll.WaitOn(t, noTasks(client), pollSettings) 76 77 err = client.NetworkRemove(context.Background(), overlayID) 78 require.NoError(t, err) 79 80 poll.WaitOn(t, networkIsRemoved(client, overlayID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) 81 } 82 83 func swarmServiceSpec(name string, replicas uint64) swarm.ServiceSpec { 84 return swarm.ServiceSpec{ 85 Annotations: swarm.Annotations{ 86 Name: name, 87 }, 88 TaskTemplate: swarm.TaskSpec{ 89 ContainerSpec: &swarm.ContainerSpec{ 90 Image: "busybox:latest", 91 Command: []string{"/bin/top"}, 92 }, 93 }, 94 Mode: swarm.ServiceMode{ 95 Replicated: &swarm.ReplicatedService{ 96 Replicas: &replicas, 97 }, 98 }, 99 } 100 } 101 102 func serviceRunningTasksCount(client client.ServiceAPIClient, serviceID string, instances uint64) func(log poll.LogT) poll.Result { 103 return func(log poll.LogT) poll.Result { 104 filter := filters.NewArgs() 105 filter.Add("service", serviceID) 106 tasks, err := client.TaskList(context.Background(), types.TaskListOptions{ 107 Filters: filter, 108 }) 109 switch { 110 case err != nil: 111 return poll.Error(err) 112 case len(tasks) == int(instances): 113 for _, task := range tasks { 114 if task.Status.State != swarm.TaskStateRunning { 115 return poll.Continue("waiting for tasks to enter run state") 116 } 117 } 118 return poll.Success() 119 default: 120 return poll.Continue("task count at %d waiting for %d", len(tasks), instances) 121 } 122 } 123 } 124 125 func noTasks(client client.ServiceAPIClient) func(log poll.LogT) poll.Result { 126 return func(log poll.LogT) poll.Result { 127 filter := filters.NewArgs() 128 tasks, err := client.TaskList(context.Background(), types.TaskListOptions{ 129 Filters: filter, 130 }) 131 switch { 132 case err != nil: 133 return poll.Error(err) 134 case len(tasks) == 0: 135 return poll.Success() 136 default: 137 return poll.Continue("task count at %d waiting for 0", len(tasks)) 138 } 139 } 140 } 141 142 func serviceIsRemoved(client client.ServiceAPIClient, serviceID string) func(log poll.LogT) poll.Result { 143 return func(log poll.LogT) poll.Result { 144 filter := filters.NewArgs() 145 filter.Add("service", serviceID) 146 _, err := client.TaskList(context.Background(), types.TaskListOptions{ 147 Filters: filter, 148 }) 149 if err == nil { 150 return poll.Continue("waiting for service %s to be deleted", serviceID) 151 } 152 return poll.Success() 153 } 154 } 155 156 func networkIsRemoved(client client.NetworkAPIClient, networkID string) func(log poll.LogT) poll.Result { 157 return func(log poll.LogT) poll.Result { 158 _, err := client.NetworkInspect(context.Background(), networkID, types.NetworkInspectOptions{}) 159 if err == nil { 160 return poll.Continue("waiting for network %s to be removed", networkID) 161 } 162 return poll.Success() 163 } 164 }