github.com/kim0/docker@v0.6.2-0.20161130212042-4addda3f07e7/cli/command/service/update_test.go (about)

     1  package service
     2  
     3  import (
     4  	"reflect"
     5  	"sort"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/docker/docker/api/types/container"
    10  	mounttypes "github.com/docker/docker/api/types/mount"
    11  	"github.com/docker/docker/api/types/swarm"
    12  	"github.com/docker/docker/pkg/testutil/assert"
    13  )
    14  
    15  func TestUpdateServiceArgs(t *testing.T) {
    16  	flags := newUpdateCommand(nil).Flags()
    17  	flags.Set("args", "the \"new args\"")
    18  
    19  	spec := &swarm.ServiceSpec{}
    20  	cspec := &spec.TaskTemplate.ContainerSpec
    21  	cspec.Args = []string{"old", "args"}
    22  
    23  	updateService(flags, spec)
    24  	assert.EqualStringSlice(t, cspec.Args, []string{"the", "new args"})
    25  }
    26  
    27  func TestUpdateLabels(t *testing.T) {
    28  	flags := newUpdateCommand(nil).Flags()
    29  	flags.Set("label-add", "toadd=newlabel")
    30  	flags.Set("label-rm", "toremove")
    31  
    32  	labels := map[string]string{
    33  		"toremove": "thelabeltoremove",
    34  		"tokeep":   "value",
    35  	}
    36  
    37  	updateLabels(flags, &labels)
    38  	assert.Equal(t, len(labels), 2)
    39  	assert.Equal(t, labels["tokeep"], "value")
    40  	assert.Equal(t, labels["toadd"], "newlabel")
    41  }
    42  
    43  func TestUpdateLabelsRemoveALabelThatDoesNotExist(t *testing.T) {
    44  	flags := newUpdateCommand(nil).Flags()
    45  	flags.Set("label-rm", "dne")
    46  
    47  	labels := map[string]string{"foo": "theoldlabel"}
    48  	updateLabels(flags, &labels)
    49  	assert.Equal(t, len(labels), 1)
    50  }
    51  
    52  func TestUpdatePlacement(t *testing.T) {
    53  	flags := newUpdateCommand(nil).Flags()
    54  	flags.Set("constraint-add", "node=toadd")
    55  	flags.Set("constraint-rm", "node!=toremove")
    56  
    57  	placement := &swarm.Placement{
    58  		Constraints: []string{"node!=toremove", "container=tokeep"},
    59  	}
    60  
    61  	updatePlacement(flags, placement)
    62  	assert.Equal(t, len(placement.Constraints), 2)
    63  	assert.Equal(t, placement.Constraints[0], "container=tokeep")
    64  	assert.Equal(t, placement.Constraints[1], "node=toadd")
    65  }
    66  
    67  func TestUpdateEnvironment(t *testing.T) {
    68  	flags := newUpdateCommand(nil).Flags()
    69  	flags.Set("env-add", "toadd=newenv")
    70  	flags.Set("env-rm", "toremove")
    71  
    72  	envs := []string{"toremove=theenvtoremove", "tokeep=value"}
    73  
    74  	updateEnvironment(flags, &envs)
    75  	assert.Equal(t, len(envs), 2)
    76  	// Order has been removed in updateEnvironment (map)
    77  	sort.Strings(envs)
    78  	assert.Equal(t, envs[0], "toadd=newenv")
    79  	assert.Equal(t, envs[1], "tokeep=value")
    80  }
    81  
    82  func TestUpdateEnvironmentWithDuplicateValues(t *testing.T) {
    83  	flags := newUpdateCommand(nil).Flags()
    84  	flags.Set("env-add", "foo=newenv")
    85  	flags.Set("env-add", "foo=dupe")
    86  	flags.Set("env-rm", "foo")
    87  
    88  	envs := []string{"foo=value"}
    89  
    90  	updateEnvironment(flags, &envs)
    91  	assert.Equal(t, len(envs), 0)
    92  }
    93  
    94  func TestUpdateEnvironmentWithDuplicateKeys(t *testing.T) {
    95  	// Test case for #25404
    96  	flags := newUpdateCommand(nil).Flags()
    97  	flags.Set("env-add", "A=b")
    98  
    99  	envs := []string{"A=c"}
   100  
   101  	updateEnvironment(flags, &envs)
   102  	assert.Equal(t, len(envs), 1)
   103  	assert.Equal(t, envs[0], "A=b")
   104  }
   105  
   106  func TestUpdateGroups(t *testing.T) {
   107  	flags := newUpdateCommand(nil).Flags()
   108  	flags.Set("group-add", "wheel")
   109  	flags.Set("group-add", "docker")
   110  	flags.Set("group-rm", "root")
   111  	flags.Set("group-add", "foo")
   112  	flags.Set("group-rm", "docker")
   113  
   114  	groups := []string{"bar", "root"}
   115  
   116  	updateGroups(flags, &groups)
   117  	assert.Equal(t, len(groups), 3)
   118  	assert.Equal(t, groups[0], "bar")
   119  	assert.Equal(t, groups[1], "foo")
   120  	assert.Equal(t, groups[2], "wheel")
   121  }
   122  
   123  func TestUpdateMounts(t *testing.T) {
   124  	flags := newUpdateCommand(nil).Flags()
   125  	flags.Set("mount-add", "type=volume,target=/toadd")
   126  	flags.Set("mount-rm", "/toremove")
   127  
   128  	mounts := []mounttypes.Mount{
   129  		{Target: "/toremove", Type: mounttypes.TypeBind},
   130  		{Target: "/tokeep", Type: mounttypes.TypeBind},
   131  	}
   132  
   133  	updateMounts(flags, &mounts)
   134  	assert.Equal(t, len(mounts), 2)
   135  	assert.Equal(t, mounts[0].Target, "/tokeep")
   136  	assert.Equal(t, mounts[1].Target, "/toadd")
   137  }
   138  
   139  func TestUpdatePorts(t *testing.T) {
   140  	flags := newUpdateCommand(nil).Flags()
   141  	flags.Set("publish-add", "1000:1000")
   142  	flags.Set("publish-rm", "333/udp")
   143  
   144  	portConfigs := []swarm.PortConfig{
   145  		{TargetPort: 333, Protocol: swarm.PortConfigProtocolUDP},
   146  		{TargetPort: 555},
   147  	}
   148  
   149  	err := updatePorts(flags, &portConfigs)
   150  	assert.Equal(t, err, nil)
   151  	assert.Equal(t, len(portConfigs), 2)
   152  	// Do a sort to have the order (might have changed by map)
   153  	targetPorts := []int{int(portConfigs[0].TargetPort), int(portConfigs[1].TargetPort)}
   154  	sort.Ints(targetPorts)
   155  	assert.Equal(t, targetPorts[0], 555)
   156  	assert.Equal(t, targetPorts[1], 1000)
   157  }
   158  
   159  func TestUpdatePortsDuplicateEntries(t *testing.T) {
   160  	// Test case for #25375
   161  	flags := newUpdateCommand(nil).Flags()
   162  	flags.Set("publish-add", "80:80")
   163  
   164  	portConfigs := []swarm.PortConfig{
   165  		{TargetPort: 80, PublishedPort: 80},
   166  	}
   167  
   168  	err := updatePorts(flags, &portConfigs)
   169  	assert.Equal(t, err, nil)
   170  	assert.Equal(t, len(portConfigs), 1)
   171  	assert.Equal(t, portConfigs[0].TargetPort, uint32(80))
   172  }
   173  
   174  func TestUpdatePortsDuplicateKeys(t *testing.T) {
   175  	// Test case for #25375
   176  	flags := newUpdateCommand(nil).Flags()
   177  	flags.Set("publish-add", "80:20")
   178  
   179  	portConfigs := []swarm.PortConfig{
   180  		{TargetPort: 80, PublishedPort: 80},
   181  	}
   182  
   183  	err := updatePorts(flags, &portConfigs)
   184  	assert.Equal(t, err, nil)
   185  	assert.Equal(t, len(portConfigs), 1)
   186  	assert.Equal(t, portConfigs[0].TargetPort, uint32(20))
   187  }
   188  
   189  func TestUpdatePortsConflictingFlags(t *testing.T) {
   190  	// Test case for #25375
   191  	flags := newUpdateCommand(nil).Flags()
   192  	flags.Set("publish-add", "80:80")
   193  	flags.Set("publish-add", "80:20")
   194  
   195  	portConfigs := []swarm.PortConfig{
   196  		{TargetPort: 80, PublishedPort: 80},
   197  	}
   198  
   199  	err := updatePorts(flags, &portConfigs)
   200  	assert.Error(t, err, "conflicting port mapping")
   201  }
   202  
   203  func TestUpdateHealthcheckTable(t *testing.T) {
   204  	type test struct {
   205  		flags    [][2]string
   206  		initial  *container.HealthConfig
   207  		expected *container.HealthConfig
   208  		err      string
   209  	}
   210  	testCases := []test{
   211  		{
   212  			flags:    [][2]string{{"no-healthcheck", "true"}},
   213  			initial:  &container.HealthConfig{Test: []string{"CMD-SHELL", "cmd1"}, Retries: 10},
   214  			expected: &container.HealthConfig{Test: []string{"NONE"}},
   215  		},
   216  		{
   217  			flags:    [][2]string{{"health-cmd", "cmd1"}},
   218  			initial:  &container.HealthConfig{Test: []string{"NONE"}},
   219  			expected: &container.HealthConfig{Test: []string{"CMD-SHELL", "cmd1"}},
   220  		},
   221  		{
   222  			flags:    [][2]string{{"health-retries", "10"}},
   223  			initial:  &container.HealthConfig{Test: []string{"NONE"}},
   224  			expected: &container.HealthConfig{Retries: 10},
   225  		},
   226  		{
   227  			flags:    [][2]string{{"health-retries", "10"}},
   228  			initial:  &container.HealthConfig{Test: []string{"CMD", "cmd1"}},
   229  			expected: &container.HealthConfig{Test: []string{"CMD", "cmd1"}, Retries: 10},
   230  		},
   231  		{
   232  			flags:    [][2]string{{"health-interval", "1m"}},
   233  			initial:  &container.HealthConfig{Test: []string{"CMD", "cmd1"}},
   234  			expected: &container.HealthConfig{Test: []string{"CMD", "cmd1"}, Interval: time.Minute},
   235  		},
   236  		{
   237  			flags:    [][2]string{{"health-cmd", ""}},
   238  			initial:  &container.HealthConfig{Test: []string{"CMD", "cmd1"}, Retries: 10},
   239  			expected: &container.HealthConfig{Retries: 10},
   240  		},
   241  		{
   242  			flags:    [][2]string{{"health-retries", "0"}},
   243  			initial:  &container.HealthConfig{Test: []string{"CMD", "cmd1"}, Retries: 10},
   244  			expected: &container.HealthConfig{Test: []string{"CMD", "cmd1"}},
   245  		},
   246  		{
   247  			flags: [][2]string{{"health-cmd", "cmd1"}, {"no-healthcheck", "true"}},
   248  			err:   "--no-healthcheck conflicts with --health-* options",
   249  		},
   250  		{
   251  			flags: [][2]string{{"health-interval", "10m"}, {"no-healthcheck", "true"}},
   252  			err:   "--no-healthcheck conflicts with --health-* options",
   253  		},
   254  		{
   255  			flags: [][2]string{{"health-timeout", "1m"}, {"no-healthcheck", "true"}},
   256  			err:   "--no-healthcheck conflicts with --health-* options",
   257  		},
   258  	}
   259  	for i, c := range testCases {
   260  		flags := newUpdateCommand(nil).Flags()
   261  		for _, flag := range c.flags {
   262  			flags.Set(flag[0], flag[1])
   263  		}
   264  		cspec := &swarm.ContainerSpec{
   265  			Healthcheck: c.initial,
   266  		}
   267  		err := updateHealthcheck(flags, cspec)
   268  		if c.err != "" {
   269  			assert.Error(t, err, c.err)
   270  		} else {
   271  			assert.NilError(t, err)
   272  			if !reflect.DeepEqual(cspec.Healthcheck, c.expected) {
   273  				t.Errorf("incorrect result for test %d, expected health config:\n\t%#v\ngot:\n\t%#v", i, c.expected, cspec.Healthcheck)
   274  			}
   275  		}
   276  	}
   277  }