1
16
17 package completion
18
19 import (
20 "net/http"
21 "sort"
22 "testing"
23
24 "github.com/spf13/cobra"
25
26 "k8s.io/cli-runtime/pkg/genericiooptions"
27 "k8s.io/cli-runtime/pkg/resource"
28 "k8s.io/client-go/rest/fake"
29 "k8s.io/client-go/tools/clientcmd"
30 "k8s.io/client-go/tools/clientcmd/api"
31 "k8s.io/kubectl/pkg/cmd/get"
32 cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
33 "k8s.io/kubectl/pkg/scheme"
34 )
35
36 func TestClusterCompletionFunc(t *testing.T) {
37 setMockFactory(api.Config{
38 Clusters: map[string]*api.Cluster{
39 "bar": {},
40 "baz": {},
41 "foo": {},
42 },
43 })
44
45 comps, directive := ClusterCompletionFunc(nil, []string{}, "")
46 checkCompletion(t, comps, []string{"bar", "baz", "foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
47
48 comps, directive = ClusterCompletionFunc(nil, []string{}, "b")
49 checkCompletion(t, comps, []string{"bar", "baz"}, directive, cobra.ShellCompDirectiveNoFileComp)
50
51 comps, directive = ClusterCompletionFunc(nil, []string{}, "ba")
52 checkCompletion(t, comps, []string{"bar", "baz"}, directive, cobra.ShellCompDirectiveNoFileComp)
53
54 comps, directive = ClusterCompletionFunc(nil, []string{}, "bar")
55 checkCompletion(t, comps, []string{"bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
56
57 comps, directive = ClusterCompletionFunc(nil, []string{}, "bart")
58 checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
59 }
60
61 func TestContextCompletionFunc(t *testing.T) {
62 setMockFactory(api.Config{
63 Contexts: map[string]*api.Context{
64 "bar": {},
65 "baz": {},
66 "foo": {},
67 },
68 })
69
70 comps, directive := ContextCompletionFunc(nil, []string{}, "")
71 checkCompletion(t, comps, []string{"bar", "baz", "foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
72
73 comps, directive = ContextCompletionFunc(nil, []string{}, "b")
74 checkCompletion(t, comps, []string{"bar", "baz"}, directive, cobra.ShellCompDirectiveNoFileComp)
75
76 comps, directive = ContextCompletionFunc(nil, []string{}, "ba")
77 checkCompletion(t, comps, []string{"bar", "baz"}, directive, cobra.ShellCompDirectiveNoFileComp)
78
79 comps, directive = ContextCompletionFunc(nil, []string{}, "bar")
80 checkCompletion(t, comps, []string{"bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
81
82 comps, directive = ContextCompletionFunc(nil, []string{}, "bart")
83 checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
84 }
85
86 func TestUserCompletionFunc(t *testing.T) {
87 setMockFactory(api.Config{
88 AuthInfos: map[string]*api.AuthInfo{
89 "bar": {},
90 "baz": {},
91 "foo": {},
92 },
93 })
94
95 comps, directive := UserCompletionFunc(nil, []string{}, "")
96 checkCompletion(t, comps, []string{"bar", "baz", "foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
97
98 comps, directive = UserCompletionFunc(nil, []string{}, "b")
99 checkCompletion(t, comps, []string{"bar", "baz"}, directive, cobra.ShellCompDirectiveNoFileComp)
100
101 comps, directive = UserCompletionFunc(nil, []string{}, "ba")
102 checkCompletion(t, comps, []string{"bar", "baz"}, directive, cobra.ShellCompDirectiveNoFileComp)
103
104 comps, directive = UserCompletionFunc(nil, []string{}, "bar")
105 checkCompletion(t, comps, []string{"bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
106
107 comps, directive = UserCompletionFunc(nil, []string{}, "bart")
108 checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
109 }
110
111 func TestResourceTypeAndNameCompletionFuncOneArg(t *testing.T) {
112 tf, cmd := prepareCompletionTest()
113 addPodsToFactory(tf)
114
115 compFunc := ResourceTypeAndNameCompletionFunc(tf)
116 comps, directive := compFunc(cmd, []string{"pod"}, "b")
117 checkCompletion(t, comps, []string{"bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
118 }
119
120 func TestResourceTypeAndNameCompletionFuncRepeating(t *testing.T) {
121 tf, cmd := prepareCompletionTest()
122 addPodsToFactory(tf)
123
124 compFunc := ResourceTypeAndNameCompletionFunc(tf)
125 comps, directive := compFunc(cmd, []string{"pod", "bar"}, "")
126
127 checkCompletion(t, comps, []string{"foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
128 }
129
130 func TestResourceTypeAndNameCompletionFuncJointForm(t *testing.T) {
131 tf, cmd := prepareCompletionTest()
132 addPodsToFactory(tf)
133
134 compFunc := ResourceTypeAndNameCompletionFunc(tf)
135 comps, directive := compFunc(cmd, []string{}, "pod/b")
136 checkCompletion(t, comps, []string{"pod/bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
137 }
138
139 func TestResourceTypeAndNameCompletionFuncJointFormRepeating(t *testing.T) {
140 tf, cmd := prepareCompletionTest()
141 addPodsToFactory(tf)
142
143 compFunc := ResourceTypeAndNameCompletionFunc(tf)
144 comps, directive := compFunc(cmd, []string{"pod/bar"}, "pod/")
145
146 checkCompletion(t, comps, []string{"pod/foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
147 }
148
149 func TestSpecifiedResourceTypeAndNameCompletionFuncNoArgs(t *testing.T) {
150 tf, cmd := prepareCompletionTest()
151 addPodsToFactory(tf)
152
153 compFunc := SpecifiedResourceTypeAndNameCompletionFunc(tf, []string{"pod", "service", "statefulset"})
154 comps, directive := compFunc(cmd, []string{}, "s")
155 checkCompletion(t, comps, []string{"service", "statefulset"}, directive, cobra.ShellCompDirectiveNoFileComp)
156 }
157
158 func TestSpecifiedResourceTypeAndNameCompletionFuncOneArg(t *testing.T) {
159 tf, cmd := prepareCompletionTest()
160 addPodsToFactory(tf)
161
162 compFunc := SpecifiedResourceTypeAndNameCompletionFunc(tf, []string{"pod"})
163 comps, directive := compFunc(cmd, []string{"pod"}, "b")
164 checkCompletion(t, comps, []string{"bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
165 }
166
167 func TestSpecifiedResourceTypeAndNameCompletionFuncRepeating(t *testing.T) {
168 tf, cmd := prepareCompletionTest()
169 addPodsToFactory(tf)
170
171 compFunc := SpecifiedResourceTypeAndNameCompletionFunc(tf, []string{"pod"})
172 comps, directive := compFunc(cmd, []string{"pod", "bar"}, "")
173
174 checkCompletion(t, comps, []string{"foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
175 }
176
177 func TestSpecifiedResourceTypeAndNameCompletionFuncJointFormOneArg(t *testing.T) {
178 tf, cmd := prepareCompletionTest()
179 addPodsToFactory(tf)
180
181 compFunc := SpecifiedResourceTypeAndNameCompletionFunc(tf, []string{"pod"})
182 comps, directive := compFunc(cmd, []string{}, "pod/b")
183 checkCompletion(t, comps, []string{"pod/bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
184 }
185
186 func TestSpecifiedResourceTypeAndNameCompletionFuncJointFormRepeating(t *testing.T) {
187 tf, cmd := prepareCompletionTest()
188 addPodsToFactory(tf)
189
190 compFunc := SpecifiedResourceTypeAndNameCompletionFunc(tf, []string{"pod"})
191 comps, directive := compFunc(cmd, []string{"pod/bar"}, "pod/")
192
193 checkCompletion(t, comps, []string{"pod/foo"}, directive, cobra.ShellCompDirectiveNoFileComp)
194 }
195 func TestSpecifiedResourceTypeAndNameCompletionNoRepeatFuncOneArg(t *testing.T) {
196 tf, cmd := prepareCompletionTest()
197 addPodsToFactory(tf)
198
199 compFunc := SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(tf, []string{"pod"})
200 comps, directive := compFunc(cmd, []string{"pod"}, "b")
201 checkCompletion(t, comps, []string{"bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
202 }
203
204 func TestSpecifiedResourceTypeAndNameCompletionNoRepeatFuncMultiArg(t *testing.T) {
205 tf, cmd := prepareCompletionTest()
206 addPodsToFactory(tf)
207
208 compFunc := SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(tf, []string{"pod"})
209 comps, directive := compFunc(cmd, []string{"pod", "bar"}, "")
210
211 checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
212 }
213
214 func TestSpecifiedResourceTypeAndNameCompletionNoRepeatFuncJointFormOneArg(t *testing.T) {
215 tf, cmd := prepareCompletionTest()
216 addPodsToFactory(tf)
217
218 compFunc := SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(tf, []string{"pod"})
219 comps, directive := compFunc(cmd, []string{}, "pod/b")
220 checkCompletion(t, comps, []string{"pod/bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
221 }
222
223 func TestSpecifiedResourceTypeAndNameCompletionNoRepeatFuncJointFormMultiArg(t *testing.T) {
224 tf, cmd := prepareCompletionTest()
225 addPodsToFactory(tf)
226
227 compFunc := SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(tf, []string{"pod"})
228 comps, directive := compFunc(cmd, []string{"pod/bar"}, "pod/")
229
230 checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
231 }
232
233 func TestResourceNameCompletionFuncNoArgs(t *testing.T) {
234 tf, cmd := prepareCompletionTest()
235 addPodsToFactory(tf)
236
237 compFunc := ResourceNameCompletionFunc(tf, "pod")
238 comps, directive := compFunc(cmd, []string{}, "b")
239 checkCompletion(t, comps, []string{"bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
240 }
241
242 func TestResourceNameCompletionFuncTooManyArgs(t *testing.T) {
243 tf, cmd := prepareCompletionTest()
244 addPodsToFactory(tf)
245
246 compFunc := ResourceNameCompletionFunc(tf, "pod")
247 comps, directive := compFunc(cmd, []string{"pod-name"}, "")
248 checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
249 }
250
251 func TestResourceNameCompletionFuncJointFormNoArgs(t *testing.T) {
252 tf, cmd := prepareCompletionTest()
253 addPodsToFactory(tf)
254
255 compFunc := ResourceNameCompletionFunc(tf, "pod")
256 comps, directive := compFunc(cmd, []string{}, "pod/b")
257
258 checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
259 }
260
261 func TestPodResourceNameCompletionFuncNoArgsPodName(t *testing.T) {
262 tf, cmd := prepareCompletionTest()
263 addPodsToFactory(tf)
264
265 compFunc := PodResourceNameCompletionFunc(tf)
266 comps, directive := compFunc(cmd, []string{}, "b")
267 checkCompletion(t, comps, []string{"bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
268 }
269
270 func TestPodResourceNameCompletionFuncNoArgsResources(t *testing.T) {
271 tf, cmd := prepareCompletionTest()
272 addPodsToFactory(tf)
273
274 compFunc := PodResourceNameCompletionFunc(tf)
275 comps, directive := compFunc(cmd, []string{}, "d")
276 checkCompletion(
277 t, comps, []string{"daemonsets/", "deployments/"},
278 directive, cobra.ShellCompDirectiveNoFileComp|cobra.ShellCompDirectiveNoSpace)
279 }
280
281 func TestPodResourceNameCompletionFuncTooManyArgs(t *testing.T) {
282 tf, cmd := prepareCompletionTest()
283 addPodsToFactory(tf)
284
285 compFunc := PodResourceNameCompletionFunc(tf)
286 comps, directive := compFunc(cmd, []string{"pod-name"}, "")
287 checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
288 }
289
290 func TestPodResourceNameCompletionFuncJointFormNoArgs(t *testing.T) {
291 tf, cmd := prepareCompletionTest()
292 addPodsToFactory(tf)
293
294 compFunc := PodResourceNameCompletionFunc(tf)
295 comps, directive := compFunc(cmd, []string{}, "pod/b")
296
297 checkCompletion(t, comps, []string{"pod/bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
298 }
299
300 func TestPodResourceNameCompletionFuncJointFormTooManyArgs(t *testing.T) {
301 tf, cmd := prepareCompletionTest()
302 addPodsToFactory(tf)
303
304 compFunc := PodResourceNameCompletionFunc(tf)
305 comps, directive := compFunc(cmd, []string{"pod/name"}, "pod/b")
306 checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
307 }
308
309 func TestPodResourceNameAndContainerCompletionFuncNoArgsPodName(t *testing.T) {
310 tf, cmd := prepareCompletionTest()
311 addPodsToFactory(tf)
312
313 compFunc := PodResourceNameAndContainerCompletionFunc(tf)
314 comps, directive := compFunc(cmd, []string{}, "b")
315 checkCompletion(t, comps, []string{"bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
316 }
317
318 func TestPodResourceNameAndContainerCompletionFuncNoArgsResources(t *testing.T) {
319 tf, cmd := prepareCompletionTest()
320 addPodsToFactory(tf)
321
322 compFunc := PodResourceNameAndContainerCompletionFunc(tf)
323 comps, directive := compFunc(cmd, []string{}, "s")
324 checkCompletion(
325 t, comps, []string{"services/", "statefulsets/"},
326 directive, cobra.ShellCompDirectiveNoFileComp|cobra.ShellCompDirectiveNoSpace)
327
328 }
329
330 func TestPodResourceNameAndContainerCompletionFuncTooManyArgs(t *testing.T) {
331 tf, cmd := prepareCompletionTest()
332 addPodsToFactory(tf)
333
334 compFunc := PodResourceNameAndContainerCompletionFunc(tf)
335 comps, directive := compFunc(cmd, []string{"pod-name", "container-name"}, "")
336 checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
337 }
338
339 func TestPodResourceNameAndContainerCompletionFuncJointFormNoArgs(t *testing.T) {
340 tf, cmd := prepareCompletionTest()
341 addPodsToFactory(tf)
342
343 compFunc := PodResourceNameAndContainerCompletionFunc(tf)
344 comps, directive := compFunc(cmd, []string{}, "pod/b")
345 checkCompletion(t, comps, []string{"pod/bar"}, directive, cobra.ShellCompDirectiveNoFileComp)
346 }
347
348 func TestPodResourceNameAndContainerCompletionFuncJointFormTooManyArgs(t *testing.T) {
349 tf, cmd := prepareCompletionTest()
350 addPodsToFactory(tf)
351
352 compFunc := PodResourceNameAndContainerCompletionFunc(tf)
353 comps, directive := compFunc(cmd, []string{"pod/pod-name", "container-name"}, "")
354 checkCompletion(t, comps, []string{}, directive, cobra.ShellCompDirectiveNoFileComp)
355 }
356
357 func setMockFactory(config api.Config) {
358 clientConfig := clientcmd.NewDefaultClientConfig(config, nil)
359 testFactory := cmdtesting.NewTestFactory().WithClientConfig(clientConfig)
360 SetFactoryForCompletion(testFactory)
361 }
362
363 func prepareCompletionTest() (*cmdtesting.TestFactory, *cobra.Command) {
364 tf := cmdtesting.NewTestFactory().WithNamespace("test")
365 defer tf.Cleanup()
366
367 streams, _, _, _ := genericiooptions.NewTestIOStreams()
368 cmd := get.NewCmdGet("kubectl", tf, streams)
369 return tf, cmd
370 }
371
372 func addPodsToFactory(tf *cmdtesting.TestFactory) {
373 pods, _, _ := cmdtesting.TestData()
374 codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
375 tf.UnstructuredClient = &fake.RESTClient{
376 NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
377 Resp: &http.Response{StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, pods)},
378 }
379 }
380
381 func checkCompletion(t *testing.T, comps, expectedComps []string, directive, expectedDirective cobra.ShellCompDirective) {
382 if e, d := expectedDirective, directive; e != d {
383 t.Errorf("expected directive\n%v\nbut got\n%v", e, d)
384 }
385
386 sort.Strings(comps)
387 sort.Strings(expectedComps)
388
389 if len(expectedComps) != len(comps) {
390 t.Fatalf("expected completions\n%v\nbut got\n%v", expectedComps, comps)
391 }
392
393 for i := range comps {
394 if expectedComps[i] != comps[i] {
395 t.Errorf("expected completions\n%v\nbut got\n%v", expectedComps, comps)
396 break
397 }
398 }
399 }
400
View as plain text