apimachinery+apiserver: extract test types to work w/ deepcopy-gen

pull/6/head
Dr. Stefan Schimanski 2017-07-06 10:46:04 +02:00 committed by Dr. Stefan Schimanski
parent 954c356dc5
commit 205cd90d46
16 changed files with 726 additions and 539 deletions

View File

@ -0,0 +1,18 @@
/*
Copyright 2017 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.
*/
// +k8s:deepcopy-gen=package
package v1

View File

@ -22,37 +22,17 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
runtimetesting "k8s.io/apimachinery/pkg/runtime/testing"
) )
type InternalComplex struct {
runtime.TypeMeta
String string
Integer int
Integer64 int64
Int64 int64
Bool bool
}
type ExternalComplex struct {
runtime.TypeMeta `json:",inline"`
String string `json:"string" description:"testing"`
Integer int `json:"int"`
Integer64 int64 `json:",omitempty"`
Int64 int64
Bool bool `json:"bool"`
}
func (obj *InternalComplex) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ExternalComplex) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func TestStringMapConversion(t *testing.T) { func TestStringMapConversion(t *testing.T) {
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal} internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
externalGV := schema.GroupVersion{Group: "test.group", Version: "external"} externalGV := schema.GroupVersion{Group: "test.group", Version: "external"}
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
scheme.Log(t) scheme.Log(t)
scheme.AddKnownTypeWithName(internalGV.WithKind("Complex"), &InternalComplex{}) scheme.AddKnownTypeWithName(internalGV.WithKind("Complex"), &runtimetesting.InternalComplex{})
scheme.AddKnownTypeWithName(externalGV.WithKind("Complex"), &ExternalComplex{}) scheme.AddKnownTypeWithName(externalGV.WithKind("Complex"), &runtimetesting.ExternalComplex{})
testCases := map[string]struct { testCases := map[string]struct {
input map[string][]string input map[string][]string
@ -66,62 +46,62 @@ func TestStringMapConversion(t *testing.T) {
"int": {"1"}, "int": {"1"},
"Integer64": {"2"}, "Integer64": {"2"},
}, },
expected: &ExternalComplex{String: "value", Integer: 1}, expected: &runtimetesting.ExternalComplex{String: "value", Integer: 1},
}, },
"returns error on bad int": { "returns error on bad int": {
input: map[string][]string{ input: map[string][]string{
"int": {"a"}, "int": {"a"},
}, },
errFn: func(err error) bool { return err != nil }, errFn: func(err error) bool { return err != nil },
expected: &ExternalComplex{}, expected: &runtimetesting.ExternalComplex{},
}, },
"parses int64": { "parses int64": {
input: map[string][]string{ input: map[string][]string{
"Int64": {"-1"}, "Int64": {"-1"},
}, },
expected: &ExternalComplex{Int64: -1}, expected: &runtimetesting.ExternalComplex{Int64: -1},
}, },
"returns error on bad int64": { "returns error on bad int64": {
input: map[string][]string{ input: map[string][]string{
"Int64": {"a"}, "Int64": {"a"},
}, },
errFn: func(err error) bool { return err != nil }, errFn: func(err error) bool { return err != nil },
expected: &ExternalComplex{}, expected: &runtimetesting.ExternalComplex{},
}, },
"parses boolean true": { "parses boolean true": {
input: map[string][]string{ input: map[string][]string{
"bool": {"true"}, "bool": {"true"},
}, },
expected: &ExternalComplex{Bool: true}, expected: &runtimetesting.ExternalComplex{Bool: true},
}, },
"parses boolean any value": { "parses boolean any value": {
input: map[string][]string{ input: map[string][]string{
"bool": {"foo"}, "bool": {"foo"},
}, },
expected: &ExternalComplex{Bool: true}, expected: &runtimetesting.ExternalComplex{Bool: true},
}, },
"parses boolean false": { "parses boolean false": {
input: map[string][]string{ input: map[string][]string{
"bool": {"false"}, "bool": {"false"},
}, },
expected: &ExternalComplex{Bool: false}, expected: &runtimetesting.ExternalComplex{Bool: false},
}, },
"parses boolean empty value": { "parses boolean empty value": {
input: map[string][]string{ input: map[string][]string{
"bool": {""}, "bool": {""},
}, },
expected: &ExternalComplex{Bool: true}, expected: &runtimetesting.ExternalComplex{Bool: true},
}, },
"parses boolean no value": { "parses boolean no value": {
input: map[string][]string{ input: map[string][]string{
"bool": {}, "bool": {},
}, },
expected: &ExternalComplex{Bool: false}, expected: &runtimetesting.ExternalComplex{Bool: false},
}, },
} }
for k, tc := range testCases { for k, tc := range testCases {
out := &ExternalComplex{} out := &runtimetesting.ExternalComplex{}
if err := scheme.Convert(&tc.input, out, nil); (tc.errFn == nil && err != nil) || (tc.errFn != nil && !tc.errFn(err)) { if err := scheme.Convert(&tc.input, out, nil); (tc.errFn == nil && err != nil) || (tc.errFn != nil && !tc.errFn(err)) {
t.Errorf("%s: unexpected error: %v", k, err) t.Errorf("%s: unexpected error: %v", k, err)
continue continue

View File

@ -25,50 +25,18 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer"
runtimetesting "k8s.io/apimachinery/pkg/runtime/testing"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
) )
type EmbeddedTest struct {
runtime.TypeMeta
ID string
Object runtime.Object
EmptyObject runtime.Object
}
type EmbeddedTestExternal struct {
runtime.TypeMeta `json:",inline"`
ID string `json:"id,omitempty"`
Object runtime.RawExtension `json:"object,omitempty"`
EmptyObject runtime.RawExtension `json:"emptyObject,omitempty"`
}
type ObjectTest struct {
runtime.TypeMeta
ID string
Items []runtime.Object
}
type ObjectTestExternal struct {
runtime.TypeMeta `yaml:",inline" json:",inline"`
ID string `json:"id,omitempty"`
Items []runtime.RawExtension `json:"items,omitempty"`
}
func (obj *ObjectTest) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ObjectTestExternal) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *EmbeddedTest) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *EmbeddedTestExternal) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func TestDecodeEmptyRawExtensionAsObject(t *testing.T) { func TestDecodeEmptyRawExtensionAsObject(t *testing.T) {
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal} internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"} externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
externalGVK := externalGV.WithKind("ObjectTest") externalGVK := externalGV.WithKind("ObjectTest")
s := runtime.NewScheme() s := runtime.NewScheme()
s.AddKnownTypes(internalGV, &ObjectTest{}) s.AddKnownTypes(internalGV, &runtimetesting.ObjectTest{})
s.AddKnownTypeWithName(externalGVK, &ObjectTestExternal{}) s.AddKnownTypeWithName(externalGVK, &runtimetesting.ObjectTestExternal{})
codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV) codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
@ -76,7 +44,7 @@ func TestDecodeEmptyRawExtensionAsObject(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
test := obj.(*ObjectTest) test := obj.(*runtimetesting.ObjectTest)
if unk, ok := test.Items[0].(*runtime.Unknown); !ok || unk.Kind != "" || unk.APIVersion != "" || string(unk.Raw) != "{}" || unk.ContentType != runtime.ContentTypeJSON { if unk, ok := test.Items[0].(*runtime.Unknown); !ok || unk.Kind != "" || unk.APIVersion != "" || string(unk.Raw) != "{}" || unk.ContentType != runtime.ContentTypeJSON {
t.Fatalf("unexpected object: %#v", test.Items[0]) t.Fatalf("unexpected object: %#v", test.Items[0])
} }
@ -88,7 +56,7 @@ func TestDecodeEmptyRawExtensionAsObject(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
test = obj.(*ObjectTest) test = obj.(*runtimetesting.ObjectTest)
if unk, ok := test.Items[0].(*runtime.Unknown); !ok || unk.Kind != "" || unk.APIVersion != "" || string(unk.Raw) != `{"kind":"Other","apiVersion":"v1"}` || unk.ContentType != runtime.ContentTypeJSON { if unk, ok := test.Items[0].(*runtime.Unknown); !ok || unk.Kind != "" || unk.APIVersion != "" || string(unk.Raw) != `{"kind":"Other","apiVersion":"v1"}` || unk.ContentType != runtime.ContentTypeJSON {
t.Fatalf("unexpected object: %#v", test.Items[0]) t.Fatalf("unexpected object: %#v", test.Items[0])
} }
@ -102,29 +70,29 @@ func TestArrayOfRuntimeObject(t *testing.T) {
externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"} externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
s := runtime.NewScheme() s := runtime.NewScheme()
s.AddKnownTypes(internalGV, &EmbeddedTest{}) s.AddKnownTypes(internalGV, &runtimetesting.EmbeddedTest{})
s.AddKnownTypeWithName(externalGV.WithKind("EmbeddedTest"), &EmbeddedTestExternal{}) s.AddKnownTypeWithName(externalGV.WithKind("EmbeddedTest"), &runtimetesting.EmbeddedTestExternal{})
s.AddKnownTypes(internalGV, &ObjectTest{}) s.AddKnownTypes(internalGV, &runtimetesting.ObjectTest{})
s.AddKnownTypeWithName(externalGV.WithKind("ObjectTest"), &ObjectTestExternal{}) s.AddKnownTypeWithName(externalGV.WithKind("ObjectTest"), &runtimetesting.ObjectTestExternal{})
codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV) codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
innerItems := []runtime.Object{ innerItems := []runtime.Object{
&EmbeddedTest{ID: "baz"}, &runtimetesting.EmbeddedTest{ID: "baz"},
} }
items := []runtime.Object{ items := []runtime.Object{
&EmbeddedTest{ID: "foo"}, &runtimetesting.EmbeddedTest{ID: "foo"},
&EmbeddedTest{ID: "bar"}, &runtimetesting.EmbeddedTest{ID: "bar"},
// TODO: until YAML is removed, this JSON must be in ascending key order to ensure consistent roundtrip serialization // TODO: until YAML is removed, this JSON must be in ascending key order to ensure consistent roundtrip serialization
&runtime.Unknown{ &runtime.Unknown{
Raw: []byte(`{"apiVersion":"unknown.group/unknown","foo":"bar","kind":"OtherTest"}`), Raw: []byte(`{"apiVersion":"unknown.group/unknown","foo":"bar","kind":"OtherTest"}`),
ContentType: runtime.ContentTypeJSON, ContentType: runtime.ContentTypeJSON,
}, },
&ObjectTest{ &runtimetesting.ObjectTest{
Items: runtime.NewEncodableList(codec, innerItems), Items: runtime.NewEncodableList(codec, innerItems),
}, },
} }
internal := &ObjectTest{ internal := &runtimetesting.ObjectTest{
Items: runtime.NewEncodableList(codec, items), Items: runtime.NewEncodableList(codec, items),
} }
wire, err := runtime.Encode(codec, internal) wire, err := runtime.Encode(codec, internal)
@ -133,13 +101,13 @@ func TestArrayOfRuntimeObject(t *testing.T) {
} }
t.Logf("Wire format is:\n%s\n", string(wire)) t.Logf("Wire format is:\n%s\n", string(wire))
obj := &ObjectTestExternal{} obj := &runtimetesting.ObjectTestExternal{}
if err := json.Unmarshal(wire, obj); err != nil { if err := json.Unmarshal(wire, obj); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
t.Logf("exact wire is: %s", string(obj.Items[0].Raw)) t.Logf("exact wire is: %s", string(obj.Items[0].Raw))
items[3] = &ObjectTest{Items: innerItems} items[3] = &runtimetesting.ObjectTest{Items: innerItems}
internal.Items = items internal.Items = items
decoded, err := runtime.Decode(codec, wire) decoded, err := runtime.Decode(codec, wire)
@ -178,15 +146,15 @@ func TestNestedObject(t *testing.T) {
embeddedTestExternalGVK := externalGV.WithKind("EmbeddedTest") embeddedTestExternalGVK := externalGV.WithKind("EmbeddedTest")
s := runtime.NewScheme() s := runtime.NewScheme()
s.AddKnownTypes(internalGV, &EmbeddedTest{}) s.AddKnownTypes(internalGV, &runtimetesting.EmbeddedTest{})
s.AddKnownTypeWithName(embeddedTestExternalGVK, &EmbeddedTestExternal{}) s.AddKnownTypeWithName(embeddedTestExternalGVK, &runtimetesting.EmbeddedTestExternal{})
codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV) codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
inner := &EmbeddedTest{ inner := &runtimetesting.EmbeddedTest{
ID: "inner", ID: "inner",
} }
outer := &EmbeddedTest{ outer := &runtimetesting.EmbeddedTest{
ID: "outer", ID: "outer",
Object: runtime.NewEncodable(codec, inner), Object: runtime.NewEncodable(codec, inner),
} }
@ -210,18 +178,18 @@ func TestNestedObject(t *testing.T) {
t.Errorf("Expected unequal %#v %#v", e, a) t.Errorf("Expected unequal %#v %#v", e, a)
} }
obj, err := runtime.Decode(codec, decoded.(*EmbeddedTest).Object.(*runtime.Unknown).Raw) obj, err := runtime.Decode(codec, decoded.(*runtimetesting.EmbeddedTest).Object.(*runtime.Unknown).Raw)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
decoded.(*EmbeddedTest).Object = obj decoded.(*runtimetesting.EmbeddedTest).Object = obj
if e, a := outer, decoded; !reflect.DeepEqual(e, a) { if e, a := outer, decoded; !reflect.DeepEqual(e, a) {
t.Errorf("Expected equal %#v %#v", e, a) t.Errorf("Expected equal %#v %#v", e, a)
} }
// test JSON decoding of the external object, which should preserve // test JSON decoding of the external object, which should preserve
// raw bytes // raw bytes
var externalViaJSON EmbeddedTestExternal var externalViaJSON runtimetesting.EmbeddedTestExternal
err = json.Unmarshal(wire, &externalViaJSON) err = json.Unmarshal(wire, &externalViaJSON)
if err != nil { if err != nil {
t.Fatalf("Unexpected decode error %v", err) t.Fatalf("Unexpected decode error %v", err)
@ -237,7 +205,7 @@ func TestNestedObject(t *testing.T) {
// Generic Unmarshalling of JSON cannot load the nested objects because there is // Generic Unmarshalling of JSON cannot load the nested objects because there is
// no default schema set. Consumers wishing to get direct JSON decoding must use // no default schema set. Consumers wishing to get direct JSON decoding must use
// the external representation // the external representation
var decodedViaJSON EmbeddedTest var decodedViaJSON runtimetesting.EmbeddedTest
err = json.Unmarshal(wire, &decodedViaJSON) err = json.Unmarshal(wire, &decodedViaJSON)
if err == nil { if err == nil {
t.Fatal("Expeceted decode error") t.Fatal("Expeceted decode error")
@ -257,12 +225,12 @@ func TestDeepCopyOfRuntimeObject(t *testing.T) {
embeddedTestExternalGVK := externalGV.WithKind("EmbeddedTest") embeddedTestExternalGVK := externalGV.WithKind("EmbeddedTest")
s := runtime.NewScheme() s := runtime.NewScheme()
s.AddKnownTypes(internalGV, &EmbeddedTest{}) s.AddKnownTypes(internalGV, &runtimetesting.EmbeddedTest{})
s.AddKnownTypeWithName(embeddedTestExternalGVK, &EmbeddedTestExternal{}) s.AddKnownTypeWithName(embeddedTestExternalGVK, &runtimetesting.EmbeddedTestExternal{})
original := &EmbeddedTest{ original := &runtimetesting.EmbeddedTest{
ID: "outer", ID: "outer",
Object: &EmbeddedTest{ Object: &runtimetesting.EmbeddedTest{
ID: "inner", ID: "inner",
}, },
} }

View File

@ -28,31 +28,19 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer"
runtimetesting "k8s.io/apimachinery/pkg/runtime/testing"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
) )
var fuzzIters = flag.Int("fuzz-iters", 50, "How many fuzzing iterations to do.") var fuzzIters = flag.Int("fuzz-iters", 50, "How many fuzzing iterations to do.")
type InternalSimple struct {
runtime.TypeMeta `json:",inline"`
TestString string `json:"testString"`
}
type ExternalSimple struct {
runtime.TypeMeta `json:",inline"`
TestString string `json:"testString"`
}
func (obj *InternalSimple) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ExternalSimple) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func TestScheme(t *testing.T) { func TestScheme(t *testing.T) {
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal} internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"} externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"}
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{}) scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &runtimetesting.InternalSimple{})
scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{}) scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &runtimetesting.ExternalSimple{})
// If set, would clear TypeMeta during conversion. // If set, would clear TypeMeta during conversion.
//scheme.AddIgnoredConversionType(&TypeMeta{}, &TypeMeta{}) //scheme.AddIgnoredConversionType(&TypeMeta{}, &TypeMeta{})
@ -65,13 +53,13 @@ func TestScheme(t *testing.T) {
// Register functions to verify that scope.Meta() gets set correctly. // Register functions to verify that scope.Meta() gets set correctly.
err := scheme.AddConversionFuncs( err := scheme.AddConversionFuncs(
func(in *InternalSimple, out *ExternalSimple, scope conversion.Scope) error { func(in *runtimetesting.InternalSimple, out *runtimetesting.ExternalSimple, scope conversion.Scope) error {
scope.Convert(&in.TypeMeta, &out.TypeMeta, 0) scope.Convert(&in.TypeMeta, &out.TypeMeta, 0)
scope.Convert(&in.TestString, &out.TestString, 0) scope.Convert(&in.TestString, &out.TestString, 0)
internalToExternalCalls++ internalToExternalCalls++
return nil return nil
}, },
func(in *ExternalSimple, out *InternalSimple, scope conversion.Scope) error { func(in *runtimetesting.ExternalSimple, out *runtimetesting.InternalSimple, scope conversion.Scope) error {
scope.Convert(&in.TypeMeta, &out.TypeMeta, 0) scope.Convert(&in.TypeMeta, &out.TypeMeta, 0)
scope.Convert(&in.TestString, &out.TestString, 0) scope.Convert(&in.TestString, &out.TestString, 0)
externalToInternalCalls++ externalToInternalCalls++
@ -87,7 +75,7 @@ func TestScheme(t *testing.T) {
info, _ := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), runtime.ContentTypeJSON) info, _ := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), runtime.ContentTypeJSON)
jsonserializer := info.Serializer jsonserializer := info.Serializer
simple := &InternalSimple{ simple := &runtimetesting.InternalSimple{
TestString: "foo", TestString: "foo",
} }
@ -102,14 +90,14 @@ func TestScheme(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, ok := obj2.(*InternalSimple); !ok { if _, ok := obj2.(*runtimetesting.InternalSimple); !ok {
t.Fatalf("Got wrong type") t.Fatalf("Got wrong type")
} }
if e, a := simple, obj2; !reflect.DeepEqual(e, a) { if e, a := simple, obj2; !reflect.DeepEqual(e, a) {
t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a) t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a)
} }
obj3 := &InternalSimple{} obj3 := &runtimetesting.InternalSimple{}
if err := runtime.DecodeInto(codec, data, obj3); err != nil { if err := runtime.DecodeInto(codec, data, obj3); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -124,12 +112,12 @@ func TestScheme(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, ok := obj4.(*ExternalSimple); !ok { if _, ok := obj4.(*runtimetesting.ExternalSimple); !ok {
t.Fatalf("Got wrong type") t.Fatalf("Got wrong type")
} }
// Test Convert // Test Convert
external := &ExternalSimple{} external := &runtimetesting.ExternalSimple{}
err = scheme.Convert(simple, external, nil) err = scheme.Convert(simple, external, nil)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
@ -168,50 +156,13 @@ func TestBadJSONRejection(t *testing.T) {
}*/ }*/
} }
type ExtensionA struct {
runtime.TypeMeta `json:",inline"`
TestString string `json:"testString"`
}
type ExtensionB struct {
runtime.TypeMeta `json:",inline"`
TestString string `json:"testString"`
}
type ExternalExtensionType struct {
runtime.TypeMeta `json:",inline"`
Extension runtime.RawExtension `json:"extension"`
}
type InternalExtensionType struct {
runtime.TypeMeta `json:",inline"`
Extension runtime.Object `json:"extension"`
}
type ExternalOptionalExtensionType struct {
runtime.TypeMeta `json:",inline"`
Extension runtime.RawExtension `json:"extension,omitempty"`
}
type InternalOptionalExtensionType struct {
runtime.TypeMeta `json:",inline"`
Extension runtime.Object `json:"extension,omitempty"`
}
func (obj *ExtensionA) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ExtensionB) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ExternalExtensionType) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *InternalExtensionType) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ExternalOptionalExtensionType) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *InternalOptionalExtensionType) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func TestExternalToInternalMapping(t *testing.T) { func TestExternalToInternalMapping(t *testing.T) {
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal} internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"} externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"}
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName(internalGV.WithKind("OptionalExtensionType"), &InternalOptionalExtensionType{}) scheme.AddKnownTypeWithName(internalGV.WithKind("OptionalExtensionType"), &runtimetesting.InternalOptionalExtensionType{})
scheme.AddKnownTypeWithName(externalGV.WithKind("OptionalExtensionType"), &ExternalOptionalExtensionType{}) scheme.AddKnownTypeWithName(externalGV.WithKind("OptionalExtensionType"), &runtimetesting.ExternalOptionalExtensionType{})
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV) codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
@ -220,7 +171,7 @@ func TestExternalToInternalMapping(t *testing.T) {
encoded string encoded string
}{ }{
{ {
&InternalOptionalExtensionType{Extension: nil}, &runtimetesting.InternalOptionalExtensionType{Extension: nil},
`{"kind":"OptionalExtensionType","apiVersion":"` + externalGV.String() + `"}`, `{"kind":"OptionalExtensionType","apiVersion":"` + externalGV.String() + `"}`,
}, },
} }
@ -240,17 +191,17 @@ func TestExtensionMapping(t *testing.T) {
externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"} externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"}
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName(internalGV.WithKind("ExtensionType"), &InternalExtensionType{}) scheme.AddKnownTypeWithName(internalGV.WithKind("ExtensionType"), &runtimetesting.InternalExtensionType{})
scheme.AddKnownTypeWithName(internalGV.WithKind("OptionalExtensionType"), &InternalOptionalExtensionType{}) scheme.AddKnownTypeWithName(internalGV.WithKind("OptionalExtensionType"), &runtimetesting.InternalOptionalExtensionType{})
scheme.AddKnownTypeWithName(externalGV.WithKind("ExtensionType"), &ExternalExtensionType{}) scheme.AddKnownTypeWithName(externalGV.WithKind("ExtensionType"), &runtimetesting.ExternalExtensionType{})
scheme.AddKnownTypeWithName(externalGV.WithKind("OptionalExtensionType"), &ExternalOptionalExtensionType{}) scheme.AddKnownTypeWithName(externalGV.WithKind("OptionalExtensionType"), &runtimetesting.ExternalOptionalExtensionType{})
// register external first when the object is the same in both schemes, so ObjectVersionAndKind reports the // register external first when the object is the same in both schemes, so ObjectVersionAndKind reports the
// external version. // external version.
scheme.AddKnownTypeWithName(externalGV.WithKind("A"), &ExtensionA{}) scheme.AddKnownTypeWithName(externalGV.WithKind("A"), &runtimetesting.ExtensionA{})
scheme.AddKnownTypeWithName(externalGV.WithKind("B"), &ExtensionB{}) scheme.AddKnownTypeWithName(externalGV.WithKind("B"), &runtimetesting.ExtensionB{})
scheme.AddKnownTypeWithName(internalGV.WithKind("A"), &ExtensionA{}) scheme.AddKnownTypeWithName(internalGV.WithKind("A"), &runtimetesting.ExtensionA{})
scheme.AddKnownTypeWithName(internalGV.WithKind("B"), &ExtensionB{}) scheme.AddKnownTypeWithName(internalGV.WithKind("B"), &runtimetesting.ExtensionB{})
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV) codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
@ -260,10 +211,10 @@ func TestExtensionMapping(t *testing.T) {
encoded string encoded string
}{ }{
{ {
&InternalExtensionType{ &runtimetesting.InternalExtensionType{
Extension: runtime.NewEncodable(codec, &ExtensionA{TestString: "foo"}), Extension: runtime.NewEncodable(codec, &runtimetesting.ExtensionA{TestString: "foo"}),
}, },
&InternalExtensionType{ &runtimetesting.InternalExtensionType{
Extension: &runtime.Unknown{ Extension: &runtime.Unknown{
Raw: []byte(`{"apiVersion":"test.group/testExternal","kind":"A","testString":"foo"}`), Raw: []byte(`{"apiVersion":"test.group/testExternal","kind":"A","testString":"foo"}`),
ContentType: runtime.ContentTypeJSON, ContentType: runtime.ContentTypeJSON,
@ -273,8 +224,8 @@ func TestExtensionMapping(t *testing.T) {
`{"apiVersion":"` + externalGV.String() + `","kind":"ExtensionType","extension":{"apiVersion":"test.group/testExternal","kind":"A","testString":"foo"}} `{"apiVersion":"` + externalGV.String() + `","kind":"ExtensionType","extension":{"apiVersion":"test.group/testExternal","kind":"A","testString":"foo"}}
`, `,
}, { }, {
&InternalExtensionType{Extension: runtime.NewEncodable(codec, &ExtensionB{TestString: "bar"})}, &runtimetesting.InternalExtensionType{Extension: runtime.NewEncodable(codec, &runtimetesting.ExtensionB{TestString: "bar"})},
&InternalExtensionType{ &runtimetesting.InternalExtensionType{
Extension: &runtime.Unknown{ Extension: &runtime.Unknown{
Raw: []byte(`{"apiVersion":"test.group/testExternal","kind":"B","testString":"bar"}`), Raw: []byte(`{"apiVersion":"test.group/testExternal","kind":"B","testString":"bar"}`),
ContentType: runtime.ContentTypeJSON, ContentType: runtime.ContentTypeJSON,
@ -284,8 +235,8 @@ func TestExtensionMapping(t *testing.T) {
`{"apiVersion":"` + externalGV.String() + `","kind":"ExtensionType","extension":{"apiVersion":"test.group/testExternal","kind":"B","testString":"bar"}} `{"apiVersion":"` + externalGV.String() + `","kind":"ExtensionType","extension":{"apiVersion":"test.group/testExternal","kind":"B","testString":"bar"}}
`, `,
}, { }, {
&InternalExtensionType{Extension: nil}, &runtimetesting.InternalExtensionType{Extension: nil},
&InternalExtensionType{ &runtimetesting.InternalExtensionType{
Extension: nil, Extension: nil,
}, },
`{"apiVersion":"` + externalGV.String() + `","kind":"ExtensionType","extension":null} `{"apiVersion":"` + externalGV.String() + `","kind":"ExtensionType","extension":null}
@ -315,12 +266,12 @@ func TestEncode(t *testing.T) {
externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"} externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"}
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{}) scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &runtimetesting.InternalSimple{})
scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{}) scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &runtimetesting.ExternalSimple{})
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV) codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
test := &InternalSimple{ test := &runtimetesting.InternalSimple{
TestString: "I'm the same", TestString: "I'm the same",
} }
obj := runtime.Object(test) obj := runtime.Object(test)
@ -329,7 +280,7 @@ func TestEncode(t *testing.T) {
if err != nil || err2 != nil { if err != nil || err2 != nil {
t.Fatalf("Failure: '%v' '%v'", err, err2) t.Fatalf("Failure: '%v' '%v'", err, err2)
} }
if _, ok := obj2.(*InternalSimple); !ok { if _, ok := obj2.(*runtimetesting.InternalSimple); !ok {
t.Fatalf("Got wrong type") t.Fatalf("Got wrong type")
} }
if !reflect.DeepEqual(obj2, test) { if !reflect.DeepEqual(obj2, test) {
@ -346,18 +297,18 @@ func TestUnversionedTypes(t *testing.T) {
otherGV := schema.GroupVersion{Group: "group", Version: "other"} otherGV := schema.GroupVersion{Group: "group", Version: "other"}
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
scheme.AddUnversionedTypes(externalGV, &InternalSimple{}) scheme.AddUnversionedTypes(externalGV, &runtimetesting.InternalSimple{})
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{}) scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &runtimetesting.InternalSimple{})
scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{}) scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &runtimetesting.ExternalSimple{})
scheme.AddKnownTypeWithName(otherGV.WithKind("Simple"), &ExternalSimple{}) scheme.AddKnownTypeWithName(otherGV.WithKind("Simple"), &runtimetesting.ExternalSimple{})
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV) codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
if unv, ok := scheme.IsUnversioned(&InternalSimple{}); !unv || !ok { if unv, ok := scheme.IsUnversioned(&runtimetesting.InternalSimple{}); !unv || !ok {
t.Fatalf("type not unversioned and in scheme: %t %t", unv, ok) t.Fatalf("type not unversioned and in scheme: %t %t", unv, ok)
} }
kinds, _, err := scheme.ObjectKinds(&InternalSimple{}) kinds, _, err := scheme.ObjectKinds(&runtimetesting.InternalSimple{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -366,7 +317,7 @@ func TestUnversionedTypes(t *testing.T) {
t.Fatalf("unexpected: %#v", kind) t.Fatalf("unexpected: %#v", kind)
} }
test := &InternalSimple{ test := &runtimetesting.InternalSimple{
TestString: "I'm the same", TestString: "I'm the same",
} }
obj := runtime.Object(test) obj := runtime.Object(test)
@ -378,7 +329,7 @@ func TestUnversionedTypes(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, ok := obj2.(*InternalSimple); !ok { if _, ok := obj2.(*runtimetesting.InternalSimple); !ok {
t.Fatalf("Got wrong type") t.Fatalf("Got wrong type")
} }
if !reflect.DeepEqual(obj2, test) { if !reflect.DeepEqual(obj2, test) {
@ -400,107 +351,9 @@ func TestUnversionedTypes(t *testing.T) {
} }
} }
// 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"`
}
type UnversionedType struct {
MyWeirdCustomEmbeddedVersionKindField `json:",inline"`
A string `json:"A,omitempty"`
}
type UnknownType struct {
MyWeirdCustomEmbeddedVersionKindField `json:",inline"`
A string `json:"A,omitempty"`
}
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
}
// TestObjectFuzzer can randomly populate all the above objects. // TestObjectFuzzer can randomly populate all the above objects.
var TestObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 100).Funcs( var TestObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 100).Funcs(
func(j *MyWeirdCustomEmbeddedVersionKindField, c fuzz.Continue) { func(j *runtimetesting.MyWeirdCustomEmbeddedVersionKindField, c fuzz.Continue) {
// We have to customize the randomization of MyWeirdCustomEmbeddedVersionKindFields because their // We have to customize the randomization of MyWeirdCustomEmbeddedVersionKindFields because their
// APIVersion and Kind must remain blank in memory. // APIVersion and Kind must remain blank in memory.
j.APIVersion = "" j.APIVersion = ""
@ -520,17 +373,17 @@ func GetTestScheme() *runtime.Scheme {
// Ordinarily, we wouldn't add TestType2, but because this is a test and // 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 // both types are from the same package, we need to get it into the system
// so that converter will match it with ExternalType2. // so that converter will match it with ExternalType2.
s.AddKnownTypes(internalGV, &TestType1{}, &TestType2{}, &ExternalInternalSame{}) s.AddKnownTypes(internalGV, &runtimetesting.TestType1{}, &runtimetesting.TestType2{}, &runtimetesting.ExternalInternalSame{})
s.AddKnownTypes(externalGV, &ExternalInternalSame{}) s.AddKnownTypes(externalGV, &runtimetesting.ExternalInternalSame{})
s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &ExternalTestType1{}) s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &runtimetesting.ExternalTestType1{})
s.AddKnownTypeWithName(externalGV.WithKind("TestType2"), &ExternalTestType2{}) s.AddKnownTypeWithName(externalGV.WithKind("TestType2"), &runtimetesting.ExternalTestType2{})
s.AddKnownTypeWithName(internalGV.WithKind("TestType3"), &TestType1{}) s.AddKnownTypeWithName(internalGV.WithKind("TestType3"), &runtimetesting.TestType1{})
s.AddKnownTypeWithName(externalGV.WithKind("TestType3"), &ExternalTestType1{}) s.AddKnownTypeWithName(externalGV.WithKind("TestType3"), &runtimetesting.ExternalTestType1{})
s.AddKnownTypeWithName(externalGV.WithKind("TestType4"), &ExternalTestType1{}) s.AddKnownTypeWithName(externalGV.WithKind("TestType4"), &runtimetesting.ExternalTestType1{})
s.AddKnownTypeWithName(alternateExternalGV.WithKind("TestType3"), &ExternalTestType1{}) s.AddKnownTypeWithName(alternateExternalGV.WithKind("TestType3"), &runtimetesting.ExternalTestType1{})
s.AddKnownTypeWithName(alternateExternalGV.WithKind("TestType5"), &ExternalTestType1{}) s.AddKnownTypeWithName(alternateExternalGV.WithKind("TestType5"), &runtimetesting.ExternalTestType1{})
s.AddKnownTypeWithName(differentExternalGV.WithKind("TestType1"), &ExternalTestType1{}) s.AddKnownTypeWithName(differentExternalGV.WithKind("TestType1"), &runtimetesting.ExternalTestType1{})
s.AddUnversionedTypes(externalGV, &UnversionedType{}) s.AddUnversionedTypes(externalGV, &runtimetesting.UnversionedType{})
return s return s
} }
@ -552,8 +405,8 @@ func TestAddKnownTypesIdemPotent(t *testing.T) {
s := runtime.NewScheme() s := runtime.NewScheme()
gv := schema.GroupVersion{Group: "foo", Version: "v1"} gv := schema.GroupVersion{Group: "foo", Version: "v1"}
s.AddKnownTypes(gv, &InternalSimple{}) s.AddKnownTypes(gv, &runtimetesting.InternalSimple{})
s.AddKnownTypes(gv, &InternalSimple{}) s.AddKnownTypes(gv, &runtimetesting.InternalSimple{})
if len(s.KnownTypes(gv)) != 1 { if len(s.KnownTypes(gv)) != 1 {
t.Errorf("expected only one %v type after double registration", gv) t.Errorf("expected only one %v type after double registration", gv)
} }
@ -561,8 +414,8 @@ func TestAddKnownTypesIdemPotent(t *testing.T) {
t.Errorf("expected only one type after double registration") t.Errorf("expected only one type after double registration")
} }
s.AddKnownTypeWithName(gv.WithKind("InternalSimple"), &InternalSimple{}) s.AddKnownTypeWithName(gv.WithKind("InternalSimple"), &runtimetesting.InternalSimple{})
s.AddKnownTypeWithName(gv.WithKind("InternalSimple"), &InternalSimple{}) s.AddKnownTypeWithName(gv.WithKind("InternalSimple"), &runtimetesting.InternalSimple{})
if len(s.KnownTypes(gv)) != 1 { if len(s.KnownTypes(gv)) != 1 {
t.Errorf("expected only one %v type after double registration with custom name", gv) t.Errorf("expected only one %v type after double registration with custom name", gv)
} }
@ -570,8 +423,8 @@ func TestAddKnownTypesIdemPotent(t *testing.T) {
t.Errorf("expected only one type after double registration with custom name") t.Errorf("expected only one type after double registration with custom name")
} }
s.AddUnversionedTypes(gv, &InternalSimple{}) s.AddUnversionedTypes(gv, &runtimetesting.InternalSimple{})
s.AddUnversionedTypes(gv, &InternalSimple{}) s.AddUnversionedTypes(gv, &runtimetesting.InternalSimple{})
if len(s.KnownTypes(gv)) != 1 { if len(s.KnownTypes(gv)) != 1 {
t.Errorf("expected only one %v type after double registration with custom name", gv) t.Errorf("expected only one %v type after double registration with custom name", gv)
} }
@ -579,7 +432,7 @@ func TestAddKnownTypesIdemPotent(t *testing.T) {
t.Errorf("expected only one type after double registration with custom name") t.Errorf("expected only one type after double registration with custom name")
} }
kinds, _, err := s.ObjectKinds(&InternalSimple{}) kinds, _, err := s.ObjectKinds(&runtimetesting.InternalSimple{})
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -593,6 +446,14 @@ type EmbeddableTypeMeta runtime.TypeMeta
func (tm *EmbeddableTypeMeta) GetObjectKind() schema.ObjectKind { return (*runtime.TypeMeta)(tm) } func (tm *EmbeddableTypeMeta) GetObjectKind() schema.ObjectKind { return (*runtime.TypeMeta)(tm) }
// redefine InternalSimple with the same name, but obviously as a different type than in runtimetesting
type InternalSimple struct {
EmbeddableTypeMeta `json:",inline"`
TestString string `json:"testString"`
}
func (s *InternalSimple) DeepCopyObject() runtime.Object { return nil }
func TestConflictingAddKnownTypes(t *testing.T) { func TestConflictingAddKnownTypes(t *testing.T) {
s := runtime.NewScheme() s := runtime.NewScheme()
gv := schema.GroupVersion{Group: "foo", Version: "v1"} gv := schema.GroupVersion{Group: "foo", Version: "v1"}
@ -604,8 +465,8 @@ func TestConflictingAddKnownTypes(t *testing.T) {
panicked <- true panicked <- true
} }
}() }()
s.AddKnownTypeWithName(gv.WithKind("InternalSimple"), &InternalSimple{}) s.AddKnownTypeWithName(gv.WithKind("InternalSimple"), &runtimetesting.InternalSimple{})
s.AddKnownTypeWithName(gv.WithKind("InternalSimple"), &ExternalSimple{}) s.AddKnownTypeWithName(gv.WithKind("InternalSimple"), &runtimetesting.ExternalSimple{})
panicked <- false panicked <- false
}() }()
if !<-panicked { if !<-panicked {
@ -619,13 +480,7 @@ func TestConflictingAddKnownTypes(t *testing.T) {
} }
}() }()
s.AddUnversionedTypes(gv, &InternalSimple{}) s.AddUnversionedTypes(gv, &runtimetesting.InternalSimple{})
// redefine InternalSimple with the same name, but obviously as a different type
type InternalSimple struct {
EmbeddableTypeMeta `json:",inline"`
TestString string `json:"testString"`
}
s.AddUnversionedTypes(gv, &InternalSimple{}) s.AddUnversionedTypes(gv, &InternalSimple{})
panicked <- false panicked <- false
}() }()
@ -636,12 +491,12 @@ func TestConflictingAddKnownTypes(t *testing.T) {
func TestConvertToVersionBasic(t *testing.T) { func TestConvertToVersionBasic(t *testing.T) {
s := GetTestScheme() s := GetTestScheme()
tt := &TestType1{A: "I'm not a pointer object"} tt := &runtimetesting.TestType1{A: "I'm not a pointer object"}
other, err := s.ConvertToVersion(tt, schema.GroupVersion{Version: "v1"}) other, err := s.ConvertToVersion(tt, schema.GroupVersion{Version: "v1"})
if err != nil { if err != nil {
t.Fatalf("Failure: %v", err) t.Fatalf("Failure: %v", err)
} }
converted, ok := other.(*ExternalTestType1) converted, ok := other.(*runtimetesting.ExternalTestType1)
if !ok { if !ok {
t.Fatalf("Got wrong type: %T", other) t.Fatalf("Got wrong type: %T", other)
} }
@ -671,13 +526,13 @@ func TestConvertToVersion(t *testing.T) {
// errors if the type is not registered in the scheme // errors if the type is not registered in the scheme
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &UnknownType{}, in: &runtimetesting.UnknownType{},
errFn: func(err error) bool { return err != nil && runtime.IsNotRegisteredError(err) }, errFn: func(err error) bool { return err != nil && runtime.IsNotRegisteredError(err) },
}, },
// errors if the group versioner returns no target // errors if the group versioner returns no target
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: testGroupVersioner{}, gv: testGroupVersioner{},
errFn: func(err error) bool { errFn: func(err error) bool {
return err != nil && strings.Contains(err.Error(), "is not suitable for converting") return err != nil && strings.Contains(err.Error(), "is not suitable for converting")
@ -686,132 +541,132 @@ func TestConvertToVersion(t *testing.T) {
// converts to internal // converts to internal
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: schema.GroupVersion{Version: "__internal"}, gv: schema.GroupVersion{Version: "__internal"},
out: &TestType1{A: "test"}, out: &runtimetesting.TestType1{A: "test"},
}, },
// prefers the best match // prefers the best match
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: schema.GroupVersions{{Version: "__internal"}, {Version: "v1"}}, gv: schema.GroupVersions{{Version: "__internal"}, {Version: "v1"}},
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test", A: "test",
}, },
}, },
// unversioned type returned as-is // unversioned type returned as-is
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &UnversionedType{A: "test"}, in: &runtimetesting.UnversionedType{A: "test"},
gv: schema.GroupVersions{{Version: "v1"}}, gv: schema.GroupVersions{{Version: "v1"}},
same: true, same: true,
out: &UnversionedType{ out: &runtimetesting.UnversionedType{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "UnversionedType"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "UnversionedType"},
A: "test", A: "test",
}, },
}, },
// unversioned type returned when not included in the target types // unversioned type returned when not included in the target types
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &UnversionedType{A: "test"}, in: &runtimetesting.UnversionedType{A: "test"},
gv: schema.GroupVersions{{Group: "other", Version: "v2"}}, gv: schema.GroupVersions{{Group: "other", Version: "v2"}},
same: true, same: true,
out: &UnversionedType{ out: &runtimetesting.UnversionedType{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "UnversionedType"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "UnversionedType"},
A: "test", A: "test",
}, },
}, },
// detected as already being in the target version // detected as already being in the target version
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: schema.GroupVersions{{Version: "v1"}}, gv: schema.GroupVersions{{Version: "v1"}},
same: true, same: true,
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test", A: "test",
}, },
}, },
// detected as already being in the first target version // detected as already being in the first target version
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: schema.GroupVersions{{Version: "v1"}, {Version: "__internal"}}, gv: schema.GroupVersions{{Version: "v1"}, {Version: "__internal"}},
same: true, same: true,
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test", A: "test",
}, },
}, },
// detected as already being in the first target version // detected as already being in the first target version
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: schema.GroupVersions{{Version: "v1"}, {Version: "__internal"}}, gv: schema.GroupVersions{{Version: "v1"}, {Version: "__internal"}},
same: true, same: true,
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test", A: "test",
}, },
}, },
// the external type is registered in multiple groups, versions, and kinds, and can be targeted to all of them (1/3): different kind // the external type is registered in multiple groups, versions, and kinds, and can be targeted to all of them (1/3): different kind
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Kind: "TestType3", Version: "v1"}}, gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Kind: "TestType3", Version: "v1"}},
same: true, same: true,
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType3"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType3"},
A: "test", A: "test",
}, },
}, },
// the external type is registered in multiple groups, versions, and kinds, and can be targeted to all of them (2/3): different gv // the external type is registered in multiple groups, versions, and kinds, and can be targeted to all of them (2/3): different gv
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Kind: "TestType3", Group: "custom", Version: "v1"}}, gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Kind: "TestType3", Group: "custom", Version: "v1"}},
same: true, same: true,
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "custom/v1", ObjectKind: "TestType3"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "custom/v1", ObjectKind: "TestType3"},
A: "test", A: "test",
}, },
}, },
// the external type is registered in multiple groups, versions, and kinds, and can be targeted to all of them (3/3): different gvk // the external type is registered in multiple groups, versions, and kinds, and can be targeted to all of them (3/3): different gvk
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Group: "custom", Version: "v1", Kind: "TestType5"}}, gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Group: "custom", Version: "v1", Kind: "TestType5"}},
same: true, same: true,
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "custom/v1", ObjectKind: "TestType5"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "custom/v1", ObjectKind: "TestType5"},
A: "test", A: "test",
}, },
}, },
// multi group versioner recognizes multiple groups and forces the output to a particular version, copies because version differs // multi group versioner recognizes multiple groups and forces the output to a particular version, copies because version differs
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "other", Version: "v2"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}, schema.GroupKind{Kind: "TestType1"}), gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "other", Version: "v2"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}, schema.GroupKind{Kind: "TestType1"}),
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "other/v2", ObjectKind: "TestType1"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "other/v2", ObjectKind: "TestType1"},
A: "test", A: "test",
}, },
}, },
// multi group versioner recognizes multiple groups and forces the output to a particular version, copies because version differs // multi group versioner recognizes multiple groups and forces the output to a particular version, copies because version differs
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "other", Version: "v2"}, schema.GroupKind{Kind: "TestType1"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}), gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "other", Version: "v2"}, schema.GroupKind{Kind: "TestType1"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}),
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "other/v2", ObjectKind: "TestType1"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "other/v2", ObjectKind: "TestType1"},
A: "test", A: "test",
}, },
}, },
// multi group versioner is unable to find a match when kind AND group don't match (there is no TestType1 kind in group "other", and no kind "TestType5" in the default group) // multi group versioner is unable to find a match when kind AND group don't match (there is no TestType1 kind in group "other", and no kind "TestType5" in the default group)
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &TestType1{A: "test"}, in: &runtimetesting.TestType1{A: "test"},
gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "custom", Version: "v1"}, schema.GroupKind{Group: "other"}, schema.GroupKind{Kind: "TestType5"}), gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "custom", Version: "v1"}, schema.GroupKind{Group: "other"}, schema.GroupKind{Kind: "TestType5"}),
errFn: func(err error) bool { errFn: func(err error) bool {
return err != nil && strings.Contains(err.Error(), "is not suitable for converting") return err != nil && strings.Contains(err.Error(), "is not suitable for converting")
@ -820,42 +675,42 @@ func TestConvertToVersion(t *testing.T) {
// multi group versioner recognizes multiple groups and forces the output to a particular version, performs no copy // multi group versioner recognizes multiple groups and forces the output to a particular version, performs no copy
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "", Version: "v1"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}, schema.GroupKind{Kind: "TestType1"}), gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "", Version: "v1"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}, schema.GroupKind{Kind: "TestType1"}),
same: true, same: true,
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test", A: "test",
}, },
}, },
// multi group versioner recognizes multiple groups and forces the output to a particular version, performs no copy // multi group versioner recognizes multiple groups and forces the output to a particular version, performs no copy
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &runtimetesting.ExternalTestType1{A: "test"},
gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "", Version: "v1"}, schema.GroupKind{Kind: "TestType1"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}), gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "", Version: "v1"}, schema.GroupKind{Kind: "TestType1"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}),
same: true, same: true,
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test", A: "test",
}, },
}, },
// group versioner can choose a particular target kind for a given input when kind is the same across group versions // group versioner can choose a particular target kind for a given input when kind is the same across group versions
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &TestType1{A: "test"}, in: &runtimetesting.TestType1{A: "test"},
gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Version: "v1", Kind: "TestType3"}}, gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Version: "v1", Kind: "TestType3"}},
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType3"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType3"},
A: "test", A: "test",
}, },
}, },
// group versioner can choose a different kind // group versioner can choose a different kind
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &TestType1{A: "test"}, in: &runtimetesting.TestType1{A: "test"},
gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Kind: "TestType5", Group: "custom", Version: "v1"}}, gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Kind: "TestType5", Group: "custom", Version: "v1"}},
out: &ExternalTestType1{ out: &runtimetesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "custom/v1", ObjectKind: "TestType5"}, MyWeirdCustomEmbeddedVersionKindField: runtimetesting.MyWeirdCustomEmbeddedVersionKindField{APIVersion: "custom/v1", ObjectKind: "TestType5"},
A: "test", A: "test",
}, },
}, },
@ -914,21 +769,21 @@ func TestMetaValues(t *testing.T) {
externalGV := schema.GroupVersion{Group: "test.group", Version: "externalVersion"} externalGV := schema.GroupVersion{Group: "test.group", Version: "externalVersion"}
s := runtime.NewScheme() s := runtime.NewScheme()
s.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{}) s.AddKnownTypeWithName(internalGV.WithKind("Simple"), &runtimetesting.InternalSimple{})
s.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{}) s.AddKnownTypeWithName(externalGV.WithKind("Simple"), &runtimetesting.ExternalSimple{})
internalToExternalCalls := 0 internalToExternalCalls := 0
externalToInternalCalls := 0 externalToInternalCalls := 0
// Register functions to verify that scope.Meta() gets set correctly. // Register functions to verify that scope.Meta() gets set correctly.
err := s.AddConversionFuncs( err := s.AddConversionFuncs(
func(in *InternalSimple, out *ExternalSimple, scope conversion.Scope) error { func(in *runtimetesting.InternalSimple, out *runtimetesting.ExternalSimple, scope conversion.Scope) error {
t.Logf("internal -> external") t.Logf("internal -> external")
scope.Convert(&in.TestString, &out.TestString, 0) scope.Convert(&in.TestString, &out.TestString, 0)
internalToExternalCalls++ internalToExternalCalls++
return nil return nil
}, },
func(in *ExternalSimple, out *InternalSimple, scope conversion.Scope) error { func(in *runtimetesting.ExternalSimple, out *runtimetesting.InternalSimple, scope conversion.Scope) error {
t.Logf("external -> internal") t.Logf("external -> internal")
scope.Convert(&in.TestString, &out.TestString, 0) scope.Convert(&in.TestString, &out.TestString, 0)
externalToInternalCalls++ externalToInternalCalls++
@ -938,7 +793,7 @@ func TestMetaValues(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
simple := &InternalSimple{ simple := &runtimetesting.InternalSimple{
TestString: "foo", TestString: "foo",
} }

View File

@ -29,6 +29,7 @@ import (
"k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
serializertesting "k8s.io/apimachinery/pkg/runtime/serializer/testing"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
@ -57,103 +58,15 @@ func (testMetaFactory) Interpret(data []byte) (*schema.GroupVersionKind, error)
return &schema.GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: findKind.ObjectKind}, nil 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. // TestObjectFuzzer can randomly populate all the above objects.
var TestObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 100).Funcs( var TestObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 100).Funcs(
func(j *MyWeirdCustomEmbeddedVersionKindField, c fuzz.Continue) { func(j *serializertesting.MyWeirdCustomEmbeddedVersionKindField, c fuzz.Continue) {
c.FuzzNoCustom(j) c.FuzzNoCustom(j)
j.APIVersion = "" j.APIVersion = ""
j.ObjectKind = "" 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. // Returns a new Scheme set up with the test objects.
func GetTestScheme() (*runtime.Scheme, runtime.Codec) { func GetTestScheme() (*runtime.Scheme, runtime.Codec) {
internalGV := schema.GroupVersion{Version: runtime.APIVersionInternal} internalGV := schema.GroupVersion{Version: runtime.APIVersionInternal}
@ -164,13 +77,13 @@ func GetTestScheme() (*runtime.Scheme, runtime.Codec) {
// Ordinarily, we wouldn't add TestType2, but because this is a test and // 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 // both types are from the same package, we need to get it into the system
// so that converter will match it with ExternalType2. // so that converter will match it with ExternalType2.
s.AddKnownTypes(internalGV, &TestType1{}, &TestType2{}, &ExternalInternalSame{}) s.AddKnownTypes(internalGV, &serializertesting.TestType1{}, &serializertesting.TestType2{}, &serializertesting.ExternalInternalSame{})
s.AddKnownTypes(externalGV, &ExternalInternalSame{}) s.AddKnownTypes(externalGV, &serializertesting.ExternalInternalSame{})
s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &ExternalTestType1{}) s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &serializertesting.ExternalTestType1{})
s.AddKnownTypeWithName(externalGV.WithKind("TestType2"), &ExternalTestType2{}) s.AddKnownTypeWithName(externalGV.WithKind("TestType2"), &serializertesting.ExternalTestType2{})
s.AddKnownTypeWithName(internalGV.WithKind("TestType3"), &TestType1{}) s.AddKnownTypeWithName(internalGV.WithKind("TestType3"), &serializertesting.TestType1{})
s.AddKnownTypeWithName(externalGV.WithKind("TestType3"), &ExternalTestType1{}) s.AddKnownTypeWithName(externalGV.WithKind("TestType3"), &serializertesting.ExternalTestType1{})
s.AddKnownTypeWithName(externalGV2.WithKind("TestType1"), &ExternalTestType1{}) s.AddKnownTypeWithName(externalGV2.WithKind("TestType1"), &serializertesting.ExternalTestType1{})
s.AddUnversionedTypes(externalGV, &metav1.Status{}) s.AddUnversionedTypes(externalGV, &metav1.Status{})
@ -180,7 +93,7 @@ func GetTestScheme() (*runtime.Scheme, runtime.Codec) {
} }
var semantic = conversion.EqualitiesOrDie( var semantic = conversion.EqualitiesOrDie(
func(a, b MyWeirdCustomEmbeddedVersionKindField) bool { func(a, b serializertesting.MyWeirdCustomEmbeddedVersionKindField) bool {
a.APIVersion, a.ObjectKind = "", "" a.APIVersion, a.ObjectKind = "", ""
b.APIVersion, b.ObjectKind = "", "" b.APIVersion, b.ObjectKind = "", ""
return a == b return a == b
@ -219,8 +132,8 @@ func runTest(t *testing.T, source interface{}) {
func TestTypes(t *testing.T) { func TestTypes(t *testing.T) {
table := []interface{}{ table := []interface{}{
&TestType1{}, &serializertesting.TestType1{},
&ExternalInternalSame{}, &serializertesting.ExternalInternalSame{},
} }
for _, item := range table { for _, item := range table {
// Try a few times, since runTest uses random values. // Try a few times, since runTest uses random values.
@ -237,7 +150,7 @@ func TestVersionedEncoding(t *testing.T) {
encoder := info.Serializer encoder := info.Serializer
codec := cf.CodecForVersions(encoder, nil, schema.GroupVersion{Version: "v2"}, nil) codec := cf.CodecForVersions(encoder, nil, schema.GroupVersion{Version: "v2"}, nil)
out, err := runtime.Encode(codec, &TestType1{}) out, err := runtime.Encode(codec, &serializertesting.TestType1{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -246,14 +159,14 @@ func TestVersionedEncoding(t *testing.T) {
} }
codec = cf.CodecForVersions(encoder, nil, schema.GroupVersion{Version: "v3"}, nil) codec = cf.CodecForVersions(encoder, nil, schema.GroupVersion{Version: "v3"}, nil)
_, err = runtime.Encode(codec, &TestType1{}) _, err = runtime.Encode(codec, &serializertesting.TestType1{})
if err == nil { if err == nil {
t.Fatal(err) t.Fatal(err)
} }
// unversioned encode with no versions is written directly to wire // unversioned encode with no versions is written directly to wire
codec = cf.CodecForVersions(encoder, nil, runtime.InternalGroupVersioner, nil) codec = cf.CodecForVersions(encoder, nil, runtime.InternalGroupVersioner, nil)
out, err = runtime.Encode(codec, &TestType1{}) out, err = runtime.Encode(codec, &serializertesting.TestType1{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -269,7 +182,7 @@ func TestMultipleNames(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
internal := obj.(*TestType1) internal := obj.(*serializertesting.TestType1)
if internal.A != "value" { if internal.A != "value" {
t.Fatalf("unexpected decoded object: %#v", internal) t.Fatalf("unexpected decoded object: %#v", internal)
} }
@ -289,13 +202,13 @@ func TestConvertTypesWhenDefaultNamesMatch(t *testing.T) {
s := runtime.NewScheme() s := runtime.NewScheme()
// create two names internally, with TestType1 being preferred // create two names internally, with TestType1 being preferred
s.AddKnownTypeWithName(internalGV.WithKind("TestType1"), &TestType1{}) s.AddKnownTypeWithName(internalGV.WithKind("TestType1"), &serializertesting.TestType1{})
s.AddKnownTypeWithName(internalGV.WithKind("OtherType1"), &TestType1{}) s.AddKnownTypeWithName(internalGV.WithKind("OtherType1"), &serializertesting.TestType1{})
// create two names externally, with TestType1 being preferred // create two names externally, with TestType1 being preferred
s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &ExternalTestType1{}) s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &serializertesting.ExternalTestType1{})
s.AddKnownTypeWithName(externalGV.WithKind("OtherType1"), &ExternalTestType1{}) s.AddKnownTypeWithName(externalGV.WithKind("OtherType1"), &serializertesting.ExternalTestType1{})
ext := &ExternalTestType1{} ext := &serializertesting.ExternalTestType1{}
ext.APIVersion = "v1" ext.APIVersion = "v1"
ext.ObjectKind = "OtherType1" ext.ObjectKind = "OtherType1"
ext.A = "test" ext.A = "test"
@ -303,7 +216,7 @@ func TestConvertTypesWhenDefaultNamesMatch(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
expect := &TestType1{A: "test"} expect := &serializertesting.TestType1{A: "test"}
codec := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{})).LegacyCodec(schema.GroupVersion{Version: "v1"}) codec := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{})).LegacyCodec(schema.GroupVersion{Version: "v1"})
@ -315,7 +228,7 @@ func TestConvertTypesWhenDefaultNamesMatch(t *testing.T) {
t.Errorf("unexpected object: %#v", obj) t.Errorf("unexpected object: %#v", obj)
} }
into := &TestType1{} into := &serializertesting.TestType1{}
if err := runtime.DecodeInto(codec, data, into); err != nil { if err := runtime.DecodeInto(codec, data, into); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -326,13 +239,13 @@ func TestConvertTypesWhenDefaultNamesMatch(t *testing.T) {
func TestEncode_Ptr(t *testing.T) { func TestEncode_Ptr(t *testing.T) {
_, codec := GetTestScheme() _, codec := GetTestScheme()
tt := &TestType1{A: "I am a pointer object"} tt := &serializertesting.TestType1{A: "I am a pointer object"}
data, err := runtime.Encode(codec, tt) data, err := runtime.Encode(codec, tt)
obj2, err2 := runtime.Decode(codec, data) obj2, err2 := runtime.Decode(codec, data)
if err != nil || err2 != nil { if err != nil || err2 != nil {
t.Fatalf("Failure: '%v' '%v'\n%s", err, err2, data) t.Fatalf("Failure: '%v' '%v'\n%s", err, err2, data)
} }
if _, ok := obj2.(*TestType1); !ok { if _, ok := obj2.(*serializertesting.TestType1); !ok {
t.Fatalf("Got wrong type") t.Fatalf("Got wrong type")
} }
if !semantic.DeepEqual(obj2, tt) { if !semantic.DeepEqual(obj2, tt) {
@ -355,10 +268,10 @@ func TestBadJSONRejection(t *testing.T) {
} }
} }
badJSONKindMismatch := []byte(`{"myVersionKey":"v1","myKindKey":"ExternalInternalSame"}`) badJSONKindMismatch := []byte(`{"myVersionKey":"v1","myKindKey":"ExternalInternalSame"}`)
if err := runtime.DecodeInto(codec, badJSONKindMismatch, &TestType1{}); err == nil { if err := runtime.DecodeInto(codec, badJSONKindMismatch, &serializertesting.TestType1{}); err == nil {
t.Errorf("Kind is set but doesn't match the object type: %s", badJSONKindMismatch) t.Errorf("Kind is set but doesn't match the object type: %s", badJSONKindMismatch)
} }
if err := runtime.DecodeInto(codec, []byte(``), &TestType1{}); err != nil { if err := runtime.DecodeInto(codec, []byte(``), &serializertesting.TestType1{}); err != nil {
t.Errorf("Should allow empty decode: %v", err) t.Errorf("Should allow empty decode: %v", err)
} }
if _, _, err := codec.Decode([]byte(``), &schema.GroupVersionKind{Kind: "ExternalInternalSame"}, nil); err == nil { if _, _, err := codec.Decode([]byte(``), &schema.GroupVersionKind{Kind: "ExternalInternalSame"}, nil); err == nil {
@ -387,8 +300,8 @@ func GetDirectCodecTestScheme() *runtime.Scheme {
// Ordinarily, we wouldn't add TestType2, but because this is a test and // 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 // both types are from the same package, we need to get it into the system
// so that converter will match it with ExternalType2. // so that converter will match it with ExternalType2.
s.AddKnownTypes(internalGV, &TestType1{}) s.AddKnownTypes(internalGV, &serializertesting.TestType1{})
s.AddKnownTypes(externalGV, &ExternalTestType1{}) s.AddKnownTypes(externalGV, &serializertesting.ExternalTestType1{})
s.AddUnversionedTypes(externalGV, &metav1.Status{}) s.AddUnversionedTypes(externalGV, &metav1.Status{})
return s return s
@ -406,7 +319,7 @@ func TestDirectCodec(t *testing.T) {
} }
directEncoder := df.EncoderForVersion(serializer, ignoredGV) directEncoder := df.EncoderForVersion(serializer, ignoredGV)
directDecoder := df.DecoderToVersion(serializer, ignoredGV) directDecoder := df.DecoderToVersion(serializer, ignoredGV)
out, err := runtime.Encode(directEncoder, &ExternalTestType1{}) out, err := runtime.Encode(directEncoder, &serializertesting.ExternalTestType1{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -414,8 +327,8 @@ func TestDirectCodec(t *testing.T) {
t.Fatal(string(out)) t.Fatal(string(out))
} }
a, _, err := directDecoder.Decode(out, nil, nil) a, _, err := directDecoder.Decode(out, nil, nil)
e := &ExternalTestType1{ e := &serializertesting.ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{ MyWeirdCustomEmbeddedVersionKindField: serializertesting.MyWeirdCustomEmbeddedVersionKindField{
APIVersion: "v1", APIVersion: "v1",
ObjectKind: "ExternalTestType1", ObjectKind: "ExternalTestType1",
}, },

View File

@ -0,0 +1,19 @@
/*
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.
*/
// +k8s:deepcopy-gen=package
package testing

View File

@ -0,0 +1,109 @@
/*
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 (
"k8s.io/apimachinery/pkg/runtime/schema"
)
// Test a weird version/kind embedding format.
// +k8s:deepcopy-gen=false
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"`
}
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 }

View File

@ -0,0 +1,19 @@
/*
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.
*/
// +k8s:deepcopy-gen=package
package testing

View File

@ -0,0 +1,212 @@
/*
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 testing
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
type EmbeddedTest struct {
runtime.TypeMeta
ID string
Object runtime.Object
EmptyObject runtime.Object
}
type EmbeddedTestExternal struct {
runtime.TypeMeta `json:",inline"`
ID string `json:"id,omitempty"`
Object runtime.RawExtension `json:"object,omitempty"`
EmptyObject runtime.RawExtension `json:"emptyObject,omitempty"`
}
type ObjectTest struct {
runtime.TypeMeta
ID string
Items []runtime.Object
}
type ObjectTestExternal struct {
runtime.TypeMeta `yaml:",inline" json:",inline"`
ID string `json:"id,omitempty"`
Items []runtime.RawExtension `json:"items,omitempty"`
}
type InternalSimple struct {
runtime.TypeMeta `json:",inline"`
TestString string `json:"testString"`
}
type ExternalSimple struct {
runtime.TypeMeta `json:",inline"`
TestString string `json:"testString"`
}
type ExtensionA struct {
runtime.TypeMeta `json:",inline"`
TestString string `json:"testString"`
}
type ExtensionB struct {
runtime.TypeMeta `json:",inline"`
TestString string `json:"testString"`
}
type ExternalExtensionType struct {
runtime.TypeMeta `json:",inline"`
Extension runtime.RawExtension `json:"extension"`
}
type InternalExtensionType struct {
runtime.TypeMeta `json:",inline"`
Extension runtime.Object `json:"extension"`
}
type ExternalOptionalExtensionType struct {
runtime.TypeMeta `json:",inline"`
Extension runtime.RawExtension `json:"extension,omitempty"`
}
type InternalOptionalExtensionType struct {
runtime.TypeMeta `json:",inline"`
Extension runtime.Object `json:"extension,omitempty"`
}
type InternalComplex struct {
runtime.TypeMeta
String string
Integer int
Integer64 int64
Int64 int64
Bool bool
}
type ExternalComplex struct {
runtime.TypeMeta `json:",inline"`
String string `json:"string" description:"testing"`
Integer int `json:"int"`
Integer64 int64 `json:",omitempty"`
Int64 int64
Bool bool `json:"bool"`
}
// Test a weird version/kind embedding format.
// +k8s:deepcopy-gen=false
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"`
}
type UnversionedType struct {
MyWeirdCustomEmbeddedVersionKindField `json:",inline"`
A string `json:"A,omitempty"`
}
type UnknownType struct {
MyWeirdCustomEmbeddedVersionKindField `json:",inline"`
A string `json:"A,omitempty"`
}
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 *TestType2) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
func (obj *ExternalTestType2) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
func (obj *InternalComplex) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ExternalComplex) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *EmbeddedTest) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *EmbeddedTestExternal) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *InternalSimple) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ExternalSimple) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *InternalOptionalExtensionType) GetObjectKind() schema.ObjectKind {
return &obj.TypeMeta
}
func (obj *ObjectTestExternal) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ObjectTest) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ExternalOptionalExtensionType) GetObjectKind() schema.ObjectKind {
return &obj.TypeMeta
}
func (obj *InternalExtensionType) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ExternalExtensionType) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ExtensionA) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ExtensionB) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }

View File

@ -174,30 +174,21 @@ func addGrouplessTypes() {
} }
func addTestTypes() { func addTestTypes() {
type ListOptions struct {
Object runtime.Object
metav1.TypeMeta `json:",inline"`
LabelSelector string `json:"labelSelector,omitempty"`
FieldSelector string `json:"fieldSelector,omitempty"`
Watch bool `json:"watch,omitempty"`
ResourceVersion string `json:"resourceVersion,omitempty"`
TimeoutSeconds *int64 `json:"timeoutSeconds,omitempty"`
}
scheme.AddKnownTypes(testGroupVersion, scheme.AddKnownTypes(testGroupVersion,
&genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &metav1.ExportOptions{}, &genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &metav1.ExportOptions{},
&metav1.DeleteOptions{}, &genericapitesting.SimpleGetOptions{}, &genericapitesting.SimpleRoot{}, &metav1.DeleteOptions{}, &genericapitesting.SimpleGetOptions{}, &genericapitesting.SimpleRoot{},
&SimpleXGSubresource{}) &genericapitesting.SimpleXGSubresource{})
scheme.AddKnownTypes(testGroupVersion, &examplev1.Pod{}) scheme.AddKnownTypes(testGroupVersion, &examplev1.Pod{})
scheme.AddKnownTypes(testInternalGroupVersion, scheme.AddKnownTypes(testInternalGroupVersion,
&genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &metav1.ExportOptions{}, &genericapitesting.Simple{}, &genericapitesting.SimpleList{}, &metav1.ExportOptions{},
&genericapitesting.SimpleGetOptions{}, &genericapitesting.SimpleRoot{}, &genericapitesting.SimpleGetOptions{}, &genericapitesting.SimpleRoot{},
&SimpleXGSubresource{}) &genericapitesting.SimpleXGSubresource{})
scheme.AddKnownTypes(testInternalGroupVersion, &example.Pod{}) scheme.AddKnownTypes(testInternalGroupVersion, &example.Pod{})
// Register SimpleXGSubresource in both testGroupVersion and testGroup2Version, and also their // Register SimpleXGSubresource in both testGroupVersion and testGroup2Version, and also their
// their corresponding internal versions, to verify that the desired group version object is // their corresponding internal versions, to verify that the desired group version object is
// served in the tests. // served in the tests.
scheme.AddKnownTypes(testGroup2Version, &SimpleXGSubresource{}, &metav1.ExportOptions{}) scheme.AddKnownTypes(testGroup2Version, &genericapitesting.SimpleXGSubresource{}, &metav1.ExportOptions{})
scheme.AddKnownTypes(testInternalGroup2Version, &SimpleXGSubresource{}, &metav1.ExportOptions{}) scheme.AddKnownTypes(testInternalGroup2Version, &genericapitesting.SimpleXGSubresource{}, &metav1.ExportOptions{})
metav1.AddToGroupVersion(scheme, testGroupVersion) metav1.AddToGroupVersion(scheme, testGroupVersion)
} }
@ -1153,10 +1144,10 @@ func TestList(t *testing.T) {
t.Errorf("%d: %q unexpected resource namespace: %s", i, testCase.url, simpleStorage.actualNamespace) t.Errorf("%d: %q unexpected resource namespace: %s", i, testCase.url, simpleStorage.actualNamespace)
} }
if simpleStorage.requestedLabelSelector == nil || simpleStorage.requestedLabelSelector.String() != testCase.label { if simpleStorage.requestedLabelSelector == nil || simpleStorage.requestedLabelSelector.String() != testCase.label {
t.Errorf("%d: unexpected label selector: %v", i, simpleStorage.requestedLabelSelector) t.Errorf("%d: unexpected label selector: expected=%v got=%v", i, testCase.label, simpleStorage.requestedLabelSelector)
} }
if simpleStorage.requestedFieldSelector == nil || simpleStorage.requestedFieldSelector.String() != testCase.field { if simpleStorage.requestedFieldSelector == nil || simpleStorage.requestedFieldSelector.String() != testCase.field {
t.Errorf("%d: unexpected field selector: %v", i, simpleStorage.requestedFieldSelector) t.Errorf("%d: unexpected field selector: expected=%v got=%v", i, testCase.field, simpleStorage.requestedFieldSelector)
} }
} }
} }
@ -3935,23 +3926,12 @@ func TestUpdateChecksAPIVersion(t *testing.T) {
} }
} }
// SimpleXGSubresource is a cross group subresource, i.e. the subresource does not belong to the
// same group as its parent resource.
type SimpleXGSubresource struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
SubresourceInfo string `json:"subresourceInfo,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
}
func (obj *SimpleXGSubresource) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
type SimpleXGSubresourceRESTStorage struct { type SimpleXGSubresourceRESTStorage struct {
item SimpleXGSubresource item genericapitesting.SimpleXGSubresource
} }
func (storage *SimpleXGSubresourceRESTStorage) New() runtime.Object { func (storage *SimpleXGSubresourceRESTStorage) New() runtime.Object {
return &SimpleXGSubresource{} return &genericapitesting.SimpleXGSubresource{}
} }
func (storage *SimpleXGSubresourceRESTStorage) Get(ctx request.Context, id string, options *metav1.GetOptions) (runtime.Object, error) { func (storage *SimpleXGSubresourceRESTStorage) Get(ctx request.Context, id string, options *metav1.GetOptions) (runtime.Object, error) {
@ -3969,7 +3949,7 @@ func TestXGSubresource(t *testing.T) {
itemID := "theID" itemID := "theID"
subresourceStorage := &SimpleXGSubresourceRESTStorage{ subresourceStorage := &SimpleXGSubresourceRESTStorage{
item: SimpleXGSubresource{ item: genericapitesting.SimpleXGSubresource{
SubresourceInfo: "foo", SubresourceInfo: "foo",
}, },
} }
@ -4018,7 +3998,7 @@ func TestXGSubresource(t *testing.T) {
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
t.Fatalf("unexpected response: %#v", resp) t.Fatalf("unexpected response: %#v", resp)
} }
var itemOut SimpleXGSubresource var itemOut genericapitesting.SimpleXGSubresource
body, err := extractBody(resp, &itemOut) body, err := extractBody(resp, &itemOut)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -4030,7 +4010,7 @@ func TestXGSubresource(t *testing.T) {
// conversion type list in API scheme and hence cannot be converted from input type object // conversion type list in API scheme and hence cannot be converted from input type object
// to output type object. So it's values don't appear in the decoded output object. // to output type object. So it's values don't appear in the decoded output object.
decoder := json.NewDecoder(strings.NewReader(body)) decoder := json.NewDecoder(strings.NewReader(body))
var itemFromBody SimpleXGSubresource var itemFromBody genericapitesting.SimpleXGSubresource
err = decoder.Decode(&itemFromBody) err = decoder.Decode(&itemFromBody)
if err != nil { if err != nil {
t.Errorf("unexpected JSON decoding error: %v", err) t.Errorf("unexpected JSON decoding error: %v", err)

View File

@ -25,27 +25,9 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" openapitesting "k8s.io/apiserver/pkg/endpoints/openapi/testing"
) )
type TestType struct {
}
func (t TestType) GetObjectKind() schema.ObjectKind {
return t
}
func (t TestType) SetGroupVersionKind(kind schema.GroupVersionKind) {
}
func (t TestType) GroupVersionKind() schema.GroupVersionKind {
return schema.GroupVersionKind{
Group: "test",
Version: "v1",
Kind: "TestType",
}
}
func assertEqual(t *testing.T, expected, actual interface{}) { func assertEqual(t *testing.T, expected, actual interface{}) {
var equal bool var equal bool
if expected == nil || actual == nil { if expected == nil || actual == nil {
@ -59,17 +41,17 @@ func assertEqual(t *testing.T, expected, actual interface{}) {
} }
func TestGetDefinitionName(t *testing.T) { func TestGetDefinitionName(t *testing.T) {
testType := TestType{} testType := openapitesting.TestType{}
// in production, the name is stripped of ".*vendor/" prefix before passed // in production, the name is stripped of ".*vendor/" prefix before passed
// to GetDefinitionName, so here typePkgName does not have the // to GetDefinitionName, so here typePkgName does not have the
// "k8s.io/kubernetes/vendor" prefix. // "k8s.io/kubernetes/vendor" prefix.
typePkgName := "k8s.io/apiserver/pkg/endpoints/openapi.TestType" typePkgName := "k8s.io/apiserver/pkg/endpoints/openapi/testing.TestType"
typeFriendlyName := "io.k8s.apiserver.pkg.endpoints.openapi.TestType" typeFriendlyName := "io.k8s.apiserver.pkg.endpoints.openapi.testing.TestType"
if strings.HasSuffix(reflect.TypeOf(testType).PkgPath(), "go_default_test") { if strings.HasSuffix(reflect.TypeOf(testType).PkgPath(), "go_default_test") {
// the test is running inside bazel where the package name is changed and // the test is running inside bazel where the package name is changed and
// "go_default_test" will add to package path. // "go_default_test" will add to package path.
typePkgName = "k8s.io/apiserver/pkg/endpoints/openapi/go_default_test.TestType" typePkgName = "k8s.io/apiserver/pkg/endpoints/openapi/testing/go_default_test.TestType"
typeFriendlyName = "io.k8s.apiserver.pkg.endpoints.openapi.go_default_test.TestType" typeFriendlyName = "io.k8s.apiserver.pkg.endpoints.openapi.testing.go_default_test.TestType"
} }
s := runtime.NewScheme() s := runtime.NewScheme()
s.AddKnownTypeWithName(testType.GroupVersionKind(), &testType) s.AddKnownTypeWithName(testType.GroupVersionKind(), &testType)

View File

@ -0,0 +1,40 @@
/*
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 testing
import (
"k8s.io/apimachinery/pkg/runtime/schema"
)
// +k8s:deepcopy-gen=true
type TestType struct {
}
func (t TestType) GetObjectKind() schema.ObjectKind {
return t
}
func (t TestType) SetGroupVersionKind(kind schema.GroupVersionKind) {
}
func (t TestType) GroupVersionKind() schema.GroupVersionKind {
return schema.GroupVersionKind{
Group: "test",
Version: "v1",
Kind: "TestType",
}
}

View File

@ -0,0 +1,43 @@
// +build !ignore_autogenerated
/*
Copyright 2017 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.
*/
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
package testing
import (
conversion "k8s.io/apimachinery/pkg/conversion"
reflect "reflect"
)
// GetGeneratedDeepCopyFuncs returns the generated funcs, since we aren't registering them.
func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc {
return []conversion.GeneratedDeepCopyFunc{
{Fn: DeepCopy_openapi_TestType, InType: reflect.TypeOf(&TestType{})},
}
}
// DeepCopy_openapi_TestType is an autogenerated deepcopy function.
func DeepCopy_openapi_TestType(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*TestType)
out := out.(*TestType)
*out = *in
return nil
}
}

View File

@ -0,0 +1,19 @@
/*
Copyright 2017 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.
*/
// +k8s:deepcopy-gen=package
package testing // import "k8s.io/apiserver/pkg/endpoints/testing"

View File

@ -67,3 +67,14 @@ type SimpleList struct {
} }
func (obj *SimpleList) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } func (obj *SimpleList) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
// SimpleXGSubresource is a cross group subresource, i.e. the subresource does not belong to the
// same group as its parent resource.
type SimpleXGSubresource struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
SubresourceInfo string `json:"subresourceInfo,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
}
func (obj *SimpleXGSubresource) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }

View File

@ -0,0 +1,19 @@
/*
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.
*/
// +k8s:deepcopy-gen=package
package testing