Skip to content

Commit

Permalink
storage: prepare TestMVCCHistories for replicated locks
Browse files Browse the repository at this point in the history
This commit prepares TestMVCCHistories for replicated locks by specifying
that the existing locks maintained by the test harness are unreplicated.

Epic: None
Release note: None
  • Loading branch information
nvanbenschoten committed Sep 14, 2023
1 parent 49573d5 commit d69608b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 35 deletions.
78 changes: 45 additions & 33 deletions pkg/storage/mvcc_history_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ var (
// txn_status t=<name> status=<txnstatus>
// txn_ignore_seqs t=<name> seqs=[<int>-<int>[,<int>-<int>...]]
//
// resolve_intent t=<name> k=<key> [status=<txnstatus>] [clockWhilePending=<int>[,<int>]] [targetBytes=<int>]
// resolve_intent_range t=<name> k=<key> end=<key> [status=<txnstatus>] [maxKeys=<int>] [targetBytes=<int>]
// check_intent k=<key> [none]
// add_lock t=<name> k=<key>
// resolve_intent t=<name> k=<key> [status=<txnstatus>] [clockWhilePending=<int>[,<int>]] [targetBytes=<int>]
// resolve_intent_range t=<name> k=<key> end=<key> [status=<txnstatus>] [maxKeys=<int>] [targetBytes=<int>]
// check_intent k=<key> [none]
// add_unreplicated_lock t=<name> k=<key>
//
// cput [t=<name>] [ts=<int>[,<int>]] [localTs=<int>[,<int>]] [resolve [status=<txnstatus>]] [ambiguousReplay] k=<key> v=<string> [raw] [cond=<string>]
// del [t=<name>] [ts=<int>[,<int>]] [localTs=<int>[,<int>]] [resolve [status=<txnstatus>]] [ambiguousReplay] k=<key>
Expand Down Expand Up @@ -349,7 +349,23 @@ func TestMVCCHistories(t *testing.T) {
}
}
}
return nil
}

// reportLockTable outputs the contents of the lock table.
reportLockTable := func(e *evalCtx, buf *redact.StringBuilder) error {
if len(e.unreplLocks) > 0 {
var ks []string
for k := range e.unreplLocks {
ks = append(ks, k)
}
sort.Strings(ks)
for _, k := range ks {
txn := e.unreplLocks[k]
buf.Printf("lock (%s): %v/%s -> %+v\n",
lock.Unreplicated, k, lock.Exclusive, txn)
}
}
return nil
}

Expand Down Expand Up @@ -470,19 +486,15 @@ func TestMVCCHistories(t *testing.T) {
}
}
if printLocks {
var ks []string
for k := range e.locks {
ks = append(ks, k)
}
sort.Strings(ks)
buf.Printf("lock-table: {")
for i, k := range ks {
if i > 0 {
buf.Printf(", ")
err = reportLockTable(e, &buf)
if err != nil {
if foundErr == nil {
// Handle the error below.
foundErr = err
} else {
buf.Printf("error reading locks: (%T:) %v\n", err, err)
}
buf.Printf("%s:%s", k, e.locks[k].ID)
}
buf.Printf("}\n")
}
}

Expand Down Expand Up @@ -720,10 +732,10 @@ var commands = map[string]cmd{
"txn_step": {typTxnUpdate, cmdTxnStep},
"txn_update": {typTxnUpdate, cmdTxnUpdate},

"resolve_intent": {typDataUpdate, cmdResolveIntent},
"resolve_intent_range": {typDataUpdate, cmdResolveIntentRange},
"check_intent": {typReadOnly, cmdCheckIntent},
"add_lock": {typLocksUpdate, cmdAddLock},
"resolve_intent": {typDataUpdate, cmdResolveIntent},
"resolve_intent_range": {typDataUpdate, cmdResolveIntentRange},
"check_intent": {typReadOnly, cmdCheckIntent},
"add_unreplicated_lock": {typLocksUpdate, cmdAddUnreplicatedLock},

"clear": {typDataUpdate, cmdClear},
"clear_range": {typDataUpdate, cmdClearRange},
Expand Down Expand Up @@ -994,10 +1006,10 @@ func cmdCheckIntent(e *evalCtx) error {
})
}

func cmdAddLock(e *evalCtx) error {
func cmdAddUnreplicatedLock(e *evalCtx) error {
txn := e.getTxn(mandatory)
key := e.getKey()
e.locks[string(key)] = txn
e.unreplLocks[string(key)] = &txn.TxnMeta
return nil
}

Expand Down Expand Up @@ -2218,7 +2230,7 @@ type evalCtx struct {
td *datadriven.TestData
txns map[string]*roachpb.Transaction
txnCounter uint32
locks map[string]*roachpb.Transaction
unreplLocks map[string]*enginepb.TxnMeta
ms *enginepb.MVCCStats
sstWriter *storage.SSTWriter
sstFile *storage.MemObject
Expand All @@ -2227,11 +2239,11 @@ type evalCtx struct {

func newEvalCtx(ctx context.Context, engine storage.Engine) *evalCtx {
return &evalCtx{
ctx: ctx,
st: cluster.MakeTestingClusterSettings(),
engine: engine,
txns: make(map[string]*roachpb.Transaction),
locks: make(map[string]*roachpb.Transaction),
ctx: ctx,
st: cluster.MakeTestingClusterSettings(),
engine: engine,
txns: make(map[string]*roachpb.Transaction),
unreplLocks: make(map[string]*enginepb.TxnMeta),
}
}

Expand Down Expand Up @@ -2526,20 +2538,20 @@ func (e *evalCtx) lookupTxn(txnName string) (*roachpb.Transaction, error) {
func (e *evalCtx) newLockTableView(
txn *roachpb.Transaction, ts hlc.Timestamp,
) storage.LockTableView {
return &mockLockTableView{locks: e.locks, txn: txn, ts: ts}
return &mockLockTableView{unreplLocks: e.unreplLocks, txn: txn, ts: ts}
}

// mockLockTableView is a mock implementation of LockTableView.
type mockLockTableView struct {
locks map[string]*roachpb.Transaction
txn *roachpb.Transaction
ts hlc.Timestamp
unreplLocks map[string]*enginepb.TxnMeta
txn *roachpb.Transaction
ts hlc.Timestamp
}

func (lt *mockLockTableView) IsKeyLockedByConflictingTxn(
k roachpb.Key, s lock.Strength,
) (bool, *enginepb.TxnMeta, error) {
holder, ok := lt.locks[string(k)]
holder, ok := lt.unreplLocks[string(k)]
if !ok {
return false, nil, nil
}
Expand All @@ -2549,7 +2561,7 @@ func (lt *mockLockTableView) IsKeyLockedByConflictingTxn(
if s == lock.None && lt.ts.Less(holder.WriteTimestamp) {
return false, nil, nil
}
return true, &holder.TxnMeta, nil
return true, holder, nil
}

func (e *evalCtx) visitWrappedIters(fn func(it storage.SimpleMVCCIterator) (done bool)) {
Expand Down
4 changes: 2 additions & 2 deletions pkg/storage/testdata/mvcc_histories/skip_locked
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ put k=k2 v=v3 ts=13,0 t=B
put k=k3 v=v4 ts=14,0 t=C
put k=k4 v=v5 ts=15,0
put k=k5 v=v6 ts=17,0
add_lock k=k4 t=E
add_unreplicated_lock k=k4 t=E
----
>> at end:
data: "k1"/11.000000000,0 -> /BYTES/v1
Expand All @@ -39,7 +39,7 @@ meta: "k3"/0,0 -> txn={id=00000003 key=/Min iso=Serializable pri=0.00000000 epo=
data: "k3"/14.000000000,0 -> /BYTES/v4
data: "k4"/15.000000000,0 -> /BYTES/v5
data: "k5"/17.000000000,0 -> /BYTES/v6
lock-table: {k4:00000005-0000-0000-0000-000000000000}
lock (Unreplicated): k4/Exclusive -> id=00000005 key=/Min iso=Serializable pri=0.00000000 epo=0 ts=16.000000000,0 min=0,0 seq=0

# Test cases:
#
Expand Down

0 comments on commit d69608b

Please sign in to comment.