2014-06-10 06:41:50 +04:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
2014-06-19 13:19:40 +04:00
|
|
|
"github.com/siddontang/ledisdb/leveldb"
|
2014-06-10 06:41:50 +04:00
|
|
|
"os"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
func checkDataEqual(master *App, slave *App) error {
|
2014-06-19 13:19:40 +04:00
|
|
|
it := master.ldb.DataDB().RangeLimitIterator(nil, nil, leveldb.RangeClose, 0, -1)
|
2014-06-10 06:41:50 +04:00
|
|
|
for ; it.Valid(); it.Next() {
|
|
|
|
key := it.Key()
|
|
|
|
value := it.Value()
|
|
|
|
|
|
|
|
if v, err := slave.ldb.DataDB().Get(key); err != nil {
|
|
|
|
return err
|
|
|
|
} else if !bytes.Equal(v, value) {
|
|
|
|
return fmt.Errorf("replication error %d != %d", len(v), len(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestReplication(t *testing.T) {
|
|
|
|
data_dir := "/tmp/test_replication"
|
|
|
|
os.RemoveAll(data_dir)
|
|
|
|
|
|
|
|
masterCfg := new(Config)
|
|
|
|
masterCfg.DataDir = fmt.Sprintf("%s/master", data_dir)
|
|
|
|
masterCfg.Addr = "127.0.0.1:11182"
|
|
|
|
masterCfg.DB.UseBinLog = true
|
|
|
|
|
|
|
|
var master *App
|
|
|
|
var slave *App
|
|
|
|
var err error
|
|
|
|
master, err = NewApp(masterCfg)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
slaveCfg := new(Config)
|
|
|
|
slaveCfg.DataDir = fmt.Sprintf("%s/slave", data_dir)
|
|
|
|
slaveCfg.Addr = "127.0.0.1:11183"
|
|
|
|
slaveCfg.SlaveOf = masterCfg.Addr
|
|
|
|
|
|
|
|
slave, err = NewApp(slaveCfg)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
go master.Run()
|
|
|
|
|
|
|
|
db, _ := master.ldb.Select(0)
|
|
|
|
|
|
|
|
value := make([]byte, 10)
|
|
|
|
|
|
|
|
db.Set([]byte("a"), value)
|
|
|
|
db.Set([]byte("b"), value)
|
|
|
|
db.HSet([]byte("a"), []byte("1"), value)
|
|
|
|
db.HSet([]byte("b"), []byte("2"), value)
|
|
|
|
|
|
|
|
go slave.Run()
|
|
|
|
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
|
|
|
|
if err = checkDataEqual(master, slave); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
db.Set([]byte("a1"), value)
|
|
|
|
db.Set([]byte("b1"), value)
|
|
|
|
db.HSet([]byte("a1"), []byte("1"), value)
|
|
|
|
db.HSet([]byte("b1"), []byte("2"), value)
|
|
|
|
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
if err = checkDataEqual(master, slave); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
slave.slaveof("")
|
|
|
|
|
|
|
|
db.Set([]byte("a2"), value)
|
|
|
|
db.Set([]byte("b2"), value)
|
|
|
|
db.HSet([]byte("a2"), []byte("1"), value)
|
|
|
|
db.HSet([]byte("b2"), []byte("2"), value)
|
|
|
|
|
|
|
|
db.Set([]byte("a3"), value)
|
|
|
|
db.Set([]byte("b3"), value)
|
|
|
|
db.HSet([]byte("a3"), []byte("1"), value)
|
|
|
|
db.HSet([]byte("b3"), []byte("2"), value)
|
|
|
|
|
|
|
|
if err = checkDataEqual(master, slave); err == nil {
|
|
|
|
t.Fatal("must error")
|
|
|
|
}
|
|
|
|
|
|
|
|
slave.slaveof(masterCfg.Addr)
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
|
|
|
|
if err = checkDataEqual(master, slave); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|