diff --git a/cli/command/task/client_test.go b/cli/command/task/client_test.go new file mode 100644 index 0000000000..d04405c236 --- /dev/null +++ b/cli/command/task/client_test.go @@ -0,0 +1,28 @@ +package task + +import ( + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/client" + "golang.org/x/net/context" +) + +type fakeClient struct { + client.APIClient + nodeInspectWithRaw func(ref string) (swarm.Node, []byte, error) + serviceInspectWithRaw func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) +} + +func (cli *fakeClient) NodeInspectWithRaw(ctx context.Context, ref string) (swarm.Node, []byte, error) { + if cli.nodeInspectWithRaw != nil { + return cli.nodeInspectWithRaw(ref) + } + return swarm.Node{}, nil, nil +} + +func (cli *fakeClient) ServiceInspectWithRaw(ctx context.Context, ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) { + if cli.serviceInspectWithRaw != nil { + return cli.serviceInspectWithRaw(ref, options) + } + return swarm.Service{}, nil, nil +} diff --git a/cli/command/task/print_test.go b/cli/command/task/print_test.go new file mode 100644 index 0000000000..93171016f2 --- /dev/null +++ b/cli/command/task/print_test.go @@ -0,0 +1,150 @@ +package task + +import ( + "bytes" + "testing" + "time" + + "github.com/docker/cli/cli/command/formatter" + "github.com/docker/cli/cli/command/idresolver" + "github.com/docker/cli/cli/internal/test" + "golang.org/x/net/context" + // Import builders to get the builder function as package function + . "github.com/docker/cli/cli/internal/test/builders" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/pkg/testutil" + "github.com/docker/docker/pkg/testutil/golden" + "github.com/stretchr/testify/assert" +) + +func TestTaskPrintWithQuietOption(t *testing.T) { + quiet := true + trunc := false + noResolve := true + buf := new(bytes.Buffer) + apiClient := &fakeClient{} + cli := test.NewFakeCli(apiClient, buf) + tasks := []swarm.Task{ + *Task(TaskID("id-foo")), + } + err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, formatter.TableFormatKey) + assert.NoError(t, err) + actual := buf.String() + expected := golden.Get(t, []byte(actual), "task-print-with-quiet-option.golden") + testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) +} + +func TestTaskPrintWithNoTruncOption(t *testing.T) { + quiet := false + trunc := false + noResolve := true + buf := new(bytes.Buffer) + apiClient := &fakeClient{} + cli := test.NewFakeCli(apiClient, buf) + tasks := []swarm.Task{ + *Task(TaskID("id-foo-yov6omdek8fg3k5stosyp2m50")), + } + err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .ID }}") + assert.NoError(t, err) + actual := buf.String() + expected := golden.Get(t, []byte(actual), "task-print-with-no-trunc-option.golden") + testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) +} + +func TestTaskPrintWithGlobalService(t *testing.T) { + quiet := false + trunc := false + noResolve := true + buf := new(bytes.Buffer) + apiClient := &fakeClient{} + cli := test.NewFakeCli(apiClient, buf) + tasks := []swarm.Task{ + *Task(TaskServiceID("service-id-foo"), TaskNodeID("node-id-bar"), TaskSlot(0)), + } + err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .Name }}") + assert.NoError(t, err) + actual := buf.String() + expected := golden.Get(t, []byte(actual), "task-print-with-global-service.golden") + testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) +} + +func TestTaskPrintWithReplicatedService(t *testing.T) { + quiet := false + trunc := false + noResolve := true + buf := new(bytes.Buffer) + apiClient := &fakeClient{} + cli := test.NewFakeCli(apiClient, buf) + tasks := []swarm.Task{ + *Task(TaskServiceID("service-id-foo"), TaskSlot(1)), + } + err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .Name }}") + assert.NoError(t, err) + actual := buf.String() + expected := golden.Get(t, []byte(actual), "task-print-with-replicated-service.golden") + testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) +} + +func TestTaskPrintWithIndentation(t *testing.T) { + quiet := false + trunc := false + noResolve := false + buf := new(bytes.Buffer) + apiClient := &fakeClient{ + serviceInspectWithRaw: func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) { + return *Service(ServiceName("service-name-foo")), nil, nil + }, + nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) { + return *Node(NodeName("node-name-bar")), nil, nil + }, + } + cli := test.NewFakeCli(apiClient, buf) + tasks := []swarm.Task{ + *Task( + TaskID("id-foo"), + TaskServiceID("service-id-foo"), + TaskNodeID("id-node"), + WithTaskSpec(TaskImage("myimage:mytag")), + TaskDesiredState(swarm.TaskStateReady), + WithStatus(TaskState(swarm.TaskStateFailed), Timestamp(time.Now().Add(-2*time.Hour))), + ), + *Task( + TaskID("id-bar"), + TaskServiceID("service-id-foo"), + TaskNodeID("id-node"), + WithTaskSpec(TaskImage("myimage:mytag")), + TaskDesiredState(swarm.TaskStateReady), + WithStatus(TaskState(swarm.TaskStateFailed), Timestamp(time.Now().Add(-2*time.Hour))), + ), + } + err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, formatter.TableFormatKey) + assert.NoError(t, err) + actual := buf.String() + expected := golden.Get(t, []byte(actual), "task-print-with-indentation.golden") + testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) +} + +func TestTaskPrintWithResolution(t *testing.T) { + quiet := false + trunc := false + noResolve := false + buf := new(bytes.Buffer) + apiClient := &fakeClient{ + serviceInspectWithRaw: func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) { + return *Service(ServiceName("service-name-foo")), nil, nil + }, + nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) { + return *Node(NodeName("node-name-bar")), nil, nil + }, + } + cli := test.NewFakeCli(apiClient, buf) + tasks := []swarm.Task{ + *Task(TaskServiceID("service-id-foo"), TaskSlot(1)), + } + err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .Name }} {{ .Node }}") + assert.NoError(t, err) + actual := buf.String() + expected := golden.Get(t, []byte(actual), "task-print-with-resolution.golden") + testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) +} diff --git a/cli/command/task/testdata/task-print-with-global-service.golden b/cli/command/task/testdata/task-print-with-global-service.golden new file mode 100644 index 0000000000..fbc81248dd --- /dev/null +++ b/cli/command/task/testdata/task-print-with-global-service.golden @@ -0,0 +1 @@ +service-id-foo.node-id-bar diff --git a/cli/command/task/testdata/task-print-with-indentation.golden b/cli/command/task/testdata/task-print-with-indentation.golden new file mode 100644 index 0000000000..932126ad94 --- /dev/null +++ b/cli/command/task/testdata/task-print-with-indentation.golden @@ -0,0 +1,3 @@ +ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS +id-foo service-name-foo.1 myimage:mytag node-name-bar Ready Failed 2 hours ago +id-bar \_ service-name-foo.1 myimage:mytag node-name-bar Ready Failed 2 hours ago diff --git a/cli/command/task/testdata/task-print-with-no-trunc-option.golden b/cli/command/task/testdata/task-print-with-no-trunc-option.golden new file mode 100644 index 0000000000..184d2de201 --- /dev/null +++ b/cli/command/task/testdata/task-print-with-no-trunc-option.golden @@ -0,0 +1 @@ +id-foo-yov6omdek8fg3k5stosyp2m50 diff --git a/cli/command/task/testdata/task-print-with-quiet-option.golden b/cli/command/task/testdata/task-print-with-quiet-option.golden new file mode 100644 index 0000000000..e2faeb6067 --- /dev/null +++ b/cli/command/task/testdata/task-print-with-quiet-option.golden @@ -0,0 +1 @@ +id-foo diff --git a/cli/command/task/testdata/task-print-with-replicated-service.golden b/cli/command/task/testdata/task-print-with-replicated-service.golden new file mode 100644 index 0000000000..9ecebdafe3 --- /dev/null +++ b/cli/command/task/testdata/task-print-with-replicated-service.golden @@ -0,0 +1 @@ +service-id-foo.1 diff --git a/cli/command/task/testdata/task-print-with-resolution.golden b/cli/command/task/testdata/task-print-with-resolution.golden new file mode 100644 index 0000000000..747d1af462 --- /dev/null +++ b/cli/command/task/testdata/task-print-with-resolution.golden @@ -0,0 +1 @@ +service-name-foo.1 node-name-bar diff --git a/cli/internal/test/builders/task.go b/cli/internal/test/builders/task.go index b4551c983b..479b6f14c5 100644 --- a/cli/internal/test/builders/task.go +++ b/cli/internal/test/builders/task.go @@ -70,6 +70,13 @@ func TaskDesiredState(state swarm.TaskState) func(*swarm.Task) { } } +// TaskSlot sets the task's slot +func TaskSlot(slot int) func(*swarm.Task) { + return func(task *swarm.Task) { + task.Slot = slot + } +} + // WithStatus sets the task status func WithStatus(statusBuilders ...func(*swarm.TaskStatus)) func(*swarm.Task) { return func(task *swarm.Task) {