This repository has been archived on 2022-07-30. You can view files and clone it, but cannot push or open issues/pull-requests.
mdb/kvstore/wal/follower_test.go

124 lines
2.9 KiB
Go

package wal
import (
"errors"
"os"
"testing"
"time"
)
// ----------------------------------------------------------------------------
func (f *Follower) getReplay(afterSeqNum uint64) (l []Record) {
f.Replay(afterSeqNum, func(rec Record) error {
l = append(l, rec)
return nil
})
return l
}
func (f *Follower) waitForSeqNum(n uint64) {
for {
maxSeqNum := f.MaxSeqNum()
//log.Printf("%d/%d", maxSeqNum, n)
if maxSeqNum == n {
return
}
time.Sleep(100 * time.Millisecond)
}
}
// ----------------------------------------------------------------------------
func TestFollower(t *testing.T) {
run := func(name string, inner func(t *testing.T, walPath string, w *Writer, f *Follower)) {
t.Run(name, func(t *testing.T) {
walPath := randPath() + ".wal"
defer os.RemoveAll(walPath)
w := newWriter(walPath, true)
defer w.Close()
f := NewFollower(walPath)
defer f.Close()
inner(t, walPath, w, f)
})
}
run("simple", func(t *testing.T, walPath string, w *Writer, f *Follower) {
w.Store("a", 1, _b("Hello"))
w.Delete("b", 1)
w.Store("a", 2, _b("World"))
w.Store("a", 1, _b("Good bye"))
expected := []Record{
{SeqNum: 1, Collection: "a", ID: 1, Store: true, Data: _b("Hello")},
{SeqNum: 2, Collection: "b", ID: 1},
{SeqNum: 3, Collection: "a", ID: 2, Store: true, Data: _b("World")},
{SeqNum: 4, Collection: "a", ID: 1, Store: true, Data: _b("Good bye")},
}
recs := f.getReplay(0)
if err := recsEqual(recs, expected); err != nil {
t.Fatal(err)
}
for i := 1; i < 4; i++ {
recs = f.getReplay(uint64(i))
if err := recsEqual(recs, expected[i:]); err != nil {
t.Fatal(err)
}
}
})
run("write async", func(t *testing.T, walPath string, w *Writer, f *Follower) {
w.storeAsync("a", 1, _b("hello1"))
w.storeAsync("a", 2, _b("hello2"))
w.deleteAsync("a", 1)
w.storeAsync("a", 3, _b("hello3"))
w.storeAsync("b", 1, _b("b1"))
f.waitForSeqNum(5)
expected := []Record{
{SeqNum: 1, Collection: "a", ID: 1, Store: true, Data: _b("hello1")},
{SeqNum: 2, Collection: "a", ID: 2, Store: true, Data: _b("hello2")},
{SeqNum: 3, Collection: "a", ID: 1, Store: false},
{SeqNum: 4, Collection: "a", ID: 3, Store: true, Data: _b("hello3")},
{SeqNum: 5, Collection: "b", ID: 1, Store: true, Data: _b("b1")},
}
recs := f.getReplay(0)
if err := recsEqual(recs, expected); err != nil {
t.Fatal(err)
}
for i := 1; i < 4; i++ {
recs = f.getReplay(uint64(i))
if err := recsEqual(recs, expected[i:]); err != nil {
t.Fatal(err)
}
}
})
run("replay error", func(t *testing.T, walPath string, w *Writer, f *Follower) {
expectedErr := errors.New("My error")
w.Store("a", 1, _b("Hello"))
w.Delete("b", 1)
w.Store("a", 2, _b("World"))
w.Store("a", 1, _b("Good bye"))
err := f.Replay(0, func(rec Record) error {
if rec.Collection == "b" {
return expectedErr
}
return nil
})
if err != expectedErr {
t.Fatal(err)
}
})
}