wip - fixing the empty response error

This commit is contained in:
tidwall 2022-09-24 06:22:58 -07:00
parent 9c8e7e90e1
commit 5460998086
4 changed files with 56 additions and 39 deletions

View File

@ -52,7 +52,8 @@ func (arr byID) Swap(a, b int) {
arr[a], arr[b] = arr[b], arr[a] arr[a], arr[b] = arr[b], arr[a]
} }
func (s *Server) cmdClient(msg *Message, client *Client) (resp.Value, error) { // CLIENT (LIST | KILL | GETNAME | SETNAME)
func (s *Server) cmdCLIENT(msg *Message, client *Client) (resp.Value, error) {
start := time.Now() start := time.Now()
if len(msg.Args) == 1 { if len(msg.Args) == 1 {
@ -89,8 +90,7 @@ func (s *Server) cmdClient(msg *Message, client *Client) (resp.Value, error) {
) )
client.mu.Unlock() client.mu.Unlock()
} }
switch msg.OutputType { if msg.OutputType == JSON {
case 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")
@ -110,32 +110,23 @@ func (s *Server) cmdClient(msg *Message, client *Client) (resp.Value, error) {
} }
} }
// Marshal the map and use the output in the JSON response data, _ := json.Marshal(cmap)
data, err := json.Marshal(cmap) return resp.StringValue(`{"ok":true,"list":` + string(data) +
if err != nil { `,"elapsed":"` + time.Since(start).String() + "\"}"), nil
return NOMessage, err
}
return resp.StringValue(`{"ok":true,"list":` + string(data) + `,"elapsed":"` + time.Since(start).String() + "\"}"), nil
case RESP:
return resp.BytesValue(buf), nil
} }
return NOMessage, nil return resp.BytesValue(buf), nil
case "getname": case "getname":
if len(msg.Args) != 2 { if len(msg.Args) != 2 {
return NOMessage, errInvalidNumberOfArguments return NOMessage, errInvalidNumberOfArguments
} }
name := "" client.mu.Lock()
switch msg.OutputType { name := client.name
case JSON: client.mu.Unlock()
client.mu.Lock() if msg.OutputType == JSON {
name := client.name return resp.StringValue(`{"ok":true,"name":` + jsonString(name) +
client.mu.Unlock()
return resp.StringValue(`{"ok":true,"name":` +
jsonString(name) +
`,"elapsed":"` + time.Since(start).String() + "\"}"), nil `,"elapsed":"` + time.Since(start).String() + "\"}"), nil
case RESP:
return resp.StringValue(name), nil
} }
return resp.StringValue(name), nil
case "setname": case "setname":
if len(msg.Args) != 3 { if len(msg.Args) != 3 {
return NOMessage, errInvalidNumberOfArguments return NOMessage, errInvalidNumberOfArguments

View File

@ -977,7 +977,7 @@ func (s *Server) handleInputCommand(client *Client, msg *Message) error {
return err return err
} }
} }
if !isRespValueEmptyString(res) { if false || !isRespValueEmptyString(res) {
var resStr string var resStr string
resStr, err := serializeOutput(res) resStr, err := serializeOutput(res)
if err != nil { if err != nil {
@ -1140,7 +1140,7 @@ func (s *Server) command(msg *Message, client *Client) (
return s.command(msg, client) return s.command(msg, client)
} }
case "client": case "client":
res, err = s.cmdClient(msg, client) res, err = s.cmdCLIENT(msg, client)
case "eval", "evalro", "evalna": case "eval", "evalro", "evalna":
res, err = s.cmdEvalUnified(false, msg) res, err = s.cmdEvalUnified(false, msg)
case "evalsha", "evalrosha", "evalnasha": case "evalsha", "evalrosha", "evalnasha":
@ -1162,6 +1162,7 @@ func (s *Server) command(msg *Message, client *Client) (
case "monitor": case "monitor":
res, err = s.cmdMonitor(msg) res, err = s.cmdMonitor(msg)
} }
s.sendMonitor(err, msg, client, false) s.sendMonitor(err, msg, client, false)
return return
} }

View File

@ -3,6 +3,7 @@ package tests
import ( import (
"errors" "errors"
"fmt" "fmt"
"strings"
"testing" "testing"
"github.com/gomodule/redigo/redis" "github.com/gomodule/redigo/redis"
@ -10,18 +11,19 @@ import (
) )
func subTestClient(t *testing.T, mc *mockServer) { func subTestClient(t *testing.T, mc *mockServer) {
runStep(t, mc, "valid json", client_valid_json_test) runStep(t, mc, "OUTPUT", client_OUTPUT_test)
runStep(t, mc, "valid client count", info_valid_client_count_test) runStep(t, mc, "CLIENT", client_CLIENT_test)
} }
func client_valid_json_test(mc *mockServer) error { func client_OUTPUT_test(mc *mockServer) error {
if err := mc.DoBatch([][]interface{}{ if err := mc.DoBatch(
// tests removal of "elapsed" member. // tests removal of "elapsed" member.
{"OUTPUT", "json"}, {`{"ok":true}`}, Do("OUTPUT", "json").Str(`{"ok":true}`),
{"OUTPUT", "resp"}, {`OK`}, Do("OUTPUT", "resp").OK(),
}); err != nil { ); err != nil {
return err return err
} }
// run direct commands // run direct commands
if _, err := mc.Do("OUTPUT", "json"); err != nil { if _, err := mc.Do("OUTPUT", "json"); err != nil {
return err return err
@ -45,9 +47,14 @@ func client_valid_json_test(mc *mockServer) error {
return nil return nil
} }
func info_valid_client_count_test(mc *mockServer) error { func client_CLIENT_test(mc *mockServer) error {
numConns := 20 numConns := 20
var conns []redis.Conn var conns []redis.Conn
defer func() {
for i := range conns {
conns[i].Close()
}
}()
for i := 0; i <= numConns; i++ { for i := 0; i <= numConns; i++ {
conn, err := redis.Dial("tcp", fmt.Sprintf(":%d", mc.port)) conn, err := redis.Dial("tcp", fmt.Sprintf(":%d", mc.port))
if err != nil { if err != nil {
@ -55,9 +62,6 @@ func info_valid_client_count_test(mc *mockServer) error {
} }
conns = append(conns, conn) conns = append(conns, conn)
} }
for i := range conns {
defer conns[i].Close()
}
if _, err := mc.Do("OUTPUT", "JSON"); err != nil { if _, err := mc.Do("OUTPUT", "JSON"); err != nil {
return err return err
} }
@ -73,5 +77,26 @@ func info_valid_client_count_test(mc *mockServer) error {
if len(gjson.Get(sres, "list").Array()) < numConns { if len(gjson.Get(sres, "list").Array()) < numConns {
return errors.New("Invalid number of connections") return errors.New("Invalid number of connections")
} }
return nil
return mc.DoBatch(
Do("CLIENT", "list").JSON().Func(func(s string) error {
if int(gjson.Get(s, "list.#").Int()) < numConns {
return errors.New("Invalid number of connections")
}
return nil
}),
Do("CLIENT", "list").Func(func(s string) error {
if len(strings.Split(strings.TrimSpace(s), "\n")) < numConns {
return errors.New("Invalid number of connections")
}
return nil
}),
Do("CLIENT").Err(`wrong number of arguments for 'client' command`),
Do("CLIENT", "hello").Err(`Syntax error, try CLIENT (LIST | KILL | GETNAME | SETNAME)`),
Do("CLIENT", "list", "arg3").Err(`wrong number of arguments for 'client' command`),
Do("CLIENT", "getname", "arg3").Err(`wrong number of arguments for 'client' command`),
Do("CLIENT", "getname").JSON().Str(`{"ok":true,"name":""}`),
Do("CLIENT", "getname").Str(``),
)
} }

View File

@ -56,10 +56,10 @@ func TestAll(t *testing.T) {
runSubTest(t, "json", mc, subTestJSON) runSubTest(t, "json", mc, subTestJSON)
runSubTest(t, "search", mc, subTestSearch) runSubTest(t, "search", mc, subTestSearch)
runSubTest(t, "testcmd", mc, subTestTestCmd) runSubTest(t, "testcmd", mc, subTestTestCmd)
runSubTest(t, "fence", mc, subTestFence)
runSubTest(t, "scripts", mc, subTestScripts)
runSubTest(t, "info", mc, subTestInfo)
runSubTest(t, "client", mc, subTestClient) 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, "timeouts", mc, subTestTimeout)
runSubTest(t, "metrics", mc, subTestMetrics) runSubTest(t, "metrics", mc, subTestMetrics)
} }