vendor: remove dep and use vndr
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
parent
16f44674a4
commit
148e72d81e
16131 changed files with 73815 additions and 4235138 deletions
19
vendor/k8s.io/apimachinery/pkg/runtime/OWNERS
generated
vendored
19
vendor/k8s.io/apimachinery/pkg/runtime/OWNERS
generated
vendored
|
@ -1,19 +0,0 @@
|
|||
approvers:
|
||||
- caesarxuchao
|
||||
- deads2k
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
reviewers:
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
- derekwaynecarr
|
||||
- caesarxuchao
|
||||
- mikedanese
|
||||
- nikhiljindal
|
||||
- gmarek
|
||||
- krousey
|
||||
- timothysc
|
||||
- piosz
|
||||
- mbohlool
|
20
vendor/k8s.io/apimachinery/pkg/runtime/codec.go
generated
vendored
20
vendor/k8s.io/apimachinery/pkg/runtime/codec.go
generated
vendored
|
@ -161,11 +161,12 @@ func (c *parameterCodec) DecodeParameters(parameters url.Values, from schema.Gro
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
targetGVK := targetGVKs[0]
|
||||
if targetGVK.GroupVersion() == from {
|
||||
return c.convertor.Convert(¶meters, into, nil)
|
||||
for i := range targetGVKs {
|
||||
if targetGVKs[i].GroupVersion() == from {
|
||||
return c.convertor.Convert(¶meters, into, nil)
|
||||
}
|
||||
}
|
||||
input, err := c.creator.New(from.WithKind(targetGVK.Kind))
|
||||
input, err := c.creator.New(from.WithKind(targetGVKs[0].Kind))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -194,16 +195,17 @@ func (c *parameterCodec) EncodeParameters(obj Object, to schema.GroupVersion) (u
|
|||
}
|
||||
|
||||
type base64Serializer struct {
|
||||
Serializer
|
||||
Encoder
|
||||
Decoder
|
||||
}
|
||||
|
||||
func NewBase64Serializer(s Serializer) Serializer {
|
||||
return &base64Serializer{s}
|
||||
func NewBase64Serializer(e Encoder, d Decoder) Serializer {
|
||||
return &base64Serializer{e, d}
|
||||
}
|
||||
|
||||
func (s base64Serializer) Encode(obj Object, stream io.Writer) error {
|
||||
e := base64.NewEncoder(base64.StdEncoding, stream)
|
||||
err := s.Serializer.Encode(obj, e)
|
||||
err := s.Encoder.Encode(obj, e)
|
||||
e.Close()
|
||||
return err
|
||||
}
|
||||
|
@ -214,7 +216,7 @@ func (s base64Serializer) Decode(data []byte, defaults *schema.GroupVersionKind,
|
|||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return s.Serializer.Decode(out[:n], defaults, into)
|
||||
return s.Decoder.Decode(out[:n], defaults, into)
|
||||
}
|
||||
|
||||
// SerializerInfoForMediaType returns the first info in types that has a matching media type (which cannot
|
||||
|
|
135
vendor/k8s.io/apimachinery/pkg/runtime/conversion_test.go
generated
vendored
135
vendor/k8s.io/apimachinery/pkg/runtime/conversion_test.go
generated
vendored
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package runtime_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
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) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "external"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.Log(t)
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("Complex"), &InternalComplex{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("Complex"), &ExternalComplex{})
|
||||
|
||||
testCases := map[string]struct {
|
||||
input map[string][]string
|
||||
errFn func(error) bool
|
||||
expected runtime.Object
|
||||
}{
|
||||
"ignores omitempty": {
|
||||
input: map[string][]string{
|
||||
"String": {"not_used"},
|
||||
"string": {"value"},
|
||||
"int": {"1"},
|
||||
"Integer64": {"2"},
|
||||
},
|
||||
expected: &ExternalComplex{String: "value", Integer: 1},
|
||||
},
|
||||
"returns error on bad int": {
|
||||
input: map[string][]string{
|
||||
"int": {"a"},
|
||||
},
|
||||
errFn: func(err error) bool { return err != nil },
|
||||
expected: &ExternalComplex{},
|
||||
},
|
||||
"parses int64": {
|
||||
input: map[string][]string{
|
||||
"Int64": {"-1"},
|
||||
},
|
||||
expected: &ExternalComplex{Int64: -1},
|
||||
},
|
||||
"returns error on bad int64": {
|
||||
input: map[string][]string{
|
||||
"Int64": {"a"},
|
||||
},
|
||||
errFn: func(err error) bool { return err != nil },
|
||||
expected: &ExternalComplex{},
|
||||
},
|
||||
"parses boolean true": {
|
||||
input: map[string][]string{
|
||||
"bool": {"true"},
|
||||
},
|
||||
expected: &ExternalComplex{Bool: true},
|
||||
},
|
||||
"parses boolean any value": {
|
||||
input: map[string][]string{
|
||||
"bool": {"foo"},
|
||||
},
|
||||
expected: &ExternalComplex{Bool: true},
|
||||
},
|
||||
"parses boolean false": {
|
||||
input: map[string][]string{
|
||||
"bool": {"false"},
|
||||
},
|
||||
expected: &ExternalComplex{Bool: false},
|
||||
},
|
||||
"parses boolean empty value": {
|
||||
input: map[string][]string{
|
||||
"bool": {""},
|
||||
},
|
||||
expected: &ExternalComplex{Bool: true},
|
||||
},
|
||||
"parses boolean no value": {
|
||||
input: map[string][]string{
|
||||
"bool": {},
|
||||
},
|
||||
expected: &ExternalComplex{Bool: false},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testCases {
|
||||
out := &ExternalComplex{}
|
||||
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)
|
||||
continue
|
||||
} else if err != nil {
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(out, tc.expected) {
|
||||
t.Errorf("%s: unexpected output: %#v", k, out)
|
||||
}
|
||||
}
|
||||
}
|
290
vendor/k8s.io/apimachinery/pkg/runtime/embedded_test.go
generated
vendored
290
vendor/k8s.io/apimachinery/pkg/runtime/embedded_test.go
generated
vendored
|
@ -1,290 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package runtime_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"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) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
|
||||
externalGVK := externalGV.WithKind("ObjectTest")
|
||||
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes(internalGV, &ObjectTest{})
|
||||
s.AddKnownTypeWithName(externalGVK, &ObjectTestExternal{})
|
||||
|
||||
codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
|
||||
|
||||
obj, gvk, err := codec.Decode([]byte(`{"kind":"`+externalGVK.Kind+`","apiVersion":"`+externalGV.String()+`","items":[{}]}`), nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
test := obj.(*ObjectTest)
|
||||
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])
|
||||
}
|
||||
if *gvk != externalGVK {
|
||||
t.Fatalf("unexpected kind: %#v", gvk)
|
||||
}
|
||||
|
||||
obj, gvk, err = codec.Decode([]byte(`{"kind":"`+externalGVK.Kind+`","apiVersion":"`+externalGV.String()+`","items":[{"kind":"Other","apiVersion":"v1"}]}`), nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
test = obj.(*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 {
|
||||
t.Fatalf("unexpected object: %#v", test.Items[0])
|
||||
}
|
||||
if *gvk != externalGVK {
|
||||
t.Fatalf("unexpected kind: %#v", gvk)
|
||||
}
|
||||
}
|
||||
|
||||
func TestArrayOfRuntimeObject(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
|
||||
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes(internalGV, &EmbeddedTest{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("EmbeddedTest"), &EmbeddedTestExternal{})
|
||||
s.AddKnownTypes(internalGV, &ObjectTest{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("ObjectTest"), &ObjectTestExternal{})
|
||||
|
||||
codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
|
||||
|
||||
innerItems := []runtime.Object{
|
||||
&EmbeddedTest{ID: "baz"},
|
||||
}
|
||||
items := []runtime.Object{
|
||||
&EmbeddedTest{ID: "foo"},
|
||||
&EmbeddedTest{ID: "bar"},
|
||||
// TODO: until YAML is removed, this JSON must be in ascending key order to ensure consistent roundtrip serialization
|
||||
&runtime.Unknown{
|
||||
Raw: []byte(`{"apiVersion":"unknown.group/unknown","foo":"bar","kind":"OtherTest"}`),
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
},
|
||||
&ObjectTest{
|
||||
Items: runtime.NewEncodableList(codec, innerItems),
|
||||
},
|
||||
}
|
||||
internal := &ObjectTest{
|
||||
Items: runtime.NewEncodableList(codec, items),
|
||||
}
|
||||
wire, err := runtime.Encode(codec, internal)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
t.Logf("Wire format is:\n%s\n", string(wire))
|
||||
|
||||
obj := &ObjectTestExternal{}
|
||||
if err := json.Unmarshal(wire, obj); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
t.Logf("exact wire is: %s", string(obj.Items[0].Raw))
|
||||
|
||||
items[3] = &ObjectTest{Items: innerItems}
|
||||
internal.Items = items
|
||||
|
||||
decoded, err := runtime.Decode(codec, wire)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
list, err := meta.ExtractList(decoded)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if errs := runtime.DecodeList(list, codec); len(errs) > 0 {
|
||||
t.Fatalf("unexpected error: %v", errs)
|
||||
}
|
||||
|
||||
list2, err := meta.ExtractList(list[3])
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if errs := runtime.DecodeList(list2, codec); len(errs) > 0 {
|
||||
t.Fatalf("unexpected error: %v", errs)
|
||||
}
|
||||
if err := meta.SetList(list[3], list2); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
// we want DecodeList to set type meta if possible, even on runtime.Unknown objects
|
||||
internal.Items[2].(*runtime.Unknown).TypeMeta = runtime.TypeMeta{Kind: "OtherTest", APIVersion: "unknown.group/unknown"}
|
||||
if e, a := internal.Items, list; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("mismatched decoded: %s", diff.ObjectGoPrintSideBySide(e, a))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNestedObject(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
|
||||
embeddedTestExternalGVK := externalGV.WithKind("EmbeddedTest")
|
||||
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes(internalGV, &EmbeddedTest{})
|
||||
s.AddKnownTypeWithName(embeddedTestExternalGVK, &EmbeddedTestExternal{})
|
||||
|
||||
codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
|
||||
|
||||
inner := &EmbeddedTest{
|
||||
ID: "inner",
|
||||
}
|
||||
outer := &EmbeddedTest{
|
||||
ID: "outer",
|
||||
Object: runtime.NewEncodable(codec, inner),
|
||||
}
|
||||
|
||||
wire, err := runtime.Encode(codec, outer)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected encode error '%v'", err)
|
||||
}
|
||||
|
||||
t.Logf("Wire format is:\n%v\n", string(wire))
|
||||
|
||||
decoded, err := runtime.Decode(codec, wire)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected decode error %v", err)
|
||||
}
|
||||
|
||||
// for later tests
|
||||
outer.Object = inner
|
||||
|
||||
if e, a := outer, decoded; reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected unequal %#v %#v", e, a)
|
||||
}
|
||||
|
||||
obj, err := runtime.Decode(codec, decoded.(*EmbeddedTest).Object.(*runtime.Unknown).Raw)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
decoded.(*EmbeddedTest).Object = obj
|
||||
if e, a := outer, decoded; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected equal %#v %#v", e, a)
|
||||
}
|
||||
|
||||
// test JSON decoding of the external object, which should preserve
|
||||
// raw bytes
|
||||
var externalViaJSON EmbeddedTestExternal
|
||||
err = json.Unmarshal(wire, &externalViaJSON)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected decode error %v", err)
|
||||
}
|
||||
if externalViaJSON.Kind == "" || externalViaJSON.APIVersion == "" || externalViaJSON.ID != "outer" {
|
||||
t.Errorf("Expected objects to have type info set, got %#v", externalViaJSON)
|
||||
}
|
||||
if !reflect.DeepEqual(externalViaJSON.EmptyObject.Raw, []byte("null")) || len(externalViaJSON.Object.Raw) == 0 {
|
||||
t.Errorf("Expected deserialization of nested objects into bytes, got %#v", externalViaJSON)
|
||||
}
|
||||
|
||||
// test JSON decoding, too, since Decode uses yaml unmarshalling.
|
||||
// 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
|
||||
// the external representation
|
||||
var decodedViaJSON EmbeddedTest
|
||||
err = json.Unmarshal(wire, &decodedViaJSON)
|
||||
if err == nil || !strings.Contains(err.Error(), "unmarshal object into Go value of type runtime.Object") {
|
||||
t.Fatalf("Unexpected decode error %v", err)
|
||||
}
|
||||
if a := decodedViaJSON; a.Object != nil || a.EmptyObject != nil {
|
||||
t.Errorf("Expected embedded objects to be nil: %#v", a)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDeepCopyOfRuntimeObject checks to make sure that runtime.Objects's can be passed through DeepCopy with fidelity
|
||||
func TestDeepCopyOfRuntimeObject(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
|
||||
embeddedTestExternalGVK := externalGV.WithKind("EmbeddedTest")
|
||||
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes(internalGV, &EmbeddedTest{})
|
||||
s.AddKnownTypeWithName(embeddedTestExternalGVK, &EmbeddedTestExternal{})
|
||||
|
||||
original := &EmbeddedTest{
|
||||
ID: "outer",
|
||||
Object: &EmbeddedTest{
|
||||
ID: "inner",
|
||||
},
|
||||
}
|
||||
|
||||
codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
|
||||
|
||||
originalData, err := runtime.Encode(codec, original)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
t.Logf("originalRole = %v\n", string(originalData))
|
||||
|
||||
copyOfOriginal, err := s.DeepCopy(original)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
copiedData, err := runtime.Encode(codec, copyOfOriginal.(runtime.Object))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
t.Logf("copyOfRole = %v\n", string(copiedData))
|
||||
|
||||
if !reflect.DeepEqual(original, copyOfOriginal) {
|
||||
t.Errorf("expected \n%v\n, got \n%v", string(originalData), string(copiedData))
|
||||
}
|
||||
}
|
39
vendor/k8s.io/apimachinery/pkg/runtime/extension_test.go
generated
vendored
39
vendor/k8s.io/apimachinery/pkg/runtime/extension_test.go
generated
vendored
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package runtime_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func TestEmbeddedRawExtensionMarshal(t *testing.T) {
|
||||
type test struct {
|
||||
Ext runtime.RawExtension
|
||||
}
|
||||
|
||||
extension := test{Ext: runtime.RawExtension{Raw: []byte(`{"foo":"bar"}`)}}
|
||||
data, err := json.Marshal(extension)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if string(data) != `{"Ext":{"foo":"bar"}}` {
|
||||
t.Errorf("unexpected data: %s", string(data))
|
||||
}
|
||||
}
|
136
vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version_test.go
generated
vendored
136
vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version_test.go
generated
vendored
|
@ -1,136 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGroupVersionParse(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
out GroupVersion
|
||||
err func(error) bool
|
||||
}{
|
||||
{input: "v1", out: GroupVersion{Version: "v1"}},
|
||||
{input: "v2", out: GroupVersion{Version: "v2"}},
|
||||
{input: "/v1", out: GroupVersion{Version: "v1"}},
|
||||
{input: "v1/", out: GroupVersion{Group: "v1"}},
|
||||
{input: "/v1/", err: func(err error) bool { return err.Error() == "unexpected GroupVersion string: /v1/" }},
|
||||
{input: "v1/a", out: GroupVersion{Group: "v1", Version: "a"}},
|
||||
}
|
||||
for i, test := range tests {
|
||||
out, err := ParseGroupVersion(test.input)
|
||||
if test.err == nil && err != nil || err == nil && test.err != nil {
|
||||
t.Errorf("%d: unexpected error: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if test.err != nil && !test.err(err) {
|
||||
t.Errorf("%d: unexpected error: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if out != test.out {
|
||||
t.Errorf("%d: unexpected output: %#v", i, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroupResourceParse(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
out GroupResource
|
||||
}{
|
||||
{input: "v1", out: GroupResource{Resource: "v1"}},
|
||||
{input: ".v1", out: GroupResource{Group: "v1"}},
|
||||
{input: "v1.", out: GroupResource{Resource: "v1"}},
|
||||
{input: "v1.a", out: GroupResource{Group: "a", Resource: "v1"}},
|
||||
{input: "b.v1.a", out: GroupResource{Group: "v1.a", Resource: "b"}},
|
||||
}
|
||||
for i, test := range tests {
|
||||
out := ParseGroupResource(test.input)
|
||||
if out != test.out {
|
||||
t.Errorf("%d: unexpected output: %#v", i, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseResourceArg(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
gvr *GroupVersionResource
|
||||
gr GroupResource
|
||||
}{
|
||||
{input: "v1", gr: GroupResource{Resource: "v1"}},
|
||||
{input: ".v1", gr: GroupResource{Group: "v1"}},
|
||||
{input: "v1.", gr: GroupResource{Resource: "v1"}},
|
||||
{input: "v1.a", gr: GroupResource{Group: "a", Resource: "v1"}},
|
||||
{input: "b.v1.a", gvr: &GroupVersionResource{Group: "a", Version: "v1", Resource: "b"}, gr: GroupResource{Group: "v1.a", Resource: "b"}},
|
||||
}
|
||||
for i, test := range tests {
|
||||
gvr, gr := ParseResourceArg(test.input)
|
||||
if (gvr != nil && test.gvr == nil) || (gvr == nil && test.gvr != nil) || (test.gvr != nil && *gvr != *test.gvr) {
|
||||
t.Errorf("%d: unexpected output: %#v", i, gvr)
|
||||
}
|
||||
if gr != test.gr {
|
||||
t.Errorf("%d: unexpected output: %#v", i, gr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestKindForGroupVersionKinds(t *testing.T) {
|
||||
gvks := GroupVersions{
|
||||
GroupVersion{Group: "batch", Version: "v1"},
|
||||
GroupVersion{Group: "batch", Version: "v2alpha1"},
|
||||
GroupVersion{Group: "policy", Version: "v1beta1"},
|
||||
}
|
||||
cases := []struct {
|
||||
input []GroupVersionKind
|
||||
target GroupVersionKind
|
||||
ok bool
|
||||
}{
|
||||
{
|
||||
input: []GroupVersionKind{{Group: "batch", Version: "v2alpha1", Kind: "ScheduledJob"}},
|
||||
target: GroupVersionKind{Group: "batch", Version: "v2alpha1", Kind: "ScheduledJob"},
|
||||
ok: true,
|
||||
},
|
||||
{
|
||||
input: []GroupVersionKind{{Group: "batch", Version: "v3alpha1", Kind: "CronJob"}},
|
||||
target: GroupVersionKind{Group: "batch", Version: "v1", Kind: "CronJob"},
|
||||
ok: true,
|
||||
},
|
||||
{
|
||||
input: []GroupVersionKind{{Group: "policy", Version: "v1beta1", Kind: "PodDisruptionBudget"}},
|
||||
target: GroupVersionKind{Group: "policy", Version: "v1beta1", Kind: "PodDisruptionBudget"},
|
||||
ok: true,
|
||||
},
|
||||
{
|
||||
input: []GroupVersionKind{{Group: "apps", Version: "v1alpha1", Kind: "StatefulSet"}},
|
||||
target: GroupVersionKind{},
|
||||
ok: false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
target, ok := gvks.KindForGroupVersionKinds(c.input)
|
||||
if c.target != target {
|
||||
t.Errorf("%d: unexpected target: %v, expected %v", i, target, c.target)
|
||||
}
|
||||
if c.ok != ok {
|
||||
t.Errorf("%d: unexpected ok: %v, expected %v", i, ok, c.ok)
|
||||
}
|
||||
}
|
||||
}
|
21
vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
generated
vendored
21
vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
generated
vendored
|
@ -163,22 +163,13 @@ func (s *Scheme) AddUnversionedTypes(version schema.GroupVersion, types ...Objec
|
|||
// the struct becomes the "kind" field when encoding. Version may not be empty - use the
|
||||
// APIVersionInternal constant if you have a type that does not have a formal version.
|
||||
func (s *Scheme) AddKnownTypes(gv schema.GroupVersion, types ...Object) {
|
||||
if len(gv.Version) == 0 {
|
||||
panic(fmt.Sprintf("version is required on all types: %s %v", gv, types[0]))
|
||||
}
|
||||
for _, obj := range types {
|
||||
t := reflect.TypeOf(obj)
|
||||
if t.Kind() != reflect.Ptr {
|
||||
panic("All types must be pointers to structs.")
|
||||
}
|
||||
t = t.Elem()
|
||||
if t.Kind() != reflect.Struct {
|
||||
panic("All types must be pointers to structs.")
|
||||
}
|
||||
|
||||
gvk := gv.WithKind(t.Name())
|
||||
s.gvkToType[gvk] = t
|
||||
s.typeToGVK[t] = append(s.typeToGVK[t], gvk)
|
||||
s.AddKnownTypeWithName(gv.WithKind(t.Name()), obj)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,7 +190,17 @@ func (s *Scheme) AddKnownTypeWithName(gvk schema.GroupVersionKind, obj Object) {
|
|||
panic("All types must be pointers to structs.")
|
||||
}
|
||||
|
||||
if oldT, found := s.gvkToType[gvk]; found && oldT != t {
|
||||
panic(fmt.Sprintf("Double registration of different types for %v: old=%v.%v, new=%v.%v", gvk, oldT.PkgPath(), oldT.Name(), t.PkgPath(), t.Name()))
|
||||
}
|
||||
|
||||
s.gvkToType[gvk] = t
|
||||
|
||||
for _, existingGvk := range s.typeToGVK[t] {
|
||||
if existingGvk == gvk {
|
||||
return
|
||||
}
|
||||
}
|
||||
s.typeToGVK[t] = append(s.typeToGVK[t], gvk)
|
||||
}
|
||||
|
||||
|
|
925
vendor/k8s.io/apimachinery/pkg/runtime/scheme_test.go
generated
vendored
925
vendor/k8s.io/apimachinery/pkg/runtime/scheme_test.go
generated
vendored
|
@ -1,925 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package runtime_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/gofuzz"
|
||||
flag "github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
)
|
||||
|
||||
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) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{})
|
||||
|
||||
// If set, would clear TypeMeta during conversion.
|
||||
//scheme.AddIgnoredConversionType(&TypeMeta{}, &TypeMeta{})
|
||||
|
||||
// test that scheme is an ObjectTyper
|
||||
var _ runtime.ObjectTyper = scheme
|
||||
|
||||
internalToExternalCalls := 0
|
||||
externalToInternalCalls := 0
|
||||
|
||||
// Register functions to verify that scope.Meta() gets set correctly.
|
||||
err := scheme.AddConversionFuncs(
|
||||
func(in *InternalSimple, out *ExternalSimple, scope conversion.Scope) error {
|
||||
scope.Convert(&in.TypeMeta, &out.TypeMeta, 0)
|
||||
scope.Convert(&in.TestString, &out.TestString, 0)
|
||||
internalToExternalCalls++
|
||||
return nil
|
||||
},
|
||||
func(in *ExternalSimple, out *InternalSimple, scope conversion.Scope) error {
|
||||
scope.Convert(&in.TypeMeta, &out.TypeMeta, 0)
|
||||
scope.Convert(&in.TestString, &out.TestString, 0)
|
||||
externalToInternalCalls++
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
codecs := serializer.NewCodecFactory(scheme)
|
||||
codec := codecs.LegacyCodec(externalGV)
|
||||
info, _ := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), runtime.ContentTypeJSON)
|
||||
jsonserializer := info.Serializer
|
||||
|
||||
simple := &InternalSimple{
|
||||
TestString: "foo",
|
||||
}
|
||||
|
||||
// Test Encode, Decode, DecodeInto, and DecodeToVersion
|
||||
obj := runtime.Object(simple)
|
||||
data, err := runtime.Encode(codec, obj)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
obj2, err := runtime.Decode(codec, data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := obj2.(*InternalSimple); !ok {
|
||||
t.Fatalf("Got wrong type")
|
||||
}
|
||||
if e, a := simple, obj2; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a)
|
||||
}
|
||||
|
||||
obj3 := &InternalSimple{}
|
||||
if err := runtime.DecodeInto(codec, data, obj3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// clearing TypeMeta is a function of the scheme, which we do not test here (ConvertToVersion
|
||||
// does not automatically clear TypeMeta anymore).
|
||||
simple.TypeMeta = runtime.TypeMeta{Kind: "Simple", APIVersion: externalGV.String()}
|
||||
if e, a := simple, obj3; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a)
|
||||
}
|
||||
|
||||
obj4, err := runtime.Decode(jsonserializer, data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := obj4.(*ExternalSimple); !ok {
|
||||
t.Fatalf("Got wrong type")
|
||||
}
|
||||
|
||||
// Test Convert
|
||||
external := &ExternalSimple{}
|
||||
err = scheme.Convert(simple, external, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
if e, a := simple.TestString, external.TestString; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
// Encode and Convert should each have caused an increment.
|
||||
if e, a := 2, internalToExternalCalls; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
// DecodeInto and Decode should each have caused an increment because of a conversion
|
||||
if e, a := 2, externalToInternalCalls; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadJSONRejection(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
codecs := serializer.NewCodecFactory(scheme)
|
||||
info, _ := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), runtime.ContentTypeJSON)
|
||||
jsonserializer := info.Serializer
|
||||
|
||||
badJSONMissingKind := []byte(`{ }`)
|
||||
if _, err := runtime.Decode(jsonserializer, badJSONMissingKind); err == nil {
|
||||
t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind)
|
||||
}
|
||||
badJSONUnknownType := []byte(`{"kind": "bar"}`)
|
||||
if _, err1 := runtime.Decode(jsonserializer, badJSONUnknownType); err1 == nil {
|
||||
t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType)
|
||||
}
|
||||
/*badJSONKindMismatch := []byte(`{"kind": "Pod"}`)
|
||||
if err2 := DecodeInto(badJSONKindMismatch, &Node{}); err2 == nil {
|
||||
t.Errorf("Kind is set but doesn't match the object type: %s", badJSONKindMismatch)
|
||||
}*/
|
||||
}
|
||||
|
||||
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) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("OptionalExtensionType"), &InternalOptionalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("OptionalExtensionType"), &ExternalOptionalExtensionType{})
|
||||
|
||||
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
|
||||
|
||||
table := []struct {
|
||||
obj runtime.Object
|
||||
encoded string
|
||||
}{
|
||||
{
|
||||
&InternalOptionalExtensionType{Extension: nil},
|
||||
`{"kind":"OptionalExtensionType","apiVersion":"` + externalGV.String() + `"}`,
|
||||
},
|
||||
}
|
||||
|
||||
for i, item := range table {
|
||||
gotDecoded, err := runtime.Decode(codec, []byte(item.encoded))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error '%v' (%v)", err, item.encoded)
|
||||
} else if e, a := item.obj, gotDecoded; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d: unexpected objects:\n%s", i, diff.ObjectGoPrintSideBySide(e, a))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtensionMapping(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("ExtensionType"), &InternalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("OptionalExtensionType"), &InternalOptionalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("ExtensionType"), &ExternalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("OptionalExtensionType"), &ExternalOptionalExtensionType{})
|
||||
|
||||
// register external first when the object is the same in both schemes, so ObjectVersionAndKind reports the
|
||||
// external version.
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("A"), &ExtensionA{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("B"), &ExtensionB{})
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("A"), &ExtensionA{})
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("B"), &ExtensionB{})
|
||||
|
||||
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
|
||||
|
||||
table := []struct {
|
||||
obj runtime.Object
|
||||
expected runtime.Object
|
||||
encoded string
|
||||
}{
|
||||
{
|
||||
&InternalExtensionType{
|
||||
Extension: runtime.NewEncodable(codec, &ExtensionA{TestString: "foo"}),
|
||||
},
|
||||
&InternalExtensionType{
|
||||
Extension: &runtime.Unknown{
|
||||
Raw: []byte(`{"apiVersion":"test.group/testExternal","kind":"A","testString":"foo"}`),
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
},
|
||||
},
|
||||
// apiVersion is set in the serialized object for easier consumption by clients
|
||||
`{"apiVersion":"` + externalGV.String() + `","kind":"ExtensionType","extension":{"apiVersion":"test.group/testExternal","kind":"A","testString":"foo"}}
|
||||
`,
|
||||
}, {
|
||||
&InternalExtensionType{Extension: runtime.NewEncodable(codec, &ExtensionB{TestString: "bar"})},
|
||||
&InternalExtensionType{
|
||||
Extension: &runtime.Unknown{
|
||||
Raw: []byte(`{"apiVersion":"test.group/testExternal","kind":"B","testString":"bar"}`),
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
},
|
||||
},
|
||||
// apiVersion is set in the serialized object for easier consumption by clients
|
||||
`{"apiVersion":"` + externalGV.String() + `","kind":"ExtensionType","extension":{"apiVersion":"test.group/testExternal","kind":"B","testString":"bar"}}
|
||||
`,
|
||||
}, {
|
||||
&InternalExtensionType{Extension: nil},
|
||||
&InternalExtensionType{
|
||||
Extension: nil,
|
||||
},
|
||||
`{"apiVersion":"` + externalGV.String() + `","kind":"ExtensionType","extension":null}
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
for i, item := range table {
|
||||
gotEncoded, err := runtime.Encode(codec, item.obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error '%v' (%#v)", err, item.obj)
|
||||
} else if e, a := item.encoded, string(gotEncoded); e != a {
|
||||
t.Errorf("expected\n%#v\ngot\n%#v\n", e, a)
|
||||
}
|
||||
|
||||
gotDecoded, err := runtime.Decode(codec, []byte(item.encoded))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error '%v' (%v)", err, item.encoded)
|
||||
} else if e, a := item.expected, gotDecoded; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d: unexpected objects:\n%s", i, diff.ObjectGoPrintSideBySide(e, a))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncode(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{})
|
||||
|
||||
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
|
||||
|
||||
test := &InternalSimple{
|
||||
TestString: "I'm the same",
|
||||
}
|
||||
obj := runtime.Object(test)
|
||||
data, err := runtime.Encode(codec, obj)
|
||||
obj2, gvk, err2 := codec.Decode(data, nil, nil)
|
||||
if err != nil || err2 != nil {
|
||||
t.Fatalf("Failure: '%v' '%v'", err, err2)
|
||||
}
|
||||
if _, ok := obj2.(*InternalSimple); !ok {
|
||||
t.Fatalf("Got wrong type")
|
||||
}
|
||||
if !reflect.DeepEqual(obj2, test) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", test, obj2)
|
||||
}
|
||||
if !reflect.DeepEqual(gvk, &schema.GroupVersionKind{Group: "test.group", Version: "testExternal", Kind: "Simple"}) {
|
||||
t.Errorf("unexpected gvk returned by decode: %#v", gvk)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnversionedTypes(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
otherGV := schema.GroupVersion{Group: "group", Version: "other"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddUnversionedTypes(externalGV, &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{})
|
||||
scheme.AddKnownTypeWithName(otherGV.WithKind("Simple"), &ExternalSimple{})
|
||||
|
||||
codec := serializer.NewCodecFactory(scheme).LegacyCodec(externalGV)
|
||||
|
||||
if unv, ok := scheme.IsUnversioned(&InternalSimple{}); !unv || !ok {
|
||||
t.Fatalf("type not unversioned and in scheme: %t %t", unv, ok)
|
||||
}
|
||||
|
||||
kinds, _, err := scheme.ObjectKinds(&InternalSimple{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
kind := kinds[0]
|
||||
if kind != externalGV.WithKind("InternalSimple") {
|
||||
t.Fatalf("unexpected: %#v", kind)
|
||||
}
|
||||
|
||||
test := &InternalSimple{
|
||||
TestString: "I'm the same",
|
||||
}
|
||||
obj := runtime.Object(test)
|
||||
data, err := runtime.Encode(codec, obj)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
obj2, gvk, err := codec.Decode(data, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := obj2.(*InternalSimple); !ok {
|
||||
t.Fatalf("Got wrong type")
|
||||
}
|
||||
if !reflect.DeepEqual(obj2, test) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", test, obj2)
|
||||
}
|
||||
// object is serialized as an unversioned object (in the group and version it was defined in)
|
||||
if !reflect.DeepEqual(gvk, &schema.GroupVersionKind{Group: "test.group", Version: "testExternal", Kind: "InternalSimple"}) {
|
||||
t.Errorf("unexpected gvk returned by decode: %#v", gvk)
|
||||
}
|
||||
|
||||
// when serialized to a different group, the object is kept in its preferred name
|
||||
codec = serializer.NewCodecFactory(scheme).LegacyCodec(otherGV)
|
||||
data, err = runtime.Encode(codec, obj)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(data) != `{"apiVersion":"test.group/testExternal","kind":"InternalSimple","testString":"I'm the same"}`+"\n" {
|
||||
t.Errorf("unexpected data: %s", data)
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
var TestObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 100).Funcs(
|
||||
func(j *MyWeirdCustomEmbeddedVersionKindField, c fuzz.Continue) {
|
||||
// We have to customize the randomization of MyWeirdCustomEmbeddedVersionKindFields because their
|
||||
// APIVersion and Kind must remain blank in memory.
|
||||
j.APIVersion = ""
|
||||
j.ObjectKind = ""
|
||||
j.ID = c.RandString()
|
||||
},
|
||||
)
|
||||
|
||||
// Returns a new Scheme set up with the test objects.
|
||||
func GetTestScheme() *runtime.Scheme {
|
||||
internalGV := schema.GroupVersion{Version: "__internal"}
|
||||
externalGV := schema.GroupVersion{Version: "v1"}
|
||||
alternateExternalGV := schema.GroupVersion{Group: "custom", Version: "v1"}
|
||||
differentExternalGV := schema.GroupVersion{Group: "other", Version: "v2"}
|
||||
|
||||
s := runtime.NewScheme()
|
||||
// Ordinarily, we wouldn't add TestType2, but because this is a test and
|
||||
// both types are from the same package, we need to get it into the system
|
||||
// so that converter will match it with ExternalType2.
|
||||
s.AddKnownTypes(internalGV, &TestType1{}, &TestType2{}, &ExternalInternalSame{})
|
||||
s.AddKnownTypes(externalGV, &ExternalInternalSame{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &ExternalTestType1{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("TestType2"), &ExternalTestType2{})
|
||||
s.AddKnownTypeWithName(internalGV.WithKind("TestType3"), &TestType1{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("TestType3"), &ExternalTestType1{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("TestType4"), &ExternalTestType1{})
|
||||
s.AddKnownTypeWithName(alternateExternalGV.WithKind("TestType3"), &ExternalTestType1{})
|
||||
s.AddKnownTypeWithName(alternateExternalGV.WithKind("TestType5"), &ExternalTestType1{})
|
||||
s.AddKnownTypeWithName(differentExternalGV.WithKind("TestType1"), &ExternalTestType1{})
|
||||
s.AddUnversionedTypes(externalGV, &UnversionedType{})
|
||||
return s
|
||||
}
|
||||
|
||||
func TestKnownTypes(t *testing.T) {
|
||||
s := GetTestScheme()
|
||||
if len(s.KnownTypes(schema.GroupVersion{Group: "group", Version: "v2"})) != 0 {
|
||||
t.Errorf("should have no known types for v2")
|
||||
}
|
||||
|
||||
types := s.KnownTypes(schema.GroupVersion{Version: "v1"})
|
||||
for _, s := range []string{"TestType1", "TestType2", "TestType3", "ExternalInternalSame"} {
|
||||
if _, ok := types[s]; !ok {
|
||||
t.Errorf("missing type %q", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertToVersionBasic(t *testing.T) {
|
||||
s := GetTestScheme()
|
||||
tt := &TestType1{A: "I'm not a pointer object"}
|
||||
other, err := s.ConvertToVersion(tt, schema.GroupVersion{Version: "v1"})
|
||||
if err != nil {
|
||||
t.Fatalf("Failure: %v", err)
|
||||
}
|
||||
converted, ok := other.(*ExternalTestType1)
|
||||
if !ok {
|
||||
t.Fatalf("Got wrong type: %T", other)
|
||||
}
|
||||
if tt.A != converted.A {
|
||||
t.Fatalf("Failed to convert object correctly: %#v", converted)
|
||||
}
|
||||
}
|
||||
|
||||
type testGroupVersioner struct {
|
||||
target schema.GroupVersionKind
|
||||
ok bool
|
||||
}
|
||||
|
||||
func (m testGroupVersioner) KindForGroupVersionKinds(kinds []schema.GroupVersionKind) (schema.GroupVersionKind, bool) {
|
||||
return m.target, m.ok
|
||||
}
|
||||
|
||||
func TestConvertToVersion(t *testing.T) {
|
||||
testCases := []struct {
|
||||
scheme *runtime.Scheme
|
||||
in runtime.Object
|
||||
gv runtime.GroupVersioner
|
||||
same bool
|
||||
out runtime.Object
|
||||
errFn func(error) bool
|
||||
}{
|
||||
// errors if the type is not registered in the scheme
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &UnknownType{},
|
||||
errFn: func(err error) bool { return err != nil && runtime.IsNotRegisteredError(err) },
|
||||
},
|
||||
// errors if the group versioner returns no target
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: testGroupVersioner{},
|
||||
errFn: func(err error) bool {
|
||||
return err != nil && strings.Contains(err.Error(), "is not suitable for converting")
|
||||
},
|
||||
},
|
||||
// converts to internal
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: schema.GroupVersion{Version: "__internal"},
|
||||
out: &TestType1{A: "test"},
|
||||
},
|
||||
// prefers the best match
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: schema.GroupVersions{{Version: "__internal"}, {Version: "v1"}},
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
|
||||
A: "test",
|
||||
},
|
||||
},
|
||||
// unversioned type returned as-is
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &UnversionedType{A: "test"},
|
||||
gv: schema.GroupVersions{{Version: "v1"}},
|
||||
same: true,
|
||||
out: &UnversionedType{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "UnversionedType"},
|
||||
A: "test",
|
||||
},
|
||||
},
|
||||
// unversioned type returned when not included in the target types
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &UnversionedType{A: "test"},
|
||||
gv: schema.GroupVersions{{Group: "other", Version: "v2"}},
|
||||
same: true,
|
||||
out: &UnversionedType{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "UnversionedType"},
|
||||
A: "test",
|
||||
},
|
||||
},
|
||||
// detected as already being in the target version
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: schema.GroupVersions{{Version: "v1"}},
|
||||
same: true,
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
|
||||
A: "test",
|
||||
},
|
||||
},
|
||||
// detected as already being in the first target version
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: schema.GroupVersions{{Version: "v1"}, {Version: "__internal"}},
|
||||
same: true,
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
|
||||
A: "test",
|
||||
},
|
||||
},
|
||||
// detected as already being in the first target version
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: schema.GroupVersions{{Version: "v1"}, {Version: "__internal"}},
|
||||
same: true,
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
|
||||
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
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Kind: "TestType3", Version: "v1"}},
|
||||
same: true,
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType3"},
|
||||
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
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Kind: "TestType3", Group: "custom", Version: "v1"}},
|
||||
same: true,
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "custom/v1", ObjectKind: "TestType3"},
|
||||
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
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Group: "custom", Version: "v1", Kind: "TestType5"}},
|
||||
same: true,
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "custom/v1", ObjectKind: "TestType5"},
|
||||
A: "test",
|
||||
},
|
||||
},
|
||||
// multi group versioner recognizes multiple groups and forces the output to a particular version, copies because version differs
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "other", Version: "v2"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}, schema.GroupKind{Kind: "TestType1"}),
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "other/v2", ObjectKind: "TestType1"},
|
||||
A: "test",
|
||||
},
|
||||
},
|
||||
// multi group versioner recognizes multiple groups and forces the output to a particular version, copies because version differs
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "other", Version: "v2"}, schema.GroupKind{Kind: "TestType1"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}),
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "other/v2", ObjectKind: "TestType1"},
|
||||
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)
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &TestType1{A: "test"},
|
||||
gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "custom", Version: "v1"}, schema.GroupKind{Group: "other"}, schema.GroupKind{Kind: "TestType5"}),
|
||||
errFn: func(err error) bool {
|
||||
return err != nil && strings.Contains(err.Error(), "is not suitable for converting")
|
||||
},
|
||||
},
|
||||
// multi group versioner recognizes multiple groups and forces the output to a particular version, performs no copy
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "", Version: "v1"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}, schema.GroupKind{Kind: "TestType1"}),
|
||||
same: true,
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
|
||||
A: "test",
|
||||
},
|
||||
},
|
||||
// multi group versioner recognizes multiple groups and forces the output to a particular version, performs no copy
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &ExternalTestType1{A: "test"},
|
||||
gv: runtime.NewMultiGroupVersioner(schema.GroupVersion{Group: "", Version: "v1"}, schema.GroupKind{Kind: "TestType1"}, schema.GroupKind{Group: "custom", Kind: "TestType3"}),
|
||||
same: true,
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
|
||||
A: "test",
|
||||
},
|
||||
},
|
||||
// group versioner can choose a particular target kind for a given input when kind is the same across group versions
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &TestType1{A: "test"},
|
||||
gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Version: "v1", Kind: "TestType3"}},
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType3"},
|
||||
A: "test",
|
||||
},
|
||||
},
|
||||
// group versioner can choose a different kind
|
||||
{
|
||||
scheme: GetTestScheme(),
|
||||
in: &TestType1{A: "test"},
|
||||
gv: testGroupVersioner{ok: true, target: schema.GroupVersionKind{Kind: "TestType5", Group: "custom", Version: "v1"}},
|
||||
out: &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "custom/v1", ObjectKind: "TestType5"},
|
||||
A: "test",
|
||||
},
|
||||
},
|
||||
}
|
||||
for i, test := range testCases {
|
||||
original, _ := test.scheme.DeepCopy(test.in)
|
||||
out, err := test.scheme.ConvertToVersion(test.in, test.gv)
|
||||
switch {
|
||||
case test.errFn != nil:
|
||||
if !test.errFn(err) {
|
||||
t.Errorf("%d: unexpected error: %v", i, err)
|
||||
}
|
||||
continue
|
||||
case err != nil:
|
||||
t.Errorf("%d: unexpected error: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if out == test.in {
|
||||
t.Errorf("%d: ConvertToVersion should always copy out: %#v", i, out)
|
||||
continue
|
||||
}
|
||||
|
||||
if test.same {
|
||||
if !reflect.DeepEqual(original, test.in) {
|
||||
t.Errorf("%d: unexpected mutation of input: %s", i, diff.ObjectReflectDiff(original, test.in))
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(out, test.out) {
|
||||
t.Errorf("%d: unexpected out: %s", i, diff.ObjectReflectDiff(out, test.out))
|
||||
continue
|
||||
}
|
||||
unsafe, err := test.scheme.UnsafeConvertToVersion(test.in, test.gv)
|
||||
if err != nil {
|
||||
t.Errorf("%d: unexpected error: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(unsafe, test.out) {
|
||||
t.Errorf("%d: unexpected unsafe: %s", i, diff.ObjectReflectDiff(unsafe, test.out))
|
||||
continue
|
||||
}
|
||||
if unsafe != test.in {
|
||||
t.Errorf("%d: UnsafeConvertToVersion should return same object: %#v", i, unsafe)
|
||||
continue
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(out, test.out) {
|
||||
t.Errorf("%d: unexpected out: %s", i, diff.ObjectReflectDiff(out, test.out))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetaValues(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: "__internal"}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "externalVersion"}
|
||||
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypeWithName(internalGV.WithKind("Simple"), &InternalSimple{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("Simple"), &ExternalSimple{})
|
||||
|
||||
internalToExternalCalls := 0
|
||||
externalToInternalCalls := 0
|
||||
|
||||
// Register functions to verify that scope.Meta() gets set correctly.
|
||||
err := s.AddConversionFuncs(
|
||||
func(in *InternalSimple, out *ExternalSimple, scope conversion.Scope) error {
|
||||
t.Logf("internal -> external")
|
||||
scope.Convert(&in.TestString, &out.TestString, 0)
|
||||
internalToExternalCalls++
|
||||
return nil
|
||||
},
|
||||
func(in *ExternalSimple, out *InternalSimple, scope conversion.Scope) error {
|
||||
t.Logf("external -> internal")
|
||||
scope.Convert(&in.TestString, &out.TestString, 0)
|
||||
externalToInternalCalls++
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
simple := &InternalSimple{
|
||||
TestString: "foo",
|
||||
}
|
||||
|
||||
s.Log(t)
|
||||
|
||||
out, err := s.ConvertToVersion(simple, externalGV)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
internal, err := s.ConvertToVersion(out, internalGV)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if e, a := simple, internal; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", e, a)
|
||||
}
|
||||
|
||||
if e, a := 1, internalToExternalCalls; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 1, externalToInternalCalls; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetaValuesUnregisteredConvert(t *testing.T) {
|
||||
type InternalSimple struct {
|
||||
Version string `json:"apiVersion,omitempty"`
|
||||
Kind string `json:"kind,omitempty"`
|
||||
TestString string `json:"testString"`
|
||||
}
|
||||
type ExternalSimple struct {
|
||||
Version string `json:"apiVersion,omitempty"`
|
||||
Kind string `json:"kind,omitempty"`
|
||||
TestString string `json:"testString"`
|
||||
}
|
||||
s := runtime.NewScheme()
|
||||
// We deliberately don't register the types.
|
||||
|
||||
internalToExternalCalls := 0
|
||||
|
||||
// Register functions to verify that scope.Meta() gets set correctly.
|
||||
err := s.AddConversionFuncs(
|
||||
func(in *InternalSimple, out *ExternalSimple, scope conversion.Scope) error {
|
||||
scope.Convert(&in.TestString, &out.TestString, 0)
|
||||
internalToExternalCalls++
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
simple := &InternalSimple{TestString: "foo"}
|
||||
external := &ExternalSimple{}
|
||||
err = s.Convert(simple, external, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
if e, a := simple.TestString, external.TestString; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
// Verify that our conversion handler got called.
|
||||
if e, a := 1, internalToExternalCalls; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
426
vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_test.go
generated
vendored
426
vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_test.go
generated
vendored
|
@ -1,426 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package serializer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/google/gofuzz"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
var fuzzIters = flag.Int("fuzz-iters", 50, "How many fuzzing iterations to do.")
|
||||
|
||||
type testMetaFactory struct{}
|
||||
|
||||
func (testMetaFactory) Interpret(data []byte) (*schema.GroupVersionKind, error) {
|
||||
findKind := struct {
|
||||
APIVersion string `json:"myVersionKey,omitempty"`
|
||||
ObjectKind string `json:"myKindKey,omitempty"`
|
||||
}{}
|
||||
// yaml is a superset of json, so we use it to decode here. That way,
|
||||
// we understand both.
|
||||
if err := yaml.Unmarshal(data, &findKind); err != nil {
|
||||
return nil, fmt.Errorf("couldn't get version/kind: %v", err)
|
||||
}
|
||||
gv, err := schema.ParseGroupVersion(findKind.APIVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &schema.GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: findKind.ObjectKind}, nil
|
||||
}
|
||||
|
||||
// Test a weird version/kind embedding format.
|
||||
type MyWeirdCustomEmbeddedVersionKindField struct {
|
||||
ID string `json:"ID,omitempty"`
|
||||
APIVersion string `json:"myVersionKey,omitempty"`
|
||||
ObjectKind string `json:"myKindKey,omitempty"`
|
||||
Z string `json:"Z,omitempty"`
|
||||
Y uint64 `json:"Y,omitempty"`
|
||||
}
|
||||
|
||||
type TestType1 struct {
|
||||
MyWeirdCustomEmbeddedVersionKindField `json:",inline"`
|
||||
A string `json:"A,omitempty"`
|
||||
B int `json:"B,omitempty"`
|
||||
C int8 `json:"C,omitempty"`
|
||||
D int16 `json:"D,omitempty"`
|
||||
E int32 `json:"E,omitempty"`
|
||||
F int64 `json:"F,omitempty"`
|
||||
G uint `json:"G,omitempty"`
|
||||
H uint8 `json:"H,omitempty"`
|
||||
I uint16 `json:"I,omitempty"`
|
||||
J uint32 `json:"J,omitempty"`
|
||||
K uint64 `json:"K,omitempty"`
|
||||
L bool `json:"L,omitempty"`
|
||||
M map[string]int `json:"M,omitempty"`
|
||||
N map[string]TestType2 `json:"N,omitempty"`
|
||||
O *TestType2 `json:"O,omitempty"`
|
||||
P []TestType2 `json:"Q,omitempty"`
|
||||
}
|
||||
|
||||
type TestType2 struct {
|
||||
A string `json:"A,omitempty"`
|
||||
B int `json:"B,omitempty"`
|
||||
}
|
||||
|
||||
type ExternalTestType2 struct {
|
||||
A string `json:"A,omitempty"`
|
||||
B int `json:"B,omitempty"`
|
||||
}
|
||||
type ExternalTestType1 struct {
|
||||
MyWeirdCustomEmbeddedVersionKindField `json:",inline"`
|
||||
A string `json:"A,omitempty"`
|
||||
B int `json:"B,omitempty"`
|
||||
C int8 `json:"C,omitempty"`
|
||||
D int16 `json:"D,omitempty"`
|
||||
E int32 `json:"E,omitempty"`
|
||||
F int64 `json:"F,omitempty"`
|
||||
G uint `json:"G,omitempty"`
|
||||
H uint8 `json:"H,omitempty"`
|
||||
I uint16 `json:"I,omitempty"`
|
||||
J uint32 `json:"J,omitempty"`
|
||||
K uint64 `json:"K,omitempty"`
|
||||
L bool `json:"L,omitempty"`
|
||||
M map[string]int `json:"M,omitempty"`
|
||||
N map[string]ExternalTestType2 `json:"N,omitempty"`
|
||||
O *ExternalTestType2 `json:"O,omitempty"`
|
||||
P []ExternalTestType2 `json:"Q,omitempty"`
|
||||
}
|
||||
|
||||
type ExternalInternalSame struct {
|
||||
MyWeirdCustomEmbeddedVersionKindField `json:",inline"`
|
||||
A TestType2 `json:"A,omitempty"`
|
||||
}
|
||||
|
||||
// TestObjectFuzzer can randomly populate all the above objects.
|
||||
var TestObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 100).Funcs(
|
||||
func(j *MyWeirdCustomEmbeddedVersionKindField, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(j)
|
||||
j.APIVersion = ""
|
||||
j.ObjectKind = ""
|
||||
},
|
||||
)
|
||||
|
||||
func (obj *MyWeirdCustomEmbeddedVersionKindField) GetObjectKind() schema.ObjectKind { return obj }
|
||||
func (obj *MyWeirdCustomEmbeddedVersionKindField) SetGroupVersionKind(gvk schema.GroupVersionKind) {
|
||||
obj.APIVersion, obj.ObjectKind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
func (obj *MyWeirdCustomEmbeddedVersionKindField) GroupVersionKind() schema.GroupVersionKind {
|
||||
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.ObjectKind)
|
||||
}
|
||||
|
||||
func (obj *ExternalInternalSame) GetObjectKind() schema.ObjectKind {
|
||||
return &obj.MyWeirdCustomEmbeddedVersionKindField
|
||||
}
|
||||
|
||||
func (obj *TestType1) GetObjectKind() schema.ObjectKind {
|
||||
return &obj.MyWeirdCustomEmbeddedVersionKindField
|
||||
}
|
||||
|
||||
func (obj *ExternalTestType1) GetObjectKind() schema.ObjectKind {
|
||||
return &obj.MyWeirdCustomEmbeddedVersionKindField
|
||||
}
|
||||
|
||||
func (obj *TestType2) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
|
||||
func (obj *ExternalTestType2) GetObjectKind() schema.ObjectKind {
|
||||
return schema.EmptyObjectKind
|
||||
}
|
||||
|
||||
// Returns a new Scheme set up with the test objects.
|
||||
func GetTestScheme() (*runtime.Scheme, runtime.Codec) {
|
||||
internalGV := schema.GroupVersion{Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Version: "v1"}
|
||||
externalGV2 := schema.GroupVersion{Version: "v2"}
|
||||
|
||||
s := runtime.NewScheme()
|
||||
// Ordinarily, we wouldn't add TestType2, but because this is a test and
|
||||
// both types are from the same package, we need to get it into the system
|
||||
// so that converter will match it with ExternalType2.
|
||||
s.AddKnownTypes(internalGV, &TestType1{}, &TestType2{}, &ExternalInternalSame{})
|
||||
s.AddKnownTypes(externalGV, &ExternalInternalSame{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &ExternalTestType1{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("TestType2"), &ExternalTestType2{})
|
||||
s.AddKnownTypeWithName(internalGV.WithKind("TestType3"), &TestType1{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("TestType3"), &ExternalTestType1{})
|
||||
s.AddKnownTypeWithName(externalGV2.WithKind("TestType1"), &ExternalTestType1{})
|
||||
|
||||
s.AddUnversionedTypes(externalGV, &metav1.Status{})
|
||||
|
||||
cf := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{}))
|
||||
codec := cf.LegacyCodec(schema.GroupVersion{Version: "v1"})
|
||||
return s, codec
|
||||
}
|
||||
|
||||
var semantic = conversion.EqualitiesOrDie(
|
||||
func(a, b MyWeirdCustomEmbeddedVersionKindField) bool {
|
||||
a.APIVersion, a.ObjectKind = "", ""
|
||||
b.APIVersion, b.ObjectKind = "", ""
|
||||
return a == b
|
||||
},
|
||||
)
|
||||
|
||||
func runTest(t *testing.T, source interface{}) {
|
||||
name := reflect.TypeOf(source).Elem().Name()
|
||||
TestObjectFuzzer.Fuzz(source)
|
||||
|
||||
_, codec := GetTestScheme()
|
||||
data, err := runtime.Encode(codec, source.(runtime.Object))
|
||||
if err != nil {
|
||||
t.Errorf("%v: %v (%#v)", name, err, source)
|
||||
return
|
||||
}
|
||||
obj2, err := runtime.Decode(codec, data)
|
||||
if err != nil {
|
||||
t.Errorf("%v: %v (%v)", name, err, string(data))
|
||||
return
|
||||
}
|
||||
if !semantic.DeepEqual(source, obj2) {
|
||||
t.Errorf("1: %v: diff: %v", name, diff.ObjectGoPrintSideBySide(source, obj2))
|
||||
return
|
||||
}
|
||||
obj3 := reflect.New(reflect.TypeOf(source).Elem()).Interface()
|
||||
if err := runtime.DecodeInto(codec, data, obj3.(runtime.Object)); err != nil {
|
||||
t.Errorf("2: %v: %v", name, err)
|
||||
return
|
||||
}
|
||||
if !semantic.DeepEqual(source, obj3) {
|
||||
t.Errorf("3: %v: diff: %v", name, diff.ObjectDiff(source, obj3))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypes(t *testing.T) {
|
||||
table := []interface{}{
|
||||
&TestType1{},
|
||||
&ExternalInternalSame{},
|
||||
}
|
||||
for _, item := range table {
|
||||
// Try a few times, since runTest uses random values.
|
||||
for i := 0; i < *fuzzIters; i++ {
|
||||
runTest(t, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionedEncoding(t *testing.T) {
|
||||
s, _ := GetTestScheme()
|
||||
cf := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{}))
|
||||
info, _ := runtime.SerializerInfoForMediaType(cf.SupportedMediaTypes(), runtime.ContentTypeJSON)
|
||||
encoder := info.Serializer
|
||||
|
||||
codec := cf.CodecForVersions(encoder, nil, schema.GroupVersion{Version: "v2"}, nil)
|
||||
out, err := runtime.Encode(codec, &TestType1{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(out) != `{"myVersionKey":"v2","myKindKey":"TestType1"}`+"\n" {
|
||||
t.Fatal(string(out))
|
||||
}
|
||||
|
||||
codec = cf.CodecForVersions(encoder, nil, schema.GroupVersion{Version: "v3"}, nil)
|
||||
_, err = runtime.Encode(codec, &TestType1{})
|
||||
if err == nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// unversioned encode with no versions is written directly to wire
|
||||
codec = cf.CodecForVersions(encoder, nil, runtime.InternalGroupVersioner, nil)
|
||||
out, err = runtime.Encode(codec, &TestType1{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(out) != `{}`+"\n" {
|
||||
t.Fatal(string(out))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleNames(t *testing.T) {
|
||||
_, codec := GetTestScheme()
|
||||
|
||||
obj, _, err := codec.Decode([]byte(`{"myKindKey":"TestType3","myVersionKey":"v1","A":"value"}`), nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
internal := obj.(*TestType1)
|
||||
if internal.A != "value" {
|
||||
t.Fatalf("unexpected decoded object: %#v", internal)
|
||||
}
|
||||
|
||||
out, err := runtime.Encode(codec, internal)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(out), `"myKindKey":"TestType1"`) {
|
||||
t.Errorf("unexpected encoded output: %s", string(out))
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertTypesWhenDefaultNamesMatch(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Version: "v1"}
|
||||
|
||||
s := runtime.NewScheme()
|
||||
// create two names internally, with TestType1 being preferred
|
||||
s.AddKnownTypeWithName(internalGV.WithKind("TestType1"), &TestType1{})
|
||||
s.AddKnownTypeWithName(internalGV.WithKind("OtherType1"), &TestType1{})
|
||||
// create two names externally, with TestType1 being preferred
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &ExternalTestType1{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("OtherType1"), &ExternalTestType1{})
|
||||
|
||||
ext := &ExternalTestType1{}
|
||||
ext.APIVersion = "v1"
|
||||
ext.ObjectKind = "OtherType1"
|
||||
ext.A = "test"
|
||||
data, err := json.Marshal(ext)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
expect := &TestType1{A: "test"}
|
||||
|
||||
codec := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{})).LegacyCodec(schema.GroupVersion{Version: "v1"})
|
||||
|
||||
obj, err := runtime.Decode(codec, data)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !semantic.DeepEqual(expect, obj) {
|
||||
t.Errorf("unexpected object: %#v", obj)
|
||||
}
|
||||
|
||||
into := &TestType1{}
|
||||
if err := runtime.DecodeInto(codec, data, into); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !semantic.DeepEqual(expect, into) {
|
||||
t.Errorf("unexpected object: %#v", obj)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncode_Ptr(t *testing.T) {
|
||||
_, codec := GetTestScheme()
|
||||
tt := &TestType1{A: "I am a pointer object"}
|
||||
data, err := runtime.Encode(codec, tt)
|
||||
obj2, err2 := runtime.Decode(codec, data)
|
||||
if err != nil || err2 != nil {
|
||||
t.Fatalf("Failure: '%v' '%v'\n%s", err, err2, data)
|
||||
}
|
||||
if _, ok := obj2.(*TestType1); !ok {
|
||||
t.Fatalf("Got wrong type")
|
||||
}
|
||||
if !semantic.DeepEqual(obj2, tt) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", tt, obj2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadJSONRejection(t *testing.T) {
|
||||
log.SetOutput(os.Stderr)
|
||||
_, codec := GetTestScheme()
|
||||
badJSONs := [][]byte{
|
||||
[]byte(`{"myVersionKey":"v1"}`), // Missing kind
|
||||
[]byte(`{"myVersionKey":"v1","myKindKey":"bar"}`), // Unknown kind
|
||||
[]byte(`{"myVersionKey":"bar","myKindKey":"TestType1"}`), // Unknown version
|
||||
[]byte(`{"myKindKey":"TestType1"}`), // Missing version
|
||||
}
|
||||
for _, b := range badJSONs {
|
||||
if _, err := runtime.Decode(codec, b); err == nil {
|
||||
t.Errorf("Did not reject bad json: %s", string(b))
|
||||
}
|
||||
}
|
||||
badJSONKindMismatch := []byte(`{"myVersionKey":"v1","myKindKey":"ExternalInternalSame"}`)
|
||||
if err := runtime.DecodeInto(codec, badJSONKindMismatch, &TestType1{}); err == nil {
|
||||
t.Errorf("Kind is set but doesn't match the object type: %s", badJSONKindMismatch)
|
||||
}
|
||||
if err := runtime.DecodeInto(codec, []byte(``), &TestType1{}); err != nil {
|
||||
t.Errorf("Should allow empty decode: %v", err)
|
||||
}
|
||||
if _, _, err := codec.Decode([]byte(``), &schema.GroupVersionKind{Kind: "ExternalInternalSame"}, nil); err == nil {
|
||||
t.Errorf("Did not give error for empty data with only kind default")
|
||||
}
|
||||
if _, _, err := codec.Decode([]byte(`{"myVersionKey":"v1"}`), &schema.GroupVersionKind{Kind: "ExternalInternalSame"}, nil); err != nil {
|
||||
t.Errorf("Gave error for version and kind default")
|
||||
}
|
||||
if _, _, err := codec.Decode([]byte(`{"myKindKey":"ExternalInternalSame"}`), &schema.GroupVersionKind{Version: "v1"}, nil); err != nil {
|
||||
t.Errorf("Gave error for version and kind default")
|
||||
}
|
||||
if _, _, err := codec.Decode([]byte(``), &schema.GroupVersionKind{Kind: "ExternalInternalSame", Version: "v1"}, nil); err != nil {
|
||||
t.Errorf("Gave error for version and kind defaulted: %v", err)
|
||||
}
|
||||
if _, err := runtime.Decode(codec, []byte(``)); err == nil {
|
||||
t.Errorf("Did not give error for empty data")
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a new Scheme set up with the test objects needed by TestDirectCodec.
|
||||
func GetDirectCodecTestScheme() *runtime.Scheme {
|
||||
internalGV := schema.GroupVersion{Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Version: "v1"}
|
||||
|
||||
s := runtime.NewScheme()
|
||||
// Ordinarily, we wouldn't add TestType2, but because this is a test and
|
||||
// both types are from the same package, we need to get it into the system
|
||||
// so that converter will match it with ExternalType2.
|
||||
s.AddKnownTypes(internalGV, &TestType1{})
|
||||
s.AddKnownTypes(externalGV, &ExternalTestType1{})
|
||||
|
||||
s.AddUnversionedTypes(externalGV, &metav1.Status{})
|
||||
return s
|
||||
}
|
||||
|
||||
func TestDirectCodec(t *testing.T) {
|
||||
s := GetDirectCodecTestScheme()
|
||||
cf := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{}))
|
||||
info, _ := runtime.SerializerInfoForMediaType(cf.SupportedMediaTypes(), runtime.ContentTypeJSON)
|
||||
serializer := info.Serializer
|
||||
df := DirectCodecFactory{cf}
|
||||
ignoredGV, err := schema.ParseGroupVersion("ignored group/ignored version")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
directEncoder := df.EncoderForVersion(serializer, ignoredGV)
|
||||
directDecoder := df.DecoderToVersion(serializer, ignoredGV)
|
||||
out, err := runtime.Encode(directEncoder, &ExternalTestType1{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(out) != `{"myVersionKey":"v1","myKindKey":"ExternalTestType1"}`+"\n" {
|
||||
t.Fatal(string(out))
|
||||
}
|
||||
a, _, err := directDecoder.Decode(out, nil, nil)
|
||||
e := &ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{
|
||||
APIVersion: "v1",
|
||||
ObjectKind: "ExternalTestType1",
|
||||
},
|
||||
}
|
||||
if !semantic.DeepEqual(e, a) {
|
||||
t.Fatalf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
264
vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json_test.go
generated
vendored
264
vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json_test.go
generated
vendored
|
@ -1,264 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package json_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
)
|
||||
|
||||
type testDecodable struct {
|
||||
Other string
|
||||
Value int `json:"value"`
|
||||
gvk schema.GroupVersionKind
|
||||
}
|
||||
|
||||
func (d *testDecodable) GetObjectKind() schema.ObjectKind { return d }
|
||||
func (d *testDecodable) SetGroupVersionKind(gvk schema.GroupVersionKind) { d.gvk = gvk }
|
||||
func (d *testDecodable) GroupVersionKind() schema.GroupVersionKind { return d.gvk }
|
||||
|
||||
func TestDecode(t *testing.T) {
|
||||
testCases := []struct {
|
||||
creater runtime.ObjectCreater
|
||||
typer runtime.ObjectTyper
|
||||
yaml bool
|
||||
pretty bool
|
||||
|
||||
data []byte
|
||||
defaultGVK *schema.GroupVersionKind
|
||||
into runtime.Object
|
||||
|
||||
errFn func(error) bool
|
||||
expectedObject runtime.Object
|
||||
expectedGVK *schema.GroupVersionKind
|
||||
}{
|
||||
{
|
||||
data: []byte("{}"),
|
||||
|
||||
expectedGVK: &schema.GroupVersionKind{},
|
||||
errFn: func(err error) bool { return strings.Contains(err.Error(), "Object 'Kind' is missing in") },
|
||||
},
|
||||
{
|
||||
data: []byte("{}"),
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
creater: &mockCreater{err: fmt.Errorf("fake error")},
|
||||
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
errFn: func(err error) bool { return err.Error() == "fake error" },
|
||||
},
|
||||
{
|
||||
data: []byte("{}"),
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
creater: &mockCreater{obj: &testDecodable{}},
|
||||
expectedObject: &testDecodable{},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
},
|
||||
|
||||
// version without group is not defaulted
|
||||
{
|
||||
data: []byte(`{"apiVersion":"blah"}`),
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
creater: &mockCreater{obj: &testDecodable{}},
|
||||
expectedObject: &testDecodable{},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "", Version: "blah"},
|
||||
},
|
||||
// group without version is defaulted
|
||||
{
|
||||
data: []byte(`{"apiVersion":"other/"}`),
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
creater: &mockCreater{obj: &testDecodable{}},
|
||||
expectedObject: &testDecodable{},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
},
|
||||
|
||||
// accept runtime.Unknown as into and bypass creator
|
||||
{
|
||||
data: []byte(`{}`),
|
||||
into: &runtime.Unknown{},
|
||||
|
||||
expectedGVK: &schema.GroupVersionKind{},
|
||||
expectedObject: &runtime.Unknown{
|
||||
Raw: []byte(`{}`),
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
},
|
||||
},
|
||||
{
|
||||
data: []byte(`{"test":"object"}`),
|
||||
into: &runtime.Unknown{},
|
||||
|
||||
expectedGVK: &schema.GroupVersionKind{},
|
||||
expectedObject: &runtime.Unknown{
|
||||
Raw: []byte(`{"test":"object"}`),
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
},
|
||||
},
|
||||
{
|
||||
data: []byte(`{"test":"object"}`),
|
||||
into: &runtime.Unknown{},
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedObject: &runtime.Unknown{
|
||||
TypeMeta: runtime.TypeMeta{APIVersion: "other/blah", Kind: "Test"},
|
||||
Raw: []byte(`{"test":"object"}`),
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
},
|
||||
},
|
||||
|
||||
// unregistered objects can be decoded into directly
|
||||
{
|
||||
data: []byte(`{"kind":"Test","apiVersion":"other/blah","value":1,"Other":"test"}`),
|
||||
into: &testDecodable{},
|
||||
typer: &mockTyper{err: runtime.NewNotRegisteredErr(schema.GroupVersionKind{}, nil)},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedObject: &testDecodable{
|
||||
Other: "test",
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
// registered types get defaulted by the into object kind
|
||||
{
|
||||
data: []byte(`{"value":1,"Other":"test"}`),
|
||||
into: &testDecodable{},
|
||||
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedObject: &testDecodable{
|
||||
Other: "test",
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
// registered types get defaulted by the into object kind even without version, but return an error
|
||||
{
|
||||
data: []byte(`{"value":1,"Other":"test"}`),
|
||||
into: &testDecodable{},
|
||||
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: ""}},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: ""},
|
||||
errFn: func(err error) bool { return strings.Contains(err.Error(), "Object 'apiVersion' is missing in") },
|
||||
expectedObject: &testDecodable{
|
||||
Other: "test",
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
|
||||
// runtime.VersionedObjects are decoded
|
||||
{
|
||||
data: []byte(`{"value":1,"Other":"test"}`),
|
||||
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
|
||||
creater: &mockCreater{obj: &testDecodable{}},
|
||||
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}},
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedObject: &runtime.VersionedObjects{
|
||||
Objects: []runtime.Object{
|
||||
&testDecodable{
|
||||
Other: "test",
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// runtime.VersionedObjects with an object are decoded into
|
||||
{
|
||||
data: []byte(`{"Other":"test"}`),
|
||||
into: &runtime.VersionedObjects{Objects: []runtime.Object{&testDecodable{Value: 2}}},
|
||||
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedObject: &runtime.VersionedObjects{
|
||||
Objects: []runtime.Object{
|
||||
&testDecodable{
|
||||
Other: "test",
|
||||
Value: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range testCases {
|
||||
var s runtime.Serializer
|
||||
if test.yaml {
|
||||
s = json.NewYAMLSerializer(json.DefaultMetaFactory, test.creater, test.typer)
|
||||
} else {
|
||||
s = json.NewSerializer(json.DefaultMetaFactory, test.creater, test.typer, test.pretty)
|
||||
}
|
||||
obj, gvk, err := s.Decode([]byte(test.data), test.defaultGVK, test.into)
|
||||
|
||||
if !reflect.DeepEqual(test.expectedGVK, gvk) {
|
||||
t.Errorf("%d: unexpected GVK: %v", i, gvk)
|
||||
}
|
||||
|
||||
switch {
|
||||
case err == nil && test.errFn != nil:
|
||||
t.Errorf("%d: failed: %v", i, err)
|
||||
continue
|
||||
case err != nil && test.errFn == nil:
|
||||
t.Errorf("%d: failed: %v", i, err)
|
||||
continue
|
||||
case err != nil:
|
||||
if !test.errFn(err) {
|
||||
t.Errorf("%d: failed: %v", i, err)
|
||||
}
|
||||
if obj != nil {
|
||||
t.Errorf("%d: should have returned nil object", i)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if test.into != nil && test.into != obj {
|
||||
t.Errorf("%d: expected into to be returned: %v", i, obj)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(test.expectedObject, obj) {
|
||||
t.Errorf("%d: unexpected object:\n%s", i, diff.ObjectGoPrintSideBySide(test.expectedObject, obj))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type mockCreater struct {
|
||||
apiVersion string
|
||||
kind string
|
||||
err error
|
||||
obj runtime.Object
|
||||
}
|
||||
|
||||
func (c *mockCreater) New(kind schema.GroupVersionKind) (runtime.Object, error) {
|
||||
c.apiVersion, c.kind = kind.GroupVersion().String(), kind.Kind
|
||||
return c.obj, c.err
|
||||
}
|
||||
|
||||
type mockTyper struct {
|
||||
gvk *schema.GroupVersionKind
|
||||
err error
|
||||
}
|
||||
|
||||
func (t *mockTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
|
||||
if t.gvk == nil {
|
||||
return nil, false, t.err
|
||||
}
|
||||
return []schema.GroupVersionKind{*t.gvk}, false, t.err
|
||||
}
|
||||
|
||||
func (t *mockTyper) Recognizes(_ schema.GroupVersionKind) bool {
|
||||
return false
|
||||
}
|
45
vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/meta_test.go
generated
vendored
45
vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/meta_test.go
generated
vendored
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package json
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSimpleMetaFactoryInterpret(t *testing.T) {
|
||||
factory := SimpleMetaFactory{}
|
||||
gvk, err := factory.Interpret([]byte(`{"apiVersion":"1","kind":"object"}`))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if gvk.Version != "1" || gvk.Kind != "object" {
|
||||
t.Errorf("unexpected interpret: %#v", gvk)
|
||||
}
|
||||
|
||||
// no kind or version
|
||||
gvk, err = factory.Interpret([]byte(`{}`))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if gvk.Version != "" || gvk.Kind != "" {
|
||||
t.Errorf("unexpected interpret: %#v", gvk)
|
||||
}
|
||||
|
||||
// unparsable
|
||||
gvk, err = factory.Interpret([]byte(`{`))
|
||||
if err == nil {
|
||||
t.Errorf("unexpected non-error")
|
||||
}
|
||||
}
|
58
vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/testing/recognizer_test.go
generated
vendored
58
vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/testing/recognizer_test.go
generated
vendored
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package testing
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
|
||||
)
|
||||
|
||||
type A struct{}
|
||||
|
||||
func (A) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
|
||||
|
||||
func TestRecognizer(t *testing.T) {
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes(schema.GroupVersion{Version: "v1"}, &A{})
|
||||
d := recognizer.NewDecoder(
|
||||
json.NewSerializer(json.DefaultMetaFactory, s, s, false),
|
||||
json.NewYAMLSerializer(json.DefaultMetaFactory, s, s),
|
||||
)
|
||||
out, _, err := d.Decode([]byte(`
|
||||
kind: A
|
||||
apiVersion: v1
|
||||
`), nil, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("%#v", out)
|
||||
|
||||
out, _, err = d.Decode([]byte(`
|
||||
{
|
||||
"kind":"A",
|
||||
"apiVersion":"v1"
|
||||
}
|
||||
`), nil, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("%#v", out)
|
||||
}
|
84
vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming_test.go
generated
vendored
84
vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming_test.go
generated
vendored
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package streaming
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/framer"
|
||||
)
|
||||
|
||||
type fakeDecoder struct {
|
||||
got []byte
|
||||
obj runtime.Object
|
||||
err error
|
||||
}
|
||||
|
||||
func (d *fakeDecoder) Decode(data []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||
d.got = data
|
||||
return d.obj, nil, d.err
|
||||
}
|
||||
|
||||
func TestEmptyDecoder(t *testing.T) {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
d := &fakeDecoder{}
|
||||
_, _, err := NewDecoder(ioutil.NopCloser(buf), d).Decode(nil, nil)
|
||||
if err != io.EOF {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecoder(t *testing.T) {
|
||||
frames := [][]byte{
|
||||
make([]byte, 1025),
|
||||
make([]byte, 1024*5),
|
||||
make([]byte, 1024*1024*5),
|
||||
make([]byte, 1025),
|
||||
}
|
||||
pr, pw := io.Pipe()
|
||||
fw := framer.NewLengthDelimitedFrameWriter(pw)
|
||||
go func() {
|
||||
for i := range frames {
|
||||
fw.Write(frames[i])
|
||||
}
|
||||
pw.Close()
|
||||
}()
|
||||
|
||||
r := framer.NewLengthDelimitedFrameReader(pr)
|
||||
d := &fakeDecoder{}
|
||||
dec := NewDecoder(r, d)
|
||||
if _, _, err := dec.Decode(nil, nil); err != nil || !bytes.Equal(d.got, frames[0]) {
|
||||
t.Fatalf("unexpected %v %v", err, len(d.got))
|
||||
}
|
||||
if _, _, err := dec.Decode(nil, nil); err != nil || !bytes.Equal(d.got, frames[1]) {
|
||||
t.Fatalf("unexpected %v %v", err, len(d.got))
|
||||
}
|
||||
if _, _, err := dec.Decode(nil, nil); err != ErrObjectTooLarge || !bytes.Equal(d.got, frames[1]) {
|
||||
t.Fatalf("unexpected %v %v", err, len(d.got))
|
||||
}
|
||||
if _, _, err := dec.Decode(nil, nil); err != nil || !bytes.Equal(d.got, frames[3]) {
|
||||
t.Fatalf("unexpected %v %v", err, len(d.got))
|
||||
}
|
||||
if _, _, err := dec.Decode(nil, nil); err != io.EOF {
|
||||
t.Fatalf("unexpected %v %v", err, len(d.got))
|
||||
}
|
||||
}
|
399
vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning_test.go
generated
vendored
399
vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning_test.go
generated
vendored
|
@ -1,399 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package versioning
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
)
|
||||
|
||||
type testDecodable struct {
|
||||
Other string
|
||||
Value int `json:"value"`
|
||||
gvk schema.GroupVersionKind
|
||||
}
|
||||
|
||||
func (d *testDecodable) GetObjectKind() schema.ObjectKind { return d }
|
||||
func (d *testDecodable) SetGroupVersionKind(gvk schema.GroupVersionKind) { d.gvk = gvk }
|
||||
func (d *testDecodable) GroupVersionKind() schema.GroupVersionKind { return d.gvk }
|
||||
|
||||
type testNestedDecodable struct {
|
||||
Other string
|
||||
Value int `json:"value"`
|
||||
|
||||
gvk schema.GroupVersionKind
|
||||
nestedCalled bool
|
||||
nestedErr error
|
||||
}
|
||||
|
||||
func (d *testNestedDecodable) GetObjectKind() schema.ObjectKind { return d }
|
||||
func (d *testNestedDecodable) SetGroupVersionKind(gvk schema.GroupVersionKind) { d.gvk = gvk }
|
||||
func (d *testNestedDecodable) GroupVersionKind() schema.GroupVersionKind { return d.gvk }
|
||||
|
||||
func (d *testNestedDecodable) EncodeNestedObjects(e runtime.Encoder) error {
|
||||
d.nestedCalled = true
|
||||
return d.nestedErr
|
||||
}
|
||||
|
||||
func (d *testNestedDecodable) DecodeNestedObjects(_ runtime.Decoder) error {
|
||||
d.nestedCalled = true
|
||||
return d.nestedErr
|
||||
}
|
||||
|
||||
func TestNestedDecode(t *testing.T) {
|
||||
n := &testNestedDecodable{nestedErr: fmt.Errorf("unable to decode")}
|
||||
decoder := &mockSerializer{obj: n}
|
||||
codec := NewCodec(nil, decoder, nil, nil, nil, nil, nil, nil, nil)
|
||||
if _, _, err := codec.Decode([]byte(`{}`), nil, n); err != n.nestedErr {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if !n.nestedCalled {
|
||||
t.Errorf("did not invoke nested decoder")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNestedEncode(t *testing.T) {
|
||||
n := &testNestedDecodable{nestedErr: fmt.Errorf("unable to decode")}
|
||||
n2 := &testNestedDecodable{nestedErr: fmt.Errorf("unable to decode 2")}
|
||||
encoder := &mockSerializer{obj: n}
|
||||
codec := NewCodec(
|
||||
encoder, nil,
|
||||
&checkConvertor{obj: n2, groupVersion: schema.GroupVersion{Group: "other"}},
|
||||
nil, nil,
|
||||
&mockTyper{gvks: []schema.GroupVersionKind{{Kind: "test"}}},
|
||||
nil,
|
||||
schema.GroupVersion{Group: "other"}, nil,
|
||||
)
|
||||
if err := codec.Encode(n, ioutil.Discard); err != n2.nestedErr {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if n.nestedCalled || !n2.nestedCalled {
|
||||
t.Errorf("did not invoke correct nested decoder")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode(t *testing.T) {
|
||||
gvk1 := &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}
|
||||
decodable1 := &testDecodable{}
|
||||
decodable2 := &testDecodable{}
|
||||
decodable3 := &testDecodable{}
|
||||
versionedDecodable1 := &runtime.VersionedObjects{Objects: []runtime.Object{decodable1}}
|
||||
|
||||
testCases := []struct {
|
||||
serializer runtime.Serializer
|
||||
convertor runtime.ObjectConvertor
|
||||
creater runtime.ObjectCreater
|
||||
copier runtime.ObjectCopier
|
||||
typer runtime.ObjectTyper
|
||||
defaulter runtime.ObjectDefaulter
|
||||
yaml bool
|
||||
pretty bool
|
||||
|
||||
encodes, decodes runtime.GroupVersioner
|
||||
|
||||
defaultGVK *schema.GroupVersionKind
|
||||
into runtime.Object
|
||||
|
||||
errFn func(error) bool
|
||||
expectedObject runtime.Object
|
||||
sameObject runtime.Object
|
||||
expectedGVK *schema.GroupVersionKind
|
||||
}{
|
||||
{
|
||||
serializer: &mockSerializer{actual: gvk1},
|
||||
convertor: &checkConvertor{groupVersion: schema.GroupVersion{Group: "other", Version: "__internal"}},
|
||||
expectedGVK: gvk1,
|
||||
decodes: schema.GroupVersion{Group: "other", Version: "__internal"},
|
||||
},
|
||||
{
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable2, groupVersion: schema.GroupVersion{Group: "other", Version: "__internal"}},
|
||||
expectedGVK: gvk1,
|
||||
sameObject: decodable2,
|
||||
decodes: schema.GroupVersion{Group: "other", Version: "__internal"},
|
||||
},
|
||||
// defaultGVK.Group is allowed to force a conversion to the destination group
|
||||
{
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
defaultGVK: &schema.GroupVersionKind{Group: "force"},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable2, groupVersion: schema.GroupVersion{Group: "force", Version: "__internal"}},
|
||||
expectedGVK: gvk1,
|
||||
sameObject: decodable2,
|
||||
decodes: schema.GroupVersion{Group: "force", Version: "__internal"},
|
||||
},
|
||||
// uses direct conversion for into when objects differ
|
||||
{
|
||||
into: decodable3,
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable3, directConvert: true},
|
||||
expectedGVK: gvk1,
|
||||
sameObject: decodable3,
|
||||
},
|
||||
{
|
||||
into: versionedDecodable1,
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable3},
|
||||
convertor: &checkConvertor{in: decodable3, obj: decodable1, directConvert: true},
|
||||
expectedGVK: gvk1,
|
||||
sameObject: versionedDecodable1,
|
||||
},
|
||||
// returns directly when serializer returns into
|
||||
{
|
||||
into: decodable3,
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable3},
|
||||
expectedGVK: gvk1,
|
||||
sameObject: decodable3,
|
||||
},
|
||||
// returns directly when serializer returns into
|
||||
{
|
||||
into: versionedDecodable1,
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
expectedGVK: gvk1,
|
||||
sameObject: versionedDecodable1,
|
||||
},
|
||||
|
||||
// runtime.VersionedObjects are decoded
|
||||
{
|
||||
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
|
||||
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
copier: &checkCopy{in: decodable1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable2, groupVersion: schema.GroupVersion{Group: "other", Version: "__internal"}},
|
||||
expectedGVK: gvk1,
|
||||
expectedObject: &runtime.VersionedObjects{Objects: []runtime.Object{decodable1, decodable2}},
|
||||
decodes: schema.GroupVersion{Group: "other", Version: "__internal"},
|
||||
},
|
||||
{
|
||||
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
|
||||
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
copier: &checkCopy{in: decodable1, obj: nil, err: fmt.Errorf("error on copy")},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable2, groupVersion: schema.GroupVersion{Group: "other", Version: "__internal"}},
|
||||
expectedGVK: gvk1,
|
||||
expectedObject: &runtime.VersionedObjects{Objects: []runtime.Object{decodable1, decodable2}},
|
||||
decodes: schema.GroupVersion{Group: "other", Version: "__internal"},
|
||||
},
|
||||
|
||||
// decode into the same version as the serialized object
|
||||
{
|
||||
decodes: schema.GroupVersions{gvk1.GroupVersion()},
|
||||
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable1, groupVersion: schema.GroupVersions{{Group: "other", Version: "blah"}}},
|
||||
expectedGVK: gvk1,
|
||||
expectedObject: decodable1,
|
||||
},
|
||||
{
|
||||
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
|
||||
decodes: schema.GroupVersions{gvk1.GroupVersion()},
|
||||
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable1, groupVersion: schema.GroupVersions{{Group: "other", Version: "blah"}}},
|
||||
copier: &checkCopy{in: decodable1, obj: decodable1, err: nil},
|
||||
expectedGVK: gvk1,
|
||||
expectedObject: &runtime.VersionedObjects{Objects: []runtime.Object{decodable1}},
|
||||
},
|
||||
|
||||
// codec with non matching version skips conversion altogether
|
||||
{
|
||||
decodes: schema.GroupVersions{{Group: "something", Version: "else"}},
|
||||
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable1, groupVersion: schema.GroupVersions{{Group: "something", Version: "else"}}},
|
||||
expectedGVK: gvk1,
|
||||
expectedObject: decodable1,
|
||||
},
|
||||
{
|
||||
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
|
||||
decodes: schema.GroupVersions{{Group: "something", Version: "else"}},
|
||||
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable1, groupVersion: schema.GroupVersions{{Group: "something", Version: "else"}}},
|
||||
copier: &checkCopy{in: decodable1, obj: decodable1, err: nil},
|
||||
expectedGVK: gvk1,
|
||||
expectedObject: &runtime.VersionedObjects{Objects: []runtime.Object{decodable1}},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range testCases {
|
||||
t.Logf("%d", i)
|
||||
s := NewCodec(test.serializer, test.serializer, test.convertor, test.creater, test.copier, test.typer, test.defaulter, test.encodes, test.decodes)
|
||||
obj, gvk, err := s.Decode([]byte(`{}`), test.defaultGVK, test.into)
|
||||
|
||||
if !reflect.DeepEqual(test.expectedGVK, gvk) {
|
||||
t.Errorf("%d: unexpected GVK: %v", i, gvk)
|
||||
}
|
||||
|
||||
switch {
|
||||
case err == nil && test.errFn != nil:
|
||||
t.Errorf("%d: failed: %v", i, err)
|
||||
continue
|
||||
case err != nil && test.errFn == nil:
|
||||
t.Errorf("%d: failed: %v", i, err)
|
||||
continue
|
||||
case err != nil:
|
||||
if !test.errFn(err) {
|
||||
t.Errorf("%d: failed: %v", i, err)
|
||||
}
|
||||
if obj != nil {
|
||||
t.Errorf("%d: should have returned nil object", i)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if test.into != nil && test.into != obj {
|
||||
t.Errorf("%d: expected into to be returned: %v", i, obj)
|
||||
continue
|
||||
}
|
||||
|
||||
switch {
|
||||
case test.expectedObject != nil:
|
||||
if !reflect.DeepEqual(test.expectedObject, obj) {
|
||||
t.Errorf("%d: unexpected object:\n%s", i, diff.ObjectGoPrintSideBySide(test.expectedObject, obj))
|
||||
}
|
||||
case test.sameObject != nil:
|
||||
if test.sameObject != obj {
|
||||
t.Errorf("%d: unexpected object:\n%s", i, diff.ObjectGoPrintSideBySide(test.sameObject, obj))
|
||||
}
|
||||
case obj != nil:
|
||||
t.Errorf("%d: unexpected object: %#v", i, obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type checkCopy struct {
|
||||
in, obj runtime.Object
|
||||
err error
|
||||
}
|
||||
|
||||
func (c *checkCopy) Copy(obj runtime.Object) (runtime.Object, error) {
|
||||
if c.in != nil && c.in != obj {
|
||||
return nil, fmt.Errorf("unexpected input to copy: %#v", obj)
|
||||
}
|
||||
return c.obj, c.err
|
||||
}
|
||||
|
||||
type checkConvertor struct {
|
||||
err error
|
||||
in, obj runtime.Object
|
||||
groupVersion runtime.GroupVersioner
|
||||
directConvert bool
|
||||
}
|
||||
|
||||
func (c *checkConvertor) Convert(in, out, context interface{}) error {
|
||||
if !c.directConvert {
|
||||
return fmt.Errorf("unexpected call to Convert")
|
||||
}
|
||||
if c.in != nil && c.in != in {
|
||||
return fmt.Errorf("unexpected in: %s", in)
|
||||
}
|
||||
if c.obj != nil && c.obj != out {
|
||||
return fmt.Errorf("unexpected out: %s", out)
|
||||
}
|
||||
return c.err
|
||||
}
|
||||
func (c *checkConvertor) ConvertToVersion(in runtime.Object, outVersion runtime.GroupVersioner) (out runtime.Object, err error) {
|
||||
if c.directConvert {
|
||||
return nil, fmt.Errorf("unexpected call to ConvertToVersion")
|
||||
}
|
||||
if c.in != nil && c.in != in {
|
||||
return nil, fmt.Errorf("unexpected in: %s", in)
|
||||
}
|
||||
if !reflect.DeepEqual(c.groupVersion, outVersion) {
|
||||
return nil, fmt.Errorf("unexpected outversion: %s (%s)", outVersion, c.groupVersion)
|
||||
}
|
||||
return c.obj, c.err
|
||||
}
|
||||
func (c *checkConvertor) ConvertFieldLabel(version, kind, label, value string) (string, string, error) {
|
||||
return "", "", fmt.Errorf("unexpected call to ConvertFieldLabel")
|
||||
}
|
||||
|
||||
type mockSerializer struct {
|
||||
err error
|
||||
obj runtime.Object
|
||||
encodingObjGVK schema.GroupVersionKind
|
||||
|
||||
defaults, actual *schema.GroupVersionKind
|
||||
into runtime.Object
|
||||
}
|
||||
|
||||
func (s *mockSerializer) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||
s.defaults = defaults
|
||||
s.into = into
|
||||
return s.obj, s.actual, s.err
|
||||
}
|
||||
|
||||
func (s *mockSerializer) Encode(obj runtime.Object, w io.Writer) error {
|
||||
s.obj = obj
|
||||
s.encodingObjGVK = obj.GetObjectKind().GroupVersionKind()
|
||||
return s.err
|
||||
}
|
||||
|
||||
type mockCreater struct {
|
||||
err error
|
||||
obj runtime.Object
|
||||
}
|
||||
|
||||
func (c *mockCreater) New(kind schema.GroupVersionKind) (runtime.Object, error) {
|
||||
return c.obj, c.err
|
||||
}
|
||||
|
||||
type mockTyper struct {
|
||||
gvks []schema.GroupVersionKind
|
||||
unversioned bool
|
||||
err error
|
||||
}
|
||||
|
||||
func (t *mockTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
|
||||
return t.gvks, t.unversioned, t.err
|
||||
}
|
||||
|
||||
func (t *mockTyper) Recognizes(_ schema.GroupVersionKind) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func TestDirectCodecEncode(t *testing.T) {
|
||||
serializer := mockSerializer{}
|
||||
typer := mockTyper{
|
||||
gvks: []schema.GroupVersionKind{
|
||||
{
|
||||
Group: "wrong_group",
|
||||
Kind: "some_kind",
|
||||
},
|
||||
{
|
||||
Group: "expected_group",
|
||||
Kind: "some_kind",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
c := DirectEncoder{
|
||||
Version: schema.GroupVersion{Group: "expected_group"},
|
||||
Encoder: &serializer,
|
||||
ObjectTyper: &typer,
|
||||
}
|
||||
c.Encode(&testDecodable{}, ioutil.Discard)
|
||||
if e, a := "expected_group", serializer.encodingObjGVK.Group; e != a {
|
||||
t.Errorf("expected group to be %v, got %v", e, a)
|
||||
}
|
||||
}
|
46
vendor/k8s.io/apimachinery/pkg/runtime/serializer/yaml/yaml.go
generated
vendored
46
vendor/k8s.io/apimachinery/pkg/runtime/serializer/yaml/yaml.go
generated
vendored
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package yaml
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
)
|
||||
|
||||
// yamlSerializer converts YAML passed to the Decoder methods to JSON.
|
||||
type yamlSerializer struct {
|
||||
// the nested serializer
|
||||
runtime.Serializer
|
||||
}
|
||||
|
||||
// yamlSerializer implements Serializer
|
||||
var _ runtime.Serializer = yamlSerializer{}
|
||||
|
||||
// NewDecodingSerializer adds YAML decoding support to a serializer that supports JSON.
|
||||
func NewDecodingSerializer(jsonSerializer runtime.Serializer) runtime.Serializer {
|
||||
return &yamlSerializer{jsonSerializer}
|
||||
}
|
||||
|
||||
func (c yamlSerializer) Decode(data []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||
out, err := yaml.ToJSON(data)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
data = out
|
||||
return c.Serializer.Decode(data, gvk, into)
|
||||
}
|
43
vendor/k8s.io/apimachinery/pkg/runtime/swagger_doc_generator_test.go
generated
vendored
43
vendor/k8s.io/apimachinery/pkg/runtime/swagger_doc_generator_test.go
generated
vendored
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFmtRawDoc(t *testing.T) {
|
||||
tests := []struct {
|
||||
t, expected string
|
||||
}{
|
||||
{"aaa\n --- asd\n TODO: tooooodo\n toooodoooooo\n", "aaa"},
|
||||
{"aaa\nasd\n TODO: tooooodo\nbbbb\n --- toooodoooooo\n", "aaa asd bbbb"},
|
||||
{" TODO: tooooodo\n", ""},
|
||||
{"Par1\n\nPar2\n\n", "Par1\\n\\nPar2"},
|
||||
{"", ""},
|
||||
{" ", ""},
|
||||
{" \n", ""},
|
||||
{" \n\n ", ""},
|
||||
{"Example:\n\tl1\n\t\tl2\n", "Example:\\n\\tl1\\n\\t\\tl2"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
if o := fmtRawDoc(test.t); o != test.expected {
|
||||
t.Fatalf("Expected: %q, got %q", test.expected, o)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue