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 }