Skip to content

Commit fa143c6

Browse files
committed
add tests
1 parent 4a3131d commit fa143c6

File tree

4 files changed

+210
-3
lines changed

4 files changed

+210
-3
lines changed

hack/make-rules/test-cmd-util.sh

+7
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,13 @@ run_pod_tests() {
430430
kubectl create -f test/fixtures/doc-yaml/admin/limitrange/valid-pod.yaml "${kube_flags[@]}"
431431
# Post-condition: valid-pod POD is created
432432
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
433+
# Command
434+
output_message=$(kubectl get pods --field-selector metadata.name=valid-pod "${kube_flags[@]}")
435+
kube::test::if_has_string "${output_message}" "valid-pod"
436+
# Command
437+
phase=$(kubectl get "${kube_flags[@]}" pod valid-pod -o go-template='{{ .status.phase }}')
438+
output_message=$(kubectl get pods --field-selector status.phase="${phase}" "${kube_flags[@]}")
439+
kube::test::if_has_string "${output_message}" "valid-pod"
433440

434441
### Delete PODs with no parameter mustn't kill everything
435442
# Pre-condition: valid-pod POD exists

pkg/kubectl/cmd/resource/get_test.go

+93-2
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,7 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) {
825825
}
826826
}
827827

828-
func TestGetMultipleTypeObjectsWithSelector(t *testing.T) {
828+
func TestGetMultipleTypeObjectsWithLabelSelector(t *testing.T) {
829829
pods, svc, _ := testData()
830830

831831
f, tf, codec, _ := cmdtesting.NewAPIFactory()
@@ -868,6 +868,49 @@ func TestGetMultipleTypeObjectsWithSelector(t *testing.T) {
868868
}
869869
}
870870

871+
func TestGetMultipleTypeObjectsWithFieldSelector(t *testing.T) {
872+
pods, svc, _ := testData()
873+
874+
f, tf, codec, _ := cmdtesting.NewAPIFactory()
875+
tf.Printer = &testPrinter{}
876+
tf.UnstructuredClient = &fake.RESTClient{
877+
NegotiatedSerializer: unstructuredSerializer,
878+
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
879+
if req.URL.Query().Get(metav1.FieldSelectorQueryParam("v1")) != "a=b" {
880+
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
881+
}
882+
switch req.URL.Path {
883+
case "/namespaces/test/pods":
884+
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, pods)}, nil
885+
case "/namespaces/test/services":
886+
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, svc)}, nil
887+
default:
888+
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
889+
return nil, nil
890+
}
891+
}),
892+
}
893+
tf.Namespace = "test"
894+
buf := bytes.NewBuffer([]byte{})
895+
errBuf := bytes.NewBuffer([]byte{})
896+
897+
cmd := NewCmdGet(f, buf, errBuf)
898+
cmd.SetOutput(buf)
899+
900+
cmd.Flags().Set("field-selector", "a=b")
901+
cmd.Run(cmd, []string{"pods,services"})
902+
903+
expected, err := extractResourceList([]runtime.Object{pods, svc})
904+
if err != nil {
905+
t.Fatal(err)
906+
}
907+
verifyObjects(t, expected, tf.Printer.(*testPrinter).Objects)
908+
909+
if len(buf.String()) == 0 {
910+
t.Errorf("unexpected empty output")
911+
}
912+
}
913+
871914
func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) {
872915
_, svc, _ := testData()
873916
node := &api.Node{
@@ -1006,7 +1049,7 @@ func watchTestData() ([]api.Pod, []watch.Event) {
10061049
return pods, events
10071050
}
10081051

1009-
func TestWatchSelector(t *testing.T) {
1052+
func TestWatchLabelSelector(t *testing.T) {
10101053
pods, events := watchTestData()
10111054

10121055
f, tf, codec, _ := cmdtesting.NewAPIFactory()
@@ -1054,6 +1097,54 @@ func TestWatchSelector(t *testing.T) {
10541097
}
10551098
}
10561099

1100+
func TestWatchFieldSelector(t *testing.T) {
1101+
pods, events := watchTestData()
1102+
1103+
f, tf, codec, _ := cmdtesting.NewAPIFactory()
1104+
tf.Printer = &testPrinter{}
1105+
podList := &api.PodList{
1106+
Items: pods,
1107+
ListMeta: metav1.ListMeta{
1108+
ResourceVersion: "10",
1109+
},
1110+
}
1111+
tf.UnstructuredClient = &fake.RESTClient{
1112+
NegotiatedSerializer: unstructuredSerializer,
1113+
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
1114+
if req.URL.Query().Get(metav1.FieldSelectorQueryParam("v1")) != "a=b" {
1115+
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
1116+
}
1117+
switch req.URL.Path {
1118+
case "/namespaces/test/pods":
1119+
if req.URL.Query().Get("watch") == "true" {
1120+
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: watchBody(codec, events[2:])}, nil
1121+
}
1122+
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, podList)}, nil
1123+
default:
1124+
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
1125+
return nil, nil
1126+
}
1127+
}),
1128+
}
1129+
tf.Namespace = "test"
1130+
buf := bytes.NewBuffer([]byte{})
1131+
errBuf := bytes.NewBuffer([]byte{})
1132+
1133+
cmd := NewCmdGet(f, buf, errBuf)
1134+
cmd.SetOutput(buf)
1135+
1136+
cmd.Flags().Set("watch", "true")
1137+
cmd.Flags().Set("field-selector", "a=b")
1138+
cmd.Run(cmd, []string{"pods"})
1139+
1140+
expected := []runtime.Object{&pods[0], &pods[1], events[2].Object, events[3].Object}
1141+
verifyObjects(t, expected, tf.Printer.(*testPrinter).Objects)
1142+
1143+
if len(buf.String()) == 0 {
1144+
t.Errorf("unexpected empty output")
1145+
}
1146+
}
1147+
10571148
func TestWatchResource(t *testing.T) {
10581149
pods, events := watchTestData()
10591150

pkg/kubectl/resource/builder_test.go

+44-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ import (
4646
restclientwatch "k8s.io/client-go/rest/watch"
4747
utiltesting "k8s.io/client-go/util/testing"
4848
"k8s.io/kubernetes/pkg/kubectl/scheme"
49-
"k8s.io/kubernetes/pkg/api/legacyscheme"
5049
)
5150

5251
var (
@@ -763,6 +762,50 @@ func TestLabelSelectorRequiresKnownTypes(t *testing.T) {
763762
}
764763
}
765764

765+
func TestFieldSelector(t *testing.T) {
766+
pods, svc := testData()
767+
fieldKey := metav1.FieldSelectorQueryParam(corev1GV.String())
768+
b := NewBuilder(restmapper, LegacyCategoryExpander, scheme.Scheme, fakeClientWith("", t, map[string]string{
769+
"/namespaces/test/pods?" + fieldKey + "=a%3Db": runtime.EncodeOrDie(corev1Codec, pods),
770+
"/namespaces/test/services?" + fieldKey + "=a%3Db": runtime.EncodeOrDie(corev1Codec, svc),
771+
}), corev1Codec).
772+
FieldSelectorParam("a=b").
773+
NamespaceParam("test").
774+
Flatten()
775+
776+
test := &testVisitor{}
777+
singleItemImplied := false
778+
779+
if b.Do().Err() == nil {
780+
t.Errorf("unexpected non-error")
781+
}
782+
783+
b.ResourceTypeOrNameArgs(true, "pods,service")
784+
785+
err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle)
786+
if err != nil || singleItemImplied || len(test.Infos) != 3 {
787+
t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos)
788+
}
789+
if !apiequality.Semantic.DeepDerivative([]runtime.Object{&pods.Items[0], &pods.Items[1], &svc.Items[0]}, test.Objects()) {
790+
t.Errorf("unexpected visited objects: %#v", test.Objects())
791+
}
792+
793+
if _, err := b.Do().ResourceMapping(); err == nil {
794+
t.Errorf("unexpected non-error")
795+
}
796+
}
797+
798+
func TestFieldSelectorRequiresKnownTypes(t *testing.T) {
799+
b := NewBuilder(restmapper, LegacyCategoryExpander, scheme.Scheme, fakeClient(), corev1Codec).
800+
FieldSelectorParam("a=b").
801+
NamespaceParam("test").
802+
ResourceTypes("unknown")
803+
804+
if b.Do().Err() == nil {
805+
t.Errorf("unexpected non-error")
806+
}
807+
}
808+
766809
func TestSingleResourceType(t *testing.T) {
767810
b := NewBuilder(restmapper, LegacyCategoryExpander, scheme.Scheme, fakeClient(), corev1Codec).
768811
LabelSelectorParam("a=b").

pkg/kubectl/resource/helper_test.go

+66
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,72 @@ func TestHelperList(t *testing.T) {
385385
}
386386
}
387387

388+
func TestHelperListSelectorCombination(t *testing.T) {
389+
tests := []struct {
390+
Name string
391+
Err bool
392+
ErrMsg string
393+
FieldSelector string
394+
LabelSelector string
395+
}{
396+
{
397+
Name: "No selector",
398+
Err: false,
399+
},
400+
{
401+
Name: "Only Label Selector",
402+
Err: false,
403+
LabelSelector: "foo=baz",
404+
},
405+
{
406+
Name: "Only Field Selector",
407+
Err: false,
408+
FieldSelector: "xyz=zyx",
409+
},
410+
{
411+
Name: "Both Label and Field Selector",
412+
Err: false,
413+
LabelSelector: "foo=baz",
414+
FieldSelector: "xyz=zyx",
415+
},
416+
}
417+
418+
resp := &http.Response{
419+
StatusCode: http.StatusOK,
420+
Header: header(),
421+
Body: objBody(&corev1.PodList{
422+
Items: []corev1.Pod{{
423+
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
424+
},
425+
},
426+
}),
427+
}
428+
client := &fake.RESTClient{
429+
NegotiatedSerializer: scheme.Codecs,
430+
Resp: resp,
431+
Err: nil,
432+
}
433+
modifier := &Helper{
434+
RESTClient: client,
435+
NamespaceScoped: true,
436+
}
437+
438+
for _, test := range tests {
439+
_, err := modifier.List("bar",
440+
corev1GV.String(),
441+
false,
442+
&metav1.ListOptions{LabelSelector: test.LabelSelector, FieldSelector: test.FieldSelector})
443+
if test.Err {
444+
if err == nil {
445+
t.Errorf("%q expected error: %q", test.Name, test.ErrMsg)
446+
}
447+
if err != nil && err.Error() != test.ErrMsg {
448+
t.Errorf("%q expected error: %q", test.Name, test.ErrMsg)
449+
}
450+
}
451+
}
452+
}
453+
388454
func TestHelperReplace(t *testing.T) {
389455
expectPut := func(path string, req *http.Request) bool {
390456
if req.Method != "PUT" {

0 commit comments

Comments
 (0)