// updateCountString describes the update counts that were recorded by // storeEventReader. The formatting is appropriate to paste into this test if // as a new expected value. func (ser *storeEventReader) updateCountString() string { var buffer bytes.Buffer w := tabwriter.NewWriter(&buffer, 2, 1, 2, ' ', 0) var storeIDs sort.IntSlice for storeID := range ser.perStoreUpdateCount { storeIDs = append(storeIDs, int(storeID)) } sort.Sort(storeIDs) for _, storeID := range storeIDs { if countset, ok := ser.perStoreUpdateCount[proto.StoreID(storeID)]; ok { fmt.Fprintf(w, "proto.StoreID(%d): {\n", storeID) var methodIDs sort.IntSlice for methodID := range countset { methodIDs = append(methodIDs, int(methodID)) } sort.Sort(methodIDs) for _, methodID := range methodIDs { method := proto.Method(methodID) if count, okCount := countset[method]; okCount { fmt.Fprintf(w, "\tproto.%s:\t%d,\n", method, count) } else { panic("unreachable!") } } } else { panic("unreachable!") } fmt.Fprintf(w, "},\n") } return buffer.String() }
// usesTimestampCache returns true if the request affects or is // affected by the timestamp cache. func usesTimestampCache(r proto.Request) bool { m := r.Method() if m < 0 || m >= proto.Method(len(tsCacheMethods)) { return false } return tsCacheMethods[m] }
// RegisterRPC registers the RPC endpoints. func (s *DBServer) RegisterRPC(rpcServer *rpc.Server) error { for i, reqType := range allExternalMethods { if reqType == nil { continue } method := proto.Method(i) if err := rpcServer.Register(fmt.Sprintf("Server.%s", method), s.executeCmd, reqType); err != nil { return err } } return nil }
func (m *LogEntry) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { var wire uint64 for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ wire |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) switch fieldNum { case 1: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Severity", wireType) } for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ m.Severity |= (int32(b) & 0x7F) << shift if b < 0x80 { break } } case 2: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType) } for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ m.Time |= (int64(b) & 0x7F) << shift if b < 0x80 { break } } case 3: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field ThreadID", wireType) } for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ m.ThreadID |= (int32(b) & 0x7F) << shift if b < 0x80 { break } } case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field File", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } postIndex := iNdEx + int(stringLen) if postIndex > l { return io.ErrUnexpectedEOF } m.File = string(data[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Line", wireType) } for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ m.Line |= (int32(b) & 0x7F) << shift if b < 0x80 { break } } case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Format", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } postIndex := iNdEx + int(stringLen) if postIndex > l { return io.ErrUnexpectedEOF } m.Format = string(data[iNdEx:postIndex]) iNdEx = postIndex case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Args", wireType) } var msglen int for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ msglen |= (int(b) & 0x7F) << shift if b < 0x80 { break } } postIndex := iNdEx + msglen if postIndex > l { return io.ErrUnexpectedEOF } m.Args = append(m.Args, LogEntry_Arg{}) if err := m.Args[len(m.Args)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 8: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field NodeID", wireType) } var v github_com_cockroachdb_cockroach_proto.NodeID for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ v |= (github_com_cockroachdb_cockroach_proto.NodeID(b) & 0x7F) << shift if b < 0x80 { break } } m.NodeID = &v case 9: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field StoreID", wireType) } var v github_com_cockroachdb_cockroach_proto.StoreID for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ v |= (github_com_cockroachdb_cockroach_proto.StoreID(b) & 0x7F) << shift if b < 0x80 { break } } m.StoreID = &v case 10: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field RangeID", wireType) } var v github_com_cockroachdb_cockroach_proto.RangeID for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ v |= (github_com_cockroachdb_cockroach_proto.RangeID(b) & 0x7F) << shift if b < 0x80 { break } } m.RangeID = &v case 11: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Method", wireType) } var v github_com_cockroachdb_cockroach_proto.Method for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ v |= (github_com_cockroachdb_cockroach_proto.Method(b) & 0x7F) << shift if b < 0x80 { break } } m.Method = &v case 12: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { break } } postIndex := iNdEx + byteLen if postIndex > l { return io.ErrUnexpectedEOF } m.Key = append([]byte{}, data[iNdEx:postIndex]...) iNdEx = postIndex case 13: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Stacks", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { if iNdEx >= l { return io.ErrUnexpectedEOF } b := data[iNdEx] iNdEx++ byteLen |= (int(b) & 0x7F) << shift if b < 0x80 { break } } postIndex := iNdEx + byteLen if postIndex > l { return io.ErrUnexpectedEOF } m.Stacks = append([]byte{}, data[iNdEx:postIndex]...) iNdEx = postIndex default: var sizeOfWire int for { sizeOfWire++ wire >>= 7 if wire == 0 { break } } iNdEx -= sizeOfWire skippy, err := skipLog(data[iNdEx:]) if err != nil { return err } if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...) iNdEx += skippy } } return nil }
// TestMultiStoreEventFeed verifies that events on multiple stores are properly // recieved by a single event reader. func TestMultiStoreEventFeed(t *testing.T) { defer leaktest.AfterTest(t) // Create a multiTestContext which publishes all store events to the given // feed. feed := &util.Feed{} mtc := &multiTestContext{ feed: feed, } // Start reading events from the feed before starting the stores. ser := &storeEventReader{ recordUpdateDetail: false, } readStopper := util.NewStopper() sub := feed.Subscribe() readStopper.RunWorker(func() { ser.readEvents(sub) }) mtc.Start(t, 3) defer mtc.Stop() // Replicate the default range. raftID := proto.RaftID(1) mtc.replicateRange(raftID, 0, 1, 2) // Add some data in a transaction err := mtc.db.Txn(func(txn *client.Txn) error { b := &client.Batch{} b.Put("a", "asdf") b.Put("c", "jkl;") return txn.Commit(b) }) if err != nil { t.Fatalf("error putting data to db: %s", err) } // AdminSplit in between the two ranges. if err := mtc.db.AdminSplit("b"); err != nil { t.Fatalf("error splitting initial: %s", err) } // AdminSplit an empty range at the end of the second range. if err := mtc.db.AdminSplit("z"); err != nil { t.Fatalf("error splitting second range: %s", err) } // AdminMerge the empty range back into the second range. if err := mtc.db.AdminMerge("c"); err != nil { t.Fatalf("error merging final range: %s", err) } // Add an additional put through the system and wait for all // replicas to receive it. if _, err := mtc.db.Inc("aa", 5); err != nil { t.Fatalf("error putting data to db: %s", err) } util.SucceedsWithin(t, time.Second, func() error { for _, eng := range mtc.engines { val, _, err := engine.MVCCGet(eng, proto.Key("aa"), mtc.clock.Now(), true, nil) if err != nil { return err } if a, e := mustGetInteger(val), int64(5); a != e { return util.Errorf("expected aa = %d, got %d", e, a) } } return nil }) // Close feed and wait for reader to receive all events. feed.Close() readStopper.Stop() // Compare events to expected values. expected := map[proto.StoreID][]string{ proto.StoreID(1): { "StartStore", "BeginScanRanges", "RegisterRange scan=true, rid=1, live=.*", "EndScanRanges", "SplitRange origId=1, newId=2, origKey=316, newKey=15", "SplitRange origId=2, newId=3, origKey=15, newKey=0", "MergeRange rid=2, subId=3, key=15, subKey=0", }, proto.StoreID(2): { "StartStore", "BeginScanRanges", "EndScanRanges", "RegisterRange scan=false, rid=1, live=.*", "SplitRange origId=1, newId=2, origKey=316, newKey=15", "SplitRange origId=2, newId=3, origKey=15, newKey=0", "MergeRange rid=2, subId=3, key=15, subKey=0", }, proto.StoreID(3): { "StartStore", "BeginScanRanges", "EndScanRanges", "RegisterRange scan=false, rid=1, live=.*", "SplitRange origId=1, newId=2, origKey=316, newKey=15", "SplitRange origId=2, newId=3, origKey=15, newKey=0", "MergeRange rid=2, subId=3, key=15, subKey=0", }, } if a, e := ser.perStoreFeeds, expected; !checkMatch(e, a) { t.Errorf("event feed did not match expected value. Actual values have been printed to compare with above expectation.\n") t.Logf("Event feed information:\n%s", ser.eventFeedString()) } // Expected count of update events on a per-method basis. expectedUpdateCount := map[proto.StoreID]map[proto.Method]int{ proto.StoreID(1): { proto.Method(22): 3, //InternalLeaderLease proto.Method(2): 7, //ConditionalPut proto.Method(1): 18, //Put proto.Method(7): 6, //EndTransaction proto.Method(3): 2, //Increment proto.Method(4): 2, //Delete }, proto.StoreID(2): { proto.Method(22): 2, //InternalLeaderLease proto.Method(4): 2, //Delete proto.Method(2): 6, //ConditionalPut proto.Method(1): 16, //Put proto.Method(7): 5, //EndTransaction proto.Method(3): 2, //Increment }, proto.StoreID(3): { proto.Method(1): 14, //Put proto.Method(7): 4, //EndTransaction proto.Method(3): 2, //Increment proto.Method(2): 5, //ConditionalPut proto.Method(22): 2, //InternalLeaderLease proto.Method(4): 2, //Delete }, } if a, e := ser.perStoreUpdateCount, expectedUpdateCount; !reflect.DeepEqual(a, e) { t.Errorf("update counts did not match expected value. Actual values have been printed to compare with above expectation.\n") t.Logf("Update count information:\n%s", ser.updateCountString()) } }