Skip to content

Commit

Permalink
add tests for ForEach in batch_tx_test.
Browse files Browse the repository at this point in the history
Signed-off-by: Siyuan Zhang <sizhang@google.com>
  • Loading branch information
siyuanfoundation committed Jan 4, 2024
1 parent 3f87822 commit 9600592
Showing 1 changed file with 70 additions and 18 deletions.
88 changes: 70 additions & 18 deletions server/storage/backend/batch_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,15 @@ func TestRangeAfterDeleteBucketMatch(t *testing.T) {
tx.Unlock()
tx.Commit()

checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0)
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0, [][]byte{[]byte("foo")}, [][]byte{[]byte("bar")})
checkForEachResponseMatch(t, b.BatchTx(), b.ReadTx(), schema.Test, [][]byte{[]byte("foo")}, [][]byte{[]byte("bar")})

tx.Lock()
tx.UnsafeDeleteBucket(schema.Test)
tx.Unlock()

checkForEachResponseMatch(t, b.BatchTx(), b.ReadTx(), schema.Test, nil, nil)

ksRead, _ := b.ReadTx().UnsafeRange(schema.Test, []byte("foo"), nil, 0)
if len(ksRead) > 0 {
t.Errorf("want no keys from ReadTx, got %v", ksRead)
Expand All @@ -244,12 +247,14 @@ func TestRangeAfterDeleteMatch(t *testing.T) {
tx.Unlock()
tx.Commit()

checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0)
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0, [][]byte{[]byte("foo")}, [][]byte{[]byte("bar")})
checkForEachResponseMatch(t, b.BatchTx(), b.ReadTx(), schema.Test, [][]byte{[]byte("foo")}, [][]byte{[]byte("bar")})

tx.Lock()
tx.UnsafeDelete(schema.Test, []byte("foo"))
tx.Unlock()
checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0)
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0, nil, nil)
checkForEachResponseMatch(t, b.BatchTx(), b.ReadTx(), schema.Test, nil, nil)
}

func TestRangeAfterOverwriteMatch(t *testing.T) {
Expand All @@ -264,7 +269,8 @@ func TestRangeAfterOverwriteMatch(t *testing.T) {
tx.Unlock()
tx.Commit()

checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0)
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0, [][]byte{[]byte("foo")}, [][]byte{[]byte("bar")})
checkForEachResponseMatch(t, b.BatchTx(), b.ReadTx(), schema.Test, [][]byte{[]byte("foo")}, [][]byte{[]byte("bar")})

tx.Lock()
tx.UnsafePut(schema.Test, []byte("foo"), []byte("bar0"))
Expand All @@ -273,14 +279,16 @@ func TestRangeAfterOverwriteMatch(t *testing.T) {
tx.UnsafePut(schema.Test, []byte("foo"), []byte("bar1"))
tx.Unlock()

checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0)
checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo1"), nil, 0)
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0, [][]byte{[]byte("foo")}, [][]byte{[]byte("bar1")})
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo1"), nil, 0, [][]byte{[]byte("foo1")}, [][]byte{[]byte("bar10")})
checkForEachResponseMatch(t, b.BatchTx(), b.ReadTx(), schema.Test, [][]byte{[]byte("foo"), []byte("foo1")}, [][]byte{[]byte("bar1"), []byte("bar10")})

tx.Lock()
tx.UnsafePut(schema.Test, []byte("foo"), []byte("bar3"))
tx.Unlock()

checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), []byte("foo3"), 1)
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), []byte("foo3"), 1, [][]byte{[]byte("foo")}, [][]byte{[]byte("bar3")})
checkForEachResponseMatch(t, b.BatchTx(), b.ReadTx(), schema.Test, [][]byte{[]byte("foo"), []byte("foo1")}, [][]byte{[]byte("bar3"), []byte("bar10")})
}

func TestRangeAfterDeleteAndOverwriteMatch(t *testing.T) {
Expand All @@ -295,12 +303,14 @@ func TestRangeAfterDeleteAndOverwriteMatch(t *testing.T) {
tx.Unlock()
tx.Commit()

checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0)
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0, [][]byte{[]byte("foo")}, [][]byte{[]byte("bar")})
checkForEachResponseMatch(t, b.BatchTx(), b.ReadTx(), schema.Test, [][]byte{[]byte("foo")}, [][]byte{[]byte("bar")})

tx.Lock()
tx.UnsafeDelete(schema.Test, []byte("foo"))
tx.Unlock()
checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0)
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0, nil, nil)
checkForEachResponseMatch(t, b.BatchTx(), b.ReadTx(), schema.Test, nil, nil)

tx.Lock()
tx.UnsafePut(schema.Test, []byte("foo"), []byte("bar0"))
Expand All @@ -309,31 +319,73 @@ func TestRangeAfterDeleteAndOverwriteMatch(t *testing.T) {
tx.UnsafePut(schema.Test, []byte("foo"), []byte("bar1"))
tx.Unlock()

checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0)
checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo1"), nil, 0)
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0, [][]byte{[]byte("foo")}, [][]byte{[]byte("bar1")})
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo1"), nil, 0, [][]byte{[]byte("foo1")}, [][]byte{[]byte("bar10")})
checkForEachResponseMatch(t, b.BatchTx(), b.ReadTx(), schema.Test, [][]byte{[]byte("foo"), []byte("foo1")}, [][]byte{[]byte("bar1"), []byte("bar10")})

tx.Lock()
tx.UnsafePut(schema.Test, []byte("foo"), []byte("bar3"))
tx.Unlock()

checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0)
checkTxnResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo1"), nil, 0)
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo"), nil, 0, [][]byte{[]byte("foo")}, [][]byte{[]byte("bar3")})
checkRangeResponseMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo1"), nil, 0, [][]byte{[]byte("foo1")}, [][]byte{[]byte("bar10")})
checkForEachResponseMatch(t, b.BatchTx(), b.ReadTx(), schema.Test, [][]byte{[]byte("foo"), []byte("foo1")}, [][]byte{[]byte("bar3"), []byte("bar10")})
}

func checkTxnResponseMatch(t *testing.T, tx backend.BatchTx, rtx backend.ReadTx, key, endKey []byte, limit int64) {
func checkRangeResponseMatch(t *testing.T, tx backend.BatchTx, rtx backend.ReadTx, key, endKey []byte, limit int64, expectedKeys, expectedValues [][]byte) {
tx.Lock()
ks1, vs1 := tx.UnsafeRange(schema.Test, key, endKey, limit)
tx.Unlock()

if diff := cmp.Diff(ks1, expectedKeys); diff != "" {
t.Errorf("keys on batch transaction doesn't match expected, diff: %s", diff)
}
if diff := cmp.Diff(vs1, expectedValues); diff != "" {
t.Errorf("values on batch transaction doesn't match expected, diff: %s", diff)
}

rtx.RLock()
ks2, vs2 := rtx.UnsafeRange(schema.Test, key, endKey, limit)
rtx.RUnlock()

if diff := cmp.Diff(ks1, ks2); diff != "" {
t.Errorf("keys on read and batch transaction doesn't match, diff: %s", diff)
if diff := cmp.Diff(ks2, expectedKeys); diff != "" {
t.Errorf("keys on read transaction doesn't match expected, diff: %s", diff)
}
if diff := cmp.Diff(vs2, expectedValues); diff != "" {
t.Errorf("values on read transaction doesn't match expected, diff: %s", diff)
}
}

if diff := cmp.Diff(vs1, vs2); diff != "" {
t.Errorf("values on read and batch transaction doesn't match, diff: %s", diff)
func checkForEachResponseMatch(t *testing.T, tx backend.BatchTx, rtx backend.ReadTx, bucket backend.Bucket, expectedKeys, expectedValues [][]byte) {
var ks1, vs1, ks2, vs2 [][]byte

tx.Lock()
tx.UnsafeForEach(bucket, func(k, v []byte) error {
ks1 = append(ks1, k)
vs1 = append(vs1, v)
return nil
})
tx.Unlock()

if diff := cmp.Diff(ks1, expectedKeys); diff != "" {
t.Errorf("keys on batch transaction doesn't match expected, diff: %s", diff)
}
if diff := cmp.Diff(vs1, expectedValues); diff != "" {
t.Errorf("values on batch transaction doesn't match expected, diff: %s", diff)
}

rtx.RLock()
rtx.UnsafeForEach(bucket, func(k, v []byte) error {
ks2 = append(ks2, k)
vs2 = append(vs2, v)
return nil
})
rtx.RUnlock()

if diff := cmp.Diff(ks2, expectedKeys); diff != "" {
t.Errorf("keys on read transaction doesn't match expected, diff: %s", diff)
}
if diff := cmp.Diff(vs2, expectedValues); diff != "" {
t.Errorf("values on read transaction doesn't match expected, diff: %s", diff)
}
}

0 comments on commit 9600592

Please sign in to comment.