mirror of https://github.com/tidwall/tile38.git
Better INFO tests
This commit is contained in:
parent
1001de7311
commit
0301545fe6
|
@ -42,10 +42,10 @@ func (client *Client) Write(b []byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CLIENT (LIST | KILL | GETNAME | SETNAME)
|
// CLIENT (LIST | KILL | GETNAME | SETNAME)
|
||||||
func (s *Server) cmdCLIENT(_msg *Message, client *Client) (resp.Value, error) {
|
func (s *Server) cmdCLIENT(msg *Message, client *Client) (resp.Value, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
args := _msg.Args
|
args := msg.Args
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
return retrerr(errInvalidNumberOfArguments)
|
return retrerr(errInvalidNumberOfArguments)
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ func (s *Server) cmdCLIENT(_msg *Message, client *Client) (resp.Value, error) {
|
||||||
)
|
)
|
||||||
client.mu.Unlock()
|
client.mu.Unlock()
|
||||||
}
|
}
|
||||||
if _msg.OutputType == JSON {
|
if msg.OutputType == JSON {
|
||||||
// Create a map of all key/value info fields
|
// Create a map of all key/value info fields
|
||||||
var cmap []map[string]interface{}
|
var cmap []map[string]interface{}
|
||||||
clients := strings.Split(string(buf), "\n")
|
clients := strings.Split(string(buf), "\n")
|
||||||
|
@ -111,7 +111,7 @@ func (s *Server) cmdCLIENT(_msg *Message, client *Client) (resp.Value, error) {
|
||||||
client.mu.Lock()
|
client.mu.Lock()
|
||||||
name := client.name
|
name := client.name
|
||||||
client.mu.Unlock()
|
client.mu.Unlock()
|
||||||
if _msg.OutputType == JSON {
|
if msg.OutputType == JSON {
|
||||||
return resp.StringValue(`{"ok":true,"name":` + jsonString(name) +
|
return resp.StringValue(`{"ok":true,"name":` + jsonString(name) +
|
||||||
`,"elapsed":"` + time.Since(start).String() + "\"}"), nil
|
`,"elapsed":"` + time.Since(start).String() + "\"}"), nil
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ func (s *Server) cmdCLIENT(_msg *Message, client *Client) (resp.Value, error) {
|
||||||
if len(args) != 3 {
|
if len(args) != 3 {
|
||||||
return retrerr(errInvalidNumberOfArguments)
|
return retrerr(errInvalidNumberOfArguments)
|
||||||
}
|
}
|
||||||
name := _msg.Args[2]
|
name := msg.Args[2]
|
||||||
for i := 0; i < len(name); i++ {
|
for i := 0; i < len(name); i++ {
|
||||||
if name[i] < '!' || name[i] > '~' {
|
if name[i] < '!' || name[i] > '~' {
|
||||||
return retrerr(clientErrorf(
|
return retrerr(clientErrorf(
|
||||||
|
@ -131,7 +131,7 @@ func (s *Server) cmdCLIENT(_msg *Message, client *Client) (resp.Value, error) {
|
||||||
client.mu.Lock()
|
client.mu.Lock()
|
||||||
client.name = name
|
client.name = name
|
||||||
client.mu.Unlock()
|
client.mu.Unlock()
|
||||||
if _msg.OutputType == JSON {
|
if msg.OutputType == JSON {
|
||||||
return resp.StringValue(`{"ok":true,"elapsed":"` +
|
return resp.StringValue(`{"ok":true,"elapsed":"` +
|
||||||
time.Since(start).String() + "\"}"), nil
|
time.Since(start).String() + "\"}"), nil
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ func (s *Server) cmdCLIENT(_msg *Message, client *Client) (resp.Value, error) {
|
||||||
closer.Close()
|
closer.Close()
|
||||||
}
|
}
|
||||||
// }()
|
// }()
|
||||||
if _msg.OutputType == JSON {
|
if msg.OutputType == JSON {
|
||||||
return resp.StringValue(`{"ok":true,"elapsed":"` +
|
return resp.StringValue(`{"ok":true,"elapsed":"` +
|
||||||
time.Since(start).String() + "\"}"), nil
|
time.Since(start).String() + "\"}"), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1081,7 +1081,7 @@ func (s *Server) command(msg *Message, client *Client) (
|
||||||
case "healthz":
|
case "healthz":
|
||||||
res, err = s.cmdHEALTHZ(msg)
|
res, err = s.cmdHEALTHZ(msg)
|
||||||
case "info":
|
case "info":
|
||||||
res, err = s.cmdInfo(msg)
|
res, err = s.cmdINFO(msg)
|
||||||
case "scan":
|
case "scan":
|
||||||
res, err = s.cmdScan(msg)
|
res, err = s.cmdScan(msg)
|
||||||
case "nearby":
|
case "nearby":
|
||||||
|
|
|
@ -457,27 +457,52 @@ func (s *Server) writeInfoCluster(w *bytes.Buffer) {
|
||||||
fmt.Fprintf(w, "cluster_enabled:0\r\n")
|
fmt.Fprintf(w, "cluster_enabled:0\r\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) cmdInfo(msg *Message) (res resp.Value, err error) {
|
// INFO [section ...]
|
||||||
|
func (s *Server) cmdINFO(msg *Message) (res resp.Value, err error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
sections := []string{"server", "clients", "memory", "persistence", "stats", "replication", "cpu", "cluster", "keyspace"}
|
// >> Args
|
||||||
switch len(msg.Args) {
|
|
||||||
default:
|
args := msg.Args
|
||||||
return NOMessage, errInvalidNumberOfArguments
|
|
||||||
case 1:
|
msects := make(map[string]bool)
|
||||||
case 2:
|
allsects := []string{
|
||||||
section := strings.ToLower(msg.Args[1])
|
"server", "clients", "memory", "persistence", "stats",
|
||||||
|
"replication", "cpu", "cluster", "keyspace",
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) == 1 {
|
||||||
|
for _, s := range allsects {
|
||||||
|
msects[s] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 1; i < len(args); i++ {
|
||||||
|
section := strings.ToLower(args[i])
|
||||||
switch section {
|
switch section {
|
||||||
|
case "all", "default":
|
||||||
|
for _, s := range allsects {
|
||||||
|
msects[s] = true
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
sections = []string{section}
|
for _, s := range allsects {
|
||||||
case "all":
|
if s == section {
|
||||||
sections = []string{"server", "clients", "memory", "persistence", "stats", "replication", "cpu", "commandstats", "cluster", "keyspace"}
|
msects[section] = true
|
||||||
case "default":
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// >> Operation
|
||||||
|
|
||||||
|
var sects []string
|
||||||
|
for _, s := range allsects {
|
||||||
|
if msects[s] {
|
||||||
|
sects = append(sects, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w := &bytes.Buffer{}
|
w := &bytes.Buffer{}
|
||||||
for i, section := range sections {
|
for i, section := range sects {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
w.WriteString("\r\n")
|
w.WriteString("\r\n")
|
||||||
}
|
}
|
||||||
|
@ -511,8 +536,9 @@ func (s *Server) cmdInfo(msg *Message) (res resp.Value, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch msg.OutputType {
|
// >> Response
|
||||||
case JSON:
|
|
||||||
|
if msg.OutputType == JSON {
|
||||||
// Create a map of all key/value info fields
|
// Create a map of all key/value info fields
|
||||||
m := make(map[string]interface{})
|
m := make(map[string]interface{})
|
||||||
for _, kv := range strings.Split(w.String(), "\r\n") {
|
for _, kv := range strings.Split(w.String(), "\r\n") {
|
||||||
|
@ -525,15 +551,11 @@ func (s *Server) cmdInfo(msg *Message) (res resp.Value, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marshal the map and use the output in the JSON response
|
// Marshal the map and use the output in the JSON response
|
||||||
data, err := json.Marshal(m)
|
data, _ := json.Marshal(m)
|
||||||
if err != nil {
|
return resp.StringValue(`{"ok":true,"info":` + string(data) +
|
||||||
return NOMessage, err
|
`,"elapsed":"` + time.Since(start).String() + "\"}"), nil
|
||||||
}
|
|
||||||
res = resp.StringValue(`{"ok":true,"info":` + string(data) + `,"elapsed":"` + time.Since(start).String() + "\"}")
|
|
||||||
case RESP:
|
|
||||||
res = resp.BytesValue(w.Bytes())
|
|
||||||
}
|
}
|
||||||
return res, nil
|
return resp.BytesValue(w.Bytes()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// tryParseType attempts to parse the passed string as an integer, float64 and
|
// tryParseType attempts to parse the passed string as an integer, float64 and
|
||||||
|
|
|
@ -35,7 +35,7 @@ func subTestKeys(t *testing.T, mc *mockServer) {
|
||||||
runStep(t, mc, "FLUSHDB", keys_FLUSHDB_test)
|
runStep(t, mc, "FLUSHDB", keys_FLUSHDB_test)
|
||||||
runStep(t, mc, "HEALTHZ", keys_HEALTHZ_test)
|
runStep(t, mc, "HEALTHZ", keys_HEALTHZ_test)
|
||||||
runStep(t, mc, "SERVER", keys_SERVER_test)
|
runStep(t, mc, "SERVER", keys_SERVER_test)
|
||||||
|
runStep(t, mc, "INFO", keys_INFO_test)
|
||||||
}
|
}
|
||||||
|
|
||||||
func keys_BOUNDS_test(mc *mockServer) error {
|
func keys_BOUNDS_test(mc *mockServer) error {
|
||||||
|
@ -545,32 +545,9 @@ func keys_FLUSHDB_test(mc *mockServer) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func keys_HEALTHZ_test(mc *mockServer) error {
|
func keys_HEALTHZ_test(mc *mockServer) error {
|
||||||
|
|
||||||
// // follow and wait
|
|
||||||
// str, err := redis.String(mc.Do("FOLLOW", "localhost", mc.alt.port))
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// if str != "OK" {
|
|
||||||
// return errors.New("not ok")
|
|
||||||
// }
|
|
||||||
// start := time.Now()
|
|
||||||
// for time.Since(start) < time.Second*5 {
|
|
||||||
// str, err = redis.String(mc.Do("HEALTHZ"))
|
|
||||||
// if str == "OK" {
|
|
||||||
// err = nil
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// time.Sleep(time.Second / 4)
|
|
||||||
// }
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
return mc.DoBatch(
|
return mc.DoBatch(
|
||||||
Do("HEALTHZ").OK(),
|
Do("HEALTHZ").OK(),
|
||||||
Do("HEALTHZ").JSON().OK(),
|
Do("HEALTHZ").JSON().OK(),
|
||||||
// Do("FOLLOW", "no", "one").OK(),
|
|
||||||
Do("HEALTHZ", "arg").Err(`wrong number of arguments for 'healthz' command`),
|
Do("HEALTHZ", "arg").Err(`wrong number of arguments for 'healthz' command`),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -621,3 +598,51 @@ func keys_SERVER_test(mc *mockServer) error {
|
||||||
Do("SERVER", "ett").JSON().Err(`invalid argument 'ett'`),
|
Do("SERVER", "ett").JSON().Err(`invalid argument 'ett'`),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func keys_INFO_test(mc *mockServer) error {
|
||||||
|
return mc.DoBatch(
|
||||||
|
Do("INFO").Func(func(s string) error {
|
||||||
|
if !strings.Contains(s, "# Clients") ||
|
||||||
|
!strings.Contains(s, "# Stats") {
|
||||||
|
return errors.New("looks invalid")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}),
|
||||||
|
Do("INFO", "all").Func(func(s string) error {
|
||||||
|
if !strings.Contains(s, "# Clients") ||
|
||||||
|
!strings.Contains(s, "# Stats") {
|
||||||
|
return errors.New("looks invalid")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}),
|
||||||
|
Do("INFO", "default").Func(func(s string) error {
|
||||||
|
if !strings.Contains(s, "# Clients") ||
|
||||||
|
!strings.Contains(s, "# Stats") {
|
||||||
|
return errors.New("looks invalid")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}),
|
||||||
|
Do("INFO", "cpu").Func(func(s string) error {
|
||||||
|
if !strings.Contains(s, "# CPU") ||
|
||||||
|
strings.Contains(s, "# Clients") ||
|
||||||
|
strings.Contains(s, "# Stats") {
|
||||||
|
return errors.New("looks invalid")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}),
|
||||||
|
Do("INFO", "cpu", "clients").Func(func(s string) error {
|
||||||
|
if !strings.Contains(s, "# CPU") ||
|
||||||
|
!strings.Contains(s, "# Clients") ||
|
||||||
|
strings.Contains(s, "# Stats") {
|
||||||
|
return errors.New("looks invalid")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}),
|
||||||
|
Do("INFO").JSON().Func(func(s string) error {
|
||||||
|
if gjson.Get(s, "info.tile38_version").String() == "" {
|
||||||
|
return errors.New("looks invalid")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue