mirror of https://github.com/docker/cli.git
550 lines
16 KiB
Go
550 lines
16 KiB
Go
package service
|
|
|
|
import (
|
|
"reflect"
|
|
"sort"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/docker/cli/internal/test/testutil"
|
|
"github.com/docker/docker/api/types"
|
|
"github.com/docker/docker/api/types/container"
|
|
mounttypes "github.com/docker/docker/api/types/mount"
|
|
"github.com/docker/docker/api/types/swarm"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"golang.org/x/net/context"
|
|
)
|
|
|
|
func TestUpdateServiceArgs(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("args", "the \"new args\"")
|
|
|
|
spec := &swarm.ServiceSpec{
|
|
TaskTemplate: swarm.TaskSpec{
|
|
ContainerSpec: &swarm.ContainerSpec{},
|
|
},
|
|
}
|
|
cspec := spec.TaskTemplate.ContainerSpec
|
|
cspec.Args = []string{"old", "args"}
|
|
|
|
updateService(nil, nil, flags, spec)
|
|
assert.Equal(t, []string{"the", "new args"}, cspec.Args)
|
|
}
|
|
|
|
func TestUpdateLabels(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("label-add", "toadd=newlabel")
|
|
flags.Set("label-rm", "toremove")
|
|
|
|
labels := map[string]string{
|
|
"toremove": "thelabeltoremove",
|
|
"tokeep": "value",
|
|
}
|
|
|
|
updateLabels(flags, &labels)
|
|
assert.Len(t, labels, 2)
|
|
assert.Equal(t, "value", labels["tokeep"])
|
|
assert.Equal(t, "newlabel", labels["toadd"])
|
|
}
|
|
|
|
func TestUpdateLabelsRemoveALabelThatDoesNotExist(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("label-rm", "dne")
|
|
|
|
labels := map[string]string{"foo": "theoldlabel"}
|
|
updateLabels(flags, &labels)
|
|
assert.Len(t, labels, 1)
|
|
}
|
|
|
|
func TestUpdatePlacementConstraints(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("constraint-add", "node=toadd")
|
|
flags.Set("constraint-rm", "node!=toremove")
|
|
|
|
placement := &swarm.Placement{
|
|
Constraints: []string{"node!=toremove", "container=tokeep"},
|
|
}
|
|
|
|
updatePlacementConstraints(flags, placement)
|
|
require.Len(t, placement.Constraints, 2)
|
|
assert.Equal(t, "container=tokeep", placement.Constraints[0])
|
|
assert.Equal(t, "node=toadd", placement.Constraints[1])
|
|
}
|
|
|
|
func TestUpdatePlacementPrefs(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("placement-pref-add", "spread=node.labels.dc")
|
|
flags.Set("placement-pref-rm", "spread=node.labels.rack")
|
|
|
|
placement := &swarm.Placement{
|
|
Preferences: []swarm.PlacementPreference{
|
|
{
|
|
Spread: &swarm.SpreadOver{
|
|
SpreadDescriptor: "node.labels.rack",
|
|
},
|
|
},
|
|
{
|
|
Spread: &swarm.SpreadOver{
|
|
SpreadDescriptor: "node.labels.row",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
updatePlacementPreferences(flags, placement)
|
|
require.Len(t, placement.Preferences, 2)
|
|
assert.Equal(t, "node.labels.row", placement.Preferences[0].Spread.SpreadDescriptor)
|
|
assert.Equal(t, "node.labels.dc", placement.Preferences[1].Spread.SpreadDescriptor)
|
|
}
|
|
|
|
func TestUpdateEnvironment(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("env-add", "toadd=newenv")
|
|
flags.Set("env-rm", "toremove")
|
|
|
|
envs := []string{"toremove=theenvtoremove", "tokeep=value"}
|
|
|
|
updateEnvironment(flags, &envs)
|
|
require.Len(t, envs, 2)
|
|
// Order has been removed in updateEnvironment (map)
|
|
sort.Strings(envs)
|
|
assert.Equal(t, "toadd=newenv", envs[0])
|
|
assert.Equal(t, "tokeep=value", envs[1])
|
|
}
|
|
|
|
func TestUpdateEnvironmentWithDuplicateValues(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("env-add", "foo=newenv")
|
|
flags.Set("env-add", "foo=dupe")
|
|
flags.Set("env-rm", "foo")
|
|
|
|
envs := []string{"foo=value"}
|
|
|
|
updateEnvironment(flags, &envs)
|
|
assert.Len(t, envs, 0)
|
|
}
|
|
|
|
func TestUpdateEnvironmentWithDuplicateKeys(t *testing.T) {
|
|
// Test case for #25404
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("env-add", "A=b")
|
|
|
|
envs := []string{"A=c"}
|
|
|
|
updateEnvironment(flags, &envs)
|
|
require.Len(t, envs, 1)
|
|
assert.Equal(t, "A=b", envs[0])
|
|
}
|
|
|
|
func TestUpdateGroups(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("group-add", "wheel")
|
|
flags.Set("group-add", "docker")
|
|
flags.Set("group-rm", "root")
|
|
flags.Set("group-add", "foo")
|
|
flags.Set("group-rm", "docker")
|
|
|
|
groups := []string{"bar", "root"}
|
|
|
|
updateGroups(flags, &groups)
|
|
require.Len(t, groups, 3)
|
|
assert.Equal(t, "bar", groups[0])
|
|
assert.Equal(t, "foo", groups[1])
|
|
assert.Equal(t, "wheel", groups[2])
|
|
}
|
|
|
|
func TestUpdateDNSConfig(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
|
|
// IPv4, with duplicates
|
|
flags.Set("dns-add", "1.1.1.1")
|
|
flags.Set("dns-add", "1.1.1.1")
|
|
flags.Set("dns-add", "2.2.2.2")
|
|
flags.Set("dns-rm", "3.3.3.3")
|
|
flags.Set("dns-rm", "2.2.2.2")
|
|
// IPv6
|
|
flags.Set("dns-add", "2001:db8:abc8::1")
|
|
// Invalid dns record
|
|
testutil.ErrorContains(t, flags.Set("dns-add", "x.y.z.w"), "x.y.z.w is not an ip address")
|
|
|
|
// domains with duplicates
|
|
flags.Set("dns-search-add", "example.com")
|
|
flags.Set("dns-search-add", "example.com")
|
|
flags.Set("dns-search-add", "example.org")
|
|
flags.Set("dns-search-rm", "example.org")
|
|
// Invalid dns search domain
|
|
testutil.ErrorContains(t, flags.Set("dns-search-add", "example$com"), "example$com is not a valid domain")
|
|
|
|
flags.Set("dns-option-add", "ndots:9")
|
|
flags.Set("dns-option-rm", "timeout:3")
|
|
|
|
config := &swarm.DNSConfig{
|
|
Nameservers: []string{"3.3.3.3", "5.5.5.5"},
|
|
Search: []string{"localdomain"},
|
|
Options: []string{"timeout:3"},
|
|
}
|
|
|
|
updateDNSConfig(flags, &config)
|
|
|
|
require.Len(t, config.Nameservers, 3)
|
|
assert.Equal(t, "1.1.1.1", config.Nameservers[0])
|
|
assert.Equal(t, "2001:db8:abc8::1", config.Nameservers[1])
|
|
assert.Equal(t, "5.5.5.5", config.Nameservers[2])
|
|
|
|
require.Len(t, config.Search, 2)
|
|
assert.Equal(t, "example.com", config.Search[0])
|
|
assert.Equal(t, "localdomain", config.Search[1])
|
|
|
|
require.Len(t, config.Options, 1)
|
|
assert.Equal(t, config.Options[0], "ndots:9")
|
|
}
|
|
|
|
func TestUpdateMounts(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("mount-add", "type=volume,source=vol2,target=/toadd")
|
|
flags.Set("mount-rm", "/toremove")
|
|
|
|
mounts := []mounttypes.Mount{
|
|
{Target: "/toremove", Source: "vol1", Type: mounttypes.TypeBind},
|
|
{Target: "/tokeep", Source: "vol3", Type: mounttypes.TypeBind},
|
|
}
|
|
|
|
updateMounts(flags, &mounts)
|
|
require.Len(t, mounts, 2)
|
|
assert.Equal(t, "/toadd", mounts[0].Target)
|
|
assert.Equal(t, "/tokeep", mounts[1].Target)
|
|
}
|
|
|
|
func TestUpdateMountsWithDuplicateMounts(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("mount-add", "type=volume,source=vol4,target=/toadd")
|
|
|
|
mounts := []mounttypes.Mount{
|
|
{Target: "/tokeep1", Source: "vol1", Type: mounttypes.TypeBind},
|
|
{Target: "/toadd", Source: "vol2", Type: mounttypes.TypeBind},
|
|
{Target: "/tokeep2", Source: "vol3", Type: mounttypes.TypeBind},
|
|
}
|
|
|
|
updateMounts(flags, &mounts)
|
|
require.Len(t, mounts, 3)
|
|
assert.Equal(t, "/tokeep1", mounts[0].Target)
|
|
assert.Equal(t, "/tokeep2", mounts[1].Target)
|
|
assert.Equal(t, "/toadd", mounts[2].Target)
|
|
}
|
|
|
|
func TestUpdatePorts(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("publish-add", "1000:1000")
|
|
flags.Set("publish-rm", "333/udp")
|
|
|
|
portConfigs := []swarm.PortConfig{
|
|
{TargetPort: 333, Protocol: swarm.PortConfigProtocolUDP},
|
|
{TargetPort: 555},
|
|
}
|
|
|
|
err := updatePorts(flags, &portConfigs)
|
|
assert.NoError(t, err)
|
|
require.Len(t, portConfigs, 2)
|
|
// Do a sort to have the order (might have changed by map)
|
|
targetPorts := []int{int(portConfigs[0].TargetPort), int(portConfigs[1].TargetPort)}
|
|
sort.Ints(targetPorts)
|
|
assert.Equal(t, 555, targetPorts[0])
|
|
assert.Equal(t, 1000, targetPorts[1])
|
|
}
|
|
|
|
func TestUpdatePortsDuplicate(t *testing.T) {
|
|
// Test case for #25375
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("publish-add", "80:80")
|
|
|
|
portConfigs := []swarm.PortConfig{
|
|
{
|
|
TargetPort: 80,
|
|
PublishedPort: 80,
|
|
Protocol: swarm.PortConfigProtocolTCP,
|
|
PublishMode: swarm.PortConfigPublishModeIngress,
|
|
},
|
|
}
|
|
|
|
err := updatePorts(flags, &portConfigs)
|
|
assert.NoError(t, err)
|
|
require.Len(t, portConfigs, 1)
|
|
assert.Equal(t, uint32(80), portConfigs[0].TargetPort)
|
|
}
|
|
|
|
func TestUpdateHealthcheckTable(t *testing.T) {
|
|
type test struct {
|
|
flags [][2]string
|
|
initial *container.HealthConfig
|
|
expected *container.HealthConfig
|
|
err string
|
|
}
|
|
testCases := []test{
|
|
{
|
|
flags: [][2]string{{"no-healthcheck", "true"}},
|
|
initial: &container.HealthConfig{Test: []string{"CMD-SHELL", "cmd1"}, Retries: 10},
|
|
expected: &container.HealthConfig{Test: []string{"NONE"}},
|
|
},
|
|
{
|
|
flags: [][2]string{{"health-cmd", "cmd1"}},
|
|
initial: &container.HealthConfig{Test: []string{"NONE"}},
|
|
expected: &container.HealthConfig{Test: []string{"CMD-SHELL", "cmd1"}},
|
|
},
|
|
{
|
|
flags: [][2]string{{"health-retries", "10"}},
|
|
initial: &container.HealthConfig{Test: []string{"NONE"}},
|
|
expected: &container.HealthConfig{Retries: 10},
|
|
},
|
|
{
|
|
flags: [][2]string{{"health-retries", "10"}},
|
|
initial: &container.HealthConfig{Test: []string{"CMD", "cmd1"}},
|
|
expected: &container.HealthConfig{Test: []string{"CMD", "cmd1"}, Retries: 10},
|
|
},
|
|
{
|
|
flags: [][2]string{{"health-interval", "1m"}},
|
|
initial: &container.HealthConfig{Test: []string{"CMD", "cmd1"}},
|
|
expected: &container.HealthConfig{Test: []string{"CMD", "cmd1"}, Interval: time.Minute},
|
|
},
|
|
{
|
|
flags: [][2]string{{"health-cmd", ""}},
|
|
initial: &container.HealthConfig{Test: []string{"CMD", "cmd1"}, Retries: 10},
|
|
expected: &container.HealthConfig{Retries: 10},
|
|
},
|
|
{
|
|
flags: [][2]string{{"health-retries", "0"}},
|
|
initial: &container.HealthConfig{Test: []string{"CMD", "cmd1"}, Retries: 10},
|
|
expected: &container.HealthConfig{Test: []string{"CMD", "cmd1"}},
|
|
},
|
|
{
|
|
flags: [][2]string{{"health-start-period", "1m"}},
|
|
initial: &container.HealthConfig{Test: []string{"CMD", "cmd1"}},
|
|
expected: &container.HealthConfig{Test: []string{"CMD", "cmd1"}, StartPeriod: time.Minute},
|
|
},
|
|
{
|
|
flags: [][2]string{{"health-cmd", "cmd1"}, {"no-healthcheck", "true"}},
|
|
err: "--no-healthcheck conflicts with --health-* options",
|
|
},
|
|
{
|
|
flags: [][2]string{{"health-interval", "10m"}, {"no-healthcheck", "true"}},
|
|
err: "--no-healthcheck conflicts with --health-* options",
|
|
},
|
|
{
|
|
flags: [][2]string{{"health-timeout", "1m"}, {"no-healthcheck", "true"}},
|
|
err: "--no-healthcheck conflicts with --health-* options",
|
|
},
|
|
}
|
|
for i, c := range testCases {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
for _, flag := range c.flags {
|
|
flags.Set(flag[0], flag[1])
|
|
}
|
|
cspec := &swarm.ContainerSpec{
|
|
Healthcheck: c.initial,
|
|
}
|
|
err := updateHealthcheck(flags, cspec)
|
|
if c.err != "" {
|
|
assert.EqualError(t, err, c.err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
if !reflect.DeepEqual(cspec.Healthcheck, c.expected) {
|
|
t.Errorf("incorrect result for test %d, expected health config:\n\t%#v\ngot:\n\t%#v", i, c.expected, cspec.Healthcheck)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUpdateHosts(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("host-add", "example.net:2.2.2.2")
|
|
flags.Set("host-add", "ipv6.net:2001:db8:abc8::1")
|
|
// remove with ipv6 should work
|
|
flags.Set("host-rm", "example.net:2001:db8:abc8::1")
|
|
// just hostname should work as well
|
|
flags.Set("host-rm", "example.net")
|
|
// bad format error
|
|
testutil.ErrorContains(t, flags.Set("host-add", "$example.com$"), `bad format for add-host: "$example.com$"`)
|
|
|
|
hosts := []string{"1.2.3.4 example.com", "4.3.2.1 example.org", "2001:db8:abc8::1 example.net"}
|
|
expected := []string{"1.2.3.4 example.com", "4.3.2.1 example.org", "2001:db8:abc8::1 ipv6.net"}
|
|
|
|
err := updateHosts(flags, &hosts)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, expected, hosts)
|
|
}
|
|
|
|
func TestUpdateHostsPreservesOrder(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("host-add", "foobar:127.0.0.2")
|
|
flags.Set("host-add", "foobar:127.0.0.1")
|
|
flags.Set("host-add", "foobar:127.0.0.3")
|
|
|
|
hosts := []string{}
|
|
err := updateHosts(flags, &hosts)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, []string{"127.0.0.2 foobar", "127.0.0.1 foobar", "127.0.0.3 foobar"}, hosts)
|
|
}
|
|
|
|
func TestUpdatePortsRmWithProtocol(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("publish-add", "8081:81")
|
|
flags.Set("publish-add", "8082:82")
|
|
flags.Set("publish-rm", "80")
|
|
flags.Set("publish-rm", "81/tcp")
|
|
flags.Set("publish-rm", "82/udp")
|
|
|
|
portConfigs := []swarm.PortConfig{
|
|
{
|
|
TargetPort: 80,
|
|
PublishedPort: 8080,
|
|
Protocol: swarm.PortConfigProtocolTCP,
|
|
PublishMode: swarm.PortConfigPublishModeIngress,
|
|
},
|
|
}
|
|
|
|
err := updatePorts(flags, &portConfigs)
|
|
assert.NoError(t, err)
|
|
require.Len(t, portConfigs, 2)
|
|
assert.Equal(t, uint32(81), portConfigs[0].TargetPort)
|
|
assert.Equal(t, uint32(82), portConfigs[1].TargetPort)
|
|
}
|
|
|
|
type secretAPIClientMock struct {
|
|
listResult []swarm.Secret
|
|
}
|
|
|
|
func (s secretAPIClientMock) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
|
|
return s.listResult, nil
|
|
}
|
|
func (s secretAPIClientMock) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (types.SecretCreateResponse, error) {
|
|
return types.SecretCreateResponse{}, nil
|
|
}
|
|
func (s secretAPIClientMock) SecretRemove(ctx context.Context, id string) error {
|
|
return nil
|
|
}
|
|
func (s secretAPIClientMock) SecretInspectWithRaw(ctx context.Context, name string) (swarm.Secret, []byte, error) {
|
|
return swarm.Secret{}, []byte{}, nil
|
|
}
|
|
func (s secretAPIClientMock) SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error {
|
|
return nil
|
|
}
|
|
|
|
// TestUpdateSecretUpdateInPlace tests the ability to update the "target" of an secret with "docker service update"
|
|
// by combining "--secret-rm" and "--secret-add" for the same secret.
|
|
func TestUpdateSecretUpdateInPlace(t *testing.T) {
|
|
apiClient := secretAPIClientMock{
|
|
listResult: []swarm.Secret{
|
|
{
|
|
ID: "tn9qiblgnuuut11eufquw5dev",
|
|
Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "foo"}},
|
|
},
|
|
},
|
|
}
|
|
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("secret-add", "source=foo,target=foo2")
|
|
flags.Set("secret-rm", "foo")
|
|
|
|
secrets := []*swarm.SecretReference{
|
|
{
|
|
File: &swarm.SecretReferenceFileTarget{
|
|
Name: "foo",
|
|
UID: "0",
|
|
GID: "0",
|
|
Mode: 292,
|
|
},
|
|
SecretID: "tn9qiblgnuuut11eufquw5dev",
|
|
SecretName: "foo",
|
|
},
|
|
}
|
|
|
|
updatedSecrets, err := getUpdatedSecrets(apiClient, flags, secrets)
|
|
|
|
assert.NoError(t, err)
|
|
require.Len(t, updatedSecrets, 1)
|
|
assert.Equal(t, "tn9qiblgnuuut11eufquw5dev", updatedSecrets[0].SecretID)
|
|
assert.Equal(t, "foo", updatedSecrets[0].SecretName)
|
|
assert.Equal(t, "foo2", updatedSecrets[0].File.Name)
|
|
}
|
|
|
|
func TestUpdateReadOnly(t *testing.T) {
|
|
spec := &swarm.ServiceSpec{
|
|
TaskTemplate: swarm.TaskSpec{
|
|
ContainerSpec: &swarm.ContainerSpec{},
|
|
},
|
|
}
|
|
cspec := spec.TaskTemplate.ContainerSpec
|
|
|
|
// Update with --read-only=true, changed to true
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("read-only", "true")
|
|
updateService(nil, nil, flags, spec)
|
|
assert.True(t, cspec.ReadOnly)
|
|
|
|
// Update without --read-only, no change
|
|
flags = newUpdateCommand(nil).Flags()
|
|
updateService(nil, nil, flags, spec)
|
|
assert.True(t, cspec.ReadOnly)
|
|
|
|
// Update with --read-only=false, changed to false
|
|
flags = newUpdateCommand(nil).Flags()
|
|
flags.Set("read-only", "false")
|
|
updateService(nil, nil, flags, spec)
|
|
assert.False(t, cspec.ReadOnly)
|
|
}
|
|
|
|
func TestUpdateStopSignal(t *testing.T) {
|
|
spec := &swarm.ServiceSpec{
|
|
TaskTemplate: swarm.TaskSpec{
|
|
ContainerSpec: &swarm.ContainerSpec{},
|
|
},
|
|
}
|
|
cspec := spec.TaskTemplate.ContainerSpec
|
|
|
|
// Update with --stop-signal=SIGUSR1
|
|
flags := newUpdateCommand(nil).Flags()
|
|
flags.Set("stop-signal", "SIGUSR1")
|
|
updateService(nil, nil, flags, spec)
|
|
assert.Equal(t, "SIGUSR1", cspec.StopSignal)
|
|
|
|
// Update without --stop-signal, no change
|
|
flags = newUpdateCommand(nil).Flags()
|
|
updateService(nil, nil, flags, spec)
|
|
assert.Equal(t, "SIGUSR1", cspec.StopSignal)
|
|
|
|
// Update with --stop-signal=SIGWINCH
|
|
flags = newUpdateCommand(nil).Flags()
|
|
flags.Set("stop-signal", "SIGWINCH")
|
|
updateService(nil, nil, flags, spec)
|
|
assert.Equal(t, "SIGWINCH", cspec.StopSignal)
|
|
}
|
|
|
|
func TestUpdateIsolationValid(t *testing.T) {
|
|
flags := newUpdateCommand(nil).Flags()
|
|
err := flags.Set("isolation", "process")
|
|
require.NoError(t, err)
|
|
spec := swarm.ServiceSpec{
|
|
TaskTemplate: swarm.TaskSpec{
|
|
ContainerSpec: &swarm.ContainerSpec{},
|
|
},
|
|
}
|
|
err = updateService(context.Background(), nil, flags, &spec)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, container.IsolationProcess, spec.TaskTemplate.ContainerSpec.Isolation)
|
|
}
|
|
|
|
func TestUpdateIsolationInvalid(t *testing.T) {
|
|
// validation depends on daemon os / version so validation should be done on the daemon side
|
|
flags := newUpdateCommand(nil).Flags()
|
|
err := flags.Set("isolation", "test")
|
|
require.NoError(t, err)
|
|
spec := swarm.ServiceSpec{
|
|
TaskTemplate: swarm.TaskSpec{
|
|
ContainerSpec: &swarm.ContainerSpec{},
|
|
},
|
|
}
|
|
err = updateService(context.Background(), nil, flags, &spec)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, container.Isolation("test"), spec.TaskTemplate.ContainerSpec.Isolation)
|
|
}
|