From c1804c161254aa03fd6ee3079f1348eaded7dce6 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 31 May 2017 21:43:56 +0200 Subject: [PATCH 1/6] Fix prefix-matching for service ps The docker CLI matches objects either by ID _prefix_ or a full name match, but not partial name matches. The correct order of resolution is; - Full ID match (a name should not be able to mask an ID) - Full name - ID-prefix This patch changes the way services are matched. Also change to use the first matching service, if there's a full match (by ID or Name) instead of continue looking for other possible matches. Error handling changed; - Do not error early if multiple services were requested and one or more services were not found. Print the services that were not found after printing those that _were_ found instead - Print an error if ID-prefix matching is ambiguous Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 62796124432c7e56e7dda226c3c53c8c2356a30c) Signed-off-by: Andrew Hsu --- components/cli/cli/command/service/ps.go | 51 ++++++++++++++++-------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/components/cli/cli/command/service/ps.go b/components/cli/cli/command/service/ps.go index 87b29d2043a..7c744478ec8 100644 --- a/components/cli/cli/command/service/ps.go +++ b/components/cli/cli/command/service/ps.go @@ -69,29 +69,43 @@ func runPS(dockerCli command.Cli, options psOptions) error { return err } + var errs []string + serviceCount := 0 +loop: + // Match services by 1. Full ID, 2. Full name, 3. ID prefix. An error is returned if the ID-prefix match is ambiguous for _, service := range options.services { - serviceCount := 0 - // Lookup by ID/Prefix - for _, serviceEntry := range serviceByIDList { - if strings.HasPrefix(serviceEntry.ID, service) { - filter.Add("service", serviceEntry.ID) + for _, s := range serviceByIDList { + if s.ID == service { + filter.Add("service", s.ID) serviceCount++ + continue loop } } - - // Lookup by Name/Prefix - for _, serviceEntry := range serviceByNameList { - if strings.HasPrefix(serviceEntry.Spec.Annotations.Name, service) { - filter.Add("service", serviceEntry.ID) + for _, s := range serviceByNameList { + if s.Spec.Annotations.Name == service { + filter.Add("service", s.ID) serviceCount++ + continue loop } } - // If nothing has been found, return immediately. - if serviceCount == 0 { - return errors.Errorf("no such services: %s", service) + found := false + for _, s := range serviceByIDList { + if strings.HasPrefix(s.ID, service) { + if found { + return errors.New("multiple services found with provided prefix: " + service) + } + filter.Add("service", s.ID) + serviceCount++ + found = true + } + } + if !found { + errs = append(errs, "no such service: "+service) } } - + if serviceCount == 0 { + return errors.New(strings.Join(errs, "\n")) + } if filter.Include("node") { nodeFilters := filter.Get("node") for _, nodeFilter := range nodeFilters { @@ -117,6 +131,11 @@ func runPS(dockerCli command.Cli, options psOptions) error { format = formatter.TableFormatKey } } - - return task.Print(ctx, dockerCli, tasks, idresolver.New(client, options.noResolve), !options.noTrunc, options.quiet, format) + if err := task.Print(ctx, dockerCli, tasks, idresolver.New(client, options.noResolve), !options.noTrunc, options.quiet, format); err != nil { + return err + } + if len(errs) != 0 { + return errors.New(strings.Join(errs, "\n")) + } + return nil } From 623e9d7bce5a0f54841f99efe13b202e6635e09b Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 1 Jun 2017 11:47:43 -0400 Subject: [PATCH 2/6] Fix complexity of service/ps. Signed-off-by: Daniel Nephin (cherry picked from commit b5baffde44cf16bc2eb030c09da76d39abb62252) Signed-off-by: Andrew Hsu --- components/cli/cli/command/service/ps.go | 65 ++++++++++++++---------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/components/cli/cli/command/service/ps.go b/components/cli/cli/command/service/ps.go index 7c744478ec8..741f6b589f2 100644 --- a/components/cli/cli/command/service/ps.go +++ b/components/cli/cli/command/service/ps.go @@ -12,6 +12,7 @@ import ( "github.com/docker/cli/opts" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/client" "github.com/pkg/errors" "github.com/spf13/cobra" "golang.org/x/net/context" @@ -52,6 +53,34 @@ func runPS(dockerCli command.Cli, options psOptions) error { client := dockerCli.Client() ctx := context.Background() + filter, notfound, err := createFilter(ctx, client, options) + if err != nil { + return err + } + + tasks, err := client.TaskList(ctx, types.TaskListOptions{Filters: filter}) + if err != nil { + return err + } + + format := options.format + if len(format) == 0 { + if len(dockerCli.ConfigFile().TasksFormat) > 0 && !options.quiet { + format = dockerCli.ConfigFile().TasksFormat + } else { + format = formatter.TableFormatKey + } + } + if err := task.Print(ctx, dockerCli, tasks, idresolver.New(client, options.noResolve), !options.noTrunc, options.quiet, format); err != nil { + return err + } + if len(notfound) != 0 { + return errors.New(strings.Join(notfound, "\n")) + } + return nil +} + +func createFilter(ctx context.Context, client client.APIClient, options psOptions) (filters.Args, []string, error) { filter := options.filter.Value() serviceIDFilter := filters.NewArgs() @@ -62,14 +91,14 @@ func runPS(dockerCli command.Cli, options psOptions) error { } serviceByIDList, err := client.ServiceList(ctx, types.ServiceListOptions{Filters: serviceIDFilter}) if err != nil { - return err + return filter, nil, err } serviceByNameList, err := client.ServiceList(ctx, types.ServiceListOptions{Filters: serviceNameFilter}) if err != nil { - return err + return filter, nil, err } - var errs []string + var notfound []string serviceCount := 0 loop: // Match services by 1. Full ID, 2. Full name, 3. ID prefix. An error is returned if the ID-prefix match is ambiguous @@ -92,7 +121,7 @@ loop: for _, s := range serviceByIDList { if strings.HasPrefix(s.ID, service) { if found { - return errors.New("multiple services found with provided prefix: " + service) + return filter, nil, errors.New("multiple services found with provided prefix: " + service) } filter.Add("service", s.ID) serviceCount++ @@ -100,42 +129,22 @@ loop: } } if !found { - errs = append(errs, "no such service: "+service) + notfound = append(notfound, "no such service: "+service) } } if serviceCount == 0 { - return errors.New(strings.Join(errs, "\n")) + return filter, nil, errors.New(strings.Join(notfound, "\n")) } if filter.Include("node") { nodeFilters := filter.Get("node") for _, nodeFilter := range nodeFilters { nodeReference, err := node.Reference(ctx, client, nodeFilter) if err != nil { - return err + return filter, nil, err } filter.Del("node", nodeFilter) filter.Add("node", nodeReference) } } - - tasks, err := client.TaskList(ctx, types.TaskListOptions{Filters: filter}) - if err != nil { - return err - } - - format := options.format - if len(format) == 0 { - if len(dockerCli.ConfigFile().TasksFormat) > 0 && !options.quiet { - format = dockerCli.ConfigFile().TasksFormat - } else { - format = formatter.TableFormatKey - } - } - if err := task.Print(ctx, dockerCli, tasks, idresolver.New(client, options.noResolve), !options.noTrunc, options.quiet, format); err != nil { - return err - } - if len(errs) != 0 { - return errors.New(strings.Join(errs, "\n")) - } - return nil + return filter, notfound, err } From 785c3478716ec545ade6bd88297074b831c7f0b1 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 1 Jun 2017 12:59:11 -0400 Subject: [PATCH 3/6] Add unit tests for service/ps Signed-off-by: Daniel Nephin (cherry picked from commit 3718833f2cecde35ae1ed007a9b2d5bf507c7c66) Signed-off-by: Andrew Hsu --- components/cli/cli/command/service/ps_test.go | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 components/cli/cli/command/service/ps_test.go diff --git a/components/cli/cli/command/service/ps_test.go b/components/cli/cli/command/service/ps_test.go new file mode 100644 index 00000000000..a53748d6d3e --- /dev/null +++ b/components/cli/cli/command/service/ps_test.go @@ -0,0 +1,118 @@ +package service + +import ( + "testing" + + "bytes" + + "github.com/docker/cli/cli/internal/test" + "github.com/docker/cli/opts" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/client" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/net/context" +) + +type fakeClient struct { + client.Client + serviceListFunc func(context.Context, types.ServiceListOptions) ([]swarm.Service, error) +} + +func (f *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { + if f.serviceListFunc != nil { + return f.serviceListFunc(ctx, options) + } + return nil, nil +} + +func (f *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) { + return nil, nil +} + +func newService(id string, name string) swarm.Service { + return swarm.Service{ + ID: id, + Spec: swarm.ServiceSpec{Annotations: swarm.Annotations{Name: name}}, + } +} + +func TestCreateFilter(t *testing.T) { + client := &fakeClient{ + serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { + return []swarm.Service{ + {ID: "idmatch"}, + {ID: "idprefixmatch"}, + newService("cccccccc", "namematch"), + newService("01010101", "notfoundprefix"), + }, nil + }, + } + + filter := opts.NewFilterOpt() + require.NoError(t, filter.Set("node=somenode")) + options := psOptions{ + services: []string{"idmatch", "idprefix", "namematch", "notfound"}, + filter: filter, + } + + actual, notfound, err := createFilter(context.Background(), client, options) + require.NoError(t, err) + assert.Equal(t, notfound, []string{"no such service: notfound"}) + + expected := filters.NewArgs() + expected.Add("service", "idmatch") + expected.Add("service", "idprefixmatch") + expected.Add("service", "cccccccc") + expected.Add("node", "somenode") + assert.Equal(t, expected, actual) +} + +func TestCreateFilterWithAmbiguousIDPrefixError(t *testing.T) { + client := &fakeClient{ + serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { + return []swarm.Service{ + {ID: "aaaone"}, + {ID: "aaatwo"}, + }, nil + }, + } + options := psOptions{ + services: []string{"aaa"}, + filter: opts.NewFilterOpt(), + } + _, _, err := createFilter(context.Background(), client, options) + assert.EqualError(t, err, "multiple services found with provided prefix: aaa") +} + +func TestCreateFilterNoneFound(t *testing.T) { + client := &fakeClient{} + options := psOptions{ + services: []string{"foo", "notfound"}, + filter: opts.NewFilterOpt(), + } + _, _, err := createFilter(context.Background(), client, options) + assert.EqualError(t, err, "no such service: foo\nno such service: notfound") +} + +func TestRunPSWarnsOnNotFound(t *testing.T) { + client := &fakeClient{ + serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { + return []swarm.Service{ + {ID: "foo"}, + }, nil + }, + } + + out := new(bytes.Buffer) + cli := test.NewFakeCli(client, out) + options := psOptions{ + services: []string{"foo", "bar"}, + filter: opts.NewFilterOpt(), + format: "{{.ID}}", + } + err := runPS(cli, options) + assert.EqualError(t, err, "no such service: bar") +} From 7beb1f75c075790cd1b4ef73a7157cb5a46cff91 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Wed, 14 Jun 2017 14:27:21 -0700 Subject: [PATCH 4/6] Fix TestSwarmServicePSMultipleServiceIDs to use the correct exec helper. Signed-off-by: Daniel Nephin (cherry picked from commit 7e135e0fa481a41a04abc434219d87c7796e2d1a) Signed-off-by: Andrew Hsu --- .../integration-cli/docker_cli_swarm_test.go | 49 +++++++++++-------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/components/engine/integration-cli/docker_cli_swarm_test.go b/components/engine/integration-cli/docker_cli_swarm_test.go index 8a8c8d0fcd5..10dd79e804c 100644 --- a/components/engine/integration-cli/docker_cli_swarm_test.go +++ b/components/engine/integration-cli/docker_cli_swarm_test.go @@ -1691,22 +1691,23 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { d := s.AddDaemon(c, true, true) name1 := "top1" - out, err := d.Cmd("service", "create", "--no-resolve-image", "--detach=true", "--name", name1, "--replicas=3", "busybox", "top") - c.Assert(err, checker.IsNil) - c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") - id1 := strings.TrimSpace(out) + result := icmd.RunCmd(d.Command("service", "create", "--no-resolve-image", "--detach=true", "--name", name1, "--replicas=3", "busybox", "top")) + result.Assert(c, icmd.Success) + id1 := strings.TrimSpace(result.Stdout()) + c.Assert(id1, checker.Not(checker.Equals), "") name2 := "top2" - out, err = d.Cmd("service", "create", "--no-resolve-image", "--detach=true", "--name", name2, "--replicas=3", "busybox", "top") - c.Assert(err, checker.IsNil) - c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") - id2 := strings.TrimSpace(out) + result = icmd.RunCmd(d.Command("service", "create", "--no-resolve-image", "--detach=true", "--name", name2, "--replicas=3", "busybox", "top")) + result.Assert(c, icmd.Success) + id2 := strings.TrimSpace(result.Stdout()) + c.Assert(id2, checker.Not(checker.Equals), "") // make sure task has been deployed. waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 6) - out, err = d.Cmd("service", "ps", name1) - c.Assert(err, checker.IsNil) + result = icmd.RunCmd(d.Command("service", "ps", name1)) + result.Assert(c, icmd.Success) + out := result.Stdout() c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") @@ -1714,8 +1715,9 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { c.Assert(out, checker.Not(checker.Contains), name2+".2") c.Assert(out, checker.Not(checker.Contains), name2+".3") - out, err = d.Cmd("service", "ps", name1, name2) - c.Assert(err, checker.IsNil) + result = icmd.RunCmd(d.Command("service", "ps", name1, name2)) + result.Assert(c, icmd.Success) + out = result.Stdout() c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") @@ -1724,8 +1726,9 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { c.Assert(out, checker.Contains, name2+".3") // Name Prefix - out, err = d.Cmd("service", "ps", "to") - c.Assert(err, checker.IsNil) + result = icmd.RunCmd(d.Command("service", "ps", "to")) + result.Assert(c, icmd.Success) + out = result.Stdout() c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") @@ -1734,12 +1737,15 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { c.Assert(out, checker.Contains, name2+".3") // Name Prefix (no hit) - out, err = d.Cmd("service", "ps", "noname") - c.Assert(err, checker.NotNil) - c.Assert(out, checker.Contains, "no such services: noname") + result = icmd.RunCmd(d.Command("service", "ps", "noname")) + result.Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "no such services: noname", + }) - out, err = d.Cmd("service", "ps", id1) - c.Assert(err, checker.IsNil) + result = icmd.RunCmd(d.Command("service", "ps", id1)) + result.Assert(c, icmd.Success) + out = result.Stdout() c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") @@ -1747,8 +1753,9 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { c.Assert(out, checker.Not(checker.Contains), name2+".2") c.Assert(out, checker.Not(checker.Contains), name2+".3") - out, err = d.Cmd("service", "ps", id1, id2) - c.Assert(err, checker.IsNil) + result = icmd.RunCmd(d.Command("service", "ps", id1, id2)) + result.Assert(c, icmd.Success) + out = result.Stdout() c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") From 6fb9dbeac0838af064b6e94b0bf16d6164552365 Mon Sep 17 00:00:00 2001 From: Andrew Hsu Date: Thu, 15 Jun 2017 01:10:23 +0000 Subject: [PATCH 5/6] Revert "Fix TestSwarmServicePSMultipleServiceIDs to use the correct exec helper." This reverts commit 7beb1f75c075790cd1b4ef73a7157cb5a46cff91. Signed-off-by: Andrew Hsu --- .../integration-cli/docker_cli_swarm_test.go | 49 ++++++++----------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/components/engine/integration-cli/docker_cli_swarm_test.go b/components/engine/integration-cli/docker_cli_swarm_test.go index 10dd79e804c..8a8c8d0fcd5 100644 --- a/components/engine/integration-cli/docker_cli_swarm_test.go +++ b/components/engine/integration-cli/docker_cli_swarm_test.go @@ -1691,23 +1691,22 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { d := s.AddDaemon(c, true, true) name1 := "top1" - result := icmd.RunCmd(d.Command("service", "create", "--no-resolve-image", "--detach=true", "--name", name1, "--replicas=3", "busybox", "top")) - result.Assert(c, icmd.Success) - id1 := strings.TrimSpace(result.Stdout()) - c.Assert(id1, checker.Not(checker.Equals), "") + out, err := d.Cmd("service", "create", "--no-resolve-image", "--detach=true", "--name", name1, "--replicas=3", "busybox", "top") + c.Assert(err, checker.IsNil) + c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") + id1 := strings.TrimSpace(out) name2 := "top2" - result = icmd.RunCmd(d.Command("service", "create", "--no-resolve-image", "--detach=true", "--name", name2, "--replicas=3", "busybox", "top")) - result.Assert(c, icmd.Success) - id2 := strings.TrimSpace(result.Stdout()) - c.Assert(id2, checker.Not(checker.Equals), "") + out, err = d.Cmd("service", "create", "--no-resolve-image", "--detach=true", "--name", name2, "--replicas=3", "busybox", "top") + c.Assert(err, checker.IsNil) + c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") + id2 := strings.TrimSpace(out) // make sure task has been deployed. waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 6) - result = icmd.RunCmd(d.Command("service", "ps", name1)) - result.Assert(c, icmd.Success) - out := result.Stdout() + out, err = d.Cmd("service", "ps", name1) + c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") @@ -1715,9 +1714,8 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { c.Assert(out, checker.Not(checker.Contains), name2+".2") c.Assert(out, checker.Not(checker.Contains), name2+".3") - result = icmd.RunCmd(d.Command("service", "ps", name1, name2)) - result.Assert(c, icmd.Success) - out = result.Stdout() + out, err = d.Cmd("service", "ps", name1, name2) + c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") @@ -1726,9 +1724,8 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { c.Assert(out, checker.Contains, name2+".3") // Name Prefix - result = icmd.RunCmd(d.Command("service", "ps", "to")) - result.Assert(c, icmd.Success) - out = result.Stdout() + out, err = d.Cmd("service", "ps", "to") + c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") @@ -1737,15 +1734,12 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { c.Assert(out, checker.Contains, name2+".3") // Name Prefix (no hit) - result = icmd.RunCmd(d.Command("service", "ps", "noname")) - result.Assert(c, icmd.Expected{ - ExitCode: 1, - Err: "no such services: noname", - }) + out, err = d.Cmd("service", "ps", "noname") + c.Assert(err, checker.NotNil) + c.Assert(out, checker.Contains, "no such services: noname") - result = icmd.RunCmd(d.Command("service", "ps", id1)) - result.Assert(c, icmd.Success) - out = result.Stdout() + out, err = d.Cmd("service", "ps", id1) + c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") @@ -1753,9 +1747,8 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { c.Assert(out, checker.Not(checker.Contains), name2+".2") c.Assert(out, checker.Not(checker.Contains), name2+".3") - result = icmd.RunCmd(d.Command("service", "ps", id1, id2)) - result.Assert(c, icmd.Success) - out = result.Stdout() + out, err = d.Cmd("service", "ps", id1, id2) + c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") From 441a76fb1ad840822eadb100d6ce1442b09bb79b Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Wed, 14 Jun 2017 14:27:21 -0700 Subject: [PATCH 6/6] Fix TestSwarmServicePSMultipleServiceIDs to use the correct exec helper. Signed-off-by: Daniel Nephin (cherry picked from commit 09b371886c5674a39dba8b13a98f01763fd7704f) Signed-off-by: Andrew Hsu --- .../integration-cli/docker_cli_swarm_test.go | 54 +++++++++---------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/components/engine/integration-cli/docker_cli_swarm_test.go b/components/engine/integration-cli/docker_cli_swarm_test.go index 8a8c8d0fcd5..e753991465b 100644 --- a/components/engine/integration-cli/docker_cli_swarm_test.go +++ b/components/engine/integration-cli/docker_cli_swarm_test.go @@ -1691,22 +1691,23 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { d := s.AddDaemon(c, true, true) name1 := "top1" - out, err := d.Cmd("service", "create", "--no-resolve-image", "--detach=true", "--name", name1, "--replicas=3", "busybox", "top") - c.Assert(err, checker.IsNil) - c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") - id1 := strings.TrimSpace(out) + result := icmd.RunCmd(d.Command("service", "create", "--no-resolve-image", "--detach=true", "--name", name1, "--replicas=3", "busybox", "top")) + result.Assert(c, icmd.Success) + id1 := strings.TrimSpace(result.Stdout()) + c.Assert(id1, checker.Not(checker.Equals), "") name2 := "top2" - out, err = d.Cmd("service", "create", "--no-resolve-image", "--detach=true", "--name", name2, "--replicas=3", "busybox", "top") - c.Assert(err, checker.IsNil) - c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") - id2 := strings.TrimSpace(out) + result = icmd.RunCmd(d.Command("service", "create", "--no-resolve-image", "--detach=true", "--name", name2, "--replicas=3", "busybox", "top")) + result.Assert(c, icmd.Success) + id2 := strings.TrimSpace(result.Stdout()) + c.Assert(id2, checker.Not(checker.Equals), "") // make sure task has been deployed. waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 6) - out, err = d.Cmd("service", "ps", name1) - c.Assert(err, checker.IsNil) + result = icmd.RunCmd(d.Command("service", "ps", name1)) + result.Assert(c, icmd.Success) + out := result.Stdout() c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") @@ -1714,18 +1715,9 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { c.Assert(out, checker.Not(checker.Contains), name2+".2") c.Assert(out, checker.Not(checker.Contains), name2+".3") - out, err = d.Cmd("service", "ps", name1, name2) - c.Assert(err, checker.IsNil) - c.Assert(out, checker.Contains, name1+".1") - c.Assert(out, checker.Contains, name1+".2") - c.Assert(out, checker.Contains, name1+".3") - c.Assert(out, checker.Contains, name2+".1") - c.Assert(out, checker.Contains, name2+".2") - c.Assert(out, checker.Contains, name2+".3") - - // Name Prefix - out, err = d.Cmd("service", "ps", "to") - c.Assert(err, checker.IsNil) + result = icmd.RunCmd(d.Command("service", "ps", name1, name2)) + result.Assert(c, icmd.Success) + out = result.Stdout() c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") @@ -1734,12 +1726,15 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { c.Assert(out, checker.Contains, name2+".3") // Name Prefix (no hit) - out, err = d.Cmd("service", "ps", "noname") - c.Assert(err, checker.NotNil) - c.Assert(out, checker.Contains, "no such services: noname") + result = icmd.RunCmd(d.Command("service", "ps", "to")) + result.Assert(c, icmd.Expected{ + ExitCode: 1, + Err: "no such services: to", + }) - out, err = d.Cmd("service", "ps", id1) - c.Assert(err, checker.IsNil) + result = icmd.RunCmd(d.Command("service", "ps", id1)) + result.Assert(c, icmd.Success) + out = result.Stdout() c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3") @@ -1747,8 +1742,9 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) { c.Assert(out, checker.Not(checker.Contains), name2+".2") c.Assert(out, checker.Not(checker.Contains), name2+".3") - out, err = d.Cmd("service", "ps", id1, id2) - c.Assert(err, checker.IsNil) + result = icmd.RunCmd(d.Command("service", "ps", id1, id2)) + result.Assert(c, icmd.Success) + out = result.Stdout() c.Assert(out, checker.Contains, name1+".1") c.Assert(out, checker.Contains, name1+".2") c.Assert(out, checker.Contains, name1+".3")