func TestValidateRangeMetaKey(t *testing.T) { defer leaktest.AfterTest(t) testCases := []struct { key []byte expErr bool }{ {roachpb.RKeyMin, false}, {roachpb.RKey("\x00"), true}, {Meta1Prefix, false}, {roachpb.MakeKey(Meta1Prefix, roachpb.RKeyMax), false}, {roachpb.MakeKey(Meta2Prefix, roachpb.RKeyMax), false}, {roachpb.MakeKey(Meta2Prefix, roachpb.RKeyMax.Next()), true}, } for i, test := range testCases { err := validateRangeMetaKey(test.key) if err != nil != test.expErr { t.Errorf("%d: expected error? %t: %s", i, test.expErr, err) } } }
// TestBootstrapCluster verifies the results of bootstrapping a // cluster. Uses an in memory engine. func TestBootstrapCluster(t *testing.T) { defer leaktest.AfterTest(t) stopper := stop.NewStopper() e := engine.NewInMem(roachpb.Attributes{}, 1<<20, stopper) localDB, err := BootstrapCluster("cluster-1", []engine.Engine{e}, stopper) if err != nil { t.Fatal(err) } defer stopper.Stop() // Scan the complete contents of the local database. rows, err := localDB.Scan(keys.LocalMax, roachpb.KeyMax, 0) if err != nil { t.Fatal(err) } var foundKeys keySlice for _, kv := range rows { foundKeys = append(foundKeys, kv.Key) } var expectedKeys = keySlice{ roachpb.MakeKey(roachpb.Key("\x02"), roachpb.KeyMax), roachpb.MakeKey(roachpb.Key("\x03"), roachpb.KeyMax), roachpb.Key("\x04node-idgen"), roachpb.Key("\x04range-tree-root"), roachpb.Key("\x04store-idgen"), } // Add the initial keys for sql. for _, kv := range sql.MakeMetadataSchema().GetInitialValues() { expectedKeys = append(expectedKeys, kv.Key) } // Resort the list. The sql values are not sorted. sort.Sort(expectedKeys) if !reflect.DeepEqual(foundKeys, expectedKeys) { t.Errorf("expected keys mismatch:\n%s\n -- vs. -- \n\n%s", formatKeys(foundKeys), formatKeys(expectedKeys)) } // TODO(spencer): check values. }
func TestPrettyPrint(t *testing.T) { defer leaktest.AfterTest(t) tm, _ := time.Parse(time.UnixDate, "Sat Mar 7 11:06:39 UTC 2015") testCases := []struct { key roachpb.Key exp string }{ // local {StoreIdentKey(), "/Local/Store/storeIdent"}, {StoreGossipKey(), "/Local/Store/gossipBootstrap"}, {SequenceCacheKeyPrefix(roachpb.RangeID(1000001), []byte("test0")), `/Local/RangeID/1000001/SequenceCache/"test0"`}, {SequenceCacheKey(roachpb.RangeID(1000001), []byte("test0"), uint32(111), uint32(222)), `/Local/RangeID/1000001/SequenceCache/"test0"/epoch:111/seq:222`}, {RaftLeaderLeaseKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftLeaderLease"}, {RaftTombstoneKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftTombstone"}, {RaftHardStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftHardState"}, {RaftAppliedIndexKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftAppliedIndex"}, {RaftLogKey(roachpb.RangeID(1000001), uint64(200001)), "/Local/RangeID/1000001/RaftLog/logIndex:200001"}, {RaftTruncatedStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftTruncatedState"}, {RaftLastIndexKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftLastIndex"}, {RangeLastVerificationTimestampKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RangeLastVerificationTimestamp"}, {RangeStatsKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RangeStats"}, {MakeRangeKeyPrefix(roachpb.RKey("ok")), `/Local/Range/"ok"`}, {RangeDescriptorKey(roachpb.RKey("111")), `/Local/Range/RangeDescriptor/"111"`}, {RangeTreeNodeKey(roachpb.RKey("111")), `/Local/Range/RangeTreeNode/"111"`}, {TransactionKey(roachpb.Key("111"), []byte("22222")), `/Local/Range/Transaction/addrKey:/"111"/id:"22222"`}, {LocalMax, "/Local/Max"}, // system {roachpb.MakeKey(Meta2Prefix, roachpb.Key("foo")), `/Meta2/"foo"`}, {roachpb.MakeKey(Meta1Prefix, roachpb.Key("foo")), `/Meta1/"foo"`}, {StoreStatusKey(2222), "/System/StatusStore/2222"}, {NodeStatusKey(1111), "/System/StatusNode/1111"}, {SystemMax, "/System/Max"}, // table {UserTableDataMin, "/Table/50"}, {MakeTablePrefix(111), "/Table/111"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey("foo")), `/Table/42/"foo"`}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeFloat(nil, float64(233.221112)))), "/Table/42/233.221112"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeVarint(nil, 1222)), roachpb.RKey(encoding.EncodeString(nil, "handsome man"))), `/Table/42/1222/"handsome man"`}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeBytes(nil, []byte{1, 2, 8, 255}))), `/Table/42/"\x01\x02\b\xff"`}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeBytes(nil, []byte{1, 2, 8, 255})), roachpb.RKey("bar")), `/Table/42/"\x01\x02\b\xff"/"bar"`}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeNull(nil))), "/Table/42/NULL"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeNotNull(nil))), "/Table/42/#"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeTime(nil, tm))), "/Table/42/Sat Mar 7 11:06:39 UTC 2015"}, // others {MakeKey([]byte("")), "/Min"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey([]byte{0x20, 'a', 0x00, 0x02})), "/Table/42/<util/encoding/encoding.go:407: unknown escape>"}, } for i, test := range testCases { keyInfo := PrettyPrint(test.key) if test.exp != keyInfo { t.Fatalf("%d: expected %s, got %s", i, test.exp, keyInfo) } if test.exp != test.key.String() { t.Fatalf("%d: expected %s, got %s", i, test.exp, keyInfo) } } }
// // The resolution refers to the sample duration at which data is stored. // Cockroach supports a fixed set of named resolutions, which are stored in the // Resolution enumeration. This value is encoded as a VarInt in the key. // // Cockroach divides all data for a series into contiguous "time slots" of // uniform length based on the "key duration" of the Resolution. For each // series/source pair, there will be one key per slot. Slot 0 begins at unix // epoch; the slot for a specific timestamp is found by truncating the // timestamp to an exact multiple of the key duration, and then dividing it by // the key duration: // // slot := (timestamp / keyDuration) // integer division var ( // keyDataPrefix is the key prefix for time series data keys. keyDataPrefix = roachpb.MakeKey(keys.SystemPrefix, roachpb.Key("tsd")) ) // MakeDataKey creates a time series data key for the given series name, source, // Resolution and timestamp. The timestamp is expressed in nanoseconds since the // epoch; it will be truncated to an exact multiple of the supplied // Resolution's KeyDuration. func MakeDataKey(name string, source string, r Resolution, timestamp int64) roachpb.Key { // Normalize timestamp into a timeslot before recording. timeslot := timestamp / r.KeyDuration() k := append(roachpb.Key(nil), keyDataPrefix...) k = encoding.EncodeBytes(k, []byte(name)) k = encoding.EncodeVarint(k, int64(r)) k = encoding.EncodeVarint(k, timeslot) k = append(k, source...)
// MakeKey makes a new key which is the concatenation of the // given inputs, in order. func MakeKey(keys ...[]byte) []byte { return roachpb.MakeKey(keys...) }
func TestMetaReverseScanBounds(t *testing.T) { defer leaktest.AfterTest(t) testCases := []struct { key []byte expStart, expEnd []byte expError string }{ { key: roachpb.RKey{}, expStart: nil, expEnd: nil, expError: "KeyMin and Meta1Prefix can't be used as the key of reverse scan", }, { key: Meta1Prefix, expStart: nil, expEnd: nil, expError: "KeyMin and Meta1Prefix can't be used as the key of reverse scan", }, { key: Meta2KeyMax.Next(), expStart: nil, expEnd: nil, expError: "body of meta key range lookup is", }, { key: Meta1KeyMax.Next(), expStart: nil, expEnd: nil, expError: "body of meta key range lookup is", }, { key: roachpb.MakeKey(Meta2Prefix, roachpb.Key("foo")), expStart: Meta2Prefix, expEnd: roachpb.MakeKey(Meta2Prefix, roachpb.Key("foo\x00")), expError: "", }, { key: roachpb.MakeKey(Meta1Prefix, roachpb.Key("foo")), expStart: Meta1Prefix, expEnd: roachpb.MakeKey(Meta1Prefix, roachpb.Key("foo\x00")), expError: "", }, { key: Addr(Meta2Prefix), expStart: Meta1Prefix, expEnd: Meta2Prefix.Next(), expError: "", }, { key: Meta2KeyMax, expStart: Meta2Prefix, expEnd: Meta2KeyMax.Next(), expError: "", }, } for i, test := range testCases { resStart, resEnd, err := MetaReverseScanBounds(roachpb.RKey(test.key)) if err != nil && !testutils.IsError(err, test.expError) { t.Errorf("expected error: %s ; got %s", test.expError, err) } else if err == nil && test.expError != "" { t.Errorf("expected error: %s", test.expError) } if !resStart.Equal(test.expStart) || !resEnd.Equal(test.expEnd) { t.Errorf("%d: range bounds %q-%q don't match expected bounds %q-%q for key %q", i, resStart, resEnd, test.expStart, test.expEnd, test.key) } } }
// MakeKey makes a new key which is the concatenation of the // given inputs, in order. func MakeKey(keys ...roachpb.Key) roachpb.Key { return roachpb.MakeKey(keys...) }