diff --git a/pkg/printers/internalversion/additional_printers_test.go b/pkg/printers/internalversion/additional_printers_test.go index 0e5057b452e..6c1002b80ee 100644 --- a/pkg/printers/internalversion/additional_printers_test.go +++ b/pkg/printers/internalversion/additional_printers_test.go @@ -202,22 +202,6 @@ func TestPrintHandlerError(t *testing.T) { } } -func TestTemplatePanic(t *testing.T) { - tmpl := `{{and ((index .currentState.info "foo").state.running.startedAt) .currentState.info.net.state.running.startedAt}}` - printer, err := genericprinters.NewGoTemplatePrinter([]byte(tmpl)) - if err != nil { - t.Fatalf("tmpl fail: %v", err) - } - buffer := &bytes.Buffer{} - err = printer.PrintObj(&v1.Pod{}, buffer) - if err == nil { - t.Fatalf("expected that template to crash") - } - if buffer.String() == "" { - t.Errorf("no debugging info was printed") - } -} - func TestNamePrinter(t *testing.T) { tests := map[string]struct { obj runtime.Object @@ -274,145 +258,15 @@ func TestNamePrinter(t *testing.T) { } } -// TODO(seans3): Move this test to cli-runtime/pkg/printers. -func TestTemplateStrings(t *testing.T) { - // This unit tests the "exists" function as well as the template from update.sh - table := map[string]struct { - pod v1.Pod - expect string - }{ - "nilInfo": {v1.Pod{}, "false"}, - "emptyInfo": {v1.Pod{Status: v1.PodStatus{ContainerStatuses: []v1.ContainerStatus{}}}, "false"}, - "fooExists": { - v1.Pod{ - Status: v1.PodStatus{ - ContainerStatuses: []v1.ContainerStatus{ - { - Name: "foo", - }, - }, - }, - }, - "false", - }, - "barExists": { - v1.Pod{ - Status: v1.PodStatus{ - ContainerStatuses: []v1.ContainerStatus{ - { - Name: "bar", - }, - }, - }, - }, - "false", - }, - "bothExist": { - v1.Pod{ - Status: v1.PodStatus{ - ContainerStatuses: []v1.ContainerStatus{ - { - Name: "foo", - }, - { - Name: "bar", - }, - }, - }, - }, - "false", - }, - "barValid": { - v1.Pod{ - Status: v1.PodStatus{ - ContainerStatuses: []v1.ContainerStatus{ - { - Name: "foo", - }, - { - Name: "bar", - State: v1.ContainerState{ - Running: &v1.ContainerStateRunning{ - StartedAt: metav1.Time{}, - }, - }, - }, - }, - }, - }, - "false", - }, - "bothValid": { - v1.Pod{ - Status: v1.PodStatus{ - ContainerStatuses: []v1.ContainerStatus{ - { - Name: "foo", - State: v1.ContainerState{ - Running: &v1.ContainerStateRunning{ - StartedAt: metav1.Time{}, - }, - }, - }, - { - Name: "bar", - State: v1.ContainerState{ - Running: &v1.ContainerStateRunning{ - StartedAt: metav1.Time{}, - }, - }, - }, - }, - }, - }, - "true", - }, - } - // The point of this test is to verify that the below template works. - tmpl := `{{if (exists . "status" "containerStatuses")}}{{range .status.containerStatuses}}{{if (and (eq .name "foo") (exists . "state" "running"))}}true{{end}}{{end}}{{end}}` - printer, err := genericprinters.NewGoTemplatePrinter([]byte(tmpl)) - if err != nil { - t.Fatalf("tmpl fail: %v", err) - } - - for name, item := range table { - buffer := &bytes.Buffer{} - err = printer.PrintObj(&item.pod, buffer) - if err != nil { - t.Errorf("%v: unexpected err: %v", name, err) - continue - } - actual := buffer.String() - if len(actual) == 0 { - actual = "false" - } - if e := item.expect; e != actual { - t.Errorf("%v: expected %v, got %v", name, e, actual) - } - } -} - // TODO(seans3): Move this test to cli-runtime/pkg/printers. func TestPrinters(t *testing.T) { om := func(name string) metav1.ObjectMeta { return metav1.ObjectMeta{Name: name} } var ( - err error - templatePrinter printers.ResourcePrinter - templatePrinter2 printers.ResourcePrinter - jsonpathPrinter printers.ResourcePrinter + err error + jsonpathPrinter printers.ResourcePrinter ) - templatePrinter, err = genericprinters.NewGoTemplatePrinter([]byte("{{.name}}")) - if err != nil { - t.Fatal(err) - } - - templatePrinter2, err = genericprinters.NewGoTemplatePrinter([]byte("{{len .items}}")) - if err != nil { - t.Fatal(err) - } - jsonpathPrinter, err = genericprinters.NewJSONPathPrinter("{.metadata.name}") if err != nil { t.Fatal(err) @@ -420,11 +274,9 @@ func TestPrinters(t *testing.T) { genericPrinters := map[string]printers.ResourcePrinter{ // TODO(juanvallejo): move "generic printer" tests to pkg/kubectl/genericclioptions/printers - "json": genericprinters.NewTypeSetter(legacyscheme.Scheme).ToPrinter(&genericprinters.JSONPrinter{}), - "yaml": genericprinters.NewTypeSetter(legacyscheme.Scheme).ToPrinter(&genericprinters.YAMLPrinter{}), - "template": templatePrinter, - "template2": templatePrinter2, - "jsonpath": jsonpathPrinter, + "json": genericprinters.NewTypeSetter(legacyscheme.Scheme).ToPrinter(&genericprinters.JSONPrinter{}), + "yaml": genericprinters.NewTypeSetter(legacyscheme.Scheme).ToPrinter(&genericprinters.YAMLPrinter{}), + "jsonpath": jsonpathPrinter, } objects := map[string]runtime.Object{ "pod": &v1.Pod{ObjectMeta: om("pod")}, @@ -438,8 +290,7 @@ func TestPrinters(t *testing.T) { } // map of printer name to set of objects it should fail on. expectedErrors := map[string]sets.String{ - "template2": sets.NewString("pod", "emptyPodList", "endpoints"), - "jsonpath": sets.NewString("emptyPodList", "nonEmptyPodList", "endpoints"), + "jsonpath": sets.NewString("emptyPodList", "nonEmptyPodList", "endpoints"), } for pName, p := range genericPrinters { diff --git a/staging/src/k8s.io/cli-runtime/pkg/printers/BUILD b/staging/src/k8s.io/cli-runtime/pkg/printers/BUILD index 918aca289a1..f7515915dd7 100644 --- a/staging/src/k8s.io/cli-runtime/pkg/printers/BUILD +++ b/staging/src/k8s.io/cli-runtime/pkg/printers/BUILD @@ -37,6 +37,7 @@ go_test( embed = [":go_default_library"], deps = [ "//staging/src/k8s.io/api/core/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", ], ) diff --git a/staging/src/k8s.io/cli-runtime/pkg/printers/template_test.go b/staging/src/k8s.io/cli-runtime/pkg/printers/template_test.go index e16f6181bcd..fb3c6ae0656 100644 --- a/staging/src/k8s.io/cli-runtime/pkg/printers/template_test.go +++ b/staging/src/k8s.io/cli-runtime/pkg/printers/template_test.go @@ -22,6 +22,7 @@ import ( "testing" "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) @@ -108,3 +109,191 @@ type badlyMarshaledSecret struct { func (a badlyMarshaledSecret) MarshalJSON() ([]byte, error) { return []byte(`{"apiVersion":"v1","data":{"username":"--THIS IS NOT BASE64--"},"kind":"Secret"}`), nil } + +func TestTemplateStrings(t *testing.T) { + // This unit tests the "exists" function as well as the template from update.sh + table := map[string]struct { + pod v1.Pod + expect string + }{ + "nilInfo": {v1.Pod{}, "false"}, + "emptyInfo": {v1.Pod{Status: v1.PodStatus{ContainerStatuses: []v1.ContainerStatus{}}}, "false"}, + "fooExists": { + v1.Pod{ + Status: v1.PodStatus{ + ContainerStatuses: []v1.ContainerStatus{ + { + Name: "foo", + }, + }, + }, + }, + "false", + }, + "barExists": { + v1.Pod{ + Status: v1.PodStatus{ + ContainerStatuses: []v1.ContainerStatus{ + { + Name: "bar", + }, + }, + }, + }, + "false", + }, + "bothExist": { + v1.Pod{ + Status: v1.PodStatus{ + ContainerStatuses: []v1.ContainerStatus{ + { + Name: "foo", + }, + { + Name: "bar", + }, + }, + }, + }, + "false", + }, + "barValid": { + v1.Pod{ + Status: v1.PodStatus{ + ContainerStatuses: []v1.ContainerStatus{ + { + Name: "foo", + }, + { + Name: "bar", + State: v1.ContainerState{ + Running: &v1.ContainerStateRunning{ + StartedAt: metav1.Time{}, + }, + }, + }, + }, + }, + }, + "false", + }, + "bothValid": { + v1.Pod{ + Status: v1.PodStatus{ + ContainerStatuses: []v1.ContainerStatus{ + { + Name: "foo", + State: v1.ContainerState{ + Running: &v1.ContainerStateRunning{ + StartedAt: metav1.Time{}, + }, + }, + }, + { + Name: "bar", + State: v1.ContainerState{ + Running: &v1.ContainerStateRunning{ + StartedAt: metav1.Time{}, + }, + }, + }, + }, + }, + }, + "true", + }, + } + // The point of this test is to verify that the below template works. + tmpl := `{{if (exists . "status" "containerStatuses")}}{{range .status.containerStatuses}}{{if (and (eq .name "foo") (exists . "state" "running"))}}true{{end}}{{end}}{{end}}` + printer, err := NewGoTemplatePrinter([]byte(tmpl)) + if err != nil { + t.Fatalf("tmpl fail: %v", err) + } + + for name, item := range table { + buffer := &bytes.Buffer{} + err = printer.PrintObj(&item.pod, buffer) + if err != nil { + t.Errorf("%v: unexpected err: %v", name, err) + continue + } + actual := buffer.String() + if len(actual) == 0 { + actual = "false" + } + if e := item.expect; e != actual { + t.Errorf("%v: expected %v, got %v", name, e, actual) + } + } +} + +func TestTemplatePanic(t *testing.T) { + tmpl := `{{and ((index .currentState.info "foo").state.running.startedAt) .currentState.info.net.state.running.startedAt}}` + printer, err := NewGoTemplatePrinter([]byte(tmpl)) + if err != nil { + t.Fatalf("tmpl fail: %v", err) + } + buffer := &bytes.Buffer{} + err = printer.PrintObj(&v1.Pod{}, buffer) + if err == nil { + t.Fatalf("expected that template to crash") + } + if buffer.String() == "" { + t.Errorf("no debugging info was printed") + } +} + +func TestTemplateSuccess(t *testing.T) { + + templatePrinter, err := NewGoTemplatePrinter([]byte("{{.name}}")) + if err != nil { + t.Fatal(err) + } + + // Template printer should succeed on these resources. + om := func(name string) metav1.ObjectMeta { return metav1.ObjectMeta{Name: name} } + objects := []runtime.Object{ + &v1.Pod{ObjectMeta: om("pod")}, + &v1.PodList{}, + &v1.PodList{Items: []v1.Pod{{}}}, + &v1.Endpoints{ + Subsets: []v1.EndpointSubset{{ + Addresses: []v1.EndpointAddress{{IP: "127.0.0.1"}, {IP: "localhost"}}, + Ports: []v1.EndpointPort{{Port: 8080}}, + }}}, + } + + for _, obj := range objects { + b := &bytes.Buffer{} + if err := templatePrinter.PrintObj(obj, b); err != nil { + t.Errorf("Unexpected template error: %v", err) + } + } +} + +func TestTemplateErrors(t *testing.T) { + + templatePrinter, err := NewGoTemplatePrinter([]byte("{{len .items}}")) + if err != nil { + t.Fatal(err) + } + + // Template printer should fail on these resources. + om := func(name string) metav1.ObjectMeta { return metav1.ObjectMeta{Name: name} } + objects := []runtime.Object{ + &v1.Pod{ObjectMeta: om("pod")}, + &v1.PodList{}, + &v1.Endpoints{ + Subsets: []v1.EndpointSubset{{ + Addresses: []v1.EndpointAddress{{IP: "127.0.0.1"}, {IP: "localhost"}}, + Ports: []v1.EndpointPort{{Port: 8080}}, + }}}, + } + + for _, obj := range objects { + b := &bytes.Buffer{} + if err := templatePrinter.PrintObj(obj, b); err == nil { + t.Errorf("Expected template printer error; received none") + } + } +}