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