plugin_test.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package service
  2. import (
  3. "context"
  4. "io"
  5. "io/ioutil"
  6. "os"
  7. "path"
  8. "testing"
  9. "github.com/docker/docker/api/types"
  10. swarmtypes "github.com/docker/docker/api/types/swarm"
  11. "github.com/docker/docker/api/types/swarm/runtime"
  12. "github.com/docker/docker/integration/internal/swarm"
  13. "github.com/docker/docker/internal/test/daemon"
  14. "github.com/docker/docker/internal/test/fixtures/plugin"
  15. "github.com/docker/docker/internal/test/registry"
  16. "github.com/gotestyourself/gotestyourself/assert"
  17. "github.com/gotestyourself/gotestyourself/poll"
  18. "github.com/gotestyourself/gotestyourself/skip"
  19. )
  20. func TestServicePlugin(t *testing.T) {
  21. skip.If(t, testEnv.DaemonInfo.OSType == "windows")
  22. skip.If(t, os.Getenv("DOCKER_ENGINE_GOARCH") != "amd64")
  23. defer setupTest(t)()
  24. reg := registry.NewV2(t)
  25. defer reg.Close()
  26. repo := path.Join(registry.DefaultURL, "swarm", "test:v1")
  27. repo2 := path.Join(registry.DefaultURL, "swarm", "test:v2")
  28. name := "test"
  29. d := daemon.New(t)
  30. d.StartWithBusybox(t)
  31. apiclient := d.NewClientT(t)
  32. err := plugin.Create(context.Background(), apiclient, repo)
  33. assert.NilError(t, err)
  34. r, err := apiclient.PluginPush(context.Background(), repo, "")
  35. assert.NilError(t, err)
  36. _, err = io.Copy(ioutil.Discard, r)
  37. assert.NilError(t, err)
  38. err = apiclient.PluginRemove(context.Background(), repo, types.PluginRemoveOptions{})
  39. assert.NilError(t, err)
  40. err = plugin.Create(context.Background(), apiclient, repo2)
  41. assert.NilError(t, err)
  42. r, err = apiclient.PluginPush(context.Background(), repo2, "")
  43. assert.NilError(t, err)
  44. _, err = io.Copy(ioutil.Discard, r)
  45. assert.NilError(t, err)
  46. err = apiclient.PluginRemove(context.Background(), repo2, types.PluginRemoveOptions{})
  47. assert.NilError(t, err)
  48. d.Stop(t)
  49. d1 := swarm.NewSwarm(t, testEnv, daemon.WithExperimental)
  50. defer d1.Stop(t)
  51. d2 := daemon.New(t, daemon.WithExperimental, daemon.WithSwarmPort(daemon.DefaultSwarmPort+1))
  52. d2.StartAndSwarmJoin(t, d1, true)
  53. defer d2.Stop(t)
  54. d3 := daemon.New(t, daemon.WithExperimental, daemon.WithSwarmPort(daemon.DefaultSwarmPort+2))
  55. d3.StartAndSwarmJoin(t, d1, false)
  56. defer d3.Stop(t)
  57. id := d1.CreateService(t, makePlugin(repo, name, nil))
  58. poll.WaitOn(t, d1.PluginIsRunning(name), swarm.ServicePoll)
  59. poll.WaitOn(t, d2.PluginIsRunning(name), swarm.ServicePoll)
  60. poll.WaitOn(t, d3.PluginIsRunning(name), swarm.ServicePoll)
  61. service := d1.GetService(t, id)
  62. d1.UpdateService(t, service, makePlugin(repo2, name, nil))
  63. poll.WaitOn(t, d1.PluginReferenceIs(name, repo2), swarm.ServicePoll)
  64. poll.WaitOn(t, d2.PluginReferenceIs(name, repo2), swarm.ServicePoll)
  65. poll.WaitOn(t, d3.PluginReferenceIs(name, repo2), swarm.ServicePoll)
  66. poll.WaitOn(t, d1.PluginIsRunning(name), swarm.ServicePoll)
  67. poll.WaitOn(t, d2.PluginIsRunning(name), swarm.ServicePoll)
  68. poll.WaitOn(t, d3.PluginIsRunning(name), swarm.ServicePoll)
  69. d1.RemoveService(t, id)
  70. poll.WaitOn(t, d1.PluginIsNotPresent(name), swarm.ServicePoll)
  71. poll.WaitOn(t, d2.PluginIsNotPresent(name), swarm.ServicePoll)
  72. poll.WaitOn(t, d3.PluginIsNotPresent(name), swarm.ServicePoll)
  73. // constrain to managers only
  74. id = d1.CreateService(t, makePlugin(repo, name, []string{"node.role==manager"}))
  75. poll.WaitOn(t, d1.PluginIsRunning(name), swarm.ServicePoll)
  76. poll.WaitOn(t, d2.PluginIsRunning(name), swarm.ServicePoll)
  77. poll.WaitOn(t, d3.PluginIsNotPresent(name), swarm.ServicePoll)
  78. d1.RemoveService(t, id)
  79. poll.WaitOn(t, d1.PluginIsNotPresent(name), swarm.ServicePoll)
  80. poll.WaitOn(t, d2.PluginIsNotPresent(name), swarm.ServicePoll)
  81. poll.WaitOn(t, d3.PluginIsNotPresent(name), swarm.ServicePoll)
  82. // with no name
  83. id = d1.CreateService(t, makePlugin(repo, "", nil))
  84. poll.WaitOn(t, d1.PluginIsRunning(repo), swarm.ServicePoll)
  85. poll.WaitOn(t, d2.PluginIsRunning(repo), swarm.ServicePoll)
  86. poll.WaitOn(t, d3.PluginIsRunning(repo), swarm.ServicePoll)
  87. d1.RemoveService(t, id)
  88. poll.WaitOn(t, d1.PluginIsNotPresent(repo), swarm.ServicePoll)
  89. poll.WaitOn(t, d2.PluginIsNotPresent(repo), swarm.ServicePoll)
  90. poll.WaitOn(t, d3.PluginIsNotPresent(repo), swarm.ServicePoll)
  91. }
  92. func makePlugin(repo, name string, constraints []string) func(*swarmtypes.Service) {
  93. return func(s *swarmtypes.Service) {
  94. s.Spec.TaskTemplate.Runtime = "plugin"
  95. s.Spec.TaskTemplate.PluginSpec = &runtime.PluginSpec{
  96. Name: name,
  97. Remote: repo,
  98. }
  99. if constraints != nil {
  100. s.Spec.TaskTemplate.Placement = &swarmtypes.Placement{
  101. Constraints: constraints,
  102. }
  103. }
  104. }
  105. }