Initial commit
This commit is contained in:
136
fstore/store-harness_test.go
Normal file
136
fstore/store-harness_test.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package fstore
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestStoreHarness(t *testing.T) {
|
||||
StoreTestHarness{}.Run(t)
|
||||
}
|
||||
|
||||
type StoreTestHarness struct{}
|
||||
|
||||
func (h StoreTestHarness) Run(t *testing.T) {
|
||||
val := reflect.ValueOf(h)
|
||||
typ := val.Type()
|
||||
for i := 0; i < typ.NumMethod(); i++ {
|
||||
method := typ.Method(i)
|
||||
|
||||
if !strings.HasPrefix(method.Name, "Test") {
|
||||
continue
|
||||
}
|
||||
|
||||
t.Run(method.Name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
rootDir := t.TempDir()
|
||||
|
||||
primary, err := Open(Config{
|
||||
RootDir: rootDir,
|
||||
Primary: true,
|
||||
WALSegMinCount: 1,
|
||||
WALSegMaxAgeSec: 1,
|
||||
WALSegGCAgeSec: 2,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer primary.Close()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/rep/", primary.Handle)
|
||||
testServer := httptest.NewServer(mux)
|
||||
defer testServer.Close()
|
||||
|
||||
rootDir2 := t.TempDir()
|
||||
secondary, err := Open(Config{
|
||||
RootDir: rootDir2,
|
||||
Primary: false,
|
||||
PrimaryEndpoint: testServer.URL + "/rep/",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer secondary.Close()
|
||||
|
||||
val.MethodByName(method.Name).Call([]reflect.Value{
|
||||
reflect.ValueOf(t),
|
||||
reflect.ValueOf(primary),
|
||||
reflect.ValueOf(secondary),
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (StoreTestHarness) TestBasic(t *testing.T, primary, secondary *Store) {
|
||||
stateChan := make(chan map[string]string, 1)
|
||||
go func() {
|
||||
stateChan <- primary.WriteRandomFor(4 * time.Second)
|
||||
}()
|
||||
|
||||
state := <-stateChan
|
||||
secondary.WaitForParity(primary)
|
||||
|
||||
primary.AssertState(t, state)
|
||||
secondary.AssertState(t, state)
|
||||
}
|
||||
|
||||
func (StoreTestHarness) TestWriteThenFollow(t *testing.T, primary, secondary *Store) {
|
||||
secondary.Close()
|
||||
stateChan := make(chan map[string]string, 1)
|
||||
go func() {
|
||||
stateChan <- primary.WriteRandomFor(4 * time.Second)
|
||||
}()
|
||||
|
||||
state := <-stateChan
|
||||
|
||||
var err error
|
||||
secondary, err = Open(secondary.conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
secondary.WaitForParity(primary)
|
||||
|
||||
primary.AssertState(t, state)
|
||||
secondary.AssertState(t, state)
|
||||
}
|
||||
|
||||
func (StoreTestHarness) TestCloseAndOpenFollowerConcurrently(t *testing.T, primary, secondary *Store) {
|
||||
secondary.Close()
|
||||
stateChan := make(chan map[string]string, 1)
|
||||
go func() {
|
||||
stateChan <- primary.WriteRandomFor(8 * time.Second)
|
||||
}()
|
||||
|
||||
var err error
|
||||
|
||||
for i := 0; i < 4; i++ {
|
||||
time.Sleep(time.Second)
|
||||
|
||||
secondary, err = Open(secondary.conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
|
||||
secondary.Close()
|
||||
}
|
||||
|
||||
secondary, err = Open(secondary.conf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
state := <-stateChan
|
||||
|
||||
secondary.WaitForParity(primary)
|
||||
|
||||
primary.AssertState(t, state)
|
||||
secondary.AssertState(t, state)
|
||||
}
|
||||
Reference in New Issue
Block a user