mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
Fix compilation errors in protobuf and add decode test
This commit is contained in:
parent
bfc991646b
commit
87146c4255
@ -23,7 +23,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
|
|
||||||
@ -41,11 +40,6 @@ var (
|
|||||||
//
|
//
|
||||||
// This encoding scheme is experimental, and is subject to change at any time.
|
// This encoding scheme is experimental, and is subject to change at any time.
|
||||||
protoEncodingPrefix = []byte{0x6b, 0x38, 0x73, 0x00}
|
protoEncodingPrefix = []byte{0x6b, 0x38, 0x73, 0x00}
|
||||||
|
|
||||||
bufferSize = uint64(16384)
|
|
||||||
availableBuffers = sync.Pool{New: func() interface{} {
|
|
||||||
return make([]byte, bufferSize)
|
|
||||||
}}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type errNotMarshalable struct {
|
type errNotMarshalable struct {
|
||||||
@ -76,9 +70,10 @@ func NewSerializer(creater runtime.ObjectCreater, typer runtime.Typer, defaultCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Serializer struct {
|
type Serializer struct {
|
||||||
prefix []byte
|
prefix []byte
|
||||||
creater runtime.ObjectCreater
|
creater runtime.ObjectCreater
|
||||||
typer runtime.Typer
|
typer runtime.Typer
|
||||||
|
contentType string
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ runtime.Serializer = &Serializer{}
|
var _ runtime.Serializer = &Serializer{}
|
||||||
@ -168,7 +163,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *unversioned.GroupVersionKi
|
|||||||
return nil, actual, runtime.NewMissingVersionErr(fmt.Sprintf("%#v", unk.TypeMeta))
|
return nil, actual, runtime.NewMissingVersionErr(fmt.Sprintf("%#v", unk.TypeMeta))
|
||||||
}
|
}
|
||||||
|
|
||||||
return unmarshalToObject(s.typer, s.creater, actual, into)
|
return unmarshalToObject(s.typer, s.creater, actual, into, unk.Raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeToStream serializes the provided object to the given writer. Overrides is ignored.
|
// EncodeToStream serializes the provided object to the given writer. Overrides is ignored.
|
||||||
@ -374,13 +369,13 @@ func (s *RawSerializer) Decode(originalData []byte, gvk *unversioned.GroupVersio
|
|||||||
return nil, actual, runtime.NewMissingVersionErr("<protobuf encoded body - must provide default type>")
|
return nil, actual, runtime.NewMissingVersionErr("<protobuf encoded body - must provide default type>")
|
||||||
}
|
}
|
||||||
|
|
||||||
return unmarshalToObject(s.typer, s.creater, actual, into)
|
return unmarshalToObject(s.typer, s.creater, actual, into, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// unmarshalToObject is the common code between decode in the raw and normal serializer.
|
// unmarshalToObject is the common code between decode in the raw and normal serializer.
|
||||||
func unmarshalToObject(typer runtime.Typer, creater runtime.ObjectCreater, actual *unversioned.GroupVersionKind, into runtime.Object) (runtime.Object, *unversioned.GroupVersionKind, error) {
|
func unmarshalToObject(typer runtime.Typer, creater runtime.ObjectCreater, actual *unversioned.GroupVersionKind, into runtime.Object, data []byte) (runtime.Object, *unversioned.GroupVersionKind, error) {
|
||||||
// use the target if necessary
|
// use the target if necessary
|
||||||
obj, err := runtime.UseOrCreateObject(s.typer, s.creater, *actual, into)
|
obj, err := runtime.UseOrCreateObject(typer, creater, *actual, into)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, actual, err
|
return nil, actual, err
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,17 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
_ "k8s.io/kubernetes/pkg/api/install"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/runtime/serializer/protobuf"
|
"k8s.io/kubernetes/pkg/runtime/serializer/protobuf"
|
||||||
|
"k8s.io/kubernetes/pkg/util/diff"
|
||||||
)
|
)
|
||||||
|
|
||||||
type testObject struct {
|
type testObject struct {
|
||||||
@ -185,3 +191,151 @@ func TestEncode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDecode(t *testing.T) {
|
||||||
|
wire1 := []byte{
|
||||||
|
0x6b, 0x38, 0x73, 0x00, // prefix
|
||||||
|
0x0a, 0x04,
|
||||||
|
0x0a, 0x00, // apiversion
|
||||||
|
0x12, 0x00, // kind
|
||||||
|
0x12, 0x00, // data
|
||||||
|
0x1a, 0x00, // content-type
|
||||||
|
0x22, 0x00, // content-encoding
|
||||||
|
}
|
||||||
|
wire2 := []byte{
|
||||||
|
0x6b, 0x38, 0x73, 0x00, // prefix
|
||||||
|
0x0a, 0x15,
|
||||||
|
0x0a, 0x0d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, // apiversion
|
||||||
|
0x12, 0x04, 0x74, 0x65, 0x73, 0x74, // kind
|
||||||
|
0x12, 0x03, 0x01, 0x02, 0x03, // data
|
||||||
|
0x1a, 0x00, // content-type
|
||||||
|
0x22, 0x00, // content-encoding
|
||||||
|
}
|
||||||
|
|
||||||
|
//err1 := fmt.Errorf("a test error")
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
obj runtime.Object
|
||||||
|
data []byte
|
||||||
|
errFn func(error) bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
obj: &runtime.Unknown{},
|
||||||
|
errFn: func(err error) bool { return err.Error() == "empty data" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: []byte{0x6b},
|
||||||
|
errFn: func(err error) bool { return strings.Contains(err.Error(), "does not appear to be a protobuf message") },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
obj: &runtime.Unknown{
|
||||||
|
ContentType: "application/protobuf",
|
||||||
|
Raw: []byte{},
|
||||||
|
},
|
||||||
|
data: wire1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
obj: &runtime.Unknown{
|
||||||
|
TypeMeta: runtime.TypeMeta{
|
||||||
|
APIVersion: "other/version",
|
||||||
|
Kind: "test",
|
||||||
|
},
|
||||||
|
ContentType: "application/protobuf",
|
||||||
|
Raw: []byte{0x01, 0x02, 0x03},
|
||||||
|
},
|
||||||
|
data: wire2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range testCases {
|
||||||
|
s := protobuf.NewSerializer(nil, nil, "application/protobuf")
|
||||||
|
unk := &runtime.Unknown{}
|
||||||
|
err := runtime.DecodeInto(s, test.data, unk)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(unk, test.obj) {
|
||||||
|
t.Errorf("%d: unexpected object:\n%#v", i, unk)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDecodeObjects(t *testing.T) {
|
||||||
|
obj1 := &v1.Pod{
|
||||||
|
ObjectMeta: v1.ObjectMeta{
|
||||||
|
Name: "cool",
|
||||||
|
},
|
||||||
|
Spec: v1.PodSpec{
|
||||||
|
Containers: []v1.Container{
|
||||||
|
{
|
||||||
|
Name: "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
obj1wire, err := obj1.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
wire1, err := (&runtime.Unknown{
|
||||||
|
TypeMeta: runtime.TypeMeta{Kind: "Pod", APIVersion: "v1"},
|
||||||
|
Raw: obj1wire,
|
||||||
|
}).Marshal()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
wire1 = append([]byte{0x6b, 0x38, 0x73, 0x00}, wire1...)
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
obj runtime.Object
|
||||||
|
data []byte
|
||||||
|
errFn func(error) bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
obj: obj1,
|
||||||
|
data: wire1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range testCases {
|
||||||
|
s := protobuf.NewSerializer(api.Scheme, runtime.ObjectTyperToTyper(api.Scheme), "application/protobuf")
|
||||||
|
obj, err := runtime.Decode(s, test.data)
|
||||||
|
|
||||||
|
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 not have returned an object", i)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !api.Semantic.DeepEqual(obj, test.obj) {
|
||||||
|
t.Errorf("%d: unexpected object:\n%s", i, diff.ObjectGoPrintDiff(test.obj, obj))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user