ledisdb/rpl/file_table_test.go

198 lines
3.3 KiB
Go
Raw Normal View History

2014-11-05 12:34:14 +03:00
package rpl
import (
2014-11-06 08:46:02 +03:00
"github.com/siddontang/go/log"
2014-11-05 17:35:43 +03:00
"io/ioutil"
"os"
2014-11-06 10:05:21 +03:00
"path"
2014-11-05 12:34:14 +03:00
"testing"
2014-11-06 08:46:02 +03:00
"time"
2014-11-05 12:34:14 +03:00
)
func TestFileTable(t *testing.T) {
useMmap = true
testFileTable(t)
useMmap = false
testFileTable(t)
useMmap = true
}
func testFileTable(t *testing.T) {
log.SetLevel(log.LevelInfo)
2014-11-06 08:46:02 +03:00
base, err := ioutil.TempDir("", "test_table")
2014-11-05 17:35:43 +03:00
if err != nil {
t.Fatal(err)
}
2014-11-06 08:46:02 +03:00
os.MkdirAll(base, 0755)
2014-11-05 17:35:43 +03:00
defer os.RemoveAll(base)
2014-11-05 12:34:14 +03:00
2014-11-06 08:46:02 +03:00
l := new(Log)
l.Compression = 0
l.Data = make([]byte, 4096)
w := newTableWriter(base, 1, 1024*1024)
defer w.Close()
for i := 0; i < 10; i++ {
l.ID = uint64(i + 1)
l.CreateTime = uint32(time.Now().Unix())
l.Data[0] = byte(i + 1)
if err := w.StoreLog(l); err != nil {
t.Fatal(err)
}
}
if w.first != 1 {
t.Fatal(w.first)
} else if w.last != 10 {
t.Fatal(w.last)
}
l.ID = 10
if err := w.StoreLog(l); err == nil {
t.Fatal("must err")
}
var ll Log
for i := 0; i < 10; i++ {
if err := w.GetLog(uint64(i+1), &ll); err != nil {
t.Fatal(err)
} else if len(ll.Data) != 4096 {
t.Fatal(len(ll.Data))
} else if ll.Data[0] != byte(i+1) {
t.Fatal(ll.Data[0])
}
}
if err := w.GetLog(12, &ll); err == nil {
t.Fatal("must nil")
}
var r *tableReader
2014-11-06 10:05:21 +03:00
name := fmtTableDataName(w.base, w.index)
2014-11-06 08:46:02 +03:00
if r, err = w.Flush(); err != nil {
t.Fatal(err)
}
for i := 10; i < 20; i++ {
l.ID = uint64(i + 1)
l.CreateTime = uint32(time.Now().Unix())
l.Data[0] = byte(i + 1)
if err := w.StoreLog(l); err != nil {
t.Fatal(err)
}
}
if w.first != 11 {
t.Fatal(w.first)
} else if w.last != 20 {
t.Fatal(w.last)
}
defer r.Close()
2014-11-06 10:25:26 +03:00
for i := 0; i < 10; i++ {
if err := r.GetLog(uint64(i+1), &ll); err != nil {
t.Fatal(err)
} else if len(ll.Data) != 4096 {
t.Fatal(len(ll.Data))
} else if ll.Data[0] != byte(i+1) {
t.Fatal(ll.Data[0])
}
}
2014-11-06 08:46:02 +03:00
if err := r.GetLog(12, &ll); err == nil {
t.Fatal("must nil")
}
r.Close()
2014-11-06 10:05:21 +03:00
if r, err = newTableReader(base, 1); err != nil {
2014-11-06 08:46:02 +03:00
t.Fatal(err)
}
defer r.Close()
for i := 0; i < 10; i++ {
if err := r.GetLog(uint64(i+1), &ll); err != nil {
t.Fatal(err)
} else if len(ll.Data) != 4096 {
t.Fatal(len(ll.Data))
} else if ll.Data[0] != byte(i+1) {
t.Fatal(ll.Data[0])
}
}
if err := r.GetLog(12, &ll); err == nil {
t.Fatal("must nil")
}
s := int64(r.data.Size())
2014-11-06 08:46:02 +03:00
r.Close()
log.SetLevel(log.LevelFatal)
2014-11-06 10:05:21 +03:00
testRepair(t, name, 1, s, 11)
testRepair(t, name, 1, s, 20)
2014-11-06 08:46:02 +03:00
if err := os.Truncate(name, s-21); err != nil {
2014-11-06 08:46:02 +03:00
t.Fatal(err)
}
if r, err := w.Flush(); err != nil {
t.Fatal(err)
} else {
r.Close()
}
2014-11-06 10:05:21 +03:00
if r, err = newTableReader(base, 2); err != nil {
2014-11-06 08:46:02 +03:00
t.Fatal(err)
}
r.Close()
2014-11-06 08:46:02 +03:00
}
2014-11-06 10:05:21 +03:00
func testRepair(t *testing.T, name string, index int64, s int64, cutSize int64) {
2014-11-06 08:46:02 +03:00
var r *tableReader
var err error
if err := os.Truncate(name, s-cutSize); err != nil {
t.Fatal(err)
}
2014-11-06 10:05:21 +03:00
if r, err = newTableReader(path.Dir(name), index); err != nil {
2014-11-06 08:46:02 +03:00
t.Fatal(err)
}
defer r.Close()
var ll Log
for i := 0; i < 10; i++ {
if err := r.GetLog(uint64(i+1), &ll); err != nil {
t.Fatal(err, i)
2014-11-06 08:46:02 +03:00
} else if len(ll.Data) != 4096 {
t.Fatal(len(ll.Data))
} else if ll.Data[0] != byte(i+1) {
t.Fatal(ll.Data[0])
}
}
if err := r.GetLog(12, &ll); err == nil {
t.Fatal("must nil")
}
if s != int64(r.data.Size()) {
t.Fatalf("repair error size %d != %d", s, r.data.Size())
2014-11-06 08:46:02 +03:00
}
2014-11-05 12:34:14 +03:00
}