mirror of https://github.com/k3s-io/k3s
Fix compilation errors in protobuf and add decode test
parent
bfc991646b
commit
87146c4255
|
@ -23,7 +23,6 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
|
@ -41,11 +40,6 @@ var (
|
|||
//
|
||||
// This encoding scheme is experimental, and is subject to change at any time.
|
||||
protoEncodingPrefix = []byte{0x6b, 0x38, 0x73, 0x00}
|
||||
|
||||
bufferSize = uint64(16384)
|
||||
availableBuffers = sync.Pool{New: func() interface{} {
|
||||
return make([]byte, bufferSize)
|
||||
}}
|
||||
)
|
||||
|
||||
type errNotMarshalable struct {
|
||||
|
@ -76,9 +70,10 @@ func NewSerializer(creater runtime.ObjectCreater, typer runtime.Typer, defaultCo
|
|||
}
|
||||
|
||||
type Serializer struct {
|
||||
prefix []byte
|
||||
creater runtime.ObjectCreater
|
||||
typer runtime.Typer
|
||||
prefix []byte
|
||||
creater runtime.ObjectCreater
|
||||
typer runtime.Typer
|
||||
contentType string
|
||||
}
|
||||
|
||||
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 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.
|
||||
|
@ -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 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.
|
||||
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
|
||||
obj, err := runtime.UseOrCreateObject(s.typer, s.creater, *actual, into)
|
||||
obj, err := runtime.UseOrCreateObject(typer, creater, *actual, into)
|
||||
if err != nil {
|
||||
return nil, actual, err
|
||||
}
|
||||
|
|
|
@ -22,11 +22,17 @@ import (
|
|||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
_ "k8s.io/kubernetes/pkg/api/install"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/runtime/serializer/protobuf"
|
||||
"k8s.io/kubernetes/pkg/util/diff"
|
||||
)
|
||||
|
||||
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