// marshal serializes to a protobuf representation. func (di DatabaseInfo) marshal() *internal.DatabaseInfo { pb := &internal.DatabaseInfo{} pb.Name = proto.String(di.Name) pb.DefaultRetentionPolicy = proto.String(di.DefaultRetentionPolicy) pb.RetentionPolicies = make([]*internal.RetentionPolicyInfo, len(di.RetentionPolicies)) for i := range di.RetentionPolicies { pb.RetentionPolicies[i] = di.RetentionPolicies[i].marshal() } pb.ContinuousQueries = make([]*internal.ContinuousQueryInfo, len(di.ContinuousQueries)) for i := range di.ContinuousQueries { pb.ContinuousQueries[i] = di.ContinuousQueries[i].marshal() } return pb }
// marshal serializes to a protobuf representation. func (ui UserInfo) marshal() *internal.UserInfo { pb := &internal.UserInfo{ Name: proto.String(ui.Name), Hash: proto.String(ui.Hash), Admin: proto.Bool(ui.Admin), } for database, privilege := range ui.Privileges { pb.Privileges = append(pb.Privileges, &internal.UserPrivilege{ Database: proto.String(database), Privilege: proto.Int32(int32(privilege)), }) } return pb }
func TestStringEscaping(t *testing.T) { testCases := []struct { in *pb.Strings out string }{ { // Test data from C++ test (TextFormatTest.StringEscape). // Single divergence: we don't escape apostrophes. &pb.Strings{StringField: proto.String("\"A string with ' characters \n and \r newlines and \t tabs and \001 slashes \\ and multiple spaces")}, "string_field: \"\\\"A string with ' characters \\n and \\r newlines and \\t tabs and \\001 slashes \\\\ and multiple spaces\"\n", }, { // Test data from the same C++ test. &pb.Strings{StringField: proto.String("\350\260\267\346\255\214")}, "string_field: \"\\350\\260\\267\\346\\255\\214\"\n", }, { // Some UTF-8. &pb.Strings{StringField: proto.String("\x00\x01\xff\x81")}, `string_field: "\000\001\377\201"` + "\n", }, } for i, tc := range testCases { var buf bytes.Buffer if err := proto.MarshalText(&buf, tc.in); err != nil { t.Errorf("proto.MarsalText: %v", err) continue } s := buf.String() if s != tc.out { t.Errorf("#%d: Got:\n%s\nExpected:\n%s\n", i, s, tc.out) continue } // Check round-trip. pb := new(pb.Strings) if err := proto.UnmarshalText(s, pb); err != nil { t.Errorf("#%d: UnmarshalText: %v", i, err) continue } if !proto.Equal(pb, tc.in) { t.Errorf("#%d: Round-trip failed:\nstart: %v\n end: %v", i, tc.in, pb) } } }
func init() { ext := &pb.Ext{ Data: proto.String("extension"), } if err := proto.SetExtension(cloneTestMessage, pb.E_Ext_More, ext); err != nil { panic("SetExtension: " + err.Error()) } }
func TestExtensionsRoundTrip(t *testing.T) { msg := &pb.MyMessage{} ext1 := &pb.Ext{ Data: proto.String("hi"), } ext2 := &pb.Ext{ Data: proto.String("there"), } exists := proto.HasExtension(msg, pb.E_Ext_More) if exists { t.Error("Extension More present unexpectedly") } if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil { t.Error(err) } if err := proto.SetExtension(msg, pb.E_Ext_More, ext2); err != nil { t.Error(err) } e, err := proto.GetExtension(msg, pb.E_Ext_More) if err != nil { t.Error(err) } x, ok := e.(*pb.Ext) if !ok { t.Errorf("e has type %T, expected testdata.Ext", e) } else if *x.Data != "there" { t.Errorf("SetExtension failed to overwrite, got %+v, not 'there'", x) } proto.ClearExtension(msg, pb.E_Ext_More) if _, err = proto.GetExtension(msg, pb.E_Ext_More); err != proto.ErrMissingExtension { t.Errorf("got %v, expected ErrMissingExtension", e) } if _, err := proto.GetExtension(msg, pb.E_X215); err == nil { t.Error("expected bad extension error, got nil") } if err := proto.SetExtension(msg, pb.E_X215, 12); err == nil { t.Error("expected extension err") } if err := proto.SetExtension(msg, pb.E_Ext_More, 12); err == nil { t.Error("expected some sort of type mismatch error, got nil") } }
func (r *rpc) sendError(conn net.Conn, msg string) { r.traceCluster(msg) resp := &internal.ErrorResponse{ Header: &internal.ResponseHeader{ OK: proto.Bool(false), Error: proto.String(msg), }, } r.sendResponse(conn, internal.RPCType_Error, resp) }
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 }
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. }
// marshal serializes to a protobuf representation. func (rpi *RetentionPolicyInfo) marshal() *internal.RetentionPolicyInfo { pb := &internal.RetentionPolicyInfo{ Name: proto.String(rpi.Name), ReplicaN: proto.Uint32(uint32(rpi.ReplicaN)), Duration: proto.Int64(int64(rpi.Duration)), ShardGroupDuration: proto.Int64(int64(rpi.ShardGroupDuration)), } pb.ShardGroups = make([]*internal.ShardGroupInfo, len(rpi.ShardGroups)) for i, sgi := range rpi.ShardGroups { pb.ShardGroups[i] = sgi.marshal() } return pb }
func TestRepeatedNilText(t *testing.T) { m := &pb.MessageList{ Message: []*pb.MessageList_Message{ nil, { Name: proto.String("Horse"), }, nil, }, } want := `Message <nil> Message { name: "Horse" } Message <nil> ` if s := proto.MarshalTextString(m); s != want { t.Errorf(" got: %s\nwant: %s", s, want) } }
// join attempts to join a cluster at remoteAddr using localAddr as the current // node's cluster address func (r *rpc) join(localAddr, remoteAddr string) (*JoinResult, error) { req := &internal.JoinRequest{ Addr: proto.String(localAddr), } resp, err := r.call(remoteAddr, req) if err != nil { return nil, err } switch t := resp.(type) { case *internal.JoinResponse: return &JoinResult{ RaftEnabled: t.GetEnableRaft(), RaftNodes: t.GetRaftNodes(), NodeID: t.GetNodeID(), }, nil case *internal.ErrorResponse: return nil, fmt.Errorf("rpc failed: %s", t.GetHeader().GetError()) default: return nil, fmt.Errorf("rpc failed: unknown response type: %v", t.String()) } }
func TestTextOneof(t *testing.T) { tests := []struct { m proto.Message want string }{ // zero message {&pb.Communique{}, ``}, // scalar field {&pb.Communique{Union: &pb.Communique_Number{Number: 4}}, `number:4`}, // message field {&pb.Communique{Union: &pb.Communique_Msg{ Msg: &pb.Strings{StringField: proto.String("why hello!")}, }}, `msg:<string_field:"why hello!" >`}, // bad oneof (should not panic) {&pb.Communique{Union: &pb.Communique_Msg{Msg: nil}}, `msg:/* nil */`}, } for _, test := range tests { got := strings.TrimSpace(test.m.String()) if got != test.want { t.Errorf("\n got %s\nwant %s", got, test.want) } } }
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package proto_test import ( "testing" "bosun.org/_third_party/github.com/gogo/protobuf/proto" proto3pb "bosun.org/_third_party/github.com/gogo/protobuf/proto/proto3_proto" pb "bosun.org/_third_party/github.com/gogo/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), }, RepBytes: [][]byte{[]byte("sham"), []byte("wow")},
// handleRPCConn reads a command from the connection and executes it. func (r *rpc) handleRPCConn(conn net.Conn) { defer conn.Close() // RPC connections should execute on the leader. If we are not the leader, // proxy the connection to the leader so that clients an connect to any node // in the cluster. r.traceCluster("rpc connection from: %v", conn.RemoteAddr()) if !r.store.IsLeader() { r.proxyLeader(conn.(*net.TCPConn)) return } // Read and execute request. typ, resp, err := func() (internal.RPCType, proto.Message, error) { // Read request size. var sz uint64 if err := binary.Read(conn, binary.BigEndian, &sz); err != nil { return internal.RPCType_Error, nil, fmt.Errorf("read size: %s", err) } if sz == 0 { return 0, nil, fmt.Errorf("invalid message size: %d", sz) } if sz >= MaxMessageSize { return 0, nil, fmt.Errorf("max message size of %d exceeded: %d", MaxMessageSize, sz) } // Read request. buf := make([]byte, sz) if _, err := io.ReadFull(conn, buf); err != nil { return internal.RPCType_Error, nil, fmt.Errorf("read request: %s", err) } // Determine the RPC type rpcType := internal.RPCType(btou64(buf[0:8])) buf = buf[8:] r.traceCluster("recv %v request on: %v", rpcType, conn.RemoteAddr()) switch rpcType { case internal.RPCType_FetchData: var req internal.FetchDataRequest if err := proto.Unmarshal(buf, &req); err != nil { return internal.RPCType_Error, nil, fmt.Errorf("fetch request unmarshal: %v", err) } resp, err := r.handleFetchData(&req) return rpcType, resp, err case internal.RPCType_Join: var req internal.JoinRequest if err := proto.Unmarshal(buf, &req); err != nil { return internal.RPCType_Error, nil, fmt.Errorf("join request unmarshal: %v", err) } resp, err := r.handleJoinRequest(&req) return rpcType, resp, err default: return internal.RPCType_Error, nil, fmt.Errorf("unknown rpc type:%v", rpcType) } }() // Handle unexpected RPC errors if err != nil { resp = &internal.ErrorResponse{ Header: &internal.ResponseHeader{ OK: proto.Bool(false), }, } typ = internal.RPCType_Error } // Set the status header and error message if reply, ok := resp.(Reply); ok { reply.GetHeader().OK = proto.Bool(err == nil) if err != nil { reply.GetHeader().Error = proto.String(err.Error()) } } r.sendResponse(conn, typ, resp) }
// marshal serializes to a protobuf representation. func (cqi ContinuousQueryInfo) marshal() *internal.ContinuousQueryInfo { return &internal.ContinuousQueryInfo{ Name: proto.String(cqi.Name), Query: proto.String(cqi.Query), } }
// marshal serializes to a protobuf representation. func (ni NodeInfo) marshal() *internal.NodeInfo { pb := &internal.NodeInfo{} pb.ID = proto.Uint64(ni.ID) pb.Host = proto.String(ni.Host) return pb }