123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- package testing
- import (
- "bytes"
- "encoding/hex"
- "fmt"
- "math/rand"
- "reflect"
- "testing"
- "github.com/gogo/protobuf/proto"
- "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
- apiequality "k8s.io/apimachinery/pkg/api/equality"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apimachinery/pkg/runtime/schema"
- "k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
- "k8s.io/apimachinery/pkg/util/diff"
- "k8s.io/kubernetes/pkg/api/legacyscheme"
- api "k8s.io/kubernetes/pkg/apis/core"
- _ "k8s.io/kubernetes/pkg/apis/extensions"
- _ "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
- )
- func TestUniversalDeserializer(t *testing.T) {
- expected := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test"}, TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Pod"}}
- d := legacyscheme.Codecs.UniversalDeserializer()
- for _, mediaType := range []string{"application/json", "application/yaml", "application/vnd.kubernetes.protobuf"} {
- info, ok := runtime.SerializerInfoForMediaType(legacyscheme.Codecs.SupportedMediaTypes(), mediaType)
- if !ok {
- t.Fatal(mediaType)
- }
- buf := &bytes.Buffer{}
- if err := info.Serializer.Encode(expected, buf); err != nil {
- t.Fatalf("%s: %v", mediaType, err)
- }
- obj, _, err := d.Decode(buf.Bytes(), &schema.GroupVersionKind{Kind: "Pod", Version: "v1"}, nil)
- if err != nil {
- t.Fatalf("%s: %v", mediaType, err)
- }
- if !apiequality.Semantic.DeepEqual(expected, obj) {
- t.Fatalf("%s: %#v", mediaType, obj)
- }
- }
- }
- func TestAllFieldsHaveTags(t *testing.T) {
- for gvk, obj := range legacyscheme.Scheme.AllKnownTypes() {
- if gvk.Version == runtime.APIVersionInternal {
-
- continue
- }
- if gvk.Group == "componentconfig" {
-
- continue
- }
- if err := fieldsHaveProtobufTags(obj); err != nil {
- t.Errorf("type %s as gvk %v is missing tags: %v", obj, gvk, err)
- }
- }
- }
- func fieldsHaveProtobufTags(obj reflect.Type) error {
- switch obj.Kind() {
- case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Array:
- return fieldsHaveProtobufTags(obj.Elem())
- case reflect.Struct:
- for i := 0; i < obj.NumField(); i++ {
- f := obj.Field(i)
- if f.Name == "TypeMeta" && f.Type.Name() == "TypeMeta" {
-
- continue
- }
- if len(f.Tag.Get("json")) > 0 && len(f.Tag.Get("protobuf")) == 0 {
- return fmt.Errorf("field %s in %s has a 'json' tag but no protobuf tag", f.Name, obj)
- }
- }
- }
- return nil
- }
- func TestProtobufRoundTrip(t *testing.T) {
- obj := &v1.Pod{}
- fuzzer.FuzzerFor(FuzzerFuncs, rand.NewSource(benchmarkSeed), legacyscheme.Codecs).Fuzz(obj)
-
- obj.Spec.InitContainers = nil
- obj.Status.InitContainerStatuses = nil
- data, err := obj.Marshal()
- if err != nil {
- t.Fatal(err)
- }
- out := &v1.Pod{}
- if err := out.Unmarshal(data); err != nil {
- t.Fatal(err)
- }
- if !apiequality.Semantic.Equalities.DeepEqual(out, obj) {
- t.Logf("marshal\n%s", hex.Dump(data))
- t.Fatalf("Unmarshal is unequal\n%s", diff.ObjectGoPrintDiff(out, obj))
- }
- }
- func BenchmarkEncodeCodecProtobuf(b *testing.B) {
- items := benchmarkItems(b)
- width := len(items)
- s := protobuf.NewSerializer(nil, nil)
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- if _, err := runtime.Encode(s, &items[i%width]); err != nil {
- b.Fatal(err)
- }
- }
- b.StopTimer()
- }
- func BenchmarkEncodeCodecFromInternalProtobuf(b *testing.B) {
- items := benchmarkItems(b)
- width := len(items)
- encodable := make([]api.Pod, width)
- for i := range items {
- if err := legacyscheme.Scheme.Convert(&items[i], &encodable[i], nil); err != nil {
- b.Fatal(err)
- }
- }
- s := protobuf.NewSerializer(nil, nil)
- codec := legacyscheme.Codecs.EncoderForVersion(s, v1.SchemeGroupVersion)
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- if _, err := runtime.Encode(codec, &encodable[i%width]); err != nil {
- b.Fatal(err)
- }
- }
- b.StopTimer()
- }
- func BenchmarkEncodeProtobufGeneratedMarshal(b *testing.B) {
- items := benchmarkItems(b)
- width := len(items)
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- if _, err := items[i%width].Marshal(); err != nil {
- b.Fatal(err)
- }
- }
- b.StopTimer()
- }
- func BenchmarkDecodeCodecToInternalProtobuf(b *testing.B) {
- items := benchmarkItems(b)
- width := len(items)
- s := protobuf.NewSerializer(legacyscheme.Scheme, legacyscheme.Scheme)
- encoder := legacyscheme.Codecs.EncoderForVersion(s, v1.SchemeGroupVersion)
- var encoded [][]byte
- for i := range items {
- data, err := runtime.Encode(encoder, &items[i])
- if err != nil {
- b.Fatal(err)
- }
- encoded = append(encoded, data)
- }
- decoder := legacyscheme.Codecs.DecoderToVersion(s, api.SchemeGroupVersion)
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- if _, err := runtime.Decode(decoder, encoded[i%width]); err != nil {
- b.Fatal(err)
- }
- }
- b.StopTimer()
- }
- func BenchmarkDecodeIntoProtobuf(b *testing.B) {
- items := benchmarkItems(b)
- width := len(items)
- encoded := make([][]byte, width)
- for i := range items {
- data, err := (&items[i]).Marshal()
- if err != nil {
- b.Fatal(err)
- }
- encoded[i] = data
- validate := &v1.Pod{}
- if err := proto.Unmarshal(data, validate); err != nil {
- b.Fatalf("Failed to unmarshal %d: %v\n%#v", i, err, items[i])
- }
- }
- for i := 0; i < b.N; i++ {
- obj := v1.Pod{}
- if err := proto.Unmarshal(encoded[i%width], &obj); err != nil {
- b.Fatal(err)
- }
- }
- }
|