github.1git.de/docker/cli@v26.1.3+incompatible/cli/command/stack/ps_test.go (about)

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