Implemented tests for AddCommand, ExecuteCommand and RemoveCommand methods

This commit is contained in:
Kelvin Clement Mwinuka
2024-04-28 10:43:46 +08:00
parent c241cc07b1
commit 1d56e9839b
10 changed files with 373 additions and 52 deletions

View File

@@ -225,18 +225,18 @@ func (server *EchoVault) RPop(key string) (string, error) {
// //
// `values` - ...string - the list of elements to add to push to the beginning of the list. // `values` - ...string - the list of elements to add to push to the beginning of the list.
// //
// Returns: "OK" when the list has been successfully modified or created. // Returns: An integer with the length of the new list.
// //
// Errors: // Errors:
// //
// "LPush command on non-list item" - when the provided key is not a list. // "LPush command on non-list item" - when the provided key is not a list.
func (server *EchoVault) LPush(key string, values ...string) (string, error) { func (server *EchoVault) LPush(key string, values ...string) (int, error) {
cmd := append([]string{"LPUSH", key}, values...) cmd := append([]string{"LPUSH", key}, values...)
b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true)
if err != nil { if err != nil {
return "", err return 0, err
} }
return internal.ParseStringResponse(b) return internal.ParseIntegerResponse(b)
} }
// LPushX pushed 1 or more values to the beginning of an existing list. The command only succeeds on a pre-existing list. // LPushX pushed 1 or more values to the beginning of an existing list. The command only succeeds on a pre-existing list.
@@ -247,18 +247,18 @@ func (server *EchoVault) LPush(key string, values ...string) (string, error) {
// //
// `values` - ...string - the list of elements to add to push to the beginning of the list. // `values` - ...string - the list of elements to add to push to the beginning of the list.
// //
// Returns: "OK" when the list has been successfully modified. // Returns: An integer with the length of the new list.
// //
// Errors: // Errors:
// //
// "LPushX command on non-list item" - when the provided key is not a list or doesn't exist. // "LPushX command on non-list item" - when the provided key is not a list or doesn't exist.
func (server *EchoVault) LPushX(key string, values ...string) (string, error) { func (server *EchoVault) LPushX(key string, values ...string) (int, error) {
cmd := append([]string{"LPUSHX", key}, values...) cmd := append([]string{"LPUSHX", key}, values...)
b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true)
if err != nil { if err != nil {
return "", err return 0, err
} }
return internal.ParseStringResponse(b) return internal.ParseIntegerResponse(b)
} }
// RPush pushed 1 or more values to the end of a list. If the list does not exist, a new list is created // RPush pushed 1 or more values to the end of a list. If the list does not exist, a new list is created
@@ -270,18 +270,18 @@ func (server *EchoVault) LPushX(key string, values ...string) (string, error) {
// //
// `values` - ...string - the list of elements to add to push to the end of the list. // `values` - ...string - the list of elements to add to push to the end of the list.
// //
// Returns: "OK" when the list has been successfully modified or created. // Returns: An integer with the length of the new list.
// //
// Errors: // Errors:
// //
// "RPush command on non-list item" - when the provided key is not a list. // "RPush command on non-list item" - when the provided key is not a list.
func (server *EchoVault) RPush(key string, values ...string) (string, error) { func (server *EchoVault) RPush(key string, values ...string) (int, error) {
cmd := append([]string{"RPUSH", key}, values...) cmd := append([]string{"RPUSH", key}, values...)
b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true)
if err != nil { if err != nil {
return "", err return 0, err
} }
return internal.ParseStringResponse(b) return internal.ParseIntegerResponse(b)
} }
// RPushX pushed 1 or more values to the end of an existing list. The command only succeeds on a pre-existing list. // RPushX pushed 1 or more values to the end of an existing list. The command only succeeds on a pre-existing list.
@@ -292,16 +292,16 @@ func (server *EchoVault) RPush(key string, values ...string) (string, error) {
// //
// `values` - ...string - the list of elements to add to push to the end of the list. // `values` - ...string - the list of elements to add to push to the end of the list.
// //
// Returns: "OK" when the list has been successfully modified. // Returns: An integer with the length of the new list.
// //
// Errors: // Errors:
// //
// "RPushX command on non-list item" - when the provided key is not a list or doesn't exist. // "RPushX command on non-list item" - when the provided key is not a list or doesn't exist.
func (server *EchoVault) RPushX(key string, values ...string) (string, error) { func (server *EchoVault) RPushX(key string, values ...string) (int, error) {
cmd := append([]string{"RPUSHX", key}, values...) cmd := append([]string{"RPUSHX", key}, values...)
b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true) b, err := server.handleCommand(server.context, internal.EncodeCommand(cmd), nil, false, true)
if err != nil { if err != nil {
return "", err return 0, err
} }
return internal.ParseStringResponse(b) return internal.ParseIntegerResponse(b)
} }

11
echovault/config.go Normal file
View File

@@ -0,0 +1,11 @@
package echovault
import (
"github.com/echovault/echovault/internal/config"
)
// DefaultConfig returns the default configuration.
// This should be used when using EchoVault as an embedded library.
func DefaultConfig() config.Config {
return config.DefaultConfig()
}

View File

@@ -73,7 +73,11 @@ func (server *EchoVault) handleCommand(ctx context.Context, message []byte, conn
synchronize := command.Sync synchronize := command.Sync
handler := command.HandlerFunc handler := command.HandlerFunc
subCommand, ok := internal.GetSubCommand(command, cmd).(internal.SubCommand) sc, err := internal.GetSubCommand(command, cmd)
if err != nil {
return nil, err
}
subCommand, ok := sc.(internal.SubCommand)
if ok { if ok {
synchronize = subCommand.Sync synchronize = subCommand.Sync
handler = subCommand.HandlerFunc handler = subCommand.HandlerFunc

View File

@@ -193,7 +193,7 @@ func (acl *ACL) DeleteUser(_ context.Context, usernames []string) error {
} }
} }
// Skip if the current username was not found in the ACL // Skip if the current username was not found in the ACL
if username != user.Username { if user == nil {
continue continue
} }
// Terminate every connection attached to this user // Terminate every connection attached to this user

View File

@@ -421,7 +421,7 @@ func handleLPush(params internal.HandlerFuncParams) ([]byte, error) {
if err = params.SetValue(params.Context, key, append(newElems, l...)); err != nil { if err = params.SetValue(params.Context, key, append(newElems, l...)); err != nil {
return nil, err return nil, err
} }
return []byte(constants.OkResponse), nil return []byte(fmt.Sprintf(":%d\r\n", len(l)+len(newElems))), nil
} }
func handleRPush(params internal.HandlerFuncParams) ([]byte, error) { func handleRPush(params internal.HandlerFuncParams) ([]byte, error) {
@@ -469,7 +469,7 @@ func handleRPush(params internal.HandlerFuncParams) ([]byte, error) {
if err = params.SetValue(params.Context, key, append(l, newElems...)); err != nil { if err = params.SetValue(params.Context, key, append(l, newElems...)); err != nil {
return nil, err return nil, err
} }
return []byte(constants.OkResponse), nil return []byte(fmt.Sprintf(":%d\r\n", len(l)+len(newElems))), nil
} }
func handlePop(params internal.HandlerFuncParams) ([]byte, error) { func handlePop(params internal.HandlerFuncParams) ([]byte, error) {

View File

@@ -102,7 +102,14 @@ func (fsm *FSM) Apply(log *raft.Log) interface{} {
handler := command.HandlerFunc handler := command.HandlerFunc
subCommand, ok := internal.GetSubCommand(command, request.CMD).(internal.SubCommand) sc, err := internal.GetSubCommand(command, request.CMD)
if err != nil {
return internal.ApplyResponse{
Error: err,
Response: nil,
}
}
subCommand, ok := sc.(internal.SubCommand)
if ok { if ok {
handler = subCommand.HandlerFunc handler = subCommand.HandlerFunc
} }

View File

@@ -128,16 +128,21 @@ func GetIPAddress() (string, error) {
return localAddr, nil return localAddr, nil
} }
func GetSubCommand(command Command, cmd []string) interface{} { func GetSubCommand(command Command, cmd []string) (interface{}, error) {
if len(command.SubCommands) == 0 || len(cmd) < 2 { if command.SubCommands == nil || len(command.SubCommands) == 0 {
return nil // If the command has no sub-commands, return nil
return nil, nil
}
if len(cmd) < 2 {
// If the cmd provided by the user has less than 2 tokens, there's no need to search for a subcommand
return nil, nil
} }
for _, subCommand := range command.SubCommands { for _, subCommand := range command.SubCommands {
if strings.EqualFold(subCommand.Command, cmd[1]) { if strings.EqualFold(subCommand.Command, cmd[1]) {
return subCommand return subCommand, nil
} }
} }
return nil return nil, fmt.Errorf("command %s %s not supported", cmd[0], cmd[1])
} }
func IsWriteCommand(command Command, subCommand SubCommand) bool { func IsWriteCommand(command Command, subCommand SubCommand) bool {

View File

@@ -13,3 +13,297 @@
// limitations under the License. // limitations under the License.
package admin package admin
import (
"bytes"
"errors"
"fmt"
"github.com/echovault/echovault/constants"
"github.com/echovault/echovault/echovault"
"github.com/echovault/echovault/internal/config"
"github.com/echovault/echovault/types"
"github.com/tidwall/resp"
"strconv"
"testing"
)
func createEchoVault() *echovault.EchoVault {
ev, _ := echovault.NewEchoVault(
echovault.WithConfig(config.Config{
DataDir: "",
}),
)
return ev
}
func TestEchoVault_AddCommand(t *testing.T) {
type args struct {
command echovault.CommandOptions
}
type scenarios struct {
name string
command []string
wantRes int
wantErr error
}
tests := []struct {
name string
args args
scenarios []scenarios
wantErr bool
}{
{
name: "1 Add command without subcommands",
wantErr: false,
args: args{
command: echovault.CommandOptions{
Command: "CommandOne",
Module: "test-module",
Description: `(CommandOne write-key read-key <value>)
Test command to handle successful addition of a single command without subcommands.
The value passed must be an integer.`,
Categories: []string{},
Sync: false,
KeyExtractionFunc: func(cmd []string) (types.PluginKeyExtractionFuncResult, error) {
if len(cmd) != 4 {
return types.PluginKeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse)
}
return types.PluginKeyExtractionFuncResult{
WriteKeys: cmd[1:2],
ReadKeys: cmd[2:3],
}, nil
},
HandlerFunc: func(params types.PluginHandlerFuncParams) ([]byte, error) {
if len(params.Command) != 4 {
return nil, errors.New(constants.WrongArgsResponse)
}
value := params.Command[3]
i, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return nil, errors.New("value must be an integer")
}
return []byte(fmt.Sprintf(":%d\r\n", i)), nil
},
},
},
scenarios: []scenarios{
{
name: "1 Successfully execute the command and return the expected integer.",
command: []string{"CommandOne", "write-key1", "read-key1", "1111"},
wantRes: 1111,
wantErr: nil,
},
{
name: "2 Get error due to command being too long",
command: []string{"CommandOne", "write-key1", "read-key1", "1111", "2222"},
wantRes: 0,
wantErr: errors.New(constants.WrongArgsResponse),
},
{
name: "3 Get error due to command being too short",
command: []string{"CommandOne", "write-key1", "read-key1"},
wantRes: 0,
wantErr: errors.New(constants.WrongArgsResponse),
},
{
name: "4 Get error due to value not being an integer",
command: []string{"CommandOne", "write-key1", "read-key1", "string"},
wantRes: 0,
wantErr: errors.New("value must be an integer"),
},
},
},
{
name: "2 Add command with subcommands",
wantErr: false,
args: args{
command: echovault.CommandOptions{
Command: "CommandTwo",
SubCommand: []echovault.SubCommandOptions{
{
Command: "SubCommandOne",
Module: "test-module",
Description: `(CommandTwo SubCommandOne write-key read-key <value>)
Test command to handle successful addition of a single command with subcommands.
The value passed must be an integer.`,
Categories: []string{},
Sync: false,
KeyExtractionFunc: func(cmd []string) (types.PluginKeyExtractionFuncResult, error) {
if len(cmd) != 5 {
return types.PluginKeyExtractionFuncResult{}, errors.New(constants.WrongArgsResponse)
}
return types.PluginKeyExtractionFuncResult{
WriteKeys: cmd[2:3],
ReadKeys: cmd[3:4],
}, nil
},
HandlerFunc: func(params types.PluginHandlerFuncParams) ([]byte, error) {
if len(params.Command) != 5 {
return nil, errors.New(constants.WrongArgsResponse)
}
value := params.Command[4]
i, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return nil, errors.New("value must be an integer")
}
return []byte(fmt.Sprintf(":%d\r\n", i)), nil
},
},
},
},
},
scenarios: []scenarios{
{
name: "1 Successfully execute the command and return the expected integer.",
command: []string{"CommandTwo", "SubCommandOne", "write-key1", "read-key1", "1111"},
wantRes: 1111,
wantErr: nil,
},
{
name: "2 Get error due to command being too long",
command: []string{"CommandTwo", "SubCommandOne", "write-key1", "read-key1", "1111", "2222"},
wantRes: 0,
wantErr: errors.New(constants.WrongArgsResponse),
},
{
name: "3 Get error due to command being too short",
command: []string{"CommandTwo", "SubCommandOne", "write-key1", "read-key1"},
wantRes: 0,
wantErr: errors.New(constants.WrongArgsResponse),
},
{
name: "4 Get error due to value not being an integer",
command: []string{"CommandTwo", "SubCommandOne", "write-key1", "read-key1", "string"},
wantRes: 0,
wantErr: errors.New("value must be an integer"),
},
},
},
}
for _, tt := range tests {
server := createEchoVault()
t.Run(tt.name, func(t *testing.T) {
if err := server.AddCommand(tt.args.command); (err != nil) != tt.wantErr {
t.Errorf("AddCommand() error = %v, wantErr %v", err, tt.wantErr)
}
for _, scenario := range tt.scenarios {
b, err := server.ExecuteCommand(scenario.command)
if scenario.wantErr != nil {
if scenario.wantErr.Error() != err.Error() {
t.Errorf("AddCommand() error = %v, wantErr %v", err, scenario.wantErr)
}
continue
}
r := resp.NewReader(bytes.NewReader(b))
v, _, _ := r.ReadValue()
if v.Integer() != scenario.wantRes {
t.Errorf("AddCommand() res = %v, wantRes %v", resp.BytesValue(b).Integer(), scenario.wantRes)
}
}
})
}
}
func TestEchoVault_ExecuteCommand(t *testing.T) {
type args struct {
key string
presetValue []string
command []string
}
tests := []struct {
name string
args args
wantRes int
wantErr error
}{
{
name: "1 Execute LPUSH command and get expected result",
args: args{
key: "key1",
presetValue: []string{"1", "2", "3"},
command: []string{"LPUSH", "key1", "4", "5", "6", "7", "8", "9", "10"},
},
wantRes: 10,
wantErr: nil,
},
{
name: "2 Expect error when trying to execute non-existent command",
args: args{
key: "key2",
presetValue: nil,
command: []string{"NON-EXISTENT", "key1", "key2"},
},
wantRes: 0,
wantErr: errors.New("command NON-EXISTENT not supported"),
},
}
for _, tt := range tests {
server := createEchoVault()
t.Run(tt.name, func(t *testing.T) {
if tt.args.presetValue != nil {
_, _ = server.LPush(tt.args.key, tt.args.presetValue...)
}
b, err := server.ExecuteCommand(tt.args.command)
if tt.wantErr != nil {
if err.Error() != tt.wantErr.Error() {
t.Errorf("ExecuteCommand() error = %v, wantErr %v", err, tt.wantErr)
}
}
r := resp.NewReader(bytes.NewReader(b))
v, _, _ := r.ReadValue()
if v.Integer() != tt.wantRes {
fmt.Println("RES: ", string(b))
t.Errorf("ExecuteCommand() response = %d, wantRes %d", v.Integer(), tt.wantRes)
}
})
}
}
func TestEchoVault_RemoveCommand(t *testing.T) {
type args struct {
removeCommand []string
executeCommand []string
}
tests := []struct {
name string
args args
wantErr error
}{
{
name: "1 Remove command and expect error when the command is called",
args: args{
removeCommand: []string{"LPUSH"},
executeCommand: []string{"LPUSH", "key", "item"},
},
wantErr: errors.New("command LPUSH not supported"),
},
{
name: "2 Remove sub-command and expect error when the subcommand is called",
args: args{
removeCommand: []string{"ACL", "CAT"},
executeCommand: []string{"ACL", "CAT"},
},
wantErr: errors.New("command ACL CAT not supported"),
},
{
name: "3 Remove sub-command and expect successful response from calling another subcommand",
args: args{
removeCommand: []string{"ACL", "WHOAMI"},
executeCommand: []string{"ACL", "DELUSER", "user-one"},
},
wantErr: nil,
},
}
for _, tt := range tests {
server := createEchoVault()
t.Run(tt.name, func(t *testing.T) {
server.RemoveCommand(tt.args.removeCommand...)
_, err := server.ExecuteCommand(tt.args.executeCommand)
if tt.wantErr != nil {
if err.Error() != tt.wantErr.Error() {
t.Errorf("RemoveCommand() error = %v, wantErr %v", err, tt.wantErr)
}
}
})
}
}

View File

@@ -436,8 +436,8 @@ func TestEchoVault_LPUSH(t *testing.T) {
key string key string
values []string values []string
presetValue interface{} presetValue interface{}
lpushFunc func(key string, values ...string) (string, error) lpushFunc func(key string, values ...string) (int, error)
want string want int
wantErr bool wantErr bool
}{ }{
{ {
@@ -447,7 +447,7 @@ func TestEchoVault_LPUSH(t *testing.T) {
key: "key1", key: "key1",
values: []string{"value1", "value2"}, values: []string{"value1", "value2"},
lpushFunc: server.LPushX, lpushFunc: server.LPushX,
want: "OK", want: 6,
wantErr: false, wantErr: false,
}, },
{ {
@@ -457,7 +457,7 @@ func TestEchoVault_LPUSH(t *testing.T) {
key: "key2", key: "key2",
values: []string{"value1", "value2"}, values: []string{"value1", "value2"},
lpushFunc: server.LPush, lpushFunc: server.LPush,
want: "OK", want: 6,
wantErr: false, wantErr: false,
}, },
{ {
@@ -467,7 +467,7 @@ func TestEchoVault_LPUSH(t *testing.T) {
key: "key3", key: "key3",
values: []string{"value1", "value2"}, values: []string{"value1", "value2"},
lpushFunc: server.LPush, lpushFunc: server.LPush,
want: "OK", want: 2,
wantErr: false, wantErr: false,
}, },
{ {
@@ -477,7 +477,7 @@ func TestEchoVault_LPUSH(t *testing.T) {
key: "key4", key: "key4",
values: []string{"value1", "value2"}, values: []string{"value1", "value2"},
lpushFunc: server.LPushX, lpushFunc: server.LPushX,
want: "", want: 0,
wantErr: true, wantErr: true,
}, },
} }
@@ -511,8 +511,8 @@ func TestEchoVault_RPUSH(t *testing.T) {
key string key string
values []string values []string
presetValue interface{} presetValue interface{}
rpushFunc func(key string, values ...string) (string, error) rpushFunc func(key string, values ...string) (int, error)
want string want int
wantErr bool wantErr bool
}{ }{
{ {
@@ -522,7 +522,7 @@ func TestEchoVault_RPUSH(t *testing.T) {
key: "key1", key: "key1",
values: []string{"value1", "value2"}, values: []string{"value1", "value2"},
rpushFunc: server.RPush, rpushFunc: server.RPush,
want: "OK", want: 2,
wantErr: false, wantErr: false,
}, },
{ {
@@ -532,7 +532,7 @@ func TestEchoVault_RPUSH(t *testing.T) {
key: "key2", key: "key2",
values: []string{"value1", "value2"}, values: []string{"value1", "value2"},
rpushFunc: server.RPushX, rpushFunc: server.RPushX,
want: "", want: 0,
wantErr: true, wantErr: true,
}, },
} }

View File

@@ -1241,7 +1241,7 @@ func Test_HandleLPUSH(t *testing.T) {
key string key string
presetValue interface{} presetValue interface{}
command []string command []string
expectedResponse interface{} expectedResponse int
expectedValue []interface{} expectedValue []interface{}
expectedError error expectedError error
}{ }{
@@ -1251,7 +1251,7 @@ func Test_HandleLPUSH(t *testing.T) {
key: "LpushKey1", key: "LpushKey1",
presetValue: []interface{}{"1", "2", "4", "5"}, presetValue: []interface{}{"1", "2", "4", "5"},
command: []string{"LPUSHX", "LpushKey1", "value1", "value2"}, command: []string{"LPUSHX", "LpushKey1", "value1", "value2"},
expectedResponse: "OK", expectedResponse: 6,
expectedValue: []interface{}{"value1", "value2", "1", "2", "4", "5"}, expectedValue: []interface{}{"value1", "value2", "1", "2", "4", "5"},
expectedError: nil, expectedError: nil,
}, },
@@ -1261,7 +1261,7 @@ func Test_HandleLPUSH(t *testing.T) {
key: "LpushKey2", key: "LpushKey2",
presetValue: []interface{}{"1", "2", "4", "5"}, presetValue: []interface{}{"1", "2", "4", "5"},
command: []string{"LPUSH", "LpushKey2", "value1", "value2"}, command: []string{"LPUSH", "LpushKey2", "value1", "value2"},
expectedResponse: "OK", expectedResponse: 6,
expectedValue: []interface{}{"value1", "value2", "1", "2", "4", "5"}, expectedValue: []interface{}{"value1", "value2", "1", "2", "4", "5"},
expectedError: nil, expectedError: nil,
}, },
@@ -1271,7 +1271,7 @@ func Test_HandleLPUSH(t *testing.T) {
key: "LpushKey3", key: "LpushKey3",
presetValue: nil, presetValue: nil,
command: []string{"LPUSH", "LpushKey3", "value1", "value2"}, command: []string{"LPUSH", "LpushKey3", "value1", "value2"},
expectedResponse: "OK", expectedResponse: 2,
expectedValue: []interface{}{"value1", "value2"}, expectedValue: []interface{}{"value1", "value2"},
expectedError: nil, expectedError: nil,
}, },
@@ -1281,7 +1281,7 @@ func Test_HandleLPUSH(t *testing.T) {
key: "LpushKey5", key: "LpushKey5",
presetValue: nil, presetValue: nil,
command: []string{"LPUSH", "LpushKey5"}, command: []string{"LPUSH", "LpushKey5"},
expectedResponse: nil, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(constants.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
@@ -1291,7 +1291,7 @@ func Test_HandleLPUSH(t *testing.T) {
key: "LpushKey6", key: "LpushKey6",
presetValue: nil, presetValue: nil,
command: []string{"LPUSHX", "LpushKey7", "count", "value1"}, command: []string{"LPUSHX", "LpushKey7", "count", "value1"},
expectedResponse: nil, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New("LPUSHX command on non-list item"), expectedError: errors.New("LPUSHX command on non-list item"),
}, },
@@ -1329,8 +1329,8 @@ func Test_HandleLPUSH(t *testing.T) {
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
if rv.String() != test.expectedResponse { if rv.Integer() != test.expectedResponse {
t.Errorf("expected \"%s\" response, got \"%s\"", test.expectedResponse, rv.String()) t.Errorf("expected \"%d\" response, got \"%s\"", test.expectedResponse, rv.String())
} }
if _, err = mockServer.KeyRLock(ctx, test.key); err != nil { if _, err = mockServer.KeyRLock(ctx, test.key); err != nil {
t.Error(err) t.Error(err)
@@ -1359,7 +1359,7 @@ func Test_HandleRPUSH(t *testing.T) {
key string key string
presetValue interface{} presetValue interface{}
command []string command []string
expectedResponse interface{} expectedResponse int
expectedValue []interface{} expectedValue []interface{}
expectedError error expectedError error
}{ }{
@@ -1369,7 +1369,7 @@ func Test_HandleRPUSH(t *testing.T) {
key: "RpushKey1", key: "RpushKey1",
presetValue: []interface{}{"1", "2", "4", "5"}, presetValue: []interface{}{"1", "2", "4", "5"},
command: []string{"RPUSHX", "RpushKey1", "value1", "value2"}, command: []string{"RPUSHX", "RpushKey1", "value1", "value2"},
expectedResponse: "OK", expectedResponse: 6,
expectedValue: []interface{}{"1", "2", "4", "5", "value1", "value2"}, expectedValue: []interface{}{"1", "2", "4", "5", "value1", "value2"},
expectedError: nil, expectedError: nil,
}, },
@@ -1379,7 +1379,7 @@ func Test_HandleRPUSH(t *testing.T) {
key: "RpushKey2", key: "RpushKey2",
presetValue: []interface{}{"1", "2", "4", "5"}, presetValue: []interface{}{"1", "2", "4", "5"},
command: []string{"RPUSH", "RpushKey2", "value1", "value2"}, command: []string{"RPUSH", "RpushKey2", "value1", "value2"},
expectedResponse: "OK", expectedResponse: 6,
expectedValue: []interface{}{"1", "2", "4", "5", "value1", "value2"}, expectedValue: []interface{}{"1", "2", "4", "5", "value1", "value2"},
expectedError: nil, expectedError: nil,
}, },
@@ -1389,7 +1389,7 @@ func Test_HandleRPUSH(t *testing.T) {
key: "RpushKey3", key: "RpushKey3",
presetValue: nil, presetValue: nil,
command: []string{"RPUSH", "RpushKey3", "value1", "value2"}, command: []string{"RPUSH", "RpushKey3", "value1", "value2"},
expectedResponse: "OK", expectedResponse: 2,
expectedValue: []interface{}{"value1", "value2"}, expectedValue: []interface{}{"value1", "value2"},
expectedError: nil, expectedError: nil,
}, },
@@ -1399,7 +1399,7 @@ func Test_HandleRPUSH(t *testing.T) {
key: "RpushKey5", key: "RpushKey5",
presetValue: nil, presetValue: nil,
command: []string{"RPUSH", "RpushKey5"}, command: []string{"RPUSH", "RpushKey5"},
expectedResponse: nil, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New(constants.WrongArgsResponse), expectedError: errors.New(constants.WrongArgsResponse),
}, },
@@ -1409,7 +1409,7 @@ func Test_HandleRPUSH(t *testing.T) {
key: "RpushKey6", key: "RpushKey6",
presetValue: nil, presetValue: nil,
command: []string{"RPUSHX", "RpushKey7", "count", "value1"}, command: []string{"RPUSHX", "RpushKey7", "count", "value1"},
expectedResponse: nil, expectedResponse: 0,
expectedValue: nil, expectedValue: nil,
expectedError: errors.New("RPUSHX command on non-list item"), expectedError: errors.New("RPUSHX command on non-list item"),
}, },
@@ -1447,8 +1447,8 @@ func Test_HandleRPUSH(t *testing.T) {
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
if rv.String() != test.expectedResponse { if rv.Integer() != test.expectedResponse {
t.Errorf("expected \"%s\" response, got \"%s\"", test.expectedResponse, rv.String()) t.Errorf("expected \"%d\" response, got \"%s\"", test.expectedResponse, rv.String())
} }
if _, err = mockServer.KeyRLock(ctx, test.key); err != nil { if _, err = mockServer.KeyRLock(ctx, test.key); err != nil {
t.Error(err) t.Error(err)