func TestUnmarshalPartiallyPopulatedOptionalFieldsFails(t *testing.T) {
	// Fill in all fields, then randomly remove one.
	dataOut := &test.NinOptNative{
		Field1:  proto.Float64(0),
		Field2:  proto.Float32(0),
		Field3:  proto.Int32(0),
		Field4:  proto.Int64(0),
		Field5:  proto.Uint32(0),
		Field6:  proto.Uint64(0),
		Field7:  proto.Int32(0),
		Field8:  proto.Int64(0),
		Field9:  proto.Uint32(0),
		Field10: proto.Int32(0),
		Field11: proto.Uint64(0),
		Field12: proto.Int64(0),
		Field13: proto.Bool(false),
		Field14: proto.String("0"),
		Field15: []byte("0"),
	}
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	fieldName := "Field" + strconv.Itoa(r.Intn(15)+1)
	field := reflect.ValueOf(dataOut).Elem().FieldByName(fieldName)
	fieldType := field.Type()
	field.Set(reflect.Zero(fieldType))
	encodedMessage, err := proto.Marshal(dataOut)
	if err != nil {
		t.Fatalf("Unexpected error when marshalling dataOut: %v", err)
	}
	dataIn := NidOptNative{}
	err = proto.Unmarshal(encodedMessage, &dataIn)
	if err.Error() != `proto: required field "`+fieldName+`" not set` {
		t.Fatalf(`err.Error() != "proto: required field "`+fieldName+`" not set"; was "%s" instead`, err.Error())
	}
}
Example #2
0
func newTestMessage() *pb.MyMessage {
	msg := &pb.MyMessage{
		Count: proto.Int32(42),
		Name:  proto.String("Dave"),
		Quote: proto.String(`"I didn't want to go."`),
		Pet:   []string{"bunny", "kitty", "horsey"},
		Inner: &pb.InnerMessage{
			Host:      proto.String("footrest.syd"),
			Port:      proto.Int32(7001),
			Connected: proto.Bool(true),
		},
		Others: []*pb.OtherMessage{
			{
				Key:   proto.Int64(0xdeadbeef),
				Value: []byte{1, 65, 7, 12},
			},
			{
				Weight: proto.Float32(6.022),
				Inner: &pb.InnerMessage{
					Host: proto.String("lesha.mtv"),
					Port: proto.Int32(8002),
				},
			},
		},
		Bikeshed: pb.MyMessage_BLUE.Enum(),
		Somegroup: &pb.MyMessage_SomeGroup{
			GroupField: proto.Int32(8),
		},
		// One normally wouldn't do this.
		// This is an undeclared tag 13, as a varint (wire type 0) with value 4.
		XXX_unrecognized: []byte{13<<3 | 0, 4},
	}
	ext := &pb.Ext{
		Data: proto.String("Big gobs for big rats"),
	}
	if err := proto.SetExtension(msg, pb.E_Ext_More, ext); err != nil {
		panic(err)
	}
	greetings := []string{"adg", "easy", "cow"}
	if err := proto.SetExtension(msg, pb.E_Greeting, greetings); err != nil {
		panic(err)
	}

	// Add an unknown extension. We marshal a pb.Ext, and fake the ID.
	b, err := proto.Marshal(&pb.Ext{Data: proto.String("3G skiing")})
	if err != nil {
		panic(err)
	}
	b = append(proto.EncodeVarint(201<<3|proto.WireBytes), b...)
	proto.SetRawExtension(msg, 201, b)

	// Extensions can be plain fields, too, so let's test that.
	b = append(proto.EncodeVarint(202<<3|proto.WireVarint), 19)
	proto.SetRawExtension(msg, 202, b)

	return msg
}
Example #3
0
func TestGetExtensionStability(t *testing.T) {
	check := func(m *pb.MyMessage) bool {
		ext1, err := proto.GetExtension(m, pb.E_Ext_More)
		if err != nil {
			t.Fatalf("GetExtension() failed: %s", err)
		}
		ext2, err := proto.GetExtension(m, pb.E_Ext_More)
		if err != nil {
			t.Fatalf("GetExtension() failed: %s", err)
		}
		return ext1 == ext2
	}
	msg := &pb.MyMessage{Count: proto.Int32(4)}
	ext0 := &pb.Ext{}
	if err := proto.SetExtension(msg, pb.E_Ext_More, ext0); err != nil {
		t.Fatalf("Could not set ext1: %s", ext0)
	}
	if !check(msg) {
		t.Errorf("GetExtension() not stable before marshaling")
	}
	bb, err := proto.Marshal(msg)
	if err != nil {
		t.Fatalf("Marshal() failed: %s", err)
	}
	msg1 := &pb.MyMessage{}
	err = proto.Unmarshal(bb, msg1)
	if err != nil {
		t.Fatalf("Unmarshal() failed: %s", err)
	}
	if !check(msg1) {
		t.Errorf("GetExtension() not stable after unmarshaling")
	}
}
Example #4
0
func TestNilExtension(t *testing.T) {
	msg := &pb.MyMessage{
		Count: proto.Int32(1),
	}
	if err := proto.SetExtension(msg, pb.E_Ext_Text, proto.String("hello")); err != nil {
		t.Fatal(err)
	}
	if err := proto.SetExtension(msg, pb.E_Ext_More, (*pb.Ext)(nil)); err == nil {
		t.Error("expected SetExtension to fail due to a nil extension")
	} else if want := "proto: SetExtension called with nil value of type *testdata.Ext"; err.Error() != want {
		t.Errorf("expected error %v, got %v", want, err)
	}
	// Note: if the behavior of Marshal is ever changed to ignore nil extensions, update
	// this test to verify that E_Ext_Text is properly propagated through marshal->unmarshal.
}
Example #5
0
func TestExtensionDescsWithMissingExtensions(t *testing.T) {
	msg := &pb.MyMessage{Count: proto.Int32(0)}
	extdesc1 := pb.E_Ext_More
	if descs, err := proto.ExtensionDescs(msg); len(descs) != 0 || err != nil {
		t.Errorf("proto.ExtensionDescs: got %d descs, error %v; want 0, nil", len(descs), err)
	}

	ext1 := &pb.Ext{}
	if err := proto.SetExtension(msg, extdesc1, ext1); err != nil {
		t.Fatalf("Could not set ext1: %s", err)
	}
	extdesc2 := &proto.ExtensionDesc{
		ExtendedType:  (*pb.MyMessage)(nil),
		ExtensionType: (*bool)(nil),
		Field:         123456789,
		Name:          "a.b",
		Tag:           "varint,123456789,opt",
	}
	ext2 := proto.Bool(false)
	if err := proto.SetExtension(msg, extdesc2, ext2); err != nil {
		t.Fatalf("Could not set ext2: %s", err)
	}

	b, err := proto.Marshal(msg)
	if err != nil {
		t.Fatalf("Could not marshal msg: %v", err)
	}
	if err = proto.Unmarshal(b, msg); err != nil {
		t.Fatalf("Could not unmarshal into msg: %v", err)
	}

	descs, err := proto.ExtensionDescs(msg)
	if err != nil {
		t.Fatalf("proto.ExtensionDescs: got error %v", err)
	}
	sortExtDescs(descs)
	wantDescs := []*proto.ExtensionDesc{extdesc1, {Field: extdesc2.Field}}
	if !reflect.DeepEqual(descs, wantDescs) {
		t.Errorf("proto.ExtensionDescs(msg) sorted extension ids: got %+v, want %+v", descs, wantDescs)
	}
}
Example #6
0
func TestUnmarshalRepeatingNonRepeatedExtension(t *testing.T) {
	// We may see multiple instances of the same extension in the wire
	// format. For example, the proto compiler may encode custom options in
	// this way. Here, we verify that we merge the extensions together.
	tests := []struct {
		name string
		ext  []*pb.ComplexExtension
	}{
		{
			"two fields",
			[]*pb.ComplexExtension{
				{First: proto.Int32(7)},
				{Second: proto.Int32(11)},
			},
		},
		{
			"repeated field",
			[]*pb.ComplexExtension{
				{Third: []int32{1000}},
				{Third: []int32{2000}},
			},
		},
		{
			"two fields and repeated field",
			[]*pb.ComplexExtension{
				{Third: []int32{1000}},
				{First: proto.Int32(9)},
				{Second: proto.Int32(21)},
				{Third: []int32{2000}},
			},
		},
	}
	for _, test := range tests {
		var buf bytes.Buffer
		var want pb.ComplexExtension

		// Generate a serialized representation of a repeated extension
		// by catenating bytes together.
		for i, e := range test.ext {
			// Merge to create the wanted proto.
			proto.Merge(&want, e)

			// serialize the message
			msg := new(pb.OtherMessage)
			err := proto.SetExtension(msg, pb.E_Complex, e)
			if err != nil {
				t.Fatalf("[%s] Error setting extension %d: %v", test.name, i, err)
			}
			b, err := proto.Marshal(msg)
			if err != nil {
				t.Fatalf("[%s] Error marshaling message %d: %v", test.name, i, err)
			}
			buf.Write(b)
		}

		// Unmarshal and read the merged proto.
		msg2 := new(pb.OtherMessage)
		err := proto.Unmarshal(buf.Bytes(), msg2)
		if err != nil {
			t.Fatalf("[%s] Error unmarshaling message: %v", test.name, err)
		}
		e, err := proto.GetExtension(msg2, pb.E_Complex)
		if err != nil {
			t.Fatalf("[%s] Error getting extension: %v", test.name, err)
		}
		ext := e.(*pb.ComplexExtension)
		if ext == nil {
			t.Fatalf("[%s] Invalid extension", test.name)
		}
		if !reflect.DeepEqual(*ext, want) {
			t.Errorf("[%s] Wrong value for ComplexExtension: got: %v want: %v\n", test.name, ext, want)
		}
	}
}
Example #7
0
func TestMarshalUnmarshalRepeatedExtension(t *testing.T) {
	// Add a repeated extension to the result.
	tests := []struct {
		name string
		ext  []*pb.ComplexExtension
	}{
		{
			"two fields",
			[]*pb.ComplexExtension{
				{First: proto.Int32(7)},
				{Second: proto.Int32(11)},
			},
		},
		{
			"repeated field",
			[]*pb.ComplexExtension{
				{Third: []int32{1000}},
				{Third: []int32{2000}},
			},
		},
		{
			"two fields and repeated field",
			[]*pb.ComplexExtension{
				{Third: []int32{1000}},
				{First: proto.Int32(9)},
				{Second: proto.Int32(21)},
				{Third: []int32{2000}},
			},
		},
	}
	for _, test := range tests {
		// Marshal message with a repeated extension.
		msg1 := new(pb.OtherMessage)
		err := proto.SetExtension(msg1, pb.E_RComplex, test.ext)
		if err != nil {
			t.Fatalf("[%s] Error setting extension: %v", test.name, err)
		}
		b, err := proto.Marshal(msg1)
		if err != nil {
			t.Fatalf("[%s] Error marshaling message: %v", test.name, err)
		}

		// Unmarshal and read the merged proto.
		msg2 := new(pb.OtherMessage)
		err = proto.Unmarshal(b, msg2)
		if err != nil {
			t.Fatalf("[%s] Error unmarshaling message: %v", test.name, err)
		}
		e, err := proto.GetExtension(msg2, pb.E_RComplex)
		if err != nil {
			t.Fatalf("[%s] Error getting extension: %v", test.name, err)
		}
		ext := e.([]*pb.ComplexExtension)
		if ext == nil {
			t.Fatalf("[%s] Invalid extension", test.name)
		}
		if !reflect.DeepEqual(ext, test.ext) {
			t.Errorf("[%s] Wrong value for ComplexExtension: got: %v want: %v\n", test.name, ext, test.ext)
		}
	}
}
Example #8
0
func makeGolden() []golden {
	nested := &pb.Nested{Bunny: "Monty"}
	nb, err := proto.Marshal(nested)
	if err != nil {
		panic(err)
	}
	m1 := &pb.Message{
		Name:        "David",
		ResultCount: 47,
		Anything:    &types.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(nested), Value: nb},
	}
	m2 := &pb.Message{
		Name:        "David",
		ResultCount: 47,
		Anything:    &types.Any{TypeUrl: "http://[::1]/type.googleapis.com/" + proto.MessageName(nested), Value: nb},
	}
	m3 := &pb.Message{
		Name:        "David",
		ResultCount: 47,
		Anything:    &types.Any{TypeUrl: `type.googleapis.com/"/` + proto.MessageName(nested), Value: nb},
	}
	m4 := &pb.Message{
		Name:        "David",
		ResultCount: 47,
		Anything:    &types.Any{TypeUrl: "type.googleapis.com/a/path/" + proto.MessageName(nested), Value: nb},
	}
	m5 := &types.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(nested), Value: nb}

	any1 := &testpb.MyMessage{Count: proto.Int32(47), Name: proto.String("David")}
	proto.SetExtension(any1, testpb.E_Ext_More, &testpb.Ext{Data: proto.String("foo")})
	proto.SetExtension(any1, testpb.E_Ext_Text, proto.String("bar"))
	any1b, err := proto.Marshal(any1)
	if err != nil {
		panic(err)
	}
	any2 := &testpb.MyMessage{Count: proto.Int32(42), Bikeshed: testpb.MyMessage_GREEN.Enum(), RepBytes: [][]byte{[]byte("roboto")}}
	proto.SetExtension(any2, testpb.E_Ext_More, &testpb.Ext{Data: proto.String("baz")})
	any2b, err := proto.Marshal(any2)
	if err != nil {
		panic(err)
	}
	m6 := &pb.Message{
		Name:        "David",
		ResultCount: 47,
		Anything:    &types.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(any1), Value: any1b},
		ManyThings: []*types.Any{
			{TypeUrl: "type.googleapis.com/" + proto.MessageName(any2), Value: any2b},
			{TypeUrl: "type.googleapis.com/" + proto.MessageName(any1), Value: any1b},
		},
	}

	const (
		m1Golden = `
name: "David"
result_count: 47
anything: <
  [type.googleapis.com/proto3_proto.Nested]: <
    bunny: "Monty"
  >
>
`
		m2Golden = `
name: "David"
result_count: 47
anything: <
  ["http://[::1]/type.googleapis.com/proto3_proto.Nested"]: <
    bunny: "Monty"
  >
>
`
		m3Golden = `
name: "David"
result_count: 47
anything: <
  ["type.googleapis.com/\"/proto3_proto.Nested"]: <
    bunny: "Monty"
  >
>
`
		m4Golden = `
name: "David"
result_count: 47
anything: <
  [type.googleapis.com/a/path/proto3_proto.Nested]: <
    bunny: "Monty"
  >
>
`
		m5Golden = `
[type.googleapis.com/proto3_proto.Nested]: <
  bunny: "Monty"
>
`
		m6Golden = `
name: "David"
result_count: 47
anything: <
  [type.googleapis.com/testdata.MyMessage]: <
    count: 47
    name: "David"
    [testdata.Ext.more]: <
      data: "foo"
    >
    [testdata.Ext.text]: "bar"
  >
>
many_things: <
  [type.googleapis.com/testdata.MyMessage]: <
    count: 42
    bikeshed: GREEN
    rep_bytes: "roboto"
    [testdata.Ext.more]: <
      data: "baz"
    >
  >
>
many_things: <
  [type.googleapis.com/testdata.MyMessage]: <
    count: 47
    name: "David"
    [testdata.Ext.more]: <
      data: "foo"
    >
    [testdata.Ext.text]: "bar"
  >
>
`
	)
	return []golden{
		{m1, strings.TrimSpace(m1Golden) + "\n", strings.TrimSpace(compact(m1Golden)) + " "},
		{m2, strings.TrimSpace(m2Golden) + "\n", strings.TrimSpace(compact(m2Golden)) + " "},
		{m3, strings.TrimSpace(m3Golden) + "\n", strings.TrimSpace(compact(m3Golden)) + " "},
		{m4, strings.TrimSpace(m4Golden) + "\n", strings.TrimSpace(compact(m4Golden)) + " "},
		{m5, strings.TrimSpace(m5Golden) + "\n", strings.TrimSpace(compact(m5Golden)) + " "},
		{m6, strings.TrimSpace(m6Golden) + "\n", strings.TrimSpace(compact(m6Golden)) + " "},
	}
}
Example #9
0
func TestInt32Int64Compatibility(t *testing.T) {

	//test nullable int32 and int64

	data1, err := testSize(&NinOptNative{
		Field3: proto.Int32(-1),
	}, "nullable", 11)
	if err != nil {
		t.Error(err)
	}
	//change marshaled data1 to unmarshal into 4th field which is an int64
	data1[0] = uint8(uint32(4 /*fieldNumber*/)<<3 | uint32(0 /*wireType*/))
	u1 := &NinOptNative{}
	if err = proto.Unmarshal(data1, u1); err != nil {
		t.Error(err)
	}
	if !u1.Equal(&NinOptNative{
		Field4: proto.Int64(-1),
	}) {
		t.Error("nullable unmarshaled int32 is not the same int64")
	}

	//test non-nullable int32 and int64

	data2, err := testSize(&NidOptNative{
		Field3: -1,
	}, "non nullable", 67)
	if err != nil {
		t.Error(err)
	}
	//change marshaled data2 to unmarshal into 4th field which is an int64
	field3 := uint8(uint32(3 /*fieldNumber*/)<<3 | uint32(0 /*wireType*/))
	field4 := uint8(uint32(4 /*fieldNumber*/)<<3 | uint32(0 /*wireType*/))
	for i, c := range data2 {
		if c == field4 {
			data2[i] = field3
		} else if c == field3 {
			data2[i] = field4
		}
	}
	u2 := &NidOptNative{}
	if err = proto.Unmarshal(data2, u2); err != nil {
		t.Error(err)
	}
	if !u2.Equal(&NidOptNative{
		Field4: -1,
	}) {
		t.Error("non nullable unmarshaled int32 is not the same int64")
	}

	//test packed repeated int32 and int64

	m4 := &NinRepPackedNative{
		Field3: []int32{-1},
	}
	data4, err := testSize(m4, "packed", 12)
	if err != nil {
		t.Error(err)
	}
	u4 := &NinRepPackedNative{}
	if err := proto.Unmarshal(data4, u4); err != nil {
		t.Error(err)
	}
	if err := u4.VerboseEqual(m4); err != nil {
		t.Fatalf("%#v", u4)
	}

	//test repeated int32 and int64

	if _, err := testSize(&NinRepNative{
		Field3: []int32{-1},
	}, "repeated", 11); err != nil {
		t.Error(err)
	}

	t.Logf("tested all")
}
Example #10
0
	pb "github.com/maditya/protobuf/jsonpb/jsonpb_test_proto"
	"github.com/maditya/protobuf/proto"
	proto3pb "github.com/maditya/protobuf/proto/proto3_proto"
	"github.com/maditya/protobuf/types"
)

var (
	marshaler = Marshaler{}

	marshalerAllOptions = Marshaler{
		Indent: "  ",
	}

	simpleObject = &pb.Simple{
		OInt32:     proto.Int32(-32),
		OInt64:     proto.Int64(-6400000000),
		OUint32:    proto.Uint32(32),
		OUint64:    proto.Uint64(6400000000),
		OSint32:    proto.Int32(-13),
		OSint64:    proto.Int64(-2600000000),
		OFloat:     proto.Float32(3.14),
		ODouble:    proto.Float64(6.02214179e23),
		OBool:      proto.Bool(true),
		OString:    proto.String("hello \"there\""),
		OBytes:     []byte("beep boop"),
		OCastBytes: pb.Bytes("wow"),
	}

	simpleObjectJSON = `{` +
		`"oBool":true,` +
Example #11
0
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package proto_test

import (
	"testing"

	"github.com/maditya/protobuf/proto"

	proto3pb "github.com/maditya/protobuf/proto/proto3_proto"
	pb "github.com/maditya/protobuf/proto/testdata"
)

var cloneTestMessage = &pb.MyMessage{
	Count: proto.Int32(42),
	Name:  proto.String("Dave"),
	Pet:   []string{"bunny", "kitty", "horsey"},
	Inner: &pb.InnerMessage{
		Host:      proto.String("niles"),
		Port:      proto.Int32(9099),
		Connected: proto.Bool(true),
	},
	Others: []*pb.OtherMessage{
		{
			Value: []byte("some bytes"),
		},
	},
	Somegroup: &pb.MyMessage_SomeGroup{
		GroupField: proto.Int32(6),
	},