github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/internal/base/internal_test.go (about) 1 // Copyright 2012 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 package base 6 7 import ( 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 ) 12 13 func (k InternalKey) encodedString() string { 14 buf := make([]byte, k.Size()) 15 k.Encode(buf) 16 return string(buf) 17 } 18 19 func TestInternalKey(t *testing.T) { 20 k := MakeInternalKey([]byte("foo"), 0x08070605040302, 1) 21 if got, want := k.encodedString(), "foo\x01\x02\x03\x04\x05\x06\x07\x08"; got != want { 22 t.Fatalf("k = %q want %q", got, want) 23 } 24 if !k.Valid() { 25 t.Fatalf("invalid key") 26 } 27 if got, want := string(k.UserKey), "foo"; got != want { 28 t.Errorf("ukey = %q want %q", got, want) 29 } 30 if got, want := k.Kind(), InternalKeyKind(1); got != want { 31 t.Errorf("kind = %d want %d", got, want) 32 } 33 if got, want := k.SeqNum(), uint64(0x08070605040302); got != want { 34 t.Errorf("seqNum = %d want %d", got, want) 35 } 36 } 37 38 func TestInvalidInternalKey(t *testing.T) { 39 testCases := []string{ 40 "", 41 "\x01\x02\x03\x04\x05\x06\x07", 42 "foo", 43 "foo\x08\x07\x06\x05\x04\x03\x02", 44 "foo\x18\x07\x06\x05\x04\x03\x02\x01", 45 } 46 for _, tc := range testCases { 47 k := DecodeInternalKey([]byte(tc)) 48 if k.Valid() { 49 t.Errorf("%q is a valid key, want invalid", tc) 50 } 51 // Invalid key kind because the key doesn't have an 8 byte trailer. 52 if k.Kind() == InternalKeyKindInvalid && k.UserKey != nil { 53 t.Errorf("expected nil UserKey after decoding encodedKey=%q", tc) 54 } 55 } 56 } 57 58 func TestInternalKeyComparer(t *testing.T) { 59 // keys are some internal keys, in sorted order. 60 keys := []string{ 61 // The remaining test keys are all valid. 62 "" + "\x01\xff\xff\xff\xff\xff\xff\xff", 63 "" + "\x00\xff\xff\xff\xff\xff\xff\xff", 64 "" + "\x01\x01\x00\x00\x00\x00\x00\x00", 65 "" + "\x00\x01\x00\x00\x00\x00\x00\x00", 66 // Invalid internal keys have no user key, but have trailer "\xff \x00 \x00 \x00 \x00 \x00 \x00 \x00" 67 // i.e. seqNum 0 and kind 255 (InternalKeyKindInvalid). 68 "", 69 "" + "\x01\x00\x00\x00\x00\x00\x00\x00", 70 "" + "\x00\x00\x00\x00\x00\x00\x00\x00", 71 "\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", 72 "\x00blue" + "\x01\x11\x00\x00\x00\x00\x00\x00", 73 "bl\x00ue" + "\x01\x11\x00\x00\x00\x00\x00\x00", 74 "blue" + "\x01\x11\x00\x00\x00\x00\x00\x00", 75 "blue\x00" + "\x01\x11\x00\x00\x00\x00\x00\x00", 76 "green" + "\xff\x11\x00\x00\x00\x00\x00\x00", 77 "green" + "\x01\x11\x00\x00\x00\x00\x00\x00", 78 "green" + "\x01\x00\x00\x00\x00\x00\x00\x00", 79 "red" + "\x01\xff\xff\xff\xff\xff\xff\xff", 80 "red" + "\x01\x72\x73\x74\x75\x76\x77\x78", 81 "red" + "\x01\x00\x00\x00\x00\x00\x00\x11", 82 "red" + "\x01\x00\x00\x00\x00\x00\x11\x00", 83 "red" + "\x01\x00\x00\x00\x00\x11\x00\x00", 84 "red" + "\x01\x00\x00\x00\x11\x00\x00\x00", 85 "red" + "\x01\x00\x00\x11\x00\x00\x00\x00", 86 "red" + "\x01\x00\x11\x00\x00\x00\x00\x00", 87 "red" + "\x01\x11\x00\x00\x00\x00\x00\x00", 88 "red" + "\x00\x11\x00\x00\x00\x00\x00\x00", 89 "red" + "\x00\x00\x00\x00\x00\x00\x00\x00", 90 "\xfe" + "\x01\xff\xff\xff\xff\xff\xff\xff", 91 "\xfe" + "\x00\x00\x00\x00\x00\x00\x00\x00", 92 "\xff" + "\x01\xff\xff\xff\xff\xff\xff\xff", 93 "\xff" + "\x00\x00\x00\x00\x00\x00\x00\x00", 94 "\xff\x40" + "\x01\xff\xff\xff\xff\xff\xff\xff", 95 "\xff\x40" + "\x00\x00\x00\x00\x00\x00\x00\x00", 96 "\xff\xff" + "\x01\xff\xff\xff\xff\xff\xff\xff", 97 "\xff\xff" + "\x00\x00\x00\x00\x00\x00\x00\x00", 98 } 99 c := DefaultComparer.Compare 100 for i := range keys { 101 for j := range keys { 102 ik := DecodeInternalKey([]byte(keys[i])) 103 jk := DecodeInternalKey([]byte(keys[j])) 104 got := InternalCompare(c, ik, jk) 105 want := 0 106 if i < j { 107 want = -1 108 } else if i > j { 109 want = +1 110 } 111 if got != want { 112 t.Errorf("i=%d, j=%d, keys[i]=%q, keys[j]=%q: got %d, want %d", 113 i, j, keys[i], keys[j], got, want) 114 } 115 } 116 } 117 } 118 119 func TestKindsRoundtrip(t *testing.T) { 120 for kindNum, prettied := range internalKeyKindNames { 121 if prettied == "" { 122 continue 123 } 124 kind := InternalKeyKind(kindNum) 125 got := ParseKind(kind.String()) 126 require.Equal(t, got, kind) 127 } 128 } 129 130 func TestInternalKeySeparator(t *testing.T) { 131 testCases := []struct { 132 a string 133 b string 134 expected string 135 }{ 136 {"foo.SET.100", "foo.SET.99", "foo.SET.100"}, 137 {"foo.SET.100", "foo.SET.100", "foo.SET.100"}, 138 {"foo.SET.100", "foo.DEL.100", "foo.SET.100"}, 139 {"foo.SET.100", "foo.SET.101", "foo.SET.100"}, 140 {"foo.SET.100", "bar.SET.99", "foo.SET.100"}, 141 {"foo.SET.100", "hello.SET.200", "g.SEPARATOR.72057594037927935"}, 142 {"ABC1AAAAA.SET.100", "ABC2ABB.SET.200", "ABC2.SEPARATOR.72057594037927935"}, 143 {"AAA1AAA.SET.100", "AAA2AA.SET.200", "AAA2.SEPARATOR.72057594037927935"}, 144 {"AAA1AAA.SET.100", "AAA4.SET.200", "AAA2.SEPARATOR.72057594037927935"}, 145 {"AAA1AAA.SET.100", "AAA2.SET.200", "AAA1B.SEPARATOR.72057594037927935"}, 146 {"AAA1AAA.SET.100", "AAA2A.SET.200", "AAA2.SEPARATOR.72057594037927935"}, 147 {"AAA1.SET.100", "AAA2.SET.200", "AAA1.SET.100"}, 148 {"foo.SET.100", "foobar.SET.200", "foo.SET.100"}, 149 {"foobar.SET.100", "foo.SET.200", "foobar.SET.100"}, 150 {"foo.INGESTSST.100", "foo.INGESTSST.99", "foo.INGESTSST.100"}, 151 } 152 d := DefaultComparer 153 for _, c := range testCases { 154 t.Run("", func(t *testing.T) { 155 a := ParseInternalKey(c.a) 156 b := ParseInternalKey(c.b) 157 expected := ParseInternalKey(c.expected) 158 result := a.Separator(d.Compare, d.Separator, nil, b) 159 if cmp := InternalCompare(d.Compare, expected, result); cmp != 0 { 160 t.Fatalf("expected %s, but found %s", expected, result) 161 } 162 }) 163 } 164 } 165 166 func TestIsExclusiveSentinel(t *testing.T) { 167 userKey := []byte("foo") 168 testCases := []struct { 169 name string 170 key InternalKey 171 want bool 172 }{ 173 { 174 name: "rangedel; max seqnum", 175 key: MakeInternalKey(userKey, InternalKeySeqNumMax, InternalKeyKindRangeKeyDelete), 176 want: true, 177 }, 178 { 179 name: "rangedel; non-max seqnum", 180 key: MakeInternalKey(userKey, 42, InternalKeyKindRangeKeyDelete), 181 want: false, 182 }, 183 { 184 name: "rangekeyset; max seqnum", 185 key: MakeInternalKey(userKey, InternalKeySeqNumMax, InternalKeyKindRangeKeySet), 186 want: true, 187 }, 188 { 189 name: "rangekeyset; non-max seqnum", 190 key: MakeInternalKey(userKey, 42, InternalKeyKindRangeKeySet), 191 want: false, 192 }, 193 { 194 name: "rangekeyunset; max seqnum", 195 key: MakeInternalKey(userKey, InternalKeySeqNumMax, InternalKeyKindRangeKeyUnset), 196 want: true, 197 }, 198 { 199 name: "rangekeyunset; non-max seqnum", 200 key: MakeInternalKey(userKey, 42, InternalKeyKindRangeKeyUnset), 201 want: false, 202 }, 203 { 204 name: "rangekeydel; max seqnum", 205 key: MakeInternalKey(userKey, InternalKeySeqNumMax, InternalKeyKindRangeKeyDelete), 206 want: true, 207 }, 208 { 209 name: "rangekeydel; non-max seqnum", 210 key: MakeInternalKey(userKey, 42, InternalKeyKindRangeKeyDelete), 211 want: false, 212 }, 213 { 214 name: "neither rangedel nor rangekey", 215 key: MakeInternalKey(userKey, InternalKeySeqNumMax, InternalKeyKindSet), 216 want: false, 217 }, 218 } 219 220 for _, tc := range testCases { 221 t.Run(tc.name, func(t *testing.T) { 222 got := tc.key.IsExclusiveSentinel() 223 require.Equal(t, tc.want, got) 224 }) 225 } 226 }