create_test.go 7.0 KB

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