Skip to content

Commit

Permalink
storage: add TestKeySchema_RandomKeys
Browse files Browse the repository at this point in the history
Add a randomized test that constructs random keys, writes them to a Pebble
columnar block, iterates over the block and asserts that the keys are
semantically equal to the original generated keys.

Epic: none
Release note: none
  • Loading branch information
jbowens committed Oct 21, 2024
1 parent bde82e8 commit abfe387
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 0 deletions.
23 changes: 23 additions & 0 deletions pkg/storage/engine_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,3 +489,26 @@ func engineKey(key string, ts int) EngineKey {
Version: encodeMVCCTimestamp(wallTS(ts)),
}
}

var possibleVersionLens = []int{
engineKeyNoVersion,
engineKeyVersionWallTimeLen,
engineKeyVersionWallAndLogicalTimeLen,
engineKeyVersionWallLogicalAndSyntheticTimeLen,
engineKeyVersionLockTableLen,
}

func randomSerializedEngineKey(r *rand.Rand, maxUserKeyLen int) []byte {
userKeyLen := randutil.RandIntInRange(r, 1, maxUserKeyLen)
versionLen := possibleVersionLens[r.Intn(len(possibleVersionLens))]
serializedLen := userKeyLen + versionLen + 1
if versionLen > 0 {
serializedLen++ // sentinel
}
k := randutil.RandBytes(r, serializedLen)
k[userKeyLen] = 0x00
if versionLen > 0 {
k[len(k)-1] = byte(versionLen + 1)
}
return k
}
48 changes: 48 additions & 0 deletions pkg/storage/pebble_key_schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"encoding/hex"
"fmt"
"math/rand"
"slices"
"strconv"
"strings"
"testing"
Expand All @@ -19,6 +20,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/util/hlc"
"github.com/cockroachdb/cockroach/pkg/util/leaktest"
"github.com/cockroachdb/cockroach/pkg/util/log"
"github.com/cockroachdb/cockroach/pkg/util/randutil"
"github.com/cockroachdb/cockroach/pkg/util/uuid"
"github.com/cockroachdb/crlib/crbytes"
"github.com/cockroachdb/crlib/crstrings"
Expand All @@ -28,6 +30,7 @@ import (
"github.com/cockroachdb/pebble/sstable/block"
"github.com/cockroachdb/pebble/sstable/colblk"
"github.com/olekukonko/tablewriter"
"github.com/stretchr/testify/require"
)

func TestKeySchema_KeyWriter(t *testing.T) {
Expand Down Expand Up @@ -312,3 +315,48 @@ func parseTestKey(s string) ([]byte, error) {
}), nil
}
}

func TestKeySchema_RandomKeys(t *testing.T) {
defer leaktest.AfterTest(t)()
defer log.Scope(t).Close(t)

rng, _ := randutil.NewTestRand()
maxUserKeyLen := randutil.RandIntInRange(rng, 2, 10)
keys := make([][]byte, randutil.RandIntInRange(rng, 1, 1000))
for i := range keys {
keys[i] = randomSerializedEngineKey(rng, maxUserKeyLen)
}
slices.SortFunc(keys, EngineKeyCompare)

var enc colblk.DataBlockEncoder
enc.Init(keySchema)
for i := range keys {
ikey := pebble.InternalKey{
UserKey: keys[i],
Trailer: pebble.MakeInternalKeyTrailer(0, pebble.InternalKeyKindSet),
}
enc.Add(ikey, keys[i], block.InPlaceValuePrefix(false), enc.KeyWriter.ComparePrev(keys[i]), false /* isObsolete */)
}
blk, _ := enc.Finish(len(keys), enc.Size())
blk = crbytes.CopyAligned(blk)

var dec colblk.DataBlockDecoder
dec.Init(keySchema, blk)
var it colblk.DataBlockIter
it.InitOnce(keySchema, EngineKeyCompare, EngineKeySplit, nil)
require.NoError(t, it.Init(&dec, block.NoTransforms))
for k, kv := 0, it.First(); kv != nil; k, kv = k+1, it.Next() {
require.True(t, EngineKeyEqual(keys[k], kv.K.UserKey))
require.Zero(t, EngineKeyCompare(keys[k], kv.K.UserKey))
// Note we allow the key read from the block to be physically different,
// because the above randomization generates point keys with the
// synthetic bit encoding. However the materialized key should not be
// longer than the original key, because we depend on the max key length
// during writing bounding the key length during reading.
if n := len(kv.K.UserKey); n > len(keys[k]) {
t.Fatalf("key %q is longer than original key %q", kv.K.UserKey, keys[k])
}
checkEngineKey(kv.K.UserKey)
}
require.NoError(t, it.Close())
}
22 changes: 22 additions & 0 deletions pkg/storage/testdata/key_schema_key_seeker
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,25 @@ MaterializeUserKey(-1, 3) = hex:6d6f6f0000000000b2d05e00000000010d
MaterializeUserKey(3, 2) = hex:666f6f0000000000b2d05e00000000010d
MaterializeUserKey(2, 0) = hex:6261720000000000b2d05e00000000010d
MaterializeUserKey(0, 1) = hex:6261780000000000b2d05e00000000010d

define-block
[email protected],0
[email protected],2
[email protected],1
[email protected],0
----
Parse("[email protected],0") = hex:6d6f6f0000000000b2d05e0109
Parse("[email protected],2") = hex:6d6f6f0000000000b2d05e00000000020d
Parse("[email protected],1") = hex:6d6f6f0000000000b2d05e00000000010d
Parse("[email protected],0") = hex:6d6f6f0000000000b2d05e0009

materialize-user-key
0
1
2
3
----
MaterializeUserKey(-1, 0) = hex:6d6f6f0000000000b2d05e0109
MaterializeUserKey(0, 1) = hex:6d6f6f0000000000b2d05e00000000020d
MaterializeUserKey(1, 2) = hex:6d6f6f0000000000b2d05e00000000010d
MaterializeUserKey(2, 3) = hex:6d6f6f0000000000b2d05e0009

0 comments on commit abfe387

Please sign in to comment.