vendor: remove dep and use vndr

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
Antonio Murdaca 2017-06-06 09:19:04 +02:00
parent 16f44674a4
commit 148e72d81e
No known key found for this signature in database
GPG key ID: B2BEAD150DE936B9
16131 changed files with 73815 additions and 4235138 deletions

View file

@ -1,426 +0,0 @@
/*
Copyright 2014 The Kubernetes Authors.
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 serializer
import (
"encoding/json"
"fmt"
"log"
"os"
"reflect"
"strings"
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
"github.com/ghodss/yaml"
"github.com/google/gofuzz"
flag "github.com/spf13/pflag"
)
var fuzzIters = flag.Int("fuzz-iters", 50, "How many fuzzing iterations to do.")
type testMetaFactory struct{}
func (testMetaFactory) Interpret(data []byte) (*schema.GroupVersionKind, error) {
findKind := struct {
APIVersion string `json:"myVersionKey,omitempty"`
ObjectKind string `json:"myKindKey,omitempty"`
}{}
// yaml is a superset of json, so we use it to decode here. That way,
// we understand both.
if err := yaml.Unmarshal(data, &findKind); err != nil {
return nil, fmt.Errorf("couldn't get version/kind: %v", err)
}
gv, err := schema.ParseGroupVersion(findKind.APIVersion)
if err != nil {
return nil, err
}
return &schema.GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: findKind.ObjectKind}, nil
}
// Test a weird version/kind embedding format.
type MyWeirdCustomEmbeddedVersionKindField struct {
ID string `json:"ID,omitempty"`
APIVersion string `json:"myVersionKey,omitempty"`
ObjectKind string `json:"myKindKey,omitempty"`
Z string `json:"Z,omitempty"`
Y uint64 `json:"Y,omitempty"`
}
type TestType1 struct {
MyWeirdCustomEmbeddedVersionKindField `json:",inline"`
A string `json:"A,omitempty"`
B int `json:"B,omitempty"`
C int8 `json:"C,omitempty"`
D int16 `json:"D,omitempty"`
E int32 `json:"E,omitempty"`
F int64 `json:"F,omitempty"`
G uint `json:"G,omitempty"`
H uint8 `json:"H,omitempty"`
I uint16 `json:"I,omitempty"`
J uint32 `json:"J,omitempty"`
K uint64 `json:"K,omitempty"`
L bool `json:"L,omitempty"`
M map[string]int `json:"M,omitempty"`
N map[string]TestType2 `json:"N,omitempty"`
O *TestType2 `json:"O,omitempty"`
P []TestType2 `json:"Q,omitempty"`
}
type TestType2 struct {
A string `json:"A,omitempty"`
B int `json:"B,omitempty"`
}
type ExternalTestType2 struct {
A string `json:"A,omitempty"`
B int `json:"B,omitempty"`
}
type ExternalTestType1 struct {
MyWeirdCustomEmbeddedVersionKindField `json:",inline"`
A string `json:"A,omitempty"`
B int `json:"B,omitempty"`
C int8 `json:"C,omitempty"`
D int16 `json:"D,omitempty"`
E int32 `json:"E,omitempty"`
F int64 `json:"F,omitempty"`
G uint `json:"G,omitempty"`
H uint8 `json:"H,omitempty"`
I uint16 `json:"I,omitempty"`
J uint32 `json:"J,omitempty"`
K uint64 `json:"K,omitempty"`
L bool `json:"L,omitempty"`
M map[string]int `json:"M,omitempty"`
N map[string]ExternalTestType2 `json:"N,omitempty"`
O *ExternalTestType2 `json:"O,omitempty"`
P []ExternalTestType2 `json:"Q,omitempty"`
}
type ExternalInternalSame struct {
MyWeirdCustomEmbeddedVersionKindField `json:",inline"`
A TestType2 `json:"A,omitempty"`
}
// TestObjectFuzzer can randomly populate all the above objects.
var TestObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 100).Funcs(
func(j *MyWeirdCustomEmbeddedVersionKindField, c fuzz.Continue) {
c.FuzzNoCustom(j)
j.APIVersion = ""
j.ObjectKind = ""
},
)
func (obj *MyWeirdCustomEmbeddedVersionKindField) GetObjectKind() schema.ObjectKind { return obj }
func (obj *MyWeirdCustomEmbeddedVersionKindField) SetGroupVersionKind(gvk schema.GroupVersionKind) {
obj.APIVersion, obj.ObjectKind = gvk.ToAPIVersionAndKind()
}
func (obj *MyWeirdCustomEmbeddedVersionKindField) GroupVersionKind() schema.GroupVersionKind {
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.ObjectKind)
}
func (obj *ExternalInternalSame) GetObjectKind() schema.ObjectKind {
return &obj.MyWeirdCustomEmbeddedVersionKindField
}
func (obj *TestType1) GetObjectKind() schema.ObjectKind {
return &obj.MyWeirdCustomEmbeddedVersionKindField
}
func (obj *ExternalTestType1) GetObjectKind() schema.ObjectKind {
return &obj.MyWeirdCustomEmbeddedVersionKindField
}
func (obj *TestType2) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
func (obj *ExternalTestType2) GetObjectKind() schema.ObjectKind {
return schema.EmptyObjectKind
}
// Returns a new Scheme set up with the test objects.
func GetTestScheme() (*runtime.Scheme, runtime.Codec) {
internalGV := schema.GroupVersion{Version: runtime.APIVersionInternal}
externalGV := schema.GroupVersion{Version: "v1"}
externalGV2 := schema.GroupVersion{Version: "v2"}
s := runtime.NewScheme()
// Ordinarily, we wouldn't add TestType2, but because this is a test and
// both types are from the same package, we need to get it into the system
// so that converter will match it with ExternalType2.
s.AddKnownTypes(internalGV, &TestType1{}, &TestType2{}, &ExternalInternalSame{})
s.AddKnownTypes(externalGV, &ExternalInternalSame{})
s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &ExternalTestType1{})
s.AddKnownTypeWithName(externalGV.WithKind("TestType2"), &ExternalTestType2{})
s.AddKnownTypeWithName(internalGV.WithKind("TestType3"), &TestType1{})
s.AddKnownTypeWithName(externalGV.WithKind("TestType3"), &ExternalTestType1{})
s.AddKnownTypeWithName(externalGV2.WithKind("TestType1"), &ExternalTestType1{})
s.AddUnversionedTypes(externalGV, &metav1.Status{})
cf := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{}))
codec := cf.LegacyCodec(schema.GroupVersion{Version: "v1"})
return s, codec
}
var semantic = conversion.EqualitiesOrDie(
func(a, b MyWeirdCustomEmbeddedVersionKindField) bool {
a.APIVersion, a.ObjectKind = "", ""
b.APIVersion, b.ObjectKind = "", ""
return a == b
},
)
func runTest(t *testing.T, source interface{}) {
name := reflect.TypeOf(source).Elem().Name()
TestObjectFuzzer.Fuzz(source)
_, codec := GetTestScheme()
data, err := runtime.Encode(codec, source.(runtime.Object))
if err != nil {
t.Errorf("%v: %v (%#v)", name, err, source)
return
}
obj2, err := runtime.Decode(codec, data)
if err != nil {
t.Errorf("%v: %v (%v)", name, err, string(data))
return
}
if !semantic.DeepEqual(source, obj2) {
t.Errorf("1: %v: diff: %v", name, diff.ObjectGoPrintSideBySide(source, obj2))
return
}
obj3 := reflect.New(reflect.TypeOf(source).Elem()).Interface()
if err := runtime.DecodeInto(codec, data, obj3.(runtime.Object)); err != nil {
t.Errorf("2: %v: %v", name, err)
return
}
if !semantic.DeepEqual(source, obj3) {
t.Errorf("3: %v: diff: %v", name, diff.ObjectDiff(source, obj3))
return
}
}
func TestTypes(t *testing.T) {
table := []interface{}{
&TestType1{},
&ExternalInternalSame{},
}
for _, item := range table {
// Try a few times, since runTest uses random values.
for i := 0; i < *fuzzIters; i++ {
runTest(t, item)
}
}
}
func TestVersionedEncoding(t *testing.T) {
s, _ := GetTestScheme()
cf := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{}))
info, _ := runtime.SerializerInfoForMediaType(cf.SupportedMediaTypes(), runtime.ContentTypeJSON)
encoder := info.Serializer
codec := cf.CodecForVersions(encoder, nil, schema.GroupVersion{Version: "v2"}, nil)
out, err := runtime.Encode(codec, &TestType1{})
if err != nil {
t.Fatal(err)
}
if string(out) != `{"myVersionKey":"v2","myKindKey":"TestType1"}`+"\n" {
t.Fatal(string(out))
}
codec = cf.CodecForVersions(encoder, nil, schema.GroupVersion{Version: "v3"}, nil)
_, err = runtime.Encode(codec, &TestType1{})
if err == nil {
t.Fatal(err)
}
// unversioned encode with no versions is written directly to wire
codec = cf.CodecForVersions(encoder, nil, runtime.InternalGroupVersioner, nil)
out, err = runtime.Encode(codec, &TestType1{})
if err != nil {
t.Fatal(err)
}
if string(out) != `{}`+"\n" {
t.Fatal(string(out))
}
}
func TestMultipleNames(t *testing.T) {
_, codec := GetTestScheme()
obj, _, err := codec.Decode([]byte(`{"myKindKey":"TestType3","myVersionKey":"v1","A":"value"}`), nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
internal := obj.(*TestType1)
if internal.A != "value" {
t.Fatalf("unexpected decoded object: %#v", internal)
}
out, err := runtime.Encode(codec, internal)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !strings.Contains(string(out), `"myKindKey":"TestType1"`) {
t.Errorf("unexpected encoded output: %s", string(out))
}
}
func TestConvertTypesWhenDefaultNamesMatch(t *testing.T) {
internalGV := schema.GroupVersion{Version: runtime.APIVersionInternal}
externalGV := schema.GroupVersion{Version: "v1"}
s := runtime.NewScheme()
// create two names internally, with TestType1 being preferred
s.AddKnownTypeWithName(internalGV.WithKind("TestType1"), &TestType1{})
s.AddKnownTypeWithName(internalGV.WithKind("OtherType1"), &TestType1{})
// create two names externally, with TestType1 being preferred
s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &ExternalTestType1{})
s.AddKnownTypeWithName(externalGV.WithKind("OtherType1"), &ExternalTestType1{})
ext := &ExternalTestType1{}
ext.APIVersion = "v1"
ext.ObjectKind = "OtherType1"
ext.A = "test"
data, err := json.Marshal(ext)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expect := &TestType1{A: "test"}
codec := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{})).LegacyCodec(schema.GroupVersion{Version: "v1"})
obj, err := runtime.Decode(codec, data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !semantic.DeepEqual(expect, obj) {
t.Errorf("unexpected object: %#v", obj)
}
into := &TestType1{}
if err := runtime.DecodeInto(codec, data, into); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !semantic.DeepEqual(expect, into) {
t.Errorf("unexpected object: %#v", obj)
}
}
func TestEncode_Ptr(t *testing.T) {
_, codec := GetTestScheme()
tt := &TestType1{A: "I am a pointer object"}
data, err := runtime.Encode(codec, tt)
obj2, err2 := runtime.Decode(codec, data)
if err != nil || err2 != nil {
t.Fatalf("Failure: '%v' '%v'\n%s", err, err2, data)
}
if _, ok := obj2.(*TestType1); !ok {
t.Fatalf("Got wrong type")
}
if !semantic.DeepEqual(obj2, tt) {
t.Errorf("Expected:\n %#v,\n Got:\n %#v", tt, obj2)
}
}
func TestBadJSONRejection(t *testing.T) {
log.SetOutput(os.Stderr)
_, codec := GetTestScheme()
badJSONs := [][]byte{
[]byte(`{"myVersionKey":"v1"}`), // Missing kind
[]byte(`{"myVersionKey":"v1","myKindKey":"bar"}`), // Unknown kind
[]byte(`{"myVersionKey":"bar","myKindKey":"TestType1"}`), // Unknown version
[]byte(`{"myKindKey":"TestType1"}`), // Missing version
}
for _, b := range badJSONs {
if _, err := runtime.Decode(codec, b); err == nil {
t.Errorf("Did not reject bad json: %s", string(b))
}
}
badJSONKindMismatch := []byte(`{"myVersionKey":"v1","myKindKey":"ExternalInternalSame"}`)
if err := runtime.DecodeInto(codec, badJSONKindMismatch, &TestType1{}); err == nil {
t.Errorf("Kind is set but doesn't match the object type: %s", badJSONKindMismatch)
}
if err := runtime.DecodeInto(codec, []byte(``), &TestType1{}); err != nil {
t.Errorf("Should allow empty decode: %v", err)
}
if _, _, err := codec.Decode([]byte(``), &schema.GroupVersionKind{Kind: "ExternalInternalSame"}, nil); err == nil {
t.Errorf("Did not give error for empty data with only kind default")
}
if _, _, err := codec.Decode([]byte(`{"myVersionKey":"v1"}`), &schema.GroupVersionKind{Kind: "ExternalInternalSame"}, nil); err != nil {
t.Errorf("Gave error for version and kind default")
}
if _, _, err := codec.Decode([]byte(`{"myKindKey":"ExternalInternalSame"}`), &schema.GroupVersionKind{Version: "v1"}, nil); err != nil {
t.Errorf("Gave error for version and kind default")
}
if _, _, err := codec.Decode([]byte(``), &schema.GroupVersionKind{Kind: "ExternalInternalSame", Version: "v1"}, nil); err != nil {
t.Errorf("Gave error for version and kind defaulted: %v", err)
}
if _, err := runtime.Decode(codec, []byte(``)); err == nil {
t.Errorf("Did not give error for empty data")
}
}
// Returns a new Scheme set up with the test objects needed by TestDirectCodec.
func GetDirectCodecTestScheme() *runtime.Scheme {
internalGV := schema.GroupVersion{Version: runtime.APIVersionInternal}
externalGV := schema.GroupVersion{Version: "v1"}
s := runtime.NewScheme()
// Ordinarily, we wouldn't add TestType2, but because this is a test and
// both types are from the same package, we need to get it into the system
// so that converter will match it with ExternalType2.
s.AddKnownTypes(internalGV, &TestType1{})
s.AddKnownTypes(externalGV, &ExternalTestType1{})
s.AddUnversionedTypes(externalGV, &metav1.Status{})
return s
}
func TestDirectCodec(t *testing.T) {
s := GetDirectCodecTestScheme()
cf := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{}))
info, _ := runtime.SerializerInfoForMediaType(cf.SupportedMediaTypes(), runtime.ContentTypeJSON)
serializer := info.Serializer
df := DirectCodecFactory{cf}
ignoredGV, err := schema.ParseGroupVersion("ignored group/ignored version")
if err != nil {
t.Fatal(err)
}
directEncoder := df.EncoderForVersion(serializer, ignoredGV)
directDecoder := df.DecoderToVersion(serializer, ignoredGV)
out, err := runtime.Encode(directEncoder, &ExternalTestType1{})
if err != nil {
t.Fatal(err)
}
if string(out) != `{"myVersionKey":"v1","myKindKey":"ExternalTestType1"}`+"\n" {
t.Fatal(string(out))
}
a, _, err := directDecoder.Decode(out, nil, nil)
e := &ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{
APIVersion: "v1",
ObjectKind: "ExternalTestType1",
},
}
if !semantic.DeepEqual(e, a) {
t.Fatalf("expect %v, got %v", e, a)
}
}

View file

@ -1,264 +0,0 @@
/*
Copyright 2015 The Kubernetes Authors.
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 json_test
import (
"fmt"
"reflect"
"strings"
"testing"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/apimachinery/pkg/util/diff"
)
type testDecodable struct {
Other string
Value int `json:"value"`
gvk schema.GroupVersionKind
}
func (d *testDecodable) GetObjectKind() schema.ObjectKind { return d }
func (d *testDecodable) SetGroupVersionKind(gvk schema.GroupVersionKind) { d.gvk = gvk }
func (d *testDecodable) GroupVersionKind() schema.GroupVersionKind { return d.gvk }
func TestDecode(t *testing.T) {
testCases := []struct {
creater runtime.ObjectCreater
typer runtime.ObjectTyper
yaml bool
pretty bool
data []byte
defaultGVK *schema.GroupVersionKind
into runtime.Object
errFn func(error) bool
expectedObject runtime.Object
expectedGVK *schema.GroupVersionKind
}{
{
data: []byte("{}"),
expectedGVK: &schema.GroupVersionKind{},
errFn: func(err error) bool { return strings.Contains(err.Error(), "Object 'Kind' is missing in") },
},
{
data: []byte("{}"),
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
creater: &mockCreater{err: fmt.Errorf("fake error")},
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
errFn: func(err error) bool { return err.Error() == "fake error" },
},
{
data: []byte("{}"),
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
creater: &mockCreater{obj: &testDecodable{}},
expectedObject: &testDecodable{},
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
},
// version without group is not defaulted
{
data: []byte(`{"apiVersion":"blah"}`),
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
creater: &mockCreater{obj: &testDecodable{}},
expectedObject: &testDecodable{},
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "", Version: "blah"},
},
// group without version is defaulted
{
data: []byte(`{"apiVersion":"other/"}`),
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
creater: &mockCreater{obj: &testDecodable{}},
expectedObject: &testDecodable{},
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
},
// accept runtime.Unknown as into and bypass creator
{
data: []byte(`{}`),
into: &runtime.Unknown{},
expectedGVK: &schema.GroupVersionKind{},
expectedObject: &runtime.Unknown{
Raw: []byte(`{}`),
ContentType: runtime.ContentTypeJSON,
},
},
{
data: []byte(`{"test":"object"}`),
into: &runtime.Unknown{},
expectedGVK: &schema.GroupVersionKind{},
expectedObject: &runtime.Unknown{
Raw: []byte(`{"test":"object"}`),
ContentType: runtime.ContentTypeJSON,
},
},
{
data: []byte(`{"test":"object"}`),
into: &runtime.Unknown{},
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
expectedObject: &runtime.Unknown{
TypeMeta: runtime.TypeMeta{APIVersion: "other/blah", Kind: "Test"},
Raw: []byte(`{"test":"object"}`),
ContentType: runtime.ContentTypeJSON,
},
},
// unregistered objects can be decoded into directly
{
data: []byte(`{"kind":"Test","apiVersion":"other/blah","value":1,"Other":"test"}`),
into: &testDecodable{},
typer: &mockTyper{err: runtime.NewNotRegisteredErr(schema.GroupVersionKind{}, nil)},
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
expectedObject: &testDecodable{
Other: "test",
Value: 1,
},
},
// registered types get defaulted by the into object kind
{
data: []byte(`{"value":1,"Other":"test"}`),
into: &testDecodable{},
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}},
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
expectedObject: &testDecodable{
Other: "test",
Value: 1,
},
},
// registered types get defaulted by the into object kind even without version, but return an error
{
data: []byte(`{"value":1,"Other":"test"}`),
into: &testDecodable{},
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: ""}},
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: ""},
errFn: func(err error) bool { return strings.Contains(err.Error(), "Object 'apiVersion' is missing in") },
expectedObject: &testDecodable{
Other: "test",
Value: 1,
},
},
// runtime.VersionedObjects are decoded
{
data: []byte(`{"value":1,"Other":"test"}`),
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
creater: &mockCreater{obj: &testDecodable{}},
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}},
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
expectedObject: &runtime.VersionedObjects{
Objects: []runtime.Object{
&testDecodable{
Other: "test",
Value: 1,
},
},
},
},
// runtime.VersionedObjects with an object are decoded into
{
data: []byte(`{"Other":"test"}`),
into: &runtime.VersionedObjects{Objects: []runtime.Object{&testDecodable{Value: 2}}},
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}},
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
expectedObject: &runtime.VersionedObjects{
Objects: []runtime.Object{
&testDecodable{
Other: "test",
Value: 2,
},
},
},
},
}
for i, test := range testCases {
var s runtime.Serializer
if test.yaml {
s = json.NewYAMLSerializer(json.DefaultMetaFactory, test.creater, test.typer)
} else {
s = json.NewSerializer(json.DefaultMetaFactory, test.creater, test.typer, test.pretty)
}
obj, gvk, err := s.Decode([]byte(test.data), test.defaultGVK, test.into)
if !reflect.DeepEqual(test.expectedGVK, gvk) {
t.Errorf("%d: unexpected GVK: %v", i, gvk)
}
switch {
case err == nil && test.errFn != nil:
t.Errorf("%d: failed: %v", i, err)
continue
case err != nil && test.errFn == nil:
t.Errorf("%d: failed: %v", i, err)
continue
case err != nil:
if !test.errFn(err) {
t.Errorf("%d: failed: %v", i, err)
}
if obj != nil {
t.Errorf("%d: should have returned nil object", i)
}
continue
}
if test.into != nil && test.into != obj {
t.Errorf("%d: expected into to be returned: %v", i, obj)
continue
}
if !reflect.DeepEqual(test.expectedObject, obj) {
t.Errorf("%d: unexpected object:\n%s", i, diff.ObjectGoPrintSideBySide(test.expectedObject, obj))
}
}
}
type mockCreater struct {
apiVersion string
kind string
err error
obj runtime.Object
}
func (c *mockCreater) New(kind schema.GroupVersionKind) (runtime.Object, error) {
c.apiVersion, c.kind = kind.GroupVersion().String(), kind.Kind
return c.obj, c.err
}
type mockTyper struct {
gvk *schema.GroupVersionKind
err error
}
func (t *mockTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
if t.gvk == nil {
return nil, false, t.err
}
return []schema.GroupVersionKind{*t.gvk}, false, t.err
}
func (t *mockTyper) Recognizes(_ schema.GroupVersionKind) bool {
return false
}

View file

@ -1,45 +0,0 @@
/*
Copyright 2014 The Kubernetes Authors.
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 json
import "testing"
func TestSimpleMetaFactoryInterpret(t *testing.T) {
factory := SimpleMetaFactory{}
gvk, err := factory.Interpret([]byte(`{"apiVersion":"1","kind":"object"}`))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if gvk.Version != "1" || gvk.Kind != "object" {
t.Errorf("unexpected interpret: %#v", gvk)
}
// no kind or version
gvk, err = factory.Interpret([]byte(`{}`))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if gvk.Version != "" || gvk.Kind != "" {
t.Errorf("unexpected interpret: %#v", gvk)
}
// unparsable
gvk, err = factory.Interpret([]byte(`{`))
if err == nil {
t.Errorf("unexpected non-error")
}
}

View file

@ -1,58 +0,0 @@
/*
Copyright 2014 The Kubernetes Authors.
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 testing
import (
"testing"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
)
type A struct{}
func (A) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
func TestRecognizer(t *testing.T) {
s := runtime.NewScheme()
s.AddKnownTypes(schema.GroupVersion{Version: "v1"}, &A{})
d := recognizer.NewDecoder(
json.NewSerializer(json.DefaultMetaFactory, s, s, false),
json.NewYAMLSerializer(json.DefaultMetaFactory, s, s),
)
out, _, err := d.Decode([]byte(`
kind: A
apiVersion: v1
`), nil, nil)
if err != nil {
t.Fatal(err)
}
t.Logf("%#v", out)
out, _, err = d.Decode([]byte(`
{
"kind":"A",
"apiVersion":"v1"
}
`), nil, nil)
if err != nil {
t.Fatal(err)
}
t.Logf("%#v", out)
}

View file

@ -1,84 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
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 streaming
import (
"bytes"
"io"
"io/ioutil"
"testing"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/framer"
)
type fakeDecoder struct {
got []byte
obj runtime.Object
err error
}
func (d *fakeDecoder) Decode(data []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
d.got = data
return d.obj, nil, d.err
}
func TestEmptyDecoder(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
d := &fakeDecoder{}
_, _, err := NewDecoder(ioutil.NopCloser(buf), d).Decode(nil, nil)
if err != io.EOF {
t.Fatal(err)
}
}
func TestDecoder(t *testing.T) {
frames := [][]byte{
make([]byte, 1025),
make([]byte, 1024*5),
make([]byte, 1024*1024*5),
make([]byte, 1025),
}
pr, pw := io.Pipe()
fw := framer.NewLengthDelimitedFrameWriter(pw)
go func() {
for i := range frames {
fw.Write(frames[i])
}
pw.Close()
}()
r := framer.NewLengthDelimitedFrameReader(pr)
d := &fakeDecoder{}
dec := NewDecoder(r, d)
if _, _, err := dec.Decode(nil, nil); err != nil || !bytes.Equal(d.got, frames[0]) {
t.Fatalf("unexpected %v %v", err, len(d.got))
}
if _, _, err := dec.Decode(nil, nil); err != nil || !bytes.Equal(d.got, frames[1]) {
t.Fatalf("unexpected %v %v", err, len(d.got))
}
if _, _, err := dec.Decode(nil, nil); err != ErrObjectTooLarge || !bytes.Equal(d.got, frames[1]) {
t.Fatalf("unexpected %v %v", err, len(d.got))
}
if _, _, err := dec.Decode(nil, nil); err != nil || !bytes.Equal(d.got, frames[3]) {
t.Fatalf("unexpected %v %v", err, len(d.got))
}
if _, _, err := dec.Decode(nil, nil); err != io.EOF {
t.Fatalf("unexpected %v %v", err, len(d.got))
}
}

View file

@ -1,399 +0,0 @@
/*
Copyright 2015 The Kubernetes Authors.
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 versioning
import (
"fmt"
"io"
"io/ioutil"
"reflect"
"testing"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
)
type testDecodable struct {
Other string
Value int `json:"value"`
gvk schema.GroupVersionKind
}
func (d *testDecodable) GetObjectKind() schema.ObjectKind { return d }
func (d *testDecodable) SetGroupVersionKind(gvk schema.GroupVersionKind) { d.gvk = gvk }
func (d *testDecodable) GroupVersionKind() schema.GroupVersionKind { return d.gvk }
type testNestedDecodable struct {
Other string
Value int `json:"value"`
gvk schema.GroupVersionKind
nestedCalled bool
nestedErr error
}
func (d *testNestedDecodable) GetObjectKind() schema.ObjectKind { return d }
func (d *testNestedDecodable) SetGroupVersionKind(gvk schema.GroupVersionKind) { d.gvk = gvk }
func (d *testNestedDecodable) GroupVersionKind() schema.GroupVersionKind { return d.gvk }
func (d *testNestedDecodable) EncodeNestedObjects(e runtime.Encoder) error {
d.nestedCalled = true
return d.nestedErr
}
func (d *testNestedDecodable) DecodeNestedObjects(_ runtime.Decoder) error {
d.nestedCalled = true
return d.nestedErr
}
func TestNestedDecode(t *testing.T) {
n := &testNestedDecodable{nestedErr: fmt.Errorf("unable to decode")}
decoder := &mockSerializer{obj: n}
codec := NewCodec(nil, decoder, nil, nil, nil, nil, nil, nil, nil)
if _, _, err := codec.Decode([]byte(`{}`), nil, n); err != n.nestedErr {
t.Errorf("unexpected error: %v", err)
}
if !n.nestedCalled {
t.Errorf("did not invoke nested decoder")
}
}
func TestNestedEncode(t *testing.T) {
n := &testNestedDecodable{nestedErr: fmt.Errorf("unable to decode")}
n2 := &testNestedDecodable{nestedErr: fmt.Errorf("unable to decode 2")}
encoder := &mockSerializer{obj: n}
codec := NewCodec(
encoder, nil,
&checkConvertor{obj: n2, groupVersion: schema.GroupVersion{Group: "other"}},
nil, nil,
&mockTyper{gvks: []schema.GroupVersionKind{{Kind: "test"}}},
nil,
schema.GroupVersion{Group: "other"}, nil,
)
if err := codec.Encode(n, ioutil.Discard); err != n2.nestedErr {
t.Errorf("unexpected error: %v", err)
}
if n.nestedCalled || !n2.nestedCalled {
t.Errorf("did not invoke correct nested decoder")
}
}
func TestDecode(t *testing.T) {
gvk1 := &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}
decodable1 := &testDecodable{}
decodable2 := &testDecodable{}
decodable3 := &testDecodable{}
versionedDecodable1 := &runtime.VersionedObjects{Objects: []runtime.Object{decodable1}}
testCases := []struct {
serializer runtime.Serializer
convertor runtime.ObjectConvertor
creater runtime.ObjectCreater
copier runtime.ObjectCopier
typer runtime.ObjectTyper
defaulter runtime.ObjectDefaulter
yaml bool
pretty bool
encodes, decodes runtime.GroupVersioner
defaultGVK *schema.GroupVersionKind
into runtime.Object
errFn func(error) bool
expectedObject runtime.Object
sameObject runtime.Object
expectedGVK *schema.GroupVersionKind
}{
{
serializer: &mockSerializer{actual: gvk1},
convertor: &checkConvertor{groupVersion: schema.GroupVersion{Group: "other", Version: "__internal"}},
expectedGVK: gvk1,
decodes: schema.GroupVersion{Group: "other", Version: "__internal"},
},
{
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
convertor: &checkConvertor{in: decodable1, obj: decodable2, groupVersion: schema.GroupVersion{Group: "other", Version: "__internal"}},
expectedGVK: gvk1,
sameObject: decodable2,
decodes: schema.GroupVersion{Group: "other", Version: "__internal"},
},
// defaultGVK.Group is allowed to force a conversion to the destination group
{
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
defaultGVK: &schema.GroupVersionKind{Group: "force"},
convertor: &checkConvertor{in: decodable1, obj: decodable2, groupVersion: schema.GroupVersion{Group: "force", Version: "__internal"}},
expectedGVK: gvk1,
sameObject: decodable2,
decodes: schema.GroupVersion{Group: "force", Version: "__internal"},
},
// uses direct conversion for into when objects differ
{
into: decodable3,
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
convertor: &checkConvertor{in: decodable1, obj: decodable3, directConvert: true},
expectedGVK: gvk1,
sameObject: decodable3,
},
{
into: versionedDecodable1,
serializer: &mockSerializer{actual: gvk1, obj: decodable3},
convertor: &checkConvertor{in: decodable3, obj: decodable1, directConvert: true},
expectedGVK: gvk1,
sameObject: versionedDecodable1,
},
// returns directly when serializer returns into
{
into: decodable3,
serializer: &mockSerializer{actual: gvk1, obj: decodable3},
expectedGVK: gvk1,
sameObject: decodable3,
},
// returns directly when serializer returns into
{
into: versionedDecodable1,
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
expectedGVK: gvk1,
sameObject: versionedDecodable1,
},
// runtime.VersionedObjects are decoded
{
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
copier: &checkCopy{in: decodable1, obj: decodable1},
convertor: &checkConvertor{in: decodable1, obj: decodable2, groupVersion: schema.GroupVersion{Group: "other", Version: "__internal"}},
expectedGVK: gvk1,
expectedObject: &runtime.VersionedObjects{Objects: []runtime.Object{decodable1, decodable2}},
decodes: schema.GroupVersion{Group: "other", Version: "__internal"},
},
{
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
copier: &checkCopy{in: decodable1, obj: nil, err: fmt.Errorf("error on copy")},
convertor: &checkConvertor{in: decodable1, obj: decodable2, groupVersion: schema.GroupVersion{Group: "other", Version: "__internal"}},
expectedGVK: gvk1,
expectedObject: &runtime.VersionedObjects{Objects: []runtime.Object{decodable1, decodable2}},
decodes: schema.GroupVersion{Group: "other", Version: "__internal"},
},
// decode into the same version as the serialized object
{
decodes: schema.GroupVersions{gvk1.GroupVersion()},
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
convertor: &checkConvertor{in: decodable1, obj: decodable1, groupVersion: schema.GroupVersions{{Group: "other", Version: "blah"}}},
expectedGVK: gvk1,
expectedObject: decodable1,
},
{
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
decodes: schema.GroupVersions{gvk1.GroupVersion()},
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
convertor: &checkConvertor{in: decodable1, obj: decodable1, groupVersion: schema.GroupVersions{{Group: "other", Version: "blah"}}},
copier: &checkCopy{in: decodable1, obj: decodable1, err: nil},
expectedGVK: gvk1,
expectedObject: &runtime.VersionedObjects{Objects: []runtime.Object{decodable1}},
},
// codec with non matching version skips conversion altogether
{
decodes: schema.GroupVersions{{Group: "something", Version: "else"}},
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
convertor: &checkConvertor{in: decodable1, obj: decodable1, groupVersion: schema.GroupVersions{{Group: "something", Version: "else"}}},
expectedGVK: gvk1,
expectedObject: decodable1,
},
{
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
decodes: schema.GroupVersions{{Group: "something", Version: "else"}},
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
convertor: &checkConvertor{in: decodable1, obj: decodable1, groupVersion: schema.GroupVersions{{Group: "something", Version: "else"}}},
copier: &checkCopy{in: decodable1, obj: decodable1, err: nil},
expectedGVK: gvk1,
expectedObject: &runtime.VersionedObjects{Objects: []runtime.Object{decodable1}},
},
}
for i, test := range testCases {
t.Logf("%d", i)
s := NewCodec(test.serializer, test.serializer, test.convertor, test.creater, test.copier, test.typer, test.defaulter, test.encodes, test.decodes)
obj, gvk, err := s.Decode([]byte(`{}`), test.defaultGVK, test.into)
if !reflect.DeepEqual(test.expectedGVK, gvk) {
t.Errorf("%d: unexpected GVK: %v", i, gvk)
}
switch {
case err == nil && test.errFn != nil:
t.Errorf("%d: failed: %v", i, err)
continue
case err != nil && test.errFn == nil:
t.Errorf("%d: failed: %v", i, err)
continue
case err != nil:
if !test.errFn(err) {
t.Errorf("%d: failed: %v", i, err)
}
if obj != nil {
t.Errorf("%d: should have returned nil object", i)
}
continue
}
if test.into != nil && test.into != obj {
t.Errorf("%d: expected into to be returned: %v", i, obj)
continue
}
switch {
case test.expectedObject != nil:
if !reflect.DeepEqual(test.expectedObject, obj) {
t.Errorf("%d: unexpected object:\n%s", i, diff.ObjectGoPrintSideBySide(test.expectedObject, obj))
}
case test.sameObject != nil:
if test.sameObject != obj {
t.Errorf("%d: unexpected object:\n%s", i, diff.ObjectGoPrintSideBySide(test.sameObject, obj))
}
case obj != nil:
t.Errorf("%d: unexpected object: %#v", i, obj)
}
}
}
type checkCopy struct {
in, obj runtime.Object
err error
}
func (c *checkCopy) Copy(obj runtime.Object) (runtime.Object, error) {
if c.in != nil && c.in != obj {
return nil, fmt.Errorf("unexpected input to copy: %#v", obj)
}
return c.obj, c.err
}
type checkConvertor struct {
err error
in, obj runtime.Object
groupVersion runtime.GroupVersioner
directConvert bool
}
func (c *checkConvertor) Convert(in, out, context interface{}) error {
if !c.directConvert {
return fmt.Errorf("unexpected call to Convert")
}
if c.in != nil && c.in != in {
return fmt.Errorf("unexpected in: %s", in)
}
if c.obj != nil && c.obj != out {
return fmt.Errorf("unexpected out: %s", out)
}
return c.err
}
func (c *checkConvertor) ConvertToVersion(in runtime.Object, outVersion runtime.GroupVersioner) (out runtime.Object, err error) {
if c.directConvert {
return nil, fmt.Errorf("unexpected call to ConvertToVersion")
}
if c.in != nil && c.in != in {
return nil, fmt.Errorf("unexpected in: %s", in)
}
if !reflect.DeepEqual(c.groupVersion, outVersion) {
return nil, fmt.Errorf("unexpected outversion: %s (%s)", outVersion, c.groupVersion)
}
return c.obj, c.err
}
func (c *checkConvertor) ConvertFieldLabel(version, kind, label, value string) (string, string, error) {
return "", "", fmt.Errorf("unexpected call to ConvertFieldLabel")
}
type mockSerializer struct {
err error
obj runtime.Object
encodingObjGVK schema.GroupVersionKind
defaults, actual *schema.GroupVersionKind
into runtime.Object
}
func (s *mockSerializer) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
s.defaults = defaults
s.into = into
return s.obj, s.actual, s.err
}
func (s *mockSerializer) Encode(obj runtime.Object, w io.Writer) error {
s.obj = obj
s.encodingObjGVK = obj.GetObjectKind().GroupVersionKind()
return s.err
}
type mockCreater struct {
err error
obj runtime.Object
}
func (c *mockCreater) New(kind schema.GroupVersionKind) (runtime.Object, error) {
return c.obj, c.err
}
type mockTyper struct {
gvks []schema.GroupVersionKind
unversioned bool
err error
}
func (t *mockTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
return t.gvks, t.unversioned, t.err
}
func (t *mockTyper) Recognizes(_ schema.GroupVersionKind) bool {
return true
}
func TestDirectCodecEncode(t *testing.T) {
serializer := mockSerializer{}
typer := mockTyper{
gvks: []schema.GroupVersionKind{
{
Group: "wrong_group",
Kind: "some_kind",
},
{
Group: "expected_group",
Kind: "some_kind",
},
},
}
c := DirectEncoder{
Version: schema.GroupVersion{Group: "expected_group"},
Encoder: &serializer,
ObjectTyper: &typer,
}
c.Encode(&testDecodable{}, ioutil.Discard)
if e, a := "expected_group", serializer.encodingObjGVK.Group; e != a {
t.Errorf("expected group to be %v, got %v", e, a)
}
}

View file

@ -1,46 +0,0 @@
/*
Copyright 2014 The Kubernetes Authors.
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 yaml
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/yaml"
)
// yamlSerializer converts YAML passed to the Decoder methods to JSON.
type yamlSerializer struct {
// the nested serializer
runtime.Serializer
}
// yamlSerializer implements Serializer
var _ runtime.Serializer = yamlSerializer{}
// NewDecodingSerializer adds YAML decoding support to a serializer that supports JSON.
func NewDecodingSerializer(jsonSerializer runtime.Serializer) runtime.Serializer {
return &yamlSerializer{jsonSerializer}
}
func (c yamlSerializer) Decode(data []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
out, err := yaml.ToJSON(data)
if err != nil {
return nil, nil, err
}
data = out
return c.Serializer.Decode(data, gvk, into)
}