
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.
192 lines
4.0 KiB
Go
192 lines
4.0 KiB
Go
package tests
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gomodule/redigo/redis"
|
|
)
|
|
|
|
const (
|
|
clear = "\x1b[0m"
|
|
bright = "\x1b[1m"
|
|
dim = "\x1b[2m"
|
|
black = "\x1b[30m"
|
|
red = "\x1b[31m"
|
|
green = "\x1b[32m"
|
|
yellow = "\x1b[33m"
|
|
blue = "\x1b[34m"
|
|
magenta = "\x1b[35m"
|
|
cyan = "\x1b[36m"
|
|
white = "\x1b[37m"
|
|
)
|
|
|
|
func TestAll(t *testing.T) {
|
|
mockCleanup(false)
|
|
defer mockCleanup(false)
|
|
|
|
ch := make(chan os.Signal, 1)
|
|
signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
|
|
go func() {
|
|
<-ch
|
|
mockCleanup(false)
|
|
os.Exit(1)
|
|
}()
|
|
|
|
mc, err := mockOpenServer(MockServerOptions{
|
|
Silent: false,
|
|
Metrics: true,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
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, "json", mc, subTestJSON)
|
|
runSubTest(t, "search", mc, subTestSearch)
|
|
runSubTest(t, "testcmd", mc, subTestTestCmd)
|
|
runSubTest(t, "client", mc, subTestClient)
|
|
runSubTest(t, "scripts", mc, subTestScripts)
|
|
runSubTest(t, "fence", mc, subTestFence)
|
|
runSubTest(t, "info", mc, subTestInfo)
|
|
runSubTest(t, "timeouts", mc, subTestTimeout)
|
|
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)) {
|
|
t.Run(name, func(t *testing.T) {
|
|
fmt.Printf(bright+"Testing %s\n"+clear, name)
|
|
test(t, mc)
|
|
})
|
|
}
|
|
|
|
func runStep(t *testing.T, mc *mockServer, name string, step func(mc *mockServer) error) {
|
|
t.Helper()
|
|
t.Run(name, func(t *testing.T) {
|
|
t.Helper()
|
|
if err := func() error {
|
|
// reset the current server
|
|
mc.ResetConn()
|
|
defer mc.ResetConn()
|
|
// clear the database so the test is consistent
|
|
if err := mc.DoBatch(
|
|
Do("OUTPUT", "resp").OK(),
|
|
Do("FLUSHDB").OK(),
|
|
); err != nil {
|
|
return err
|
|
}
|
|
if err := step(mc); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}(); err != nil {
|
|
fmt.Fprintf(os.Stderr, "["+red+"fail"+clear+"]: %s\n", name)
|
|
t.Fatal(err)
|
|
// t.Fatal(err)
|
|
}
|
|
fmt.Printf("["+green+"ok"+clear+"]: %s\n", name)
|
|
})
|
|
}
|
|
|
|
func BenchmarkAll(b *testing.B) {
|
|
mockCleanup(true)
|
|
defer mockCleanup(true)
|
|
|
|
ch := make(chan os.Signal, 1)
|
|
signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
|
|
go func() {
|
|
<-ch
|
|
mockCleanup(true)
|
|
os.Exit(1)
|
|
}()
|
|
|
|
mc, err := mockOpenServer(MockServerOptions{
|
|
Silent: true, Metrics: true,
|
|
})
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
defer mc.Close()
|
|
runSubBenchmark(b, "search", mc, subBenchSearch)
|
|
}
|
|
|
|
func loadBenchmarkPoints(b *testing.B, mc *mockServer) (err error) {
|
|
const nPoints = 200000
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
// add a bunch of points
|
|
for i := 0; i < nPoints; i++ {
|
|
val := fmt.Sprintf("val:%d", i)
|
|
var resp string
|
|
var lat, lon, fval float64
|
|
fval = rand.Float64()
|
|
lat = rand.Float64()*180 - 90
|
|
lon = rand.Float64()*360 - 180
|
|
resp, err = redis.String(mc.conn.Do("SET",
|
|
"mykey", val,
|
|
"FIELD", "foo", fval,
|
|
"POINT", lat, lon))
|
|
if err != nil {
|
|
return
|
|
}
|
|
if resp != "OK" {
|
|
err = fmt.Errorf("expected 'OK', got '%s'", resp)
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func runSubBenchmark(b *testing.B, name string, mc *mockServer, bench func(t *testing.B, mc *mockServer)) {
|
|
b.Run(name, func(b *testing.B) {
|
|
bench(b, mc)
|
|
})
|
|
}
|
|
|
|
func runBenchStep(b *testing.B, mc *mockServer, name string, step func(mc *mockServer) error) {
|
|
b.Helper()
|
|
b.Run(name, func(b *testing.B) {
|
|
b.Helper()
|
|
if err := func() error {
|
|
// reset the current server
|
|
mc.ResetConn()
|
|
defer mc.ResetConn()
|
|
// clear the database so the test is consistent
|
|
if err := mc.DoBatch([][]interface{}{
|
|
{"OUTPUT", "resp"}, {"OK"},
|
|
{"FLUSHDB"}, {"OK"},
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
err := loadBenchmarkPoints(b, mc)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
if err := step(mc); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}(); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
})
|
|
}
|