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") } }
func TestRoundTripProto3(t *testing.T) { m := &pb.Message{ Name: "David", // (2 | 1<<3): 0x0a 0x05 "David" Hilarity: pb.Message_PUNS, // (0 | 2<<3): 0x10 0x01 HeightInCm: 178, // (0 | 3<<3): 0x18 0xb2 0x01 Data: []byte("roboto"), // (2 | 4<<3): 0x20 0x06 "roboto" ResultCount: 47, // (0 | 7<<3): 0x38 0x2f TrueScotsman: true, // (0 | 8<<3): 0x40 0x01 Score: 8.1, // (5 | 9<<3): 0x4d <8.1> Key: []uint64{1, 0xdeadbeef}, Nested: &pb.Nested{ Bunny: "Monty", }, } t.Logf(" m: %v", m) b, err := proto.Marshal(m) if err != nil { t.Fatalf("proto.Marshal: %v", err) } t.Logf(" b: %q", b) m2 := new(pb.Message) if err := proto.Unmarshal(b, m2); err != nil { t.Fatalf("proto.Unmarshal: %v", err) } t.Logf("m2: %v", m2) if !proto.Equal(m, m2) { t.Errorf("proto.Equal returned false:\n m: %v\nm2: %v", m, m2) } }
// Ensure shards with deprecated "OwnerIDs" can be decoded. func TestShardInfo_UnmarshalBinary_OwnerIDs(t *testing.T) { // Encode deprecated form to bytes. buf, err := proto.Marshal(&internal.ShardInfo{ ID: proto.Uint64(1), OwnerIDs: []uint64{10, 20, 30}, }) if err != nil { t.Fatal(err) } // Decode deprecated form. var si meta.ShardInfo if err := si.UnmarshalBinary(buf); err != nil { t.Fatal(err) } // Verify data is migrated correctly. if !reflect.DeepEqual(si, meta.ShardInfo{ ID: 1, Owners: []meta.ShardOwner{ {NodeID: 10}, {NodeID: 20}, {NodeID: 30}, }, }) { t.Fatalf("unexpected shard info: %s", spew.Sdump(si)) } }
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 }
// MarshalBinary encodes the object to a binary format. func (m *MeasurementFields) MarshalBinary() ([]byte, error) { var pb internal.MeasurementFields for _, f := range m.Fields { id := int32(f.ID) name := f.Name t := int32(f.Type) pb.Fields = append(pb.Fields, &internal.Field{ID: &id, Name: &name, Type: &t}) } return proto.Marshal(&pb) }
// MarshalBinary encodes the object to a binary format. func (s *Series) MarshalBinary() ([]byte, error) { var pb internal.Series pb.Key = &s.Key for k, v := range s.Tags { key := k value := v pb.Tags = append(pb.Tags, &internal.Tag{Key: &key, Value: &value}) } return proto.Marshal(&pb) }
func (r *rpc) sendResponse(conn net.Conn, typ internal.RPCType, resp proto.Message) { // Marshal the response back to a protobuf buf, err := proto.Marshal(resp) if err != nil { r.logger.Printf("unable to marshal response: %v", err) return } // Encode response back to connection. if _, err := conn.Write(r.pack(typ, buf)); err != nil { r.logger.Printf("unable to write rpc response: %s", err) } }
func TestProto3ZeroValues(t *testing.T) { tests := []struct { desc string m proto.Message }{ {"zero message", &pb.Message{}}, {"empty bytes field", &pb.Message{Data: []byte{}}}, } for _, test := range tests { b, err := proto.Marshal(test.m) if err != nil { t.Errorf("%s: proto.Marshal: %v", test.desc, err) continue } if len(b) > 0 { t.Errorf("%s: Encoding is non-empty: %q", test.desc, b) } } }
// call sends an encoded request to the remote leader and returns // an encoded response value. func (r *rpc) call(dest string, req proto.Message) (proto.Message, error) { // Determine type of request var rpcType internal.RPCType switch t := req.(type) { case *internal.JoinRequest: rpcType = internal.RPCType_Join case *internal.FetchDataRequest: rpcType = internal.RPCType_FetchData default: return nil, fmt.Errorf("unknown rpc request type: %v", t) } // Create a connection to the leader. conn, err := net.DialTimeout("tcp", dest, leaderDialTimeout) if err != nil { return nil, fmt.Errorf("rpc dial: %v", err) } defer conn.Close() // Write a marker byte for rpc messages. _, err = conn.Write([]byte{MuxRPCHeader}) if err != nil { return nil, err } b, err := proto.Marshal(req) if err != nil { return nil, fmt.Errorf("rpc marshal: %v", err) } // Write request size & bytes. if _, err := conn.Write(r.pack(rpcType, b)); err != nil { return nil, fmt.Errorf("write %v rpc: %s", rpcType, err) } data, err := ioutil.ReadAll(conn) if err != nil { return nil, fmt.Errorf("read %v rpc: %v", rpcType, err) } // Should always have a size and type if exp := 16; len(data) < exp { r.traceCluster("recv: %v", string(data)) return nil, fmt.Errorf("rpc %v failed: short read: got %v, exp %v", rpcType, len(data), exp) } sz := btou64(data[0:8]) if len(data[8:]) != int(sz) { r.traceCluster("recv: %v", string(data)) return nil, fmt.Errorf("rpc %v failed: short read: got %v, exp %v", rpcType, len(data[8:]), sz) } // See what response type we got back, could get a general error response rpcType = internal.RPCType(btou64(data[8:16])) data = data[16:] var resp proto.Message switch rpcType { case internal.RPCType_Join: resp = &internal.JoinResponse{} case internal.RPCType_FetchData: resp = &internal.FetchDataResponse{} case internal.RPCType_Error: resp = &internal.ErrorResponse{} default: return nil, fmt.Errorf("unknown rpc response type: %v", rpcType) } if err := proto.Unmarshal(data, resp); err != nil { return nil, fmt.Errorf("rpc unmarshal: %v", err) } if reply, ok := resp.(Reply); ok { if !reply.GetHeader().GetOK() { return nil, fmt.Errorf("rpc %v failed: %s", rpcType, reply.GetHeader().GetError()) } } return resp, nil }
// MarshalBinary encodes the metadata to a binary format. func (data *Data) MarshalBinary() ([]byte, error) { return proto.Marshal(data.marshal()) }