mirror of https://github.com/tidwall/tile38.git
wip - aof tests
This commit is contained in:
parent
13ceb7da41
commit
f2c3b3924a
|
@ -41,10 +41,7 @@ func (s *Server) loadAOF() (err error) {
|
||||||
ps := float64(count) / (float64(d) / float64(time.Second))
|
ps := float64(count) / (float64(d) / float64(time.Second))
|
||||||
suf := []string{"bytes/s", "KB/s", "MB/s", "GB/s", "TB/s"}
|
suf := []string{"bytes/s", "KB/s", "MB/s", "GB/s", "TB/s"}
|
||||||
bps := float64(fi.Size()) / (float64(d) / float64(time.Second))
|
bps := float64(fi.Size()) / (float64(d) / float64(time.Second))
|
||||||
for i := 0; bps > 1024; i++ {
|
for i := 0; bps > 1024 && len(suf) > 1; i++ {
|
||||||
if len(suf) == 1 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
bps /= 1024
|
bps /= 1024
|
||||||
suf = suf[1:]
|
suf = suf[1:]
|
||||||
}
|
}
|
||||||
|
@ -123,11 +120,7 @@ func commandErrIsFatal(err error) bool {
|
||||||
// FSET (and other writable commands) may return errors that we need
|
// FSET (and other writable commands) may return errors that we need
|
||||||
// to ignore during the loading process. These errors may occur (though unlikely)
|
// to ignore during the loading process. These errors may occur (though unlikely)
|
||||||
// due to the aof rewrite operation.
|
// due to the aof rewrite operation.
|
||||||
switch err {
|
return !(err == errKeyNotFound || err == errIDNotFound)
|
||||||
case errKeyNotFound, errIDNotFound:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// flushAOF flushes all aof buffer data to disk. Set sync to true to sync the
|
// flushAOF flushes all aof buffer data to disk. Set sync to true to sync the
|
||||||
|
|
|
@ -1,35 +1,89 @@
|
||||||
package tests
|
package tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func subTestAOF(t *testing.T, mc *mockServer) {
|
func subTestAOF(t *testing.T, mc *mockServer) {
|
||||||
runStep(t, mc, "loading", aof_loading_test)
|
runStep(t, mc, "loading", aof_loading_test)
|
||||||
|
// runStep(t, mc, "AOFMD5", aof_AOFMD5_test)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadAOFAndClose(aof any) error {
|
||||||
|
var aofb []byte
|
||||||
|
switch aof := aof.(type) {
|
||||||
|
case []byte:
|
||||||
|
aofb = []byte(aof)
|
||||||
|
case string:
|
||||||
|
aofb = []byte(aof)
|
||||||
|
default:
|
||||||
|
return errors.New("aof is not string or bytes")
|
||||||
|
}
|
||||||
|
mc, err := mockOpenServer(MockServerOptions{
|
||||||
|
Silent: true,
|
||||||
|
Metrics: false,
|
||||||
|
AOFData: aofb,
|
||||||
|
})
|
||||||
|
if mc != nil {
|
||||||
|
mc.Close()
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func aof_loading_test(mc *mockServer) error {
|
func aof_loading_test(mc *mockServer) error {
|
||||||
|
|
||||||
// aof, err := mc.readAOF()
|
var err error
|
||||||
// if err != nil {
|
// invalid command
|
||||||
// return err
|
err = loadAOFAndClose("asdfasdf\r\n")
|
||||||
// }
|
if err == nil || err.Error() != "unknown command 'asdfasdf'" {
|
||||||
|
return fmt.Errorf("expected '%v', got '%v'",
|
||||||
|
"unknown command 'asdfasdf'", err)
|
||||||
|
}
|
||||||
|
|
||||||
// aof = append(aof, "asdfasdf\r\n"...)
|
// incomplete command
|
||||||
// aof = nil
|
err = loadAOFAndClose("set fleet truck point 10 10\r\nasdfasdf")
|
||||||
// mc2, err := mockOpenServer(MockServerOptions{
|
if err != nil {
|
||||||
// Silent: false,
|
return err
|
||||||
// Metrics: false,
|
}
|
||||||
// AOFData: aof,
|
|
||||||
// })
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// defer mc2.Close()
|
|
||||||
|
|
||||||
// time.Sleep(time.Minute)
|
// big aof file
|
||||||
|
var aof string
|
||||||
|
for i := 0; i < 10000; i++ {
|
||||||
|
aof += fmt.Sprintf("SET fleet truck%d POINT 10 10\r\n", i)
|
||||||
|
}
|
||||||
|
err = loadAOFAndClose(aof)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// `
|
// extra zeros at various places
|
||||||
|
aof = ""
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
if i%10 == 0 {
|
||||||
|
aof += string(bytes.Repeat([]byte{0}, 100))
|
||||||
|
}
|
||||||
|
aof += fmt.Sprintf("SET fleet truck%d POINT 10 10\r\n", i)
|
||||||
|
}
|
||||||
|
aof += string(bytes.Repeat([]byte{0}, 5000))
|
||||||
|
err = loadAOFAndClose(aof)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// bad protocol
|
||||||
|
aof = "*2\r\n$1\r\nh\r\n+OK\r\n"
|
||||||
|
err = loadAOFAndClose(aof)
|
||||||
|
if fmt.Sprintf("%v", err) != "Protocol error: expected '$', got '+'" {
|
||||||
|
return fmt.Errorf("expected '%v', got '%v'",
|
||||||
|
"Protocol error: expected '$', got '+'", err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func aof_AOFMD5_test(mc *mockServer) error {
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
|
@ -4,11 +4,11 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gomodule/redigo/redis"
|
"github.com/gomodule/redigo/redis"
|
||||||
|
@ -39,7 +39,6 @@ type mockServer struct {
|
||||||
conn redis.Conn
|
conn redis.Conn
|
||||||
ioJSON bool
|
ioJSON bool
|
||||||
dir string
|
dir string
|
||||||
// alt *mockServer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *mockServer) readAOF() ([]byte, error) {
|
func (mc *mockServer) readAOF() ([]byte, error) {
|
||||||
|
@ -73,8 +72,10 @@ func mockOpenServer(opts MockServerOptions) (*mockServer, error) {
|
||||||
if os.Getenv("PRINTLOG") == "1" {
|
if os.Getenv("PRINTLOG") == "1" {
|
||||||
logOutput = os.Stderr
|
logOutput = os.Stderr
|
||||||
}
|
}
|
||||||
s := &mockServer{port: port}
|
s := &mockServer{port: port, dir: dir}
|
||||||
tlog.SetOutput(logOutput)
|
tlog.SetOutput(logOutput)
|
||||||
|
var ferrt int32 // atomic flag for when ferr has been set
|
||||||
|
var ferr error // ferr for when the server fails to start
|
||||||
go func() {
|
go func() {
|
||||||
sopts := server.Options{
|
sopts := server.Options{
|
||||||
Host: "localhost",
|
Host: "localhost",
|
||||||
|
@ -82,26 +83,30 @@ func mockOpenServer(opts MockServerOptions) (*mockServer, error) {
|
||||||
Dir: dir,
|
Dir: dir,
|
||||||
UseHTTP: true,
|
UseHTTP: true,
|
||||||
DevMode: true,
|
DevMode: true,
|
||||||
|
AppendOnly: true,
|
||||||
}
|
}
|
||||||
if opts.Metrics {
|
if opts.Metrics {
|
||||||
sopts.MetricsAddr = ":4321"
|
sopts.MetricsAddr = ":4321"
|
||||||
}
|
}
|
||||||
if err := server.Serve(sopts); err != nil {
|
if err := server.Serve(sopts); err != nil {
|
||||||
log.Fatal(err)
|
ferr = err
|
||||||
|
atomic.StoreInt32(&ferrt, 1)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if err := s.waitForStartup(); err != nil {
|
if err := s.waitForStartup(&ferr, &ferrt); err != nil {
|
||||||
s.Close()
|
s.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.dir = dir
|
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *mockServer) waitForStartup() error {
|
func (s *mockServer) waitForStartup(ferr *error, ferrt *int32) error {
|
||||||
var lerr error
|
var lerr error
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
for {
|
for {
|
||||||
|
if atomic.LoadInt32(ferrt) != 0 {
|
||||||
|
return *ferr
|
||||||
|
}
|
||||||
if time.Since(start) > time.Second*5 {
|
if time.Since(start) > time.Second*5 {
|
||||||
if lerr != nil {
|
if lerr != nil {
|
||||||
return lerr
|
return lerr
|
||||||
|
@ -131,6 +136,9 @@ func (mc *mockServer) Close() {
|
||||||
if mc.conn != nil {
|
if mc.conn != nil {
|
||||||
mc.conn.Close()
|
mc.conn.Close()
|
||||||
}
|
}
|
||||||
|
if mc.dir != "" {
|
||||||
|
os.RemoveAll(mc.dir)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *mockServer) ResetConn() {
|
func (mc *mockServer) ResetConn() {
|
||||||
|
|
|
@ -47,14 +47,6 @@ func TestAll(t *testing.T) {
|
||||||
}
|
}
|
||||||
defer mc.Close()
|
defer mc.Close()
|
||||||
|
|
||||||
// mc2, err := mockOpenServer(false, false)
|
|
||||||
// if err != nil {
|
|
||||||
// t.Fatal(err)
|
|
||||||
// }
|
|
||||||
// defer mc2.Close()
|
|
||||||
// mc.alt = mc2
|
|
||||||
// mc2.alt = mc
|
|
||||||
|
|
||||||
runSubTest(t, "keys", mc, subTestKeys)
|
runSubTest(t, "keys", mc, subTestKeys)
|
||||||
runSubTest(t, "json", mc, subTestJSON)
|
runSubTest(t, "json", mc, subTestJSON)
|
||||||
runSubTest(t, "search", mc, subTestSearch)
|
runSubTest(t, "search", mc, subTestSearch)
|
||||||
|
|
Loading…
Reference in New Issue