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  }