mirror of https://github.com/tidwall/tile38.git
Removed global variables from core package
The core package uses global variables that keep from having more than one Tile38 instance runnning in the same process. Move the core variables in the server.Options type which are uniquely stated per Server instance. The build variables are still present in the core package.
This commit is contained in:
parent
0301545fe6
commit
13ceb7da41
|
@ -141,12 +141,33 @@ Developer Options:
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
devMode bool
|
|
||||||
nohup bool
|
nohup bool
|
||||||
showEvioDisabled bool
|
showEvioDisabled bool
|
||||||
showThreadsDisabled bool
|
showThreadsDisabled bool
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// use to be in core/options.go
|
||||||
|
|
||||||
|
// DevMode puts application in to dev mode
|
||||||
|
devMode = false
|
||||||
|
|
||||||
|
// ShowDebugMessages allows for log.Debug to print to console.
|
||||||
|
showDebugMessages = false
|
||||||
|
|
||||||
|
// ProtectedMode forces Tile38 to default in protected mode.
|
||||||
|
protectedMode = "no"
|
||||||
|
|
||||||
|
// AppendOnly allows for disabling the appendonly file.
|
||||||
|
appendOnly = true
|
||||||
|
|
||||||
|
// AppendFileName allows for custom appendonly file path
|
||||||
|
appendFileName = ""
|
||||||
|
|
||||||
|
// QueueFileName allows for custom queue.db file path
|
||||||
|
queueFileName = ""
|
||||||
|
)
|
||||||
|
|
||||||
// parse non standard args.
|
// parse non standard args.
|
||||||
nargs := []string{os.Args[0]}
|
nargs := []string{os.Args[0]}
|
||||||
for i := 1; i < len(os.Args); i++ {
|
for i := 1; i < len(os.Args); i++ {
|
||||||
|
@ -163,10 +184,10 @@ Developer Options:
|
||||||
if i < len(os.Args) {
|
if i < len(os.Args) {
|
||||||
switch strings.ToLower(os.Args[i]) {
|
switch strings.ToLower(os.Args[i]) {
|
||||||
case "no":
|
case "no":
|
||||||
core.ProtectedMode = "no"
|
protectedMode = "no"
|
||||||
continue
|
continue
|
||||||
case "yes":
|
case "yes":
|
||||||
core.ProtectedMode = "yes"
|
protectedMode = "yes"
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,10 +204,10 @@ Developer Options:
|
||||||
if i < len(os.Args) {
|
if i < len(os.Args) {
|
||||||
switch strings.ToLower(os.Args[i]) {
|
switch strings.ToLower(os.Args[i]) {
|
||||||
case "no":
|
case "no":
|
||||||
core.AppendOnly = false
|
appendOnly = false
|
||||||
continue
|
continue
|
||||||
case "yes":
|
case "yes":
|
||||||
core.AppendOnly = true
|
appendOnly = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,14 +219,14 @@ Developer Options:
|
||||||
fmt.Fprintf(os.Stderr, "appendfilename must have a value\n")
|
fmt.Fprintf(os.Stderr, "appendfilename must have a value\n")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
core.AppendFileName = os.Args[i]
|
appendFileName = os.Args[i]
|
||||||
case "--queuefilename", "-queuefilename":
|
case "--queuefilename", "-queuefilename":
|
||||||
i++
|
i++
|
||||||
if i == len(os.Args) || os.Args[i] == "" {
|
if i == len(os.Args) || os.Args[i] == "" {
|
||||||
fmt.Fprintf(os.Stderr, "queuefilename must have a value\n")
|
fmt.Fprintf(os.Stderr, "queuefilename must have a value\n")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
core.QueueFileName = os.Args[i]
|
queueFileName = os.Args[i]
|
||||||
case "--http-transport", "-http-transport":
|
case "--http-transport", "-http-transport":
|
||||||
i++
|
i++
|
||||||
if i < len(os.Args) {
|
if i < len(os.Args) {
|
||||||
|
@ -308,8 +329,7 @@ Developer Options:
|
||||||
log.Level = 1
|
log.Level = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
core.DevMode = devMode
|
showDebugMessages = veryVerbose
|
||||||
core.ShowDebugMessages = veryVerbose
|
|
||||||
|
|
||||||
hostd := ""
|
hostd := ""
|
||||||
if host != "" {
|
if host != "" {
|
||||||
|
@ -455,6 +475,12 @@ Developer Options:
|
||||||
UseHTTP: httpTransport,
|
UseHTTP: httpTransport,
|
||||||
MetricsAddr: *metricsAddr,
|
MetricsAddr: *metricsAddr,
|
||||||
UnixSocketPath: unixSocket,
|
UnixSocketPath: unixSocket,
|
||||||
|
DevMode: devMode,
|
||||||
|
ShowDebugMessages: showDebugMessages,
|
||||||
|
ProtectedMode: protectedMode,
|
||||||
|
AppendOnly: appendOnly,
|
||||||
|
AppendFileName: appendFileName,
|
||||||
|
QueueFileName: queueFileName,
|
||||||
}
|
}
|
||||||
if err := server.Serve(opts); err != nil {
|
if err := server.Serve(opts); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
package core
|
|
||||||
|
|
||||||
// DevMode puts application in to dev mode
|
|
||||||
var DevMode = false
|
|
||||||
|
|
||||||
// ShowDebugMessages allows for log.Debug to print to console.
|
|
||||||
var ShowDebugMessages = false
|
|
||||||
|
|
||||||
// ProtectedMode forces Tile38 to default in protected mode.
|
|
||||||
var ProtectedMode = "no"
|
|
||||||
|
|
||||||
// AppendOnly allows for disabling the appendonly file.
|
|
||||||
var AppendOnly = true
|
|
||||||
|
|
||||||
// AppendFileName allows for custom appendonly file path
|
|
||||||
var AppendFileName = ""
|
|
||||||
|
|
||||||
// QueueFileName allows for custom queue.db file path
|
|
||||||
var QueueFileName = ""
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tidwall/btree"
|
"github.com/tidwall/btree"
|
||||||
"github.com/tidwall/tile38/core"
|
|
||||||
"github.com/tidwall/tile38/internal/collection"
|
"github.com/tidwall/tile38/internal/collection"
|
||||||
"github.com/tidwall/tile38/internal/field"
|
"github.com/tidwall/tile38/internal/field"
|
||||||
"github.com/tidwall/tile38/internal/log"
|
"github.com/tidwall/tile38/internal/log"
|
||||||
|
@ -42,7 +41,7 @@ func (s *Server) aofshrink() {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err := func() error {
|
err := func() error {
|
||||||
f, err := os.Create(core.AppendFileName + "-shrink")
|
f, err := os.Create(s.opts.AppendFileName + "-shrink")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -279,13 +278,13 @@ func (s *Server) aofshrink() {
|
||||||
if err := f.Close(); err != nil {
|
if err := f.Close(); err != nil {
|
||||||
log.Fatalf("shrink new aof close fatal operation: %v", err)
|
log.Fatalf("shrink new aof close fatal operation: %v", err)
|
||||||
}
|
}
|
||||||
if err := os.Rename(core.AppendFileName, core.AppendFileName+"-bak"); err != nil {
|
if err := os.Rename(s.opts.AppendFileName, s.opts.AppendFileName+"-bak"); err != nil {
|
||||||
log.Fatalf("shrink backup fatal operation: %v", err)
|
log.Fatalf("shrink backup fatal operation: %v", err)
|
||||||
}
|
}
|
||||||
if err := os.Rename(core.AppendFileName+"-shrink", core.AppendFileName); err != nil {
|
if err := os.Rename(s.opts.AppendFileName+"-shrink", s.opts.AppendFileName); err != nil {
|
||||||
log.Fatalf("shrink rename fatal operation: %v", err)
|
log.Fatalf("shrink rename fatal operation: %v", err)
|
||||||
}
|
}
|
||||||
s.aof, err = os.OpenFile(core.AppendFileName, os.O_CREATE|os.O_RDWR, 0600)
|
s.aof, err = os.OpenFile(s.opts.AppendFileName, os.O_CREATE|os.O_RDWR, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("shrink openfile fatal operation: %v", err)
|
log.Fatalf("shrink openfile fatal operation: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -296,7 +295,7 @@ func (s *Server) aofshrink() {
|
||||||
}
|
}
|
||||||
s.aofsz = int(n)
|
s.aofsz = int(n)
|
||||||
|
|
||||||
os.Remove(core.AppendFileName + "-bak") // ignore error
|
os.Remove(s.opts.AppendFileName + "-bak") // ignore error
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tidwall/resp"
|
"github.com/tidwall/resp"
|
||||||
"github.com/tidwall/tile38/core"
|
|
||||||
"github.com/tidwall/tile38/internal/log"
|
"github.com/tidwall/tile38/internal/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -140,7 +139,7 @@ func getEndOfLastValuePositionInFile(fname string, startPos int64) (int64, error
|
||||||
// We will do some various checksums on the leader until we find the correct position to start at.
|
// We will do some various checksums on the leader until we find the correct position to start at.
|
||||||
func (s *Server) followCheckSome(addr string, followc int, auth string,
|
func (s *Server) followCheckSome(addr string, followc int, auth string,
|
||||||
) (pos int64, err error) {
|
) (pos int64, err error) {
|
||||||
if core.ShowDebugMessages {
|
if s.opts.ShowDebugMessages {
|
||||||
log.Debug("follow:", addr, ":check some")
|
log.Debug("follow:", addr, ":check some")
|
||||||
}
|
}
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
|
@ -211,7 +210,7 @@ func (s *Server) followCheckSome(addr string, followc int, auth string,
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if pos == fullpos {
|
if pos == fullpos {
|
||||||
if core.ShowDebugMessages {
|
if s.opts.ShowDebugMessages {
|
||||||
log.Debug("follow: aof fully intact")
|
log.Debug("follow: aof fully intact")
|
||||||
}
|
}
|
||||||
return pos, nil
|
return pos, nil
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tidwall/resp"
|
"github.com/tidwall/resp"
|
||||||
"github.com/tidwall/tile38/core"
|
|
||||||
"github.com/tidwall/tile38/internal/log"
|
"github.com/tidwall/tile38/internal/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -240,7 +239,7 @@ func (s *Server) followStep(host string, port int, followc int) error {
|
||||||
if v.String() != "OK" {
|
if v.String() != "OK" {
|
||||||
return errors.New("invalid response to replconf request")
|
return errors.New("invalid response to replconf request")
|
||||||
}
|
}
|
||||||
if core.ShowDebugMessages {
|
if s.opts.ShowDebugMessages {
|
||||||
log.Debug("follow:", addr, ":replconf")
|
log.Debug("follow:", addr, ":replconf")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +253,7 @@ func (s *Server) followStep(host string, port int, followc int) error {
|
||||||
if v.String() != "OK" {
|
if v.String() != "OK" {
|
||||||
return errors.New("invalid response to aof live request")
|
return errors.New("invalid response to aof live request")
|
||||||
}
|
}
|
||||||
if core.ShowDebugMessages {
|
if s.opts.ShowDebugMessages {
|
||||||
log.Debug("follow:", addr, ":read aof")
|
log.Debug("follow:", addr, ":read aof")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,8 @@ type Server struct {
|
||||||
|
|
||||||
monconnsMu sync.RWMutex
|
monconnsMu sync.RWMutex
|
||||||
monconns map[net.Conn]bool // monitor connections
|
monconns map[net.Conn]bool // monitor connections
|
||||||
|
|
||||||
|
opts Options
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options for Serve()
|
// Options for Serve()
|
||||||
|
@ -145,15 +147,36 @@ type Options struct {
|
||||||
UseHTTP bool
|
UseHTTP bool
|
||||||
MetricsAddr string
|
MetricsAddr string
|
||||||
UnixSocketPath string // path for unix socket
|
UnixSocketPath string // path for unix socket
|
||||||
|
|
||||||
|
// DevMode puts application in to dev mode
|
||||||
|
DevMode bool
|
||||||
|
|
||||||
|
// ShowDebugMessages allows for log.Debug to print to console.
|
||||||
|
ShowDebugMessages bool
|
||||||
|
|
||||||
|
// ProtectedMode forces Tile38 to default in protected mode.
|
||||||
|
ProtectedMode string
|
||||||
|
|
||||||
|
// AppendOnly allows for disabling the appendonly file.
|
||||||
|
AppendOnly bool
|
||||||
|
|
||||||
|
// AppendFileName allows for custom appendonly file path
|
||||||
|
AppendFileName string
|
||||||
|
|
||||||
|
// QueueFileName allows for custom queue.db file path
|
||||||
|
QueueFileName string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve starts a new tile38 server
|
// Serve starts a new tile38 server
|
||||||
func Serve(opts Options) error {
|
func Serve(opts Options) error {
|
||||||
if core.AppendFileName == "" {
|
if opts.AppendFileName == "" {
|
||||||
core.AppendFileName = path.Join(opts.Dir, "appendonly.aof")
|
opts.AppendFileName = path.Join(opts.Dir, "appendonly.aof")
|
||||||
}
|
}
|
||||||
if core.QueueFileName == "" {
|
if opts.QueueFileName == "" {
|
||||||
core.QueueFileName = path.Join(opts.Dir, "queue.db")
|
opts.QueueFileName = path.Join(opts.Dir, "queue.db")
|
||||||
|
}
|
||||||
|
if opts.ProtectedMode == "" {
|
||||||
|
opts.ProtectedMode = "no"
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("Server started, Tile38 version %s, git %s", core.Version, core.GitSHA)
|
log.Infof("Server started, Tile38 version %s, git %s", core.Version, core.GitSHA)
|
||||||
|
@ -183,6 +206,7 @@ func Serve(opts Options) error {
|
||||||
groupHooks: btree.NewNonConcurrent(byGroupHook),
|
groupHooks: btree.NewNonConcurrent(byGroupHook),
|
||||||
groupObjects: btree.NewNonConcurrent(byGroupObject),
|
groupObjects: btree.NewNonConcurrent(byGroupObject),
|
||||||
hookExpires: btree.NewNonConcurrent(byHookExpires),
|
hookExpires: btree.NewNonConcurrent(byHookExpires),
|
||||||
|
opts: opts,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.epc = endpoint.NewManager(s)
|
s.epc = endpoint.NewManager(s)
|
||||||
|
@ -256,7 +280,7 @@ func Serve(opts Options) error {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Load the queue before the aof
|
// Load the queue before the aof
|
||||||
qdb, err := buntdb.Open(core.QueueFileName)
|
qdb, err := buntdb.Open(opts.QueueFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -284,8 +308,8 @@ func Serve(opts Options) error {
|
||||||
if err := s.migrateAOF(); err != nil {
|
if err := s.migrateAOF(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if core.AppendOnly {
|
if opts.AppendOnly {
|
||||||
f, err := os.OpenFile(core.AppendFileName, os.O_CREATE|os.O_RDWR, 0600)
|
f, err := os.OpenFile(opts.AppendFileName, os.O_CREATE|os.O_RDWR, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -334,7 +358,7 @@ func Serve(opts Options) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) isProtected() bool {
|
func (s *Server) isProtected() bool {
|
||||||
if core.ProtectedMode == "no" {
|
if s.opts.ProtectedMode == "no" {
|
||||||
// --protected-mode no
|
// --protected-mode no
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -1051,19 +1075,19 @@ func (s *Server) command(msg *Message, client *Client) (
|
||||||
case "ttl":
|
case "ttl":
|
||||||
res, err = s.cmdTTL(msg)
|
res, err = s.cmdTTL(msg)
|
||||||
case "shutdown":
|
case "shutdown":
|
||||||
if !core.DevMode {
|
if !s.opts.DevMode {
|
||||||
err = fmt.Errorf("unknown command '%s'", msg.Args[0])
|
err = fmt.Errorf("unknown command '%s'", msg.Args[0])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Fatal("shutdown requested by developer")
|
log.Fatal("shutdown requested by developer")
|
||||||
case "massinsert":
|
case "massinsert":
|
||||||
if !core.DevMode {
|
if !s.opts.DevMode {
|
||||||
err = fmt.Errorf("unknown command '%s'", msg.Args[0])
|
err = fmt.Errorf("unknown command '%s'", msg.Args[0])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res, err = s.cmdMassInsert(msg)
|
res, err = s.cmdMassInsert(msg)
|
||||||
case "sleep":
|
case "sleep":
|
||||||
if !core.DevMode {
|
if !s.opts.DevMode {
|
||||||
err = fmt.Errorf("unknown command '%s'", msg.Args[0])
|
err = fmt.Errorf("unknown command '%s'", msg.Args[0])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,7 +318,7 @@ func (s *Server) extStats(m map[string]interface{}) {
|
||||||
// Whether or not a cluster is enabled
|
// Whether or not a cluster is enabled
|
||||||
m["tile38_cluster_enabled"] = false
|
m["tile38_cluster_enabled"] = false
|
||||||
// Whether or not the Tile38 AOF is enabled
|
// Whether or not the Tile38 AOF is enabled
|
||||||
m["tile38_aof_enabled"] = core.AppendOnly
|
m["tile38_aof_enabled"] = s.opts.AppendOnly
|
||||||
// Whether or not an AOF shrink is currently in progress
|
// Whether or not an AOF shrink is currently in progress
|
||||||
m["tile38_aof_rewrite_in_progress"] = s.shrinking
|
m["tile38_aof_rewrite_in_progress"] = s.shrinking
|
||||||
// Length of time the last AOF shrink took
|
// Length of time the last AOF shrink took
|
||||||
|
@ -409,7 +409,7 @@ func boolInt(t bool) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
func (s *Server) writeInfoPersistence(w *bytes.Buffer) {
|
func (s *Server) writeInfoPersistence(w *bytes.Buffer) {
|
||||||
fmt.Fprintf(w, "aof_enabled:%d\r\n", boolInt(core.AppendOnly))
|
fmt.Fprintf(w, "aof_enabled:%d\r\n", boolInt(s.opts.AppendOnly))
|
||||||
fmt.Fprintf(w, "aof_rewrite_in_progress:%d\r\n", boolInt(s.shrinking)) // Flag indicating a AOF rewrite operation is on-going
|
fmt.Fprintf(w, "aof_rewrite_in_progress:%d\r\n", boolInt(s.shrinking)) // Flag indicating a AOF rewrite operation is on-going
|
||||||
fmt.Fprintf(w, "aof_last_rewrite_time_sec:%d\r\n", s.lastShrinkDuration.get()/int(time.Second)) // Duration of the last AOF rewrite operation in seconds
|
fmt.Fprintf(w, "aof_last_rewrite_time_sec:%d\r\n", s.lastShrinkDuration.get()/int(time.Second)) // Duration of the last AOF rewrite operation in seconds
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,12 @@ export CGO_ENABLED=0
|
||||||
|
|
||||||
cd tests
|
cd tests
|
||||||
go test -coverpkg=../internal/server -coverprofile=/tmp/coverage.out $GOTEST
|
go test -coverpkg=../internal/server -coverprofile=/tmp/coverage.out $GOTEST
|
||||||
|
|
||||||
|
|
||||||
|
# go test \
|
||||||
|
# -coverpkg=../internal/... -coverprofile=/tmp/coverage.out \
|
||||||
|
# -v . -v ../... $GOTEST
|
||||||
|
|
||||||
go tool cover -html=/tmp/coverage.out -o /tmp/coverage.html
|
go tool cover -html=/tmp/coverage.out -o /tmp/coverage.html
|
||||||
echo "details: file:///tmp/coverage.html"
|
echo "details: file:///tmp/coverage.html"
|
||||||
cd ..
|
cd ..
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func subTestAOF(t *testing.T, mc *mockServer) {
|
||||||
|
runStep(t, mc, "loading", aof_loading_test)
|
||||||
|
}
|
||||||
|
|
||||||
|
func aof_loading_test(mc *mockServer) error {
|
||||||
|
|
||||||
|
// aof, err := mc.readAOF()
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// aof = append(aof, "asdfasdf\r\n"...)
|
||||||
|
// aof = nil
|
||||||
|
// mc2, err := mockOpenServer(MockServerOptions{
|
||||||
|
// Silent: false,
|
||||||
|
// Metrics: false,
|
||||||
|
// AOFData: aof,
|
||||||
|
// })
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// defer mc2.Close()
|
||||||
|
|
||||||
|
// time.Sleep(time.Minute)
|
||||||
|
|
||||||
|
// `
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -7,12 +7,12 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gomodule/redigo/redis"
|
"github.com/gomodule/redigo/redis"
|
||||||
"github.com/tidwall/sjson"
|
"github.com/tidwall/sjson"
|
||||||
"github.com/tidwall/tile38/core"
|
|
||||||
tlog "github.com/tidwall/tile38/internal/log"
|
tlog "github.com/tidwall/tile38/internal/log"
|
||||||
"github.com/tidwall/tile38/internal/server"
|
"github.com/tidwall/tile38/internal/server"
|
||||||
)
|
)
|
||||||
|
@ -38,34 +38,55 @@ type mockServer struct {
|
||||||
port int
|
port int
|
||||||
conn redis.Conn
|
conn redis.Conn
|
||||||
ioJSON bool
|
ioJSON bool
|
||||||
|
dir string
|
||||||
// alt *mockServer
|
// alt *mockServer
|
||||||
}
|
}
|
||||||
|
|
||||||
func mockOpenServer(silent, metrics bool) (*mockServer, error) {
|
func (mc *mockServer) readAOF() ([]byte, error) {
|
||||||
|
return os.ReadFile(filepath.Join(mc.dir, "appendonly.aof"))
|
||||||
|
}
|
||||||
|
|
||||||
|
type MockServerOptions struct {
|
||||||
|
AOFData []byte
|
||||||
|
Silent bool
|
||||||
|
Metrics bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func mockOpenServer(opts MockServerOptions) (*mockServer, error) {
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
port := rand.Int()%20000 + 20000
|
port := rand.Int()%20000 + 20000
|
||||||
dir := fmt.Sprintf("data-mock-%d", port)
|
dir := fmt.Sprintf("data-mock-%d", port)
|
||||||
if !silent {
|
if !opts.Silent {
|
||||||
fmt.Printf("Starting test server at port %d\n", port)
|
fmt.Printf("Starting test server at port %d\n", port)
|
||||||
}
|
}
|
||||||
|
if len(opts.AOFData) > 0 {
|
||||||
|
if err := os.MkdirAll(dir, 0777); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err := os.WriteFile(filepath.Join(dir, "appendonly.aof"),
|
||||||
|
opts.AOFData, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
logOutput := io.Discard
|
logOutput := io.Discard
|
||||||
if os.Getenv("PRINTLOG") == "1" {
|
if os.Getenv("PRINTLOG") == "1" {
|
||||||
logOutput = os.Stderr
|
logOutput = os.Stderr
|
||||||
}
|
}
|
||||||
core.DevMode = true
|
|
||||||
s := &mockServer{port: port}
|
s := &mockServer{port: port}
|
||||||
tlog.SetOutput(logOutput)
|
tlog.SetOutput(logOutput)
|
||||||
go func() {
|
go func() {
|
||||||
opts := server.Options{
|
sopts := server.Options{
|
||||||
Host: "localhost",
|
Host: "localhost",
|
||||||
Port: port,
|
Port: port,
|
||||||
Dir: dir,
|
Dir: dir,
|
||||||
UseHTTP: true,
|
UseHTTP: true,
|
||||||
|
DevMode: true,
|
||||||
}
|
}
|
||||||
if metrics {
|
if opts.Metrics {
|
||||||
opts.MetricsAddr = ":4321"
|
sopts.MetricsAddr = ":4321"
|
||||||
}
|
}
|
||||||
if err := server.Serve(opts); err != nil {
|
if err := server.Serve(sopts); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -73,6 +94,7 @@ func mockOpenServer(silent, metrics bool) (*mockServer, error) {
|
||||||
s.Close()
|
s.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
s.dir = dir
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,10 @@ func TestAll(t *testing.T) {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
mc, err := mockOpenServer(false, true)
|
mc, err := mockOpenServer(MockServerOptions{
|
||||||
|
Silent: false,
|
||||||
|
Metrics: true,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -62,6 +65,7 @@ func TestAll(t *testing.T) {
|
||||||
runSubTest(t, "info", mc, subTestInfo)
|
runSubTest(t, "info", mc, subTestInfo)
|
||||||
runSubTest(t, "timeouts", mc, subTestTimeout)
|
runSubTest(t, "timeouts", mc, subTestTimeout)
|
||||||
runSubTest(t, "metrics", mc, subTestMetrics)
|
runSubTest(t, "metrics", mc, subTestMetrics)
|
||||||
|
runSubTest(t, "aof", mc, subTestAOF)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runSubTest(t *testing.T, name string, mc *mockServer, test func(t *testing.T, mc *mockServer)) {
|
func runSubTest(t *testing.T, name string, mc *mockServer, test func(t *testing.T, mc *mockServer)) {
|
||||||
|
@ -111,7 +115,9 @@ func BenchmarkAll(b *testing.B) {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
mc, err := mockOpenServer(true, true)
|
mc, err := mockOpenServer(MockServerOptions{
|
||||||
|
Silent: true, Metrics: true,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue