Make GetPrinter take the necessary conversion arguments

This fully encapsulates decisions about conversion within GetPrinter,
which prevents users from accidentally not converting.
This commit is contained in:
Clayton Coleman 2014-11-18 13:04:10 -05:00
parent 811f77894c
commit 487e5cd061
6 changed files with 341 additions and 102 deletions

117
pkg/kubectl/cmd/cmd_test.go Normal file
View File

@ -0,0 +1,117 @@
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd_test
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
. "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/spf13/cobra"
)
type internalType struct {
Kind string
APIVersion string
Name string
}
type externalType struct {
Kind string `json:"kind"`
APIVersion string `json:"apiVersion"`
Name string `json:"name"`
}
func (*internalType) IsAnAPIObject() {}
func (*externalType) IsAnAPIObject() {}
func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName("", "Type", &internalType{})
scheme.AddKnownTypeWithName("unlikelyversion", "Type", &externalType{})
codec := runtime.CodecFor(scheme, "unlikelyversion")
mapper := meta.NewDefaultRESTMapper([]string{"unlikelyversion"}, func(version string) (*meta.VersionInterfaces, bool) {
return &meta.VersionInterfaces{
Codec: codec,
ObjectConvertor: scheme,
MetadataAccessor: meta.NewAccessor(),
}, (version == "unlikelyversion")
})
mapper.Add(scheme, false, "unlikelyversion")
return scheme, mapper, codec
}
type testPrinter struct {
Obj runtime.Object
Err error
}
func (t *testPrinter) PrintObj(obj runtime.Object, out io.Writer) error {
t.Obj = obj
fmt.Fprintf(out, "%#v", obj)
return t.Err
}
type testDescriber struct {
Name, Namespace string
Output string
Err error
}
func (t *testDescriber) Describe(namespace, name string) (output string, err error) {
t.Namespace, t.Name = namespace, name
return t.Output, t.Err
}
type testFactory struct {
Client kubectl.RESTClient
Describer kubectl.Describer
Printer kubectl.ResourcePrinter
Err error
}
func NewTestFactory() (*Factory, *testFactory, runtime.Codec) {
scheme, mapper, codec := newExternalScheme()
t := &testFactory{}
return &Factory{
Mapper: mapper,
Typer: scheme,
Client: func(*cobra.Command, *meta.RESTMapping) (kubectl.RESTClient, error) {
return t.Client, t.Err
},
Describer: func(*cobra.Command, *meta.RESTMapping) (kubectl.Describer, error) {
return t.Describer, t.Err
},
Printer: func(cmd *cobra.Command, mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) {
return t.Printer, t.Err
},
}, t, codec
}
func objBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
}

View File

@ -0,0 +1,50 @@
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd_test
import (
"bytes"
"fmt"
"net/http"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
)
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
func TestDescribeUnknownSchemaObject(t *testing.T) {
d := &testDescriber{Output: "test output"}
f, tf, codec := NewTestFactory()
tf.Describer = d
tf.Client = &client.FakeRESTClient{
Codec: codec,
Resp: &http.Response{StatusCode: 200, Body: objBody(codec, &internalType{Name: "foo"})},
}
buf := bytes.NewBuffer([]byte{})
cmd := f.NewCmdDescribe(buf)
cmd.Flags().String("namespace", "test", "")
cmd.Run(cmd, []string{"type", "foo"})
if d.Name != "foo" || d.Namespace != "test" {
t.Errorf("unexpected describer: %#v", d)
}
if buf.String() != fmt.Sprintf("%s\n", d.Output) {
t.Errorf("unexpected output: %s", buf.String())
}
}

View File

@ -20,9 +20,9 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -66,27 +66,29 @@ Examples:
if len(outputVersion) == 0 { if len(outputVersion) == 0 {
outputVersion = mapping.APIVersion outputVersion = mapping.APIVersion
} }
printer, err := kubectl.GetPrinter(outputVersion, outputFormat, templateFile, defaultPrinter)
printer, err := kubectl.GetPrinter(outputFormat, templateFile, outputVersion, mapping.ObjectConvertor, defaultPrinter)
checkErr(err) checkErr(err)
restHelper := kubectl.NewRESTHelper(client, mapping) restHelper := kubectl.NewRESTHelper(client, mapping)
obj, err := restHelper.Get(namespace, name, labelSelector) obj, err := restHelper.Get(namespace, name, labelSelector)
checkErr(err) checkErr(err)
if !GetFlagBool(cmd, "watch-only") { isWatch, isWatchOnly := GetFlagBool(cmd, "watch"), GetFlagBool(cmd, "watch-only")
// print the current object
if !isWatchOnly {
if err := printer.PrintObj(obj, out); err != nil { if err := printer.PrintObj(obj, out); err != nil {
checkErr(fmt.Errorf("Unable to output the provided object: %v", err)) checkErr(fmt.Errorf("Unable to output the provided object: %v", err))
} }
} }
if GetFlagBool(cmd, "watch") || GetFlagBool(cmd, "watch-only") { // print watched changes
vi, err := latest.InterfacesFor(outputVersion) if isWatch || isWatchOnly {
rv, err := mapping.MetadataAccessor.ResourceVersion(obj)
checkErr(err) checkErr(err)
rv, err := vi.MetadataAccessor.ResourceVersion(obj) w, err := restHelper.Watch(namespace, rv, labelSelector, labels.Everything())
checkErr(err)
w, err := restHelper.Watch(namespace, rv, labelSelector, labels.Set{}.AsSelector())
checkErr(err) checkErr(err)
kubectl.WatchLoop(w, printer, out) kubectl.WatchLoop(w, printer, out)

View File

@ -0,0 +1,51 @@
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd_test
import (
"bytes"
"fmt"
"net/http"
"reflect"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
)
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
func TestGetUnknownSchemaObject(t *testing.T) {
f, tf, codec := NewTestFactory()
tf.Printer = &testPrinter{}
tf.Client = &client.FakeRESTClient{
Codec: codec,
Resp: &http.Response{StatusCode: 200, Body: objBody(codec, &internalType{Name: "foo"})},
}
buf := bytes.NewBuffer([]byte{})
cmd := f.NewCmdGet(buf)
cmd.Flags().String("namespace", "test", "")
cmd.Run(cmd, []string{"type", "foo"})
expected := &internalType{Name: "foo"}
actual := tf.Printer.(*testPrinter).Obj
if !reflect.DeepEqual(expected, actual) {
t.Errorf("unexpected object: %#v", actual)
}
if buf.String() != fmt.Sprintf("%#v", expected) {
t.Errorf("unexpected output: %s", buf.String())
}
}

View File

@ -28,40 +28,40 @@ import (
"text/template" "text/template"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/golang/glog" "github.com/golang/glog"
"gopkg.in/v1/yaml" "gopkg.in/v1/yaml"
) )
// GetPrinter returns a resource printer and a bool indicating whether the object must be // GetPrinter takes a format type, an optional format argument, a version and a convertor
// versioned for the given format. // to be used if the underlying printer requires the object to be in a specific schema (
func GetPrinter(version, format, templateFile string, defaultPrinter ResourcePrinter) (ResourcePrinter, error) { // any of the generic formatters), and the default printer to use for this object.
func GetPrinter(format, formatArgument, version string, convertor runtime.ObjectConvertor, defaultPrinter ResourcePrinter) (ResourcePrinter, error) {
var printer ResourcePrinter var printer ResourcePrinter
switch format { switch format {
case "json": case "json":
printer = &JSONPrinter{version} printer = &JSONPrinter{version, convertor}
case "yaml": case "yaml":
printer = &YAMLPrinter{version} printer = &YAMLPrinter{version, convertor}
case "template": case "template":
if len(templateFile) == 0 { if len(formatArgument) == 0 {
return nil, fmt.Errorf("template format specified but no template given") return nil, fmt.Errorf("template format specified but no template given")
} }
var err error var err error
printer, err = NewTemplatePrinter(version, []byte(templateFile)) printer, err = NewTemplatePrinter([]byte(formatArgument), version, convertor)
if err != nil { if err != nil {
return nil, fmt.Errorf("error parsing template %s, %v\n", templateFile, err) return nil, fmt.Errorf("error parsing template %s, %v\n", formatArgument, err)
} }
case "templatefile": case "templatefile":
if len(templateFile) == 0 { if len(formatArgument) == 0 {
return nil, fmt.Errorf("templatefile format specified but no template file given") return nil, fmt.Errorf("templatefile format specified but no template file given")
} }
data, err := ioutil.ReadFile(templateFile) data, err := ioutil.ReadFile(formatArgument)
if err != nil { if err != nil {
return nil, fmt.Errorf("error reading template %s, %v\n", templateFile, err) return nil, fmt.Errorf("error reading template %s, %v\n", formatArgument, err)
} }
printer, err = NewTemplatePrinter(version, data) printer, err = NewTemplatePrinter(data, version, convertor)
if err != nil { if err != nil {
return nil, fmt.Errorf("error parsing template %s, %v\n", string(data), err) return nil, fmt.Errorf("error parsing template %s, %v\n", string(data), err)
} }
@ -73,28 +73,27 @@ func GetPrinter(version, format, templateFile string, defaultPrinter ResourcePri
return printer, nil return printer, nil
} }
// ResourcePrinter is an interface that knows how to print API resources. // ResourcePrinter is an interface that knows how to print runtime objects.
type ResourcePrinter interface { type ResourcePrinter interface {
// Print receives an arbitrary object, formats it and prints it to a writer. // Print receives an arbitrary object, formats it and prints it to a writer.
PrintObj(runtime.Object, io.Writer) error PrintObj(runtime.Object, io.Writer) error
// Returns true if this printer emits properly versioned output.
IsVersioned() bool
} }
// JSONPrinter is an implementation of ResourcePrinter which prints as JSON. // JSONPrinter is an implementation of ResourcePrinter which outputs an object as JSON.
// The input object is assumed to be in the internal version of an API and is converted
// to the given version first.
type JSONPrinter struct { type JSONPrinter struct {
version string version string
convertor runtime.ObjectConvertor
} }
// PrintObj is an implementation of ResourcePrinter.PrintObj which simply writes the object to the Writer. // PrintObj is an implementation of ResourcePrinter.PrintObj which simply writes the object to the Writer.
func (j *JSONPrinter) PrintObj(obj runtime.Object, w io.Writer) error { func (p *JSONPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
vi, err := latest.InterfacesFor(j.version) outObj, err := p.convertor.ConvertToVersion(obj, p.version)
if err != nil { if err != nil {
return err return err
} }
data, err := json.Marshal(outObj)
data, err := vi.Codec.Encode(obj)
if err != nil { if err != nil {
return err return err
} }
@ -105,39 +104,20 @@ func (j *JSONPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
return err return err
} }
// IsVersioned returns true. // YAMLPrinter is an implementation of ResourcePrinter which outputs an object as YAML.
func (*JSONPrinter) IsVersioned() bool { return true } // The input object is assumed to be in the internal version of an API and is converted
// to the given version first.
func toVersionedMap(version string, obj runtime.Object) (map[string]interface{}, error) {
vi, err := latest.InterfacesFor(version)
if err != nil {
return nil, err
}
data, err := vi.Codec.Encode(obj)
if err != nil {
return nil, err
}
outObj := map[string]interface{}{}
err = json.Unmarshal(data, &outObj)
if err != nil {
return nil, err
}
return outObj, nil
}
// YAMLPrinter is an implementation of ResourcePrinter which prints as YAML.
type YAMLPrinter struct { type YAMLPrinter struct {
version string version string
convertor runtime.ObjectConvertor
} }
// PrintObj prints the data as YAML. // PrintObj prints the data as YAML.
func (y *YAMLPrinter) PrintObj(obj runtime.Object, w io.Writer) error { func (p *YAMLPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
outObj, err := toVersionedMap(y.version, obj) outObj, err := p.convertor.ConvertToVersion(obj, p.version)
if err != nil { if err != nil {
return err return err
} }
output, err := yaml.Marshal(outObj) output, err := yaml.Marshal(outObj)
if err != nil { if err != nil {
return err return err
@ -146,9 +126,6 @@ func (y *YAMLPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
return err return err
} }
// IsVersioned returns true.
func (*YAMLPrinter) IsVersioned() bool { return true }
type handlerEntry struct { type handlerEntry struct {
columns []string columns []string
printFunc reflect.Value printFunc reflect.Value
@ -164,9 +141,6 @@ type HumanReadablePrinter struct {
lastType reflect.Type lastType reflect.Type
} }
// IsVersioned returns false-- human readable printers do not make versioned output.
func (*HumanReadablePrinter) IsVersioned() bool { return false }
// NewHumanReadablePrinter creates a HumanReadablePrinter. // NewHumanReadablePrinter creates a HumanReadablePrinter.
func NewHumanReadablePrinter(noHeaders bool) *HumanReadablePrinter { func NewHumanReadablePrinter(noHeaders bool) *HumanReadablePrinter {
printer := &HumanReadablePrinter{ printer := &HumanReadablePrinter{
@ -387,28 +361,34 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
// TemplatePrinter is an implementation of ResourcePrinter which formats data with a Go Template. // TemplatePrinter is an implementation of ResourcePrinter which formats data with a Go Template.
type TemplatePrinter struct { type TemplatePrinter struct {
version string
template *template.Template template *template.Template
version string
convertor runtime.ObjectConvertor
} }
func NewTemplatePrinter(version string, tmpl []byte) (*TemplatePrinter, error) { func NewTemplatePrinter(tmpl []byte, asVersion string, convertor runtime.ObjectConvertor) (*TemplatePrinter, error) {
t, err := template.New("output").Parse(string(tmpl)) t, err := template.New("output").Parse(string(tmpl))
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &TemplatePrinter{version, t}, nil return &TemplatePrinter{t, asVersion, convertor}, nil
} }
// IsVersioned returns true.
func (*TemplatePrinter) IsVersioned() bool { return true }
// PrintObj formats the obj with the Go Template. // PrintObj formats the obj with the Go Template.
func (t *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error { func (p *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
outObj, err := toVersionedMap(t.version, obj) outObj, err := p.convertor.ConvertToVersion(obj, p.version)
if err != nil { if err != nil {
return err return err
} }
return t.template.Execute(w, outObj) data, err := json.Marshal(outObj)
if err != nil {
return err
}
out := map[string]interface{}{}
if err := json.Unmarshal(data, &out); err != nil {
return err
}
return p.template.Execute(w, out)
} }
func tabbedString(f func(io.Writer) error) (string, error) { func tabbedString(f func(io.Writer) error) (string, error) {

View File

@ -25,7 +25,8 @@ import (
"testing" "testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"gopkg.in/v1/yaml" "gopkg.in/v1/yaml"
@ -42,11 +43,9 @@ type testStruct struct {
func (ts *testStruct) IsAnAPIObject() {} func (ts *testStruct) IsAnAPIObject() {}
const TestVersion = latest.Version
func init() { func init() {
api.Scheme.AddKnownTypes("", &testStruct{}) api.Scheme.AddKnownTypes("", &testStruct{})
api.Scheme.AddKnownTypes(TestVersion, &testStruct{}) api.Scheme.AddKnownTypes(testapi.Version(), &testStruct{})
} }
var testData = testStruct{ var testData = testStruct{
@ -57,21 +56,67 @@ var testData = testStruct{
} }
func TestYAMLPrinter(t *testing.T) { func TestYAMLPrinter(t *testing.T) {
testPrinter(t, &YAMLPrinter{TestVersion}, yaml.Unmarshal) testPrinter(t, &YAMLPrinter{testapi.Version(), api.Scheme}, yaml.Unmarshal)
} }
func TestJSONPrinter(t *testing.T) { func TestJSONPrinter(t *testing.T) {
testPrinter(t, &JSONPrinter{TestVersion}, json.Unmarshal) testPrinter(t, &JSONPrinter{testapi.Version(), api.Scheme}, json.Unmarshal)
}
type internalType struct {
Name string
Kind string
}
type externalType struct {
Name string
Kind string `json:"kind"`
}
func (*internalType) IsAnAPIObject() {}
func (*externalType) IsAnAPIObject() {}
func newExternalScheme() *runtime.Scheme {
scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName("", "Type", &internalType{})
scheme.AddKnownTypeWithName("unlikelyversion", "Type", &externalType{})
return scheme
}
func TestPrintJSONForUnknownSchema(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
printer, err := GetPrinter("json", "", "unlikelyversion", newExternalScheme(), nil)
if err != nil {
t.Fatalf("unexpected error: %#v", err)
}
if err := printer.PrintObj(&internalType{Name: "foo"}, buf); err != nil {
t.Fatalf("unexpected error: %#v", err)
}
obj := map[string]interface{}{}
if err := json.Unmarshal(buf.Bytes(), &obj); err != nil {
t.Fatalf("unexpected error: %#v\n%s", err, buf.String())
}
if obj["Name"] != "foo" {
t.Errorf("unexpected field: %#v", obj)
}
}
func TestPrintJSONForUnknownSchemaAndWrongVersion(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
printer, err := GetPrinter("json", "", "badversion", newExternalScheme(), nil)
if err != nil {
t.Fatalf("unexpected error: %#v", err)
}
if err := printer.PrintObj(&internalType{Name: "foo"}, buf); err == nil {
t.Errorf("unexpected non-error")
}
} }
func TestPrintJSON(t *testing.T) { func TestPrintJSON(t *testing.T) {
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
printer, err := GetPrinter(TestVersion, "json", "", nil) printer, err := GetPrinter("json", "", testapi.Version(), api.Scheme, nil)
if err != nil { if err != nil {
t.Errorf("unexpected error: %#v", err) t.Fatalf("unexpected error: %#v", err)
}
if !printer.IsVersioned() {
t.Errorf("printer should be versioned")
} }
printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf) printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf)
obj := map[string]interface{}{} obj := map[string]interface{}{}
@ -82,12 +127,9 @@ func TestPrintJSON(t *testing.T) {
func TestPrintYAML(t *testing.T) { func TestPrintYAML(t *testing.T) {
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
printer, err := GetPrinter(TestVersion, "yaml", "", nil) printer, err := GetPrinter("yaml", "", testapi.Version(), api.Scheme, nil)
if err != nil { if err != nil {
t.Errorf("unexpected error: %#v", err) t.Fatalf("unexpected error: %#v", err)
}
if !printer.IsVersioned() {
t.Errorf("printer should be versioned")
} }
printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf) printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf)
obj := map[string]interface{}{} obj := map[string]interface{}{}
@ -98,13 +140,10 @@ func TestPrintYAML(t *testing.T) {
func TestPrintTemplate(t *testing.T) { func TestPrintTemplate(t *testing.T) {
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
printer, err := GetPrinter(TestVersion, "template", "{{.id}}", nil) printer, err := GetPrinter("template", "{{.id}}", "v1beta1", api.Scheme, nil)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %#v", err) t.Fatalf("unexpected error: %#v", err)
} }
if !printer.IsVersioned() {
t.Errorf("printer should be versioned")
}
err = printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf) err = printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %#v", err) t.Fatalf("unexpected error: %#v", err)
@ -115,19 +154,19 @@ func TestPrintTemplate(t *testing.T) {
} }
func TestPrintEmptyTemplate(t *testing.T) { func TestPrintEmptyTemplate(t *testing.T) {
if _, err := GetPrinter(TestVersion, "template", "", nil); err == nil { if _, err := GetPrinter("template", "", testapi.Version(), api.Scheme, nil); err == nil {
t.Errorf("unexpected non-error") t.Errorf("unexpected non-error")
} }
} }
func TestPrintBadTemplate(t *testing.T) { func TestPrintBadTemplate(t *testing.T) {
if _, err := GetPrinter(TestVersion, "template", "{{ .Name", nil); err == nil { if _, err := GetPrinter("template", "{{ .Name", testapi.Version(), api.Scheme, nil); err == nil {
t.Errorf("unexpected non-error") t.Errorf("unexpected non-error")
} }
} }
func TestPrintBadTemplateFile(t *testing.T) { func TestPrintBadTemplateFile(t *testing.T) {
if _, err := GetPrinter(TestVersion, "templatefile", "", nil); err == nil { if _, err := GetPrinter("templatefile", "", testapi.Version(), api.Scheme, nil); err == nil {
t.Errorf("unexpected non-error") t.Errorf("unexpected non-error")
} }
} }
@ -147,7 +186,7 @@ func testPrinter(t *testing.T, printer ResourcePrinter, unmarshalFunc func(data
} }
// Use real decode function to undo the versioning process. // Use real decode function to undo the versioning process.
poutput = testStruct{} poutput = testStruct{}
err = latest.Codec.DecodeInto(buf.Bytes(), &poutput) err = testapi.Codec().DecodeInto(buf.Bytes(), &poutput)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -164,11 +203,11 @@ func testPrinter(t *testing.T, printer ResourcePrinter, unmarshalFunc func(data
// Verify that given function runs without error. // Verify that given function runs without error.
err = unmarshalFunc(buf.Bytes(), &objOut) err = unmarshalFunc(buf.Bytes(), &objOut)
if err != nil { if err != nil {
t.Errorf("Unexpeted error: %#v", err) t.Fatalf("unexpected error: %#v", err)
} }
// Use real decode function to undo the versioning process. // Use real decode function to undo the versioning process.
objOut = api.Pod{} objOut = api.Pod{}
err = latest.Codec.DecodeInto(buf.Bytes(), &objOut) err = testapi.Codec().DecodeInto(buf.Bytes(), &objOut)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -205,7 +244,7 @@ func TestCustomTypePrinting(t *testing.T) {
buffer := &bytes.Buffer{} buffer := &bytes.Buffer{}
err := printer.PrintObj(&obj, buffer) err := printer.PrintObj(&obj, buffer)
if err != nil { if err != nil {
t.Errorf("An error occurred printing the custom type: %#v", err) t.Fatalf("An error occurred printing the custom type: %#v", err)
} }
expectedOutput := "Data\ntest object" expectedOutput := "Data\ntest object"
if buffer.String() != expectedOutput { if buffer.String() != expectedOutput {
@ -236,7 +275,7 @@ func TestUnknownTypePrinting(t *testing.T) {
func TestTemplateEmitsVersionedObjects(t *testing.T) { func TestTemplateEmitsVersionedObjects(t *testing.T) {
// kind is always blank in memory and set on the wire // kind is always blank in memory and set on the wire
printer, err := NewTemplatePrinter(TestVersion, []byte(`{{.kind}}`)) printer, err := NewTemplatePrinter([]byte(`{{.kind}}`), testapi.Version(), api.Scheme)
if err != nil { if err != nil {
t.Fatalf("tmpl fail: %v", err) t.Fatalf("tmpl fail: %v", err)
} }