create_test.go 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. package service // import "github.com/docker/docker/integration/service"
  2. import (
  3. "context"
  4. "io/ioutil"
  5. "testing"
  6. "time"
  7. "github.com/docker/docker/api/types"
  8. "github.com/docker/docker/api/types/filters"
  9. swarmtypes "github.com/docker/docker/api/types/swarm"
  10. "github.com/docker/docker/client"
  11. "github.com/docker/docker/integration/internal/swarm"
  12. "github.com/gotestyourself/gotestyourself/assert"
  13. is "github.com/gotestyourself/gotestyourself/assert/cmp"
  14. "github.com/gotestyourself/gotestyourself/poll"
  15. )
  16. func TestCreateServiceMultipleTimes(t *testing.T) {
  17. defer setupTest(t)()
  18. d := swarm.NewSwarm(t, testEnv)
  19. defer d.Stop(t)
  20. client := d.NewClientT(t)
  21. defer client.Close()
  22. overlayName := "overlay1"
  23. networkCreate := types.NetworkCreate{
  24. CheckDuplicate: true,
  25. Driver: "overlay",
  26. }
  27. netResp, err := client.NetworkCreate(context.Background(), overlayName, networkCreate)
  28. assert.NilError(t, err)
  29. overlayID := netResp.ID
  30. var instances uint64 = 4
  31. serviceSpec := []swarm.ServiceSpecOpt{
  32. swarm.ServiceWithReplicas(instances),
  33. swarm.ServiceWithName("TestService"),
  34. swarm.ServiceWithNetwork(overlayName),
  35. }
  36. serviceID := swarm.CreateService(t, d, serviceSpec...)
  37. poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances), swarm.ServicePoll)
  38. _, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
  39. assert.NilError(t, err)
  40. err = client.ServiceRemove(context.Background(), serviceID)
  41. assert.NilError(t, err)
  42. poll.WaitOn(t, serviceIsRemoved(client, serviceID), swarm.ServicePoll)
  43. poll.WaitOn(t, noTasks(client), swarm.ServicePoll)
  44. serviceID2 := swarm.CreateService(t, d, serviceSpec...)
  45. poll.WaitOn(t, serviceRunningTasksCount(client, serviceID2, instances), swarm.ServicePoll)
  46. err = client.ServiceRemove(context.Background(), serviceID2)
  47. assert.NilError(t, err)
  48. poll.WaitOn(t, serviceIsRemoved(client, serviceID2), swarm.ServicePoll)
  49. poll.WaitOn(t, noTasks(client), swarm.ServicePoll)
  50. err = client.NetworkRemove(context.Background(), overlayID)
  51. assert.NilError(t, err)
  52. poll.WaitOn(t, networkIsRemoved(client, overlayID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second))
  53. }
  54. func TestCreateWithDuplicateNetworkNames(t *testing.T) {
  55. defer setupTest(t)()
  56. d := swarm.NewSwarm(t, testEnv)
  57. defer d.Stop(t)
  58. client := d.NewClientT(t)
  59. defer client.Close()
  60. name := "foo"
  61. networkCreate := types.NetworkCreate{
  62. CheckDuplicate: false,
  63. Driver: "bridge",
  64. }
  65. n1, err := client.NetworkCreate(context.Background(), name, networkCreate)
  66. assert.NilError(t, err)
  67. n2, err := client.NetworkCreate(context.Background(), name, networkCreate)
  68. assert.NilError(t, err)
  69. // Dupliates with name but with different driver
  70. networkCreate.Driver = "overlay"
  71. n3, err := client.NetworkCreate(context.Background(), name, networkCreate)
  72. assert.NilError(t, err)
  73. // Create Service with the same name
  74. var instances uint64 = 1
  75. serviceID := swarm.CreateService(t, d,
  76. swarm.ServiceWithReplicas(instances),
  77. swarm.ServiceWithName("top"),
  78. swarm.ServiceWithNetwork(name),
  79. )
  80. poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances), swarm.ServicePoll)
  81. resp, _, err := client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
  82. assert.NilError(t, err)
  83. assert.Check(t, is.Equal(n3.ID, resp.Spec.TaskTemplate.Networks[0].Target))
  84. // Remove Service
  85. err = client.ServiceRemove(context.Background(), serviceID)
  86. assert.NilError(t, err)
  87. // Make sure task has been destroyed.
  88. poll.WaitOn(t, serviceIsRemoved(client, serviceID), swarm.ServicePoll)
  89. // Remove networks
  90. err = client.NetworkRemove(context.Background(), n3.ID)
  91. assert.NilError(t, err)
  92. err = client.NetworkRemove(context.Background(), n2.ID)
  93. assert.NilError(t, err)
  94. err = client.NetworkRemove(context.Background(), n1.ID)
  95. assert.NilError(t, err)
  96. // Make sure networks have been destroyed.
  97. poll.WaitOn(t, networkIsRemoved(client, n3.ID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second))
  98. poll.WaitOn(t, networkIsRemoved(client, n2.ID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second))
  99. poll.WaitOn(t, networkIsRemoved(client, n1.ID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second))
  100. }
  101. func TestCreateServiceSecretFileMode(t *testing.T) {
  102. defer setupTest(t)()
  103. d := swarm.NewSwarm(t, testEnv)
  104. defer d.Stop(t)
  105. client := d.NewClientT(t)
  106. defer client.Close()
  107. ctx := context.Background()
  108. secretResp, err := client.SecretCreate(ctx, swarmtypes.SecretSpec{
  109. Annotations: swarmtypes.Annotations{
  110. Name: "TestSecret",
  111. },
  112. Data: []byte("TESTSECRET"),
  113. })
  114. assert.NilError(t, err)
  115. var instances uint64 = 1
  116. serviceID := swarm.CreateService(t, d,
  117. swarm.ServiceWithReplicas(instances),
  118. swarm.ServiceWithName("TestService"),
  119. swarm.ServiceWithCommand([]string{"/bin/sh", "-c", "ls -l /etc/secret || /bin/top"}),
  120. swarm.ServiceWithSecret(&swarmtypes.SecretReference{
  121. File: &swarmtypes.SecretReferenceFileTarget{
  122. Name: "/etc/secret",
  123. UID: "0",
  124. GID: "0",
  125. Mode: 0777,
  126. },
  127. SecretID: secretResp.ID,
  128. SecretName: "TestSecret",
  129. }),
  130. )
  131. poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances), swarm.ServicePoll)
  132. filter := filters.NewArgs()
  133. filter.Add("service", serviceID)
  134. tasks, err := client.TaskList(ctx, types.TaskListOptions{
  135. Filters: filter,
  136. })
  137. assert.NilError(t, err)
  138. assert.Check(t, is.Equal(len(tasks), 1))
  139. body, err := client.ContainerLogs(ctx, tasks[0].Status.ContainerStatus.ContainerID, types.ContainerLogsOptions{
  140. ShowStdout: true,
  141. })
  142. assert.NilError(t, err)
  143. defer body.Close()
  144. content, err := ioutil.ReadAll(body)
  145. assert.NilError(t, err)
  146. assert.Check(t, is.Contains(string(content), "-rwxrwxrwx"))
  147. err = client.ServiceRemove(ctx, serviceID)
  148. assert.NilError(t, err)
  149. poll.WaitOn(t, serviceIsRemoved(client, serviceID), swarm.ServicePoll)
  150. poll.WaitOn(t, noTasks(client), swarm.ServicePoll)
  151. err = client.SecretRemove(ctx, "TestSecret")
  152. assert.NilError(t, err)
  153. }
  154. func TestCreateServiceConfigFileMode(t *testing.T) {
  155. defer setupTest(t)()
  156. d := swarm.NewSwarm(t, testEnv)
  157. defer d.Stop(t)
  158. client := d.NewClientT(t)
  159. defer client.Close()
  160. ctx := context.Background()
  161. configResp, err := client.ConfigCreate(ctx, swarmtypes.ConfigSpec{
  162. Annotations: swarmtypes.Annotations{
  163. Name: "TestConfig",
  164. },
  165. Data: []byte("TESTCONFIG"),
  166. })
  167. assert.NilError(t, err)
  168. var instances uint64 = 1
  169. serviceID := swarm.CreateService(t, d,
  170. swarm.ServiceWithName("TestService"),
  171. swarm.ServiceWithCommand([]string{"/bin/sh", "-c", "ls -l /etc/config || /bin/top"}),
  172. swarm.ServiceWithReplicas(instances),
  173. swarm.ServiceWithConfig(&swarmtypes.ConfigReference{
  174. File: &swarmtypes.ConfigReferenceFileTarget{
  175. Name: "/etc/config",
  176. UID: "0",
  177. GID: "0",
  178. Mode: 0777,
  179. },
  180. ConfigID: configResp.ID,
  181. ConfigName: "TestConfig",
  182. }),
  183. )
  184. poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances))
  185. filter := filters.NewArgs()
  186. filter.Add("service", serviceID)
  187. tasks, err := client.TaskList(ctx, types.TaskListOptions{
  188. Filters: filter,
  189. })
  190. assert.NilError(t, err)
  191. assert.Check(t, is.Equal(len(tasks), 1))
  192. body, err := client.ContainerLogs(ctx, tasks[0].Status.ContainerStatus.ContainerID, types.ContainerLogsOptions{
  193. ShowStdout: true,
  194. })
  195. assert.NilError(t, err)
  196. defer body.Close()
  197. content, err := ioutil.ReadAll(body)
  198. assert.NilError(t, err)
  199. assert.Check(t, is.Contains(string(content), "-rwxrwxrwx"))
  200. err = client.ServiceRemove(ctx, serviceID)
  201. assert.NilError(t, err)
  202. poll.WaitOn(t, serviceIsRemoved(client, serviceID))
  203. poll.WaitOn(t, noTasks(client))
  204. err = client.ConfigRemove(ctx, "TestConfig")
  205. assert.NilError(t, err)
  206. }
  207. func serviceRunningTasksCount(client client.ServiceAPIClient, serviceID string, instances uint64) func(log poll.LogT) poll.Result {
  208. return func(log poll.LogT) poll.Result {
  209. filter := filters.NewArgs()
  210. filter.Add("service", serviceID)
  211. tasks, err := client.TaskList(context.Background(), types.TaskListOptions{
  212. Filters: filter,
  213. })
  214. switch {
  215. case err != nil:
  216. return poll.Error(err)
  217. case len(tasks) == int(instances):
  218. for _, task := range tasks {
  219. if task.Status.State != swarmtypes.TaskStateRunning {
  220. return poll.Continue("waiting for tasks to enter run state")
  221. }
  222. }
  223. return poll.Success()
  224. default:
  225. return poll.Continue("task count at %d waiting for %d", len(tasks), instances)
  226. }
  227. }
  228. }
  229. func noTasks(client client.ServiceAPIClient) func(log poll.LogT) poll.Result {
  230. return func(log poll.LogT) poll.Result {
  231. filter := filters.NewArgs()
  232. tasks, err := client.TaskList(context.Background(), types.TaskListOptions{
  233. Filters: filter,
  234. })
  235. switch {
  236. case err != nil:
  237. return poll.Error(err)
  238. case len(tasks) == 0:
  239. return poll.Success()
  240. default:
  241. return poll.Continue("task count at %d waiting for 0", len(tasks))
  242. }
  243. }
  244. }
  245. func serviceIsRemoved(client client.ServiceAPIClient, serviceID string) func(log poll.LogT) poll.Result {
  246. return func(log poll.LogT) poll.Result {
  247. filter := filters.NewArgs()
  248. filter.Add("service", serviceID)
  249. _, err := client.TaskList(context.Background(), types.TaskListOptions{
  250. Filters: filter,
  251. })
  252. if err == nil {
  253. return poll.Continue("waiting for service %s to be deleted", serviceID)
  254. }
  255. return poll.Success()
  256. }
  257. }
  258. func networkIsRemoved(client client.NetworkAPIClient, networkID string) func(log poll.LogT) poll.Result {
  259. return func(log poll.LogT) poll.Result {
  260. _, err := client.NetworkInspect(context.Background(), networkID, types.NetworkInspectOptions{})
  261. if err == nil {
  262. return poll.Continue("waiting for network %s to be removed", networkID)
  263. }
  264. return poll.Success()
  265. }
  266. }