mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-10-08 14:29:45 +00:00
Simplify Codec and split responsibilities
Break Codec into two general purpose interfaces, Encoder and Decoder, and move parameter codec responsibilities to ParameterCodec. Make unversioned types explicit when registering - these types go through conversion without modification. Switch to use "__internal" instead of "" to represent the internal version. Future commits will also add group defaulting (so that "" is expanded internally into a known group version, and only cleared during set). For embedded types like runtime.Object -> runtime.RawExtension, put the responsibility on the caller of Decode/Encode to handle transformation into destination serialization. Future commits will expand RawExtension and Unknown to accept a content encoding as well as bytes. Make Unknown a bit more powerful and use it to carry unrecognized types.
This commit is contained in:
@@ -23,6 +23,8 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/conversion"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/runtime/serializer"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
)
|
||||
|
||||
type TypeMeta struct {
|
||||
@@ -51,23 +53,19 @@ type ExternalSimple struct {
|
||||
}
|
||||
|
||||
func (obj *InternalSimple) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *InternalSimple) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
|
||||
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
func (obj *ExternalSimple) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *ExternalSimple) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
|
||||
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
|
||||
func TestScheme(t *testing.T) {
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddInternalGroupVersion(internalGV)
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{})
|
||||
|
||||
// If set, would clear TypeMeta during conversion.
|
||||
//scheme.AddIgnoredConversionType(&TypeMeta{}, &TypeMeta{})
|
||||
|
||||
// test that scheme is an ObjectTyper
|
||||
var _ runtime.ObjectTyper = scheme
|
||||
|
||||
@@ -102,21 +100,27 @@ func TestScheme(t *testing.T) {
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
codecs := serializer.NewCodecFactory(scheme)
|
||||
codec := codecs.LegacyCodec(externalGV)
|
||||
jsonserializer, _ := codecs.SerializerForFileExtension("json")
|
||||
|
||||
simple := &InternalSimple{
|
||||
TestString: "foo",
|
||||
}
|
||||
|
||||
// Test Encode, Decode, DecodeInto, and DecodeToVersion
|
||||
obj := runtime.Object(simple)
|
||||
data, err := scheme.EncodeToVersion(obj, externalGV.String())
|
||||
obj2, err2 := runtime.Decode(scheme, data)
|
||||
obj3 := &InternalSimple{}
|
||||
err3 := runtime.DecodeInto(scheme, data, obj3)
|
||||
obj4, err4 := scheme.DecodeToVersion(data, externalGV)
|
||||
if err != nil || err2 != nil || err3 != nil || err4 != nil {
|
||||
t.Fatalf("Failure: '%v' '%v' '%v' '%v'", err, err2, err3, err4)
|
||||
data, err := runtime.Encode(codec, obj)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
obj2, err := runtime.Decode(codec, data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := obj2.(*InternalSimple); !ok {
|
||||
t.Fatalf("Got wrong type")
|
||||
@@ -124,9 +128,22 @@ func TestScheme(t *testing.T) {
|
||||
if e, a := simple, obj2; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a)
|
||||
}
|
||||
|
||||
obj3 := &InternalSimple{}
|
||||
if err := runtime.DecodeInto(codec, data, obj3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// clearing TypeMeta is a function of the scheme, which we do not test here (ConvertToVersion
|
||||
// does not automatically clear TypeMeta anymore).
|
||||
simple.TypeMeta = TypeMeta{Kind: "Simple", APIVersion: externalGV.String()}
|
||||
if e, a := simple, obj3; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a)
|
||||
}
|
||||
|
||||
obj4, err := runtime.Decode(jsonserializer, data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := obj4.(*ExternalSimple); !ok {
|
||||
t.Fatalf("Got wrong type")
|
||||
}
|
||||
@@ -135,7 +152,7 @@ func TestScheme(t *testing.T) {
|
||||
external := &ExternalSimple{}
|
||||
err = scheme.Convert(simple, external)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
if e, a := simple.TestString, external.TestString; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
@@ -145,36 +162,23 @@ func TestScheme(t *testing.T) {
|
||||
if e, a := 2, internalToExternalCalls; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
// Decode and DecodeInto should each have caused an increment.
|
||||
// DecodeInto and Decode should each have caused an increment because of a conversion
|
||||
if e, a := 2, externalToInternalCalls; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidObjectValueKind(t *testing.T) {
|
||||
internalGV := unversioned.GroupVersion{Group: "", Version: ""}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{})
|
||||
|
||||
embedded := &runtime.EmbeddedObject{}
|
||||
switch obj := embedded.Object.(type) {
|
||||
default:
|
||||
_, err := scheme.ObjectKind(obj)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error on invalid kind")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadJSONRejection(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
codecs := serializer.NewCodecFactory(scheme)
|
||||
jsonserializer, _ := codecs.SerializerForFileExtension("json")
|
||||
|
||||
badJSONMissingKind := []byte(`{ }`)
|
||||
if _, err := runtime.Decode(scheme, badJSONMissingKind); err == nil {
|
||||
if _, err := runtime.Decode(jsonserializer, badJSONMissingKind); err == nil {
|
||||
t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind)
|
||||
}
|
||||
badJSONUnknownType := []byte(`{"kind": "bar"}`)
|
||||
if _, err1 := runtime.Decode(scheme, badJSONUnknownType); err1 == nil {
|
||||
if _, err1 := runtime.Decode(jsonserializer, badJSONUnknownType); err1 == nil {
|
||||
t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType)
|
||||
}
|
||||
/*badJSONKindMismatch := []byte(`{"kind": "Pod"}`)
|
||||
@@ -184,13 +188,13 @@ func TestBadJSONRejection(t *testing.T) {
|
||||
}
|
||||
|
||||
type ExtensionA struct {
|
||||
runtime.PluginBase `json:",inline"`
|
||||
TestString string `json:"testString"`
|
||||
TypeMeta `json:",inline"`
|
||||
TestString string `json:"testString"`
|
||||
}
|
||||
|
||||
type ExtensionB struct {
|
||||
runtime.PluginBase `json:",inline"`
|
||||
TestString string `json:"testString"`
|
||||
TypeMeta `json:",inline"`
|
||||
TestString string `json:"testString"`
|
||||
}
|
||||
|
||||
type ExternalExtensionType struct {
|
||||
@@ -200,7 +204,7 @@ type ExternalExtensionType struct {
|
||||
|
||||
type InternalExtensionType struct {
|
||||
TypeMeta `json:",inline"`
|
||||
Extension runtime.EmbeddedObject `json:"extension"`
|
||||
Extension runtime.Object `json:"extension"`
|
||||
}
|
||||
|
||||
type ExternalOptionalExtensionType struct {
|
||||
@@ -210,143 +214,135 @@ type ExternalOptionalExtensionType struct {
|
||||
|
||||
type InternalOptionalExtensionType struct {
|
||||
TypeMeta `json:",inline"`
|
||||
Extension runtime.EmbeddedObject `json:"extension,omitempty"`
|
||||
Extension runtime.Object `json:"extension,omitempty"`
|
||||
}
|
||||
|
||||
func (obj *ExtensionA) GetObjectKind() unversioned.ObjectKind { return &obj.PluginBase }
|
||||
func (obj *ExtensionA) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
|
||||
_, obj.PluginBase.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
func (obj *ExtensionB) GetObjectKind() unversioned.ObjectKind { return &obj.PluginBase }
|
||||
func (obj *ExtensionB) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
|
||||
_, obj.PluginBase.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
func (obj *ExternalExtensionType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *ExternalExtensionType) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
|
||||
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
func (obj *InternalExtensionType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *InternalExtensionType) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
|
||||
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
func (obj *ExtensionA) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *ExtensionB) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *ExternalExtensionType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *InternalExtensionType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *ExternalOptionalExtensionType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *ExternalOptionalExtensionType) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
|
||||
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
func (obj *InternalOptionalExtensionType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *InternalOptionalExtensionType) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
|
||||
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
|
||||
func TestExternalToInternalMapping(t *testing.T) {
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddInternalGroupVersion(internalGV)
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("OptionalExtensionType"), &InternalOptionalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("OptionalExtensionType"), &ExternalOptionalExtensionType{})
|
||||
|
||||
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
|
||||
|
||||
table := []struct {
|
||||
obj runtime.Object
|
||||
encoded string
|
||||
}{
|
||||
{
|
||||
&InternalOptionalExtensionType{Extension: runtime.EmbeddedObject{Object: nil}},
|
||||
&InternalOptionalExtensionType{Extension: nil},
|
||||
`{"kind":"OptionalExtensionType","apiVersion":"` + externalGV.String() + `"}`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, item := range table {
|
||||
gotDecoded, err := runtime.Decode(scheme, []byte(item.encoded))
|
||||
for i, item := range table {
|
||||
gotDecoded, err := runtime.Decode(codec, []byte(item.encoded))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error '%v' (%v)", err, item.encoded)
|
||||
} else if e, a := item.obj, gotDecoded; !reflect.DeepEqual(e, a) {
|
||||
var eEx, aEx runtime.Object
|
||||
if obj, ok := e.(*InternalOptionalExtensionType); ok {
|
||||
eEx = obj.Extension.Object
|
||||
}
|
||||
if obj, ok := a.(*InternalOptionalExtensionType); ok {
|
||||
aEx = obj.Extension.Object
|
||||
}
|
||||
t.Errorf("expected %#v, got %#v (%#v, %#v)", e, a, eEx, aEx)
|
||||
t.Errorf("%d: unexpected objects:\n%s", i, util.ObjectGoPrintSideBySide(e, a))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtensionMapping(t *testing.T) {
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddInternalGroupVersion(internalGV)
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("ExtensionType"), &InternalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("OptionalExtensionType"), &InternalOptionalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("A"), &ExtensionA{})
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("B"), &ExtensionB{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("ExtensionType"), &ExternalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("OptionalExtensionType"), &ExternalOptionalExtensionType{})
|
||||
|
||||
// register external first when the object is the same in both schemes, so ObjectVersionAndKind reports the
|
||||
// external version.
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("A"), &ExtensionA{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("B"), &ExtensionB{})
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("A"), &ExtensionA{})
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("B"), &ExtensionB{})
|
||||
|
||||
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
|
||||
|
||||
table := []struct {
|
||||
obj runtime.Object
|
||||
encoded string
|
||||
obj runtime.Object
|
||||
expected runtime.Object
|
||||
encoded string
|
||||
}{
|
||||
{
|
||||
&InternalExtensionType{Extension: runtime.EmbeddedObject{Object: &ExtensionA{TestString: "foo"}}},
|
||||
`{"kind":"ExtensionType","apiVersion":"` + externalGV.String() + `","extension":{"kind":"A","testString":"foo"}}
|
||||
&InternalExtensionType{
|
||||
Extension: runtime.NewEncodable(codec, &ExtensionA{TestString: "foo"}),
|
||||
},
|
||||
&InternalExtensionType{
|
||||
Extension: &runtime.Unknown{
|
||||
RawJSON: []byte(`{"kind":"A","apiVersion":"test.group/testExternal","testString":"foo"}`),
|
||||
},
|
||||
},
|
||||
// apiVersion is set in the serialized object for easier consumption by clients
|
||||
`{"kind":"ExtensionType","apiVersion":"` + externalGV.String() + `","extension":{"kind":"A","apiVersion":"test.group/testExternal","testString":"foo"}}
|
||||
`,
|
||||
}, {
|
||||
&InternalExtensionType{Extension: runtime.EmbeddedObject{Object: &ExtensionB{TestString: "bar"}}},
|
||||
`{"kind":"ExtensionType","apiVersion":"` + externalGV.String() + `","extension":{"kind":"B","testString":"bar"}}
|
||||
&InternalExtensionType{Extension: runtime.NewEncodable(codec, &ExtensionB{TestString: "bar"})},
|
||||
&InternalExtensionType{
|
||||
Extension: &runtime.Unknown{
|
||||
RawJSON: []byte(`{"kind":"B","apiVersion":"test.group/testExternal","testString":"bar"}`),
|
||||
},
|
||||
},
|
||||
// apiVersion is set in the serialized object for easier consumption by clients
|
||||
`{"kind":"ExtensionType","apiVersion":"` + externalGV.String() + `","extension":{"kind":"B","apiVersion":"test.group/testExternal","testString":"bar"}}
|
||||
`,
|
||||
}, {
|
||||
&InternalExtensionType{Extension: runtime.EmbeddedObject{Object: nil}},
|
||||
&InternalExtensionType{Extension: nil},
|
||||
&InternalExtensionType{
|
||||
Extension: nil,
|
||||
},
|
||||
`{"kind":"ExtensionType","apiVersion":"` + externalGV.String() + `","extension":null}
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, item := range table {
|
||||
gotEncoded, err := scheme.EncodeToVersion(item.obj, externalGV.String())
|
||||
for i, item := range table {
|
||||
gotEncoded, err := runtime.Encode(codec, item.obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error '%v' (%#v)", err, item.obj)
|
||||
} else if e, a := item.encoded, string(gotEncoded); e != a {
|
||||
t.Errorf("expected\n%#v\ngot\n%#v\n", e, a)
|
||||
}
|
||||
|
||||
gotDecoded, err := runtime.Decode(scheme, []byte(item.encoded))
|
||||
gotDecoded, err := runtime.Decode(codec, []byte(item.encoded))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error '%v' (%v)", err, item.encoded)
|
||||
} else if e, a := item.obj, gotDecoded; !reflect.DeepEqual(e, a) {
|
||||
var eEx, aEx runtime.Object
|
||||
if obj, ok := e.(*InternalExtensionType); ok {
|
||||
eEx = obj.Extension.Object
|
||||
}
|
||||
if obj, ok := a.(*InternalExtensionType); ok {
|
||||
aEx = obj.Extension.Object
|
||||
}
|
||||
t.Errorf("expected %#v, got %#v (%#v, %#v)", e, a, eEx, aEx)
|
||||
} else if e, a := item.expected, gotDecoded; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d: unexpected objects:\n%s", i, util.ObjectGoPrintSideBySide(e, a))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncode(t *testing.T) {
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddInternalGroupVersion(internalGV)
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{})
|
||||
codec := runtime.CodecFor(scheme, externalGV)
|
||||
|
||||
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
|
||||
|
||||
test := &InternalSimple{
|
||||
TestString: "I'm the same",
|
||||
}
|
||||
obj := runtime.Object(test)
|
||||
data, err := runtime.Encode(codec, obj)
|
||||
obj2, err2 := runtime.Decode(codec, data)
|
||||
obj2, gvk, err2 := codec.Decode(data, nil, nil)
|
||||
if err != nil || err2 != nil {
|
||||
t.Fatalf("Failure: '%v' '%v'", err, err2)
|
||||
}
|
||||
@@ -354,6 +350,68 @@ func TestEncode(t *testing.T) {
|
||||
t.Fatalf("Got wrong type")
|
||||
}
|
||||
if !reflect.DeepEqual(obj2, test) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", &test, obj2)
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", test, obj2)
|
||||
}
|
||||
if !reflect.DeepEqual(gvk, &unversioned.GroupVersionKind{Group: "test.group", Version: "testExternal", Kind: "Simple"}) {
|
||||
t.Errorf("unexpected gvk returned by decode: %#v", gvk)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnversionedTypes(t *testing.T) {
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
otherGV := unversioned.GroupVersion{Group: "group", Version: "other"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddUnversionedTypes(externalGV, &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{})
|
||||
scheme.AddKnownTypeWithName(otherGV.WithKind("Simple"), &ExternalSimple{})
|
||||
|
||||
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
|
||||
|
||||
if unv, ok := scheme.IsUnversioned(&InternalSimple{}); !unv || !ok {
|
||||
t.Fatal("type not unversioned and in scheme: %t %t", unv, ok)
|
||||
}
|
||||
|
||||
kind, err := scheme.ObjectKind(&InternalSimple{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if kind != externalGV.WithKind("InternalSimple") {
|
||||
t.Fatalf("unexpected: %#v", kind)
|
||||
}
|
||||
|
||||
test := &InternalSimple{
|
||||
TestString: "I'm the same",
|
||||
}
|
||||
obj := runtime.Object(test)
|
||||
data, err := runtime.Encode(codec, obj)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
obj2, gvk, err := codec.Decode(data, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := obj2.(*InternalSimple); !ok {
|
||||
t.Fatalf("Got wrong type")
|
||||
}
|
||||
if !reflect.DeepEqual(obj2, test) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", test, obj2)
|
||||
}
|
||||
// object is serialized as an unversioned object (in the group and version it was defined in)
|
||||
if !reflect.DeepEqual(gvk, &unversioned.GroupVersionKind{Group: "test.group", Version: "testExternal", Kind: "InternalSimple"}) {
|
||||
t.Errorf("unexpected gvk returned by decode: %#v", gvk)
|
||||
}
|
||||
|
||||
// when serialized to a different group, the object is kept in its preferred name
|
||||
codec = serializer.NewCodecFactory(scheme).LegacyCodec(otherGV)
|
||||
data, err = runtime.Encode(codec, obj)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(data) != `{"kind":"InternalSimple","apiVersion":"test.group/testExternal","testString":"I'm the same"}`+"\n" {
|
||||
t.Errorf("unexpected data: %s", data)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user