create_test.go 11 KB

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