From 432cf39c0c9c737ea15d5384a7041c6677953392 Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Thu, 20 Nov 2014 14:09:59 -0800 Subject: [PATCH] add test and more helpful error message --- pkg/kubectl/resource_printer.go | 19 +++++++++---- pkg/kubectl/resource_printer_test.go | 42 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/pkg/kubectl/resource_printer.go b/pkg/kubectl/resource_printer.go index 9e8852638d0..3230a1727e9 100644 --- a/pkg/kubectl/resource_printer.go +++ b/pkg/kubectl/resource_printer.go @@ -361,9 +361,10 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er // TemplatePrinter is an implementation of ResourcePrinter which formats data with a Go Template. type TemplatePrinter struct { - template *template.Template - version string - convertor runtime.ObjectConvertor + rawTemplate string + template *template.Template + version string + convertor runtime.ObjectConvertor } func NewTemplatePrinter(tmpl []byte, asVersion string, convertor runtime.ObjectConvertor) (*TemplatePrinter, error) { @@ -371,7 +372,12 @@ func NewTemplatePrinter(tmpl []byte, asVersion string, convertor runtime.ObjectC if err != nil { return nil, err } - return &TemplatePrinter{t, asVersion, convertor}, nil + return &TemplatePrinter{ + rawTemplate: string(tmpl), + template: t, + version: asVersion, + convertor: convertor, + }, nil } // PrintObj formats the obj with the Go Template. @@ -388,7 +394,10 @@ func (p *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error { if err := json.Unmarshal(data, &out); err != nil { return err } - return p.template.Execute(w, out) + if err = p.template.Execute(w, out); err != nil { + return fmt.Errorf("error executing template '%v': '%v'\n----data----\n%#v\n", p.rawTemplate, err, out) + } + return nil } func tabbedString(f func(io.Writer) error) (string, error) { diff --git a/pkg/kubectl/resource_printer_test.go b/pkg/kubectl/resource_printer_test.go index 47dc714873c..676d9d7a0d3 100644 --- a/pkg/kubectl/resource_printer_test.go +++ b/pkg/kubectl/resource_printer_test.go @@ -288,3 +288,45 @@ func TestTemplateEmitsVersionedObjects(t *testing.T) { t.Errorf("Expected %v, got %v", e, a) } } + +func TestPrinters(t *testing.T) { + om := func(name string) api.ObjectMeta { return api.ObjectMeta{Name: name} } + templatePrinter, err := NewTemplatePrinter([]byte("{{.name}}"), testapi.Version(), api.Scheme) + if err != nil { + t.Fatal(err) + } + templatePrinter2, err := NewTemplatePrinter([]byte("{{len .items}}"), testapi.Version(), api.Scheme) + if err != nil { + t.Fatal(err) + } + printers := map[string]ResourcePrinter{ + "humanReadable": NewHumanReadablePrinter(true), + "humanReadableHeaders": NewHumanReadablePrinter(false), + "json": &JSONPrinter{testapi.Version(), api.Scheme}, + "yaml": &YAMLPrinter{testapi.Version(), api.Scheme}, + "template": templatePrinter, + "template2": templatePrinter2, + } + objects := map[string]runtime.Object{ + "pod": &api.Pod{ObjectMeta: om("pod")}, + "emptyPodList": &api.PodList{}, + "nonEmptyPodList": &api.PodList{Items: []api.Pod{{}}}, + } + // map of printer name to set of objects it should fail on. + expectedErrors := map[string]util.StringSet{ + "template2": util.NewStringSet("pod", "emptyPodList"), + } + + for pName, p := range printers { + for oName, obj := range objects { + b := &bytes.Buffer{} + if err := p.PrintObj(obj, b); err != nil { + if set, found := expectedErrors[pName]; found && set.Has(oName) { + // expected error + continue + } + t.Errorf("printer '%v', object '%v'; error: '%v'", pName, oName, err) + } + } + } +}