Files
redis-go/aof_test.go
2021-06-15 01:03:13 +08:00

181 lines
4.7 KiB
Go

package godis
import (
"github.com/hdt3213/godis/config"
"github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/reply"
"io/ioutil"
"os"
"path"
"strconv"
"testing"
"time"
)
func TestAof(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "godis")
if err != nil {
t.Error(err)
return
}
aofFilename := path.Join(tmpDir, "a.aof")
defer func() {
_ = os.Remove(aofFilename)
}()
config.Properties = &config.ServerProperties{
AppendOnly: true,
AppendFilename: aofFilename,
}
aofWriteDB := MakeDB()
size := 10
keys := make([]string, 0)
cursor := 0
for i := 0; i < size; i++ {
key := strconv.Itoa(cursor)
cursor++
execSet(aofWriteDB, utils.ToCmdLine(key, utils.RandString(8), "EX", "10000"))
keys = append(keys, key)
}
for i := 0; i < size; i++ {
key := strconv.Itoa(cursor)
cursor++
execRPush(aofWriteDB, utils.ToCmdLine(key, utils.RandString(8)))
keys = append(keys, key)
}
for i := 0; i < size; i++ {
key := strconv.Itoa(cursor)
cursor++
execHSet(aofWriteDB, utils.ToCmdLine(key, utils.RandString(8), utils.RandString(8)))
keys = append(keys, key)
}
for i := 0; i < size; i++ {
key := strconv.Itoa(cursor)
cursor++
execSAdd(aofWriteDB, utils.ToCmdLine(key, utils.RandString(8)))
keys = append(keys, key)
}
for i := 0; i < size; i++ {
key := strconv.Itoa(cursor)
cursor++
execZAdd(aofWriteDB, utils.ToCmdLine(key, "10", utils.RandString(8)))
keys = append(keys, key)
}
aofWriteDB.Close() // wait for aof finished
aofReadDB := MakeDB() // start new db and read aof file
for _, key := range keys {
expect, ok := aofWriteDB.GetEntity(key)
if !ok {
t.Errorf("key not found in origin: %s", key)
continue
}
actual, ok := aofReadDB.GetEntity(key)
if !ok {
t.Errorf("key not found: %s", key)
continue
}
expectData := EntityToCmd(key, expect).ToBytes()
actualData := EntityToCmd(key, actual).ToBytes()
if !utils.BytesEquals(expectData, actualData) {
t.Errorf("wrong value of key: %s", key)
}
}
aofReadDB.Close()
}
func TestRewriteAOF(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "godis")
if err != nil {
t.Error(err)
return
}
aofFilename := path.Join(tmpDir, "a.aof")
defer func() {
_ = os.Remove(aofFilename)
}()
config.Properties = &config.ServerProperties{
AppendOnly: true,
AppendFilename: aofFilename,
}
aofWriteDB := MakeDB()
size := 1
keys := make([]string, 0)
ttlKeys := make([]string, 0)
cursor := 0
for i := 0; i < size; i++ {
key := "str" + strconv.Itoa(cursor)
cursor++
execSet(aofWriteDB, utils.ToCmdLine(key, utils.RandString(8)))
execSet(aofWriteDB, utils.ToCmdLine(key, utils.RandString(8)))
keys = append(keys, key)
}
// test ttl
for i := 0; i < size; i++ {
key := "str" + strconv.Itoa(cursor)
cursor++
execSet(aofWriteDB, utils.ToCmdLine(key, utils.RandString(8), "EX", "1000"))
ttlKeys = append(ttlKeys, key)
}
for i := 0; i < size; i++ {
key := "list" + strconv.Itoa(cursor)
cursor++
execRPush(aofWriteDB, utils.ToCmdLine(key, utils.RandString(8)))
execRPush(aofWriteDB, utils.ToCmdLine(key, utils.RandString(8)))
keys = append(keys, key)
}
for i := 0; i < size; i++ {
key := "hash" + strconv.Itoa(cursor)
cursor++
field := utils.RandString(8)
execHSet(aofWriteDB, utils.ToCmdLine(key, field, utils.RandString(8)))
execHSet(aofWriteDB, utils.ToCmdLine(key, field, utils.RandString(8)))
keys = append(keys, key)
}
for i := 0; i < size; i++ {
key := "set" + strconv.Itoa(cursor)
cursor++
member := utils.RandString(8)
execSAdd(aofWriteDB, utils.ToCmdLine(key, member))
execSAdd(aofWriteDB, utils.ToCmdLine(key, member))
keys = append(keys, key)
}
for i := 0; i < size; i++ {
key := "zset" + strconv.Itoa(cursor)
cursor++
execZAdd(aofWriteDB, utils.ToCmdLine(key, "10", utils.RandString(8)))
keys = append(keys, key)
}
time.Sleep(time.Second) // wait for async goroutine finish its job
aofWriteDB.aofRewrite()
aofWriteDB.Close() // wait for aof finished
aofReadDB := MakeDB() // start new db and read aof file
for _, key := range keys {
expect, ok := aofWriteDB.GetEntity(key)
if !ok {
t.Errorf("key not found in origin: %s", key)
continue
}
actual, ok := aofReadDB.GetEntity(key)
if !ok {
t.Errorf("key not found: %s", key)
continue
}
expectData := EntityToCmd(key, expect).ToBytes()
actualData := EntityToCmd(key, actual).ToBytes()
if !utils.BytesEquals(expectData, actualData) {
t.Errorf("wrong value of key: %s", key)
}
}
for _, key := range ttlKeys {
ret := execTTL(aofReadDB, utils.ToCmdLine(key))
intResult, ok := ret.(*reply.IntReply)
if !ok {
t.Errorf("expected int reply, actually %s", ret.ToBytes())
return
}
if intResult.Code <= 0 {
t.Errorf("expect a positive integer, actual: %d", intResult.Code)
}
}
aofReadDB.Close()
}