From e83cc64ca880d8aedf7f66e7bf3c4ea7da8b3389 Mon Sep 17 00:00:00 2001 From: fanmin shi Date: Tue, 25 Jul 2017 16:23:58 -0700 Subject: [PATCH] mvcc: add TestHashKVWhenCompacting to kvstore_test --- mvcc/kvstore_test.go | 78 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/mvcc/kvstore_test.go b/mvcc/kvstore_test.go index e3970af7c7dd..3c6305f6aa08 100644 --- a/mvcc/kvstore_test.go +++ b/mvcc/kvstore_test.go @@ -22,6 +22,8 @@ import ( mrand "math/rand" "os" "reflect" + "strconv" + "sync" "testing" "time" @@ -510,6 +512,82 @@ func TestRestoreContinueUnfinishedCompaction(t *testing.T) { t.Errorf("key for rev %+v still exists, want deleted", bytesToRev(revbytes)) } +// TestHashKVWhenCompacting ensures that HashKV returns correct hash when compacting. +func TestHashKVWhenCompacting(t *testing.T) { + b, tmpPath := backend.NewDefaultTmpBackend() + s := NewStore(b, &lease.FakeLessor{}, nil) + defer os.Remove(tmpPath) + + rev := 1000 + for i := 2; i <= rev; i++ { + s.Put([]byte("foo"), []byte("bar"+strconv.Itoa(i)), lease.NoLease) + } + + hashCompactc := make(chan struct { + hash uint32 + compactRev int64 + }, 1) + + donec := make(chan struct{}) + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for { + hash, _, compactRev, err := s.HashByRev(int64(rev)) + if err != nil { + t.Fatal(err) + } + select { + case <-donec: + return + case hashCompactc <- struct { + hash uint32 + compactRev int64 + }{hash, compactRev}: + } + } + }() + } + + go func() { + defer close(donec) + revHash := make(map[int64]uint32) + for round := 0; round < 1000; round++ { + select { + case r := <-hashCompactc: + if revHash[r.compactRev] == 0 { + revHash[r.compactRev] = r.hash + break + } + if r.hash != revHash[r.compactRev] { + t.Fatalf("Hashes differ (current %v) != (saved %v)", r.hash, revHash[r.compactRev]) + } + } + } + }() + + wg.Add(1) + go func() { + defer wg.Done() + for i := 100; i >= 0; i-- { + _, err := s.Compact(int64(rev - 1 - i)) + if err != nil { + t.Fatal(err) + } + time.Sleep(10) + } + }() + + select { + case <-donec: + wg.Wait() + case <-time.After(10 * time.Second): + testutil.FatalStack(t, "timeout") + } +} + func TestTxnPut(t *testing.T) { // assign arbitrary size bytesN := 30