2017-11-20 09:30:52 -05:00
|
|
|
package swarm
|
2017-02-22 15:43:13 -05:00
|
|
|
|
|
|
|
import (
|
2018-05-03 21:02:44 -04:00
|
|
|
"context"
|
2017-02-22 15:43:13 -05:00
|
|
|
"testing"
|
|
|
|
|
2018-05-28 06:21:41 -04:00
|
|
|
"github.com/docker/cli/cli/command/stack/options"
|
2017-04-17 18:07:56 -04:00
|
|
|
"github.com/docker/cli/cli/compose/convert"
|
2017-08-21 16:30:09 -04:00
|
|
|
"github.com/docker/cli/internal/test"
|
2017-07-26 09:33:57 -04:00
|
|
|
"github.com/docker/docker/api/types"
|
|
|
|
"github.com/docker/docker/api/types/swarm"
|
2018-03-05 18:53:52 -05:00
|
|
|
"github.com/gotestyourself/gotestyourself/assert"
|
|
|
|
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
2017-02-22 15:43:13 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestPruneServices(t *testing.T) {
|
|
|
|
ctx := context.Background()
|
|
|
|
namespace := convert.NewNamespace("foo")
|
|
|
|
services := map[string]struct{}{
|
|
|
|
"new": {},
|
|
|
|
"keep": {},
|
|
|
|
}
|
2017-03-26 02:23:24 -04:00
|
|
|
client := &fakeClient{services: []string{objectName("foo", "keep"), objectName("foo", "remove")}}
|
2017-07-05 14:43:39 -04:00
|
|
|
dockerCli := test.NewFakeCli(client)
|
2017-02-22 15:43:13 -05:00
|
|
|
|
|
|
|
pruneServices(ctx, dockerCli, namespace, services)
|
2018-03-05 18:53:52 -05:00
|
|
|
assert.Check(t, is.DeepEqual(buildObjectIDs([]string{objectName("foo", "remove")}), client.removedServices))
|
2017-02-22 15:43:13 -05:00
|
|
|
}
|
2017-07-26 09:33:57 -04:00
|
|
|
|
2018-05-28 06:21:41 -04:00
|
|
|
func TestDeployWithEmptyName(t *testing.T) {
|
|
|
|
ctx := context.Background()
|
|
|
|
client := &fakeClient{}
|
|
|
|
dockerCli := test.NewFakeCli(client)
|
|
|
|
|
|
|
|
err := deployCompose(ctx, dockerCli, options.Deploy{Namespace: "' '", Prune: true})
|
|
|
|
assert.Check(t, is.Error(err, `invalid stack name: "' '"`))
|
|
|
|
}
|
|
|
|
|
2017-07-26 09:33:57 -04:00
|
|
|
// TestServiceUpdateResolveImageChanged tests that the service's
|
2018-03-26 09:24:28 -04:00
|
|
|
// image digest, and "ForceUpdate" is preserved if the image did not change in
|
|
|
|
// the compose file
|
2017-07-26 09:33:57 -04:00
|
|
|
func TestServiceUpdateResolveImageChanged(t *testing.T) {
|
|
|
|
namespace := convert.NewNamespace("mystack")
|
|
|
|
|
|
|
|
var (
|
|
|
|
receivedOptions types.ServiceUpdateOptions
|
|
|
|
receivedService swarm.ServiceSpec
|
|
|
|
)
|
|
|
|
|
|
|
|
client := test.NewFakeCli(&fakeClient{
|
|
|
|
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
|
|
|
return []swarm.Service{
|
|
|
|
{
|
|
|
|
Spec: swarm.ServiceSpec{
|
|
|
|
Annotations: swarm.Annotations{
|
|
|
|
Name: namespace.Name() + "_myservice",
|
|
|
|
Labels: map[string]string{"com.docker.stack.image": "foobar:1.2.3"},
|
|
|
|
},
|
|
|
|
TaskTemplate: swarm.TaskSpec{
|
2017-08-07 05:52:40 -04:00
|
|
|
ContainerSpec: &swarm.ContainerSpec{
|
2017-07-26 09:33:57 -04:00
|
|
|
Image: "foobar:1.2.3@sha256:deadbeef",
|
|
|
|
},
|
2018-03-26 09:24:28 -04:00
|
|
|
ForceUpdate: 123,
|
2017-07-26 09:33:57 -04:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
},
|
|
|
|
serviceUpdateFunc: func(serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) {
|
|
|
|
receivedOptions = options
|
|
|
|
receivedService = service
|
|
|
|
return types.ServiceUpdateResponse{}, nil
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
var testcases = []struct {
|
|
|
|
image string
|
|
|
|
expectedQueryRegistry bool
|
|
|
|
expectedImage string
|
2018-03-26 09:24:28 -04:00
|
|
|
expectedForceUpdate uint64
|
2017-07-26 09:33:57 -04:00
|
|
|
}{
|
|
|
|
// Image not changed
|
|
|
|
{
|
|
|
|
image: "foobar:1.2.3",
|
|
|
|
expectedQueryRegistry: false,
|
|
|
|
expectedImage: "foobar:1.2.3@sha256:deadbeef",
|
2018-03-26 09:24:28 -04:00
|
|
|
expectedForceUpdate: 123,
|
2017-07-26 09:33:57 -04:00
|
|
|
},
|
|
|
|
// Image changed
|
|
|
|
{
|
|
|
|
image: "foobar:1.2.4",
|
|
|
|
expectedQueryRegistry: true,
|
|
|
|
expectedImage: "foobar:1.2.4",
|
2018-03-26 09:24:28 -04:00
|
|
|
expectedForceUpdate: 123,
|
2017-07-26 09:33:57 -04:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
for _, testcase := range testcases {
|
|
|
|
t.Logf("Testing image %q", testcase.image)
|
|
|
|
spec := map[string]swarm.ServiceSpec{
|
|
|
|
"myservice": {
|
|
|
|
TaskTemplate: swarm.TaskSpec{
|
2017-08-07 05:52:40 -04:00
|
|
|
ContainerSpec: &swarm.ContainerSpec{
|
2017-07-26 09:33:57 -04:00
|
|
|
Image: testcase.image,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2017-12-04 06:30:39 -05:00
|
|
|
err := deployServices(ctx, client, spec, namespace, false, ResolveImageChanged)
|
2018-03-06 14:44:13 -05:00
|
|
|
assert.NilError(t, err)
|
2018-03-26 09:24:28 -04:00
|
|
|
assert.Check(t, is.Equal(receivedOptions.QueryRegistry, testcase.expectedQueryRegistry))
|
|
|
|
assert.Check(t, is.Equal(receivedService.TaskTemplate.ContainerSpec.Image, testcase.expectedImage))
|
|
|
|
assert.Check(t, is.Equal(receivedService.TaskTemplate.ForceUpdate, testcase.expectedForceUpdate))
|
2017-07-26 09:33:57 -04:00
|
|
|
|
|
|
|
receivedService = swarm.ServiceSpec{}
|
|
|
|
receivedOptions = types.ServiceUpdateOptions{}
|
|
|
|
}
|
|
|
|
}
|