github.com/justincormack/cli@v0.0.0-20201215022714-831ebeae9675/cli/command/stack/ps_test.go (about)

     1  package stack
     2  
     3  import (
     4  	"io/ioutil"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/docker/cli/cli/config/configfile"
     9  	"github.com/docker/cli/internal/test"
    10  	. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
    11  	"github.com/docker/docker/api/types"
    12  	"github.com/docker/docker/api/types/swarm"
    13  	"github.com/pkg/errors"
    14  	"gotest.tools/v3/assert"
    15  	is "gotest.tools/v3/assert/cmp"
    16  	"gotest.tools/v3/golden"
    17  )
    18  
    19  func TestStackPsErrors(t *testing.T) {
    20  	testCases := []struct {
    21  		args          []string
    22  		taskListFunc  func(options types.TaskListOptions) ([]swarm.Task, error)
    23  		expectedError string
    24  	}{
    25  
    26  		{
    27  			args:          []string{},
    28  			expectedError: "requires exactly 1 argument",
    29  		},
    30  		{
    31  			args:          []string{"foo", "bar"},
    32  			expectedError: "requires exactly 1 argument",
    33  		},
    34  		{
    35  			args: []string{"foo"},
    36  			taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
    37  				return nil, errors.Errorf("error getting tasks")
    38  			},
    39  			expectedError: "error getting tasks",
    40  		},
    41  	}
    42  
    43  	for _, tc := range testCases {
    44  		cmd := newPsCommand(test.NewFakeCli(&fakeClient{
    45  			taskListFunc: tc.taskListFunc,
    46  		}), &orchestrator)
    47  		cmd.SetArgs(tc.args)
    48  		cmd.SetOut(ioutil.Discard)
    49  		assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
    50  	}
    51  }
    52  
    53  func TestStackPs(t *testing.T) {
    54  	testCases := []struct {
    55  		doc                string
    56  		taskListFunc       func(types.TaskListOptions) ([]swarm.Task, error)
    57  		nodeInspectWithRaw func(string) (swarm.Node, []byte, error)
    58  		config             configfile.ConfigFile
    59  		args               []string
    60  		flags              map[string]string
    61  		expectedErr        string
    62  		golden             string
    63  	}{
    64  		{
    65  			doc:         "WithEmptyName",
    66  			args:        []string{"'   '"},
    67  			expectedErr: `invalid stack name: "'   '"`,
    68  		},
    69  		{
    70  			doc: "WithEmptyStack",
    71  			taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
    72  				return []swarm.Task{}, nil
    73  			},
    74  			args:        []string{"foo"},
    75  			expectedErr: "nothing found in stack: foo",
    76  		},
    77  		{
    78  			doc: "WithQuietOption",
    79  			taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
    80  				return []swarm.Task{*Task(TaskID("id-foo"))}, nil
    81  			},
    82  			args: []string{"foo"},
    83  			flags: map[string]string{
    84  				"quiet": "true",
    85  			},
    86  			golden: "stack-ps-with-quiet-option.golden",
    87  		},
    88  		{
    89  			doc: "WithNoTruncOption",
    90  			taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
    91  				return []swarm.Task{*Task(TaskID("xn4cypcov06f2w8gsbaf2lst3"))}, nil
    92  			},
    93  			args: []string{"foo"},
    94  			flags: map[string]string{
    95  				"no-trunc": "true",
    96  				"format":   "{{ .ID }}",
    97  			},
    98  			golden: "stack-ps-with-no-trunc-option.golden",
    99  		},
   100  		{
   101  			doc: "WithNoResolveOption",
   102  			taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
   103  				return []swarm.Task{*Task(
   104  					TaskNodeID("id-node-foo"),
   105  				)}, nil
   106  			},
   107  			nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
   108  				return *Node(NodeName("node-name-bar")), nil, nil
   109  			},
   110  			args: []string{"foo"},
   111  			flags: map[string]string{
   112  				"no-resolve": "true",
   113  				"format":     "{{ .Node }}",
   114  			},
   115  			golden: "stack-ps-with-no-resolve-option.golden",
   116  		},
   117  		{
   118  			doc: "WithFormat",
   119  			taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
   120  				return []swarm.Task{*Task(TaskServiceID("service-id-foo"))}, nil
   121  			},
   122  			args: []string{"foo"},
   123  			flags: map[string]string{
   124  				"format": "{{ .Name }}",
   125  			},
   126  			golden: "stack-ps-with-format.golden",
   127  		},
   128  		{
   129  			doc: "WithConfigFormat",
   130  			taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
   131  				return []swarm.Task{*Task(TaskServiceID("service-id-foo"))}, nil
   132  			},
   133  			config: configfile.ConfigFile{
   134  				TasksFormat: "{{ .Name }}",
   135  			},
   136  			args:   []string{"foo"},
   137  			golden: "stack-ps-with-config-format.golden",
   138  		},
   139  		{
   140  			doc: "WithoutFormat",
   141  			taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
   142  				return []swarm.Task{*Task(
   143  					TaskID("id-foo"),
   144  					TaskServiceID("service-id-foo"),
   145  					TaskNodeID("id-node"),
   146  					WithTaskSpec(TaskImage("myimage:mytag")),
   147  					TaskDesiredState(swarm.TaskStateReady),
   148  					WithStatus(TaskState(swarm.TaskStateFailed), Timestamp(time.Now().Add(-2*time.Hour))),
   149  				)}, nil
   150  			},
   151  			nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
   152  				return *Node(NodeName("node-name-bar")), nil, nil
   153  			},
   154  			args:   []string{"foo"},
   155  			golden: "stack-ps-without-format.golden",
   156  		},
   157  	}
   158  
   159  	for _, tc := range testCases {
   160  		t.Run(tc.doc, func(t *testing.T) {
   161  			cli := test.NewFakeCli(&fakeClient{
   162  				taskListFunc:       tc.taskListFunc,
   163  				nodeInspectWithRaw: tc.nodeInspectWithRaw,
   164  			})
   165  			cli.SetConfigFile(&tc.config)
   166  
   167  			cmd := newPsCommand(cli, &orchestrator)
   168  			cmd.SetArgs(tc.args)
   169  			for key, value := range tc.flags {
   170  				cmd.Flags().Set(key, value)
   171  			}
   172  			cmd.SetOut(ioutil.Discard)
   173  
   174  			if tc.expectedErr != "" {
   175  				assert.Error(t, cmd.Execute(), tc.expectedErr)
   176  				assert.Check(t, is.Equal("", cli.OutBuffer().String()))
   177  				return
   178  			}
   179  			assert.NilError(t, cmd.Execute())
   180  			golden.Assert(t, cli.OutBuffer().String(), tc.golden)
   181  		})
   182  	}
   183  }