func startTestApp() { f := func() { newTestLedisClient() cfg := config.NewConfigDefault() cfg.DataDir = "/tmp/testdb" os.RemoveAll(cfg.DataDir) cfg.Addr = "127.0.0.1:16380" cfg.HttpAddr = "127.0.0.1:21181" os.RemoveAll(cfg.DataDir) var err error testApp, err = NewApp(cfg) if err != nil { println(err.Error()) panic(err) } go testApp.Run() } testAppOnce.Do(f) }
func TestReplication(t *testing.T) { dir, err := ioutil.TempDir("", "rpl") if err != nil { t.Fatalf("err: %v ", err) } defer os.RemoveAll(dir) c := config.NewConfigDefault() c.Replication.Path = dir r, err := NewReplication(c) if err != nil { t.Fatal(err) } if l1, err := r.Log([]byte("hello world")); err != nil { t.Fatal(err) } else if l1.ID != 1 { t.Fatal(l1.ID) } if b, _ := r.CommitIDBehind(); !b { t.Fatal("must backward") } if err := r.UpdateCommitID(1); err != nil { t.Fatal(err) } if b, _ := r.CommitIDBehind(); b { t.Fatal("must not backward") } r.Close() }
func startTestAppAuth(password string) { f := func() { newTestLedisClientAuth() cfg := config.NewConfigDefault() cfg.DataDir = "/tmp/testdb_auth" os.RemoveAll(cfg.DataDir) cfg.Addr = "127.0.0.1:20000" cfg.HttpAddr = "127.0.0.1:20001" cfg.AuthPassword = password os.RemoveAll(cfg.DataDir) var err error testApp, err = NewApp(cfg) if err != nil { println(err.Error()) panic(err) } go testApp.Run() } testAppAuthOnce.Do(f) }
func TestScan(t *testing.T) { cfg := config.NewConfigDefault() cfg.DataDir = "/tmp/test_scan" cfg.Addr = "127.0.0.1:11185" os.RemoveAll(cfg.DataDir) s, err := NewApp(cfg) if err != nil { t.Fatal(err) } go s.Run() defer s.Close() c := goredis.NewClient(cfg.Addr, "") c.SetMaxIdleConns(1) defer c.Close() testKVScan(t, c) testHashKeyScan(t, c) testListKeyScan(t, c) testZSetKeyScan(t, c) testSetKeyScan(t, c) }
func TestSnapshot(t *testing.T) { cfg := config.NewConfigDefault() cfg.Snapshot.MaxNum = 2 cfg.Snapshot.Path = path.Join(os.TempDir(), "snapshot") defer os.RemoveAll(cfg.Snapshot.Path) d := new(testSnapshotDumper) s, err := newSnapshotStore(cfg) if err != nil { t.Fatal(err) } if f, _, err := s.Create(d); err != nil { t.Fatal(err) } else { defer f.Close() if b, _ := ioutil.ReadAll(f); string(b) != "hello world" { t.Fatal("invalid read snapshot") } if len(s.names) != 1 { t.Fatal("must 1 snapshot") } } if f, _, err := s.Create(d); err != nil { t.Fatal(err) } else { defer f.Close() if b, _ := ioutil.ReadAll(f); string(b) != "hello world" { t.Fatal("invalid read snapshot") } if len(s.names) != 2 { t.Fatal("must 2 snapshot") } } if f, _, err := s.Create(d); err != nil { t.Fatal(err) } else { defer f.Close() if b, _ := ioutil.ReadAll(f); string(b) != "hello world" { t.Fatal("invalid read snapshot") } if len(s.names) != 2 { t.Fatal("must 2 snapshot") } } fs, _ := ioutil.ReadDir(cfg.Snapshot.Path) if len(fs) != 2 { t.Fatal("must 2 snapshot") } s.Close() }
func TestDump(t *testing.T) { cfgM := config.NewConfigDefault() cfgM.DataDir = "/tmp/test_ledis_master" os.RemoveAll(cfgM.DataDir) master, err := Open(cfgM) if err != nil { t.Fatal(err) } cfgS := config.NewConfigDefault() cfgS.DataDir = "/tmp/test_ledis_slave" os.RemoveAll(cfgS.DataDir) var slave *Ledis if slave, err = Open(cfgS); err != nil { t.Fatal(err) } db, _ := master.Select(0) db.Set([]byte("a"), []byte("1")) db.Set([]byte("b"), []byte("2")) db.Set([]byte("c"), []byte("3")) if err := master.DumpFile("/tmp/testdb.dump"); err != nil { t.Fatal(err) } if _, err := slave.LoadDumpFile("/tmp/testdb.dump"); err != nil { t.Fatal(err) } it := master.ldb.RangeLimitIterator(nil, nil, store.RangeClose, 0, -1) for ; it.Valid(); it.Next() { key := it.Key() value := it.Value() if v, err := slave.ldb.Get(key); err != nil { t.Fatal(err) } else if !bytes.Equal(v, value) { t.Fatal("load dump error") } } }
// Start in-process ledis server. Data will go in the specified directory and it will bind to the given port. // Return value is a function you can call to stop the server. func StartLedis(dataDir string, bind string) (stop func(), err error) { cfg := config.NewConfigDefault() cfg.DBName = "goleveldb" cfg.Addr = bind cfg.DataDir = dataDir app, err := server.NewApp(cfg) if err != nil { log.Fatal(err) return func() {}, err } go app.Run() return app.Close, nil }
func NewGoLevelDBStore(base string, syncLog int) (*GoLevelDBStore, error) { cfg := config.NewConfigDefault() cfg.DBName = "goleveldb" cfg.DBPath = base cfg.LevelDB.BlockSize = 16 * 1024 * 1024 cfg.LevelDB.CacheSize = 64 * 1024 * 1024 cfg.LevelDB.WriteBufferSize = 64 * 1024 * 1024 cfg.LevelDB.Compression = false cfg.DBSyncCommit = syncLog s := new(GoLevelDBStore) s.cfg = cfg if err := s.open(); err != nil { return nil, err } return s, nil }
func TestFileStore(t *testing.T) { // Create a test dir dir, err := ioutil.TempDir("", "ldb") if err != nil { t.Fatalf("err: %v ", err) } defer os.RemoveAll(dir) // New level cfg := config.NewConfigDefault() cfg.Replication.MaxLogFileSize = 4096 l, err := NewFileStore(dir, cfg) if err != nil { t.Fatalf("err: %v ", err) } defer l.Close() testLogs(t, l) }
func getTestDB() *DB { f := func() { cfg := config.NewConfigDefault() cfg.DataDir = "/tmp/test_ledis" cfg.Databases = 10240 os.RemoveAll(cfg.DataDir) var err error testLedis, err = Open(cfg) if err != nil { println(err.Error()) panic(err) } } testLedisOnce.Do(f) db, _ := testLedis.Select(0) return db }
func TestStore(t *testing.T) { cfg := config.NewConfigDefault() cfg.DataDir = "/tmp/testdb" cfg.LMDB.MapSize = 10 * 1024 * 1024 ns := driver.ListStores() for _, s := range ns { cfg.DBName = s os.RemoveAll(getStorePath(cfg)) db, err := Open(cfg) if err != nil { t.Fatal(err) } testStore(db, t) testClear(db, t) testTx(db, t) db.Close() } }
func TestMigrate(t *testing.T) { data_dir := "/tmp/test_migrate" os.RemoveAll(data_dir) s1Cfg := config.NewConfigDefault() s1Cfg.DataDir = fmt.Sprintf("%s/s1", data_dir) s1Cfg.Addr = "127.0.0.1:11185" s2Cfg := config.NewConfigDefault() s2Cfg.DataDir = fmt.Sprintf("%s/s2", data_dir) s2Cfg.Addr = "127.0.0.1:11186" s1, err := NewApp(s1Cfg) if err != nil { t.Fatal(err) } defer s1.Close() s2, err := NewApp(s2Cfg) if err != nil { t.Fatal(err) } defer s2.Close() go s1.Run() go s2.Run() time.Sleep(1 * time.Second) c1, _ := goredis.Connect(s1Cfg.Addr) defer c1.Close() c2, _ := goredis.Connect(s2Cfg.Addr) defer c2.Close() if _, err = c1.Do("set", "a", "1"); err != nil { t.Fatal(err) } timeout := 30000 if _, err = c1.Do("xmigrate", "127.0.0.1", 11186, "KV", "a", 0, timeout); err != nil { t.Fatal(err) } if s, err := goredis.String(c2.Do("get", "a")); err != nil { t.Fatal(err) } else if s != "1" { t.Fatal(s, "must 1") } if s, err := goredis.String(c1.Do("get", "a")); err != nil && err != goredis.ErrNil { t.Fatal(err) } else if s != "" { t.Fatal(s, "must empty") } if num, err := goredis.Int(c2.Do("xmigratedb", "127.0.0.1", 11185, "KV", 10, 0, timeout)); err != nil { t.Fatal(err) } else if num != 1 { t.Fatal(num, "must number 1") } if s, err := goredis.String(c1.Do("get", "a")); err != nil { t.Fatal(err) } else if s != "1" { t.Fatal(s, "must 1") } if s, err := goredis.String(c2.Do("get", "a")); err != nil && err != goredis.ErrNil { t.Fatal(err) } else if s != "" { t.Fatal(s, "must empty") } if _, err = c1.Do("xmigrate", "127.0.0.1", 11186, "ALL", "a", 0, timeout); err != nil { t.Fatal(err) } if s, err := goredis.String(c2.Do("get", "a")); err != nil { t.Fatal(err) } else if s != "1" { t.Fatal(s, "must 1") } if s, err := goredis.String(c1.Do("get", "a")); err != nil && err != goredis.ErrNil { t.Fatal(err) } else if s != "" { t.Fatal(s, "must empty") } }
func TestReplication(t *testing.T) { data_dir := "/tmp/test_replication" os.RemoveAll(data_dir) masterCfg := config.NewConfigDefault() masterCfg.DataDir = fmt.Sprintf("%s/master", data_dir) masterCfg.Addr = "127.0.0.1:11182" masterCfg.UseReplication = true masterCfg.Replication.Sync = true masterCfg.Replication.WaitSyncTime = 5000 var master *App var slave *App var err error master, err = NewApp(masterCfg) if err != nil { t.Fatal(err) } defer master.Close() slaveCfg := config.NewConfigDefault() slaveCfg.DataDir = fmt.Sprintf("%s/slave", data_dir) slaveCfg.Addr = "127.0.0.1:11183" slaveCfg.SlaveOf = masterCfg.Addr slaveCfg.UseReplication = true slave, err = NewApp(slaveCfg) if err != nil { t.Fatal(err) } defer slave.Close() go master.Run() time.Sleep(1 * time.Second) go slave.Run() db, _ := master.ldb.Select(0) value := make([]byte, 10) db.Set([]byte("a"), value) db.Set([]byte("b"), value) db.Set([]byte("c"), value) db.Set([]byte("d"), value) 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.Set([]byte("c1"), value) db.Set([]byte("d1"), value) //time.Sleep(1 * time.Second) slave.ldb.WaitReplication() if err = checkDataEqual(master, slave); err != nil { t.Fatal(err) } slave.slaveof("", false, false) db.Set([]byte("a2"), value) db.Set([]byte("b2"), value) db.Set([]byte("c2"), value) db.Set([]byte("d2"), value) db.Set([]byte("a3"), value) db.Set([]byte("b3"), value) db.Set([]byte("c3"), value) db.Set([]byte("d3"), value) if err = checkDataEqual(master, slave); err == nil { t.Fatal("must error") } slave.slaveof(masterCfg.Addr, false, false) time.Sleep(1 * time.Second) if err = checkDataEqual(master, slave); err != nil { t.Fatal(err) } mStat, _ := master.ldb.ReplicationStat() sStat, _ := slave.ldb.ReplicationStat() if err = checkTestRole(masterCfg.Addr, []interface{}{ []byte("master"), int64(mStat.LastID), []interface{}{ []interface{}{ []byte("127.0.0.1"), []byte("11183"), []byte(fmt.Sprintf("%d", sStat.LastID)), }}, }); err != nil { t.Fatal(err) } if err = checkTestRole(slaveCfg.Addr, []interface{}{ []byte("slave"), []byte("127.0.0.1"), int64(11182), []byte("connected"), int64(sStat.LastID), }); err != nil { t.Fatal(err) } slave.tryReSlaveof() time.Sleep(1 * time.Second) slave.ldb.WaitReplication() if err = checkDataEqual(master, slave); err != nil { t.Fatal(err) } }
func TestMigrate(t *testing.T) { cfg1 := config.NewConfigDefault() cfg1.DataDir = "/tmp/test_ledisdb_migrate1" os.RemoveAll(cfg1.DataDir) defer os.RemoveAll(cfg1.DataDir) l1, _ := Open(cfg1) defer l1.Close() cfg2 := config.NewConfigDefault() cfg2.DataDir = "/tmp/test_ledisdb_migrate2" os.RemoveAll(cfg2.DataDir) defer os.RemoveAll(cfg2.DataDir) l2, _ := Open(cfg2) defer l2.Close() db1, _ := l1.Select(0) db2, _ := l2.Select(0) key := []byte("a") lkey := []byte("a") hkey := []byte("a") skey := []byte("a") zkey := []byte("a") value := []byte("1") db1.Set(key, value) if data, err := db1.Dump(key); err != nil { t.Fatal(err) } else if err := db2.Restore(key, 0, data); err != nil { t.Fatal(err) } db1.RPush(lkey, []byte("1"), []byte("2"), []byte("3")) if data, err := db1.LDump(lkey); err != nil { t.Fatal(err) } else if err := db2.Restore(lkey, 0, data); err != nil { t.Fatal(err) } db1.SAdd(skey, []byte("1"), []byte("2"), []byte("3")) if data, err := db1.SDump(skey); err != nil { t.Fatal(err) } else if err := db2.Restore(skey, 0, data); err != nil { t.Fatal(err) } db1.HMset(hkey, FVPair{[]byte("a"), []byte("1")}, FVPair{[]byte("b"), []byte("2")}, FVPair{[]byte("c"), []byte("3")}) if data, err := db1.HDump(hkey); err != nil { t.Fatal(err) } else if err := db2.Restore(hkey, 0, data); err != nil { t.Fatal(err) } db1.ZAdd(zkey, ScorePair{1, []byte("a")}, ScorePair{2, []byte("b")}, ScorePair{3, []byte("c")}) if data, err := db1.ZDump(zkey); err != nil { t.Fatal(err) } else if err := db2.Restore(zkey, 0, data); err != nil { t.Fatal(err) } if err := checkLedisEqual(l1, l2); err != nil { t.Fatal(err) } }
func TestReplication(t *testing.T) { var master *Ledis var slave *Ledis var err error cfgM := config.NewConfigDefault() cfgM.DataDir = "/tmp/test_repl/master" cfgM.UseReplication = true cfgM.Replication.Compression = true os.RemoveAll(cfgM.DataDir) master, err = Open(cfgM) if err != nil { t.Fatal(err) } defer master.Close() cfgS := config.NewConfigDefault() cfgS.DataDir = "/tmp/test_repl/slave" cfgS.UseReplication = true cfgS.Readonly = true os.RemoveAll(cfgS.DataDir) slave, err = Open(cfgS) if err != nil { t.Fatal(err) } defer slave.Close() db, _ := master.Select(0) db.Set([]byte("a"), []byte("value")) db.Set([]byte("b"), []byte("value")) db.Set([]byte("c"), []byte("value")) db.HSet([]byte("a"), []byte("1"), []byte("value")) db.HSet([]byte("b"), []byte("2"), []byte("value")) db.HSet([]byte("c"), []byte("3"), []byte("value")) // m, _ := db.Multi() // m.Set([]byte("a1"), []byte("value")) // m.Set([]byte("b1"), []byte("value")) // m.Set([]byte("c1"), []byte("value")) // m.Close() slave.FlushAll() db.Set([]byte("a1"), []byte("value")) db.Set([]byte("b1"), []byte("value")) db.Set([]byte("c1"), []byte("value")) db.HSet([]byte("a1"), []byte("1"), []byte("value")) db.HSet([]byte("b1"), []byte("2"), []byte("value")) db.HSet([]byte("c1"), []byte("3"), []byte("value")) var buf bytes.Buffer var n int var id uint64 = 1 for { buf.Reset() n, id, err = master.ReadLogsTo(id, &buf) if err != nil { t.Fatal(err) } else if n != 0 { if err = slave.StoreLogsFromReader(&buf); err != nil { t.Fatal(err) } } else if n == 0 { break } } slave.WaitReplication() if err = checkLedisEqual(master, slave); err != nil { t.Fatal(err) } }
func TestLuaCall(t *testing.T) { cfg := config.NewConfigDefault() cfg.Addr = ":11188" cfg.DataDir = "/tmp/testscript" cfg.DBName = "memory" app, e := NewApp(cfg) if e != nil { t.Fatal(e) } go app.Run() defer app.Close() db, _ := app.ldb.Select(0) luaClient := app.script.c luaClient.db = db l := app.script.l err := app.script.l.DoString(testScript1) if err != nil { t.Fatal(err) } v := luaReplyToLedisReply(l) if vv, ok := v.([]interface{}); ok { if len(vv) != 3 { t.Fatal(len(vv)) } } else { t.Fatal(fmt.Sprintf("%v %T", v, v)) } err = app.script.l.DoString(testScript2) if err != nil { t.Fatal(err) } v = luaReplyToLedisReply(l) if vv := v.(string); vv != "PONG" { t.Fatal(fmt.Sprintf("%v %T", v, v)) } err = app.script.l.DoString(testScript3) if err != nil { t.Fatal(err) } if v, err := db.Get([]byte("1")); err != nil { t.Fatal(err) } else if string(v) != "a" { t.Fatal(string(v)) } err = app.script.l.DoString(testScript4) if err != nil { t.Fatal(err) } if luaClient.db.Index() != 2 { t.Fatal(luaClient.db.Index()) } db2, _ := app.ldb.Select(2) if v, err := db2.Get([]byte("2")); err != nil { t.Fatal(err) } else if string(v) != "b" { t.Fatal(string(v)) } luaClient.db = nil }