Better SET/PERSIST/TTL/STATS tests
This commit is contained in:
parent
7fa2dc4419
commit
295a9c45a8
@ -2,7 +2,7 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -706,23 +706,22 @@ func (s *Server) cmdSET(msg *Message) (resp.Value, commandDetails, error) {
|
|||||||
return retwerr(errInvalidArgument(args[i]))
|
return retwerr(errInvalidArgument(args[i]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if oobj == nil {
|
||||||
|
return retwerr(errInvalidNumberOfArguments)
|
||||||
|
}
|
||||||
|
|
||||||
// >> Operation
|
// >> Operation
|
||||||
|
|
||||||
nada := func() (resp.Value, commandDetails, error) {
|
nada := func() (resp.Value, commandDetails, error) {
|
||||||
// exclude operation due to 'xx' or 'nx' match
|
// exclude operation due to 'xx' or 'nx' match
|
||||||
switch msg.OutputType {
|
if msg.OutputType == JSON {
|
||||||
default:
|
|
||||||
case JSON:
|
|
||||||
if nx {
|
if nx {
|
||||||
return retwerr(errIDAlreadyExists)
|
return retwerr(errIDAlreadyExists)
|
||||||
} else {
|
} else {
|
||||||
return retwerr(errIDNotFound)
|
return retwerr(errIDNotFound)
|
||||||
}
|
}
|
||||||
case RESP:
|
|
||||||
return resp.NullValue(), commandDetails{}, nil
|
|
||||||
}
|
}
|
||||||
return retwerr(errors.New("nada unknown output"))
|
return resp.NullValue(), commandDetails{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
col, ok := s.cols.Get(key)
|
col, ok := s.cols.Get(key)
|
||||||
@ -931,11 +930,17 @@ func (s *Server) cmdEXPIRE(msg *Message) (resp.Value, commandDetails, error) {
|
|||||||
// PERSIST key id
|
// PERSIST key id
|
||||||
func (s *Server) cmdPERSIST(msg *Message) (resp.Value, commandDetails, error) {
|
func (s *Server) cmdPERSIST(msg *Message) (resp.Value, commandDetails, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
|
// >> Args
|
||||||
|
|
||||||
args := msg.Args
|
args := msg.Args
|
||||||
if len(args) != 3 {
|
if len(args) != 3 {
|
||||||
return retwerr(errInvalidNumberOfArguments)
|
return retwerr(errInvalidNumberOfArguments)
|
||||||
}
|
}
|
||||||
key, id := args[1], args[2]
|
key, id := args[1], args[2]
|
||||||
|
|
||||||
|
// >> Operation
|
||||||
|
|
||||||
col, _ := s.cols.Get(key)
|
col, _ := s.cols.Get(key)
|
||||||
if col == nil {
|
if col == nil {
|
||||||
if msg.OutputType == RESP {
|
if msg.OutputType == RESP {
|
||||||
@ -959,6 +964,8 @@ func (s *Server) cmdPERSIST(msg *Message) (resp.Value, commandDetails, error) {
|
|||||||
cleared = true
|
cleared = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// >> Response
|
||||||
|
|
||||||
var res resp.Value
|
var res resp.Value
|
||||||
|
|
||||||
var d commandDetails
|
var d commandDetails
|
||||||
@ -985,62 +992,47 @@ func (s *Server) cmdPERSIST(msg *Message) (resp.Value, commandDetails, error) {
|
|||||||
// TTL key id
|
// TTL key id
|
||||||
func (s *Server) cmdTTL(msg *Message) (resp.Value, error) {
|
func (s *Server) cmdTTL(msg *Message) (resp.Value, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
|
// >> Args
|
||||||
|
|
||||||
args := msg.Args
|
args := msg.Args
|
||||||
if len(args) != 3 {
|
if len(args) != 3 {
|
||||||
return retrerr(errInvalidNumberOfArguments)
|
return retrerr(errInvalidNumberOfArguments)
|
||||||
}
|
}
|
||||||
key, id := args[1], args[2]
|
key, id := args[1], args[2]
|
||||||
var v float64
|
|
||||||
var ok bool
|
// >> Operation
|
||||||
var ok2 bool
|
|
||||||
col, _ := s.cols.Get(key)
|
col, _ := s.cols.Get(key)
|
||||||
if col != nil {
|
if col == nil {
|
||||||
o := col.Get(id)
|
if msg.OutputType == JSON {
|
||||||
ok = o != nil
|
return retrerr(errKeyNotFound)
|
||||||
if ok {
|
|
||||||
if o.Expires() != 0 {
|
|
||||||
now := start.UnixNano()
|
|
||||||
if now > o.Expires() {
|
|
||||||
ok2 = false
|
|
||||||
} else {
|
|
||||||
v = float64(o.Expires()-now) / float64(time.Second)
|
|
||||||
if v < 0 {
|
|
||||||
v = 0
|
|
||||||
}
|
|
||||||
ok2 = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return resp.IntegerValue(-2), nil
|
||||||
}
|
}
|
||||||
var res resp.Value
|
|
||||||
switch msg.OutputType {
|
o := col.Get(id)
|
||||||
case JSON:
|
if o == nil {
|
||||||
if ok {
|
if msg.OutputType == JSON {
|
||||||
var ttl string
|
|
||||||
if ok2 {
|
|
||||||
ttl = strconv.FormatFloat(v, 'f', -1, 64)
|
|
||||||
} else {
|
|
||||||
ttl = "-1"
|
|
||||||
}
|
|
||||||
res = resp.SimpleStringValue(
|
|
||||||
`{"ok":true,"ttl":` + ttl + `,"elapsed":"` +
|
|
||||||
time.Since(start).String() + "\"}")
|
|
||||||
} else {
|
|
||||||
if col == nil {
|
|
||||||
return retrerr(errKeyNotFound)
|
|
||||||
}
|
|
||||||
return retrerr(errIDNotFound)
|
return retrerr(errIDNotFound)
|
||||||
}
|
}
|
||||||
case RESP:
|
return resp.IntegerValue(-2), nil
|
||||||
if ok {
|
|
||||||
if ok2 {
|
|
||||||
res = resp.IntegerValue(int(v))
|
|
||||||
} else {
|
|
||||||
res = resp.IntegerValue(-1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res = resp.IntegerValue(-2)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return res, nil
|
|
||||||
|
var ttl float64
|
||||||
|
if o.Expires() == 0 {
|
||||||
|
ttl = -1
|
||||||
|
} else {
|
||||||
|
now := start.UnixNano()
|
||||||
|
ttl = math.Max(float64(o.Expires()-now)/float64(time.Second), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// >> Response
|
||||||
|
|
||||||
|
if msg.OutputType == JSON {
|
||||||
|
return resp.SimpleStringValue(
|
||||||
|
`{"ok":true,"ttl":` + strconv.Itoa(int(ttl)) + `,"elapsed":"` +
|
||||||
|
time.Since(start).String() + "\"}"), nil
|
||||||
|
}
|
||||||
|
return resp.IntegerValue(int(ttl)), nil
|
||||||
}
|
}
|
||||||
|
@ -612,7 +612,7 @@ func (s *Server) commandInScript(msg *Message) (
|
|||||||
case "ttl":
|
case "ttl":
|
||||||
res, err = s.cmdTTL(msg)
|
res, err = s.cmdTTL(msg)
|
||||||
case "stats":
|
case "stats":
|
||||||
res, err = s.cmdStats(msg)
|
res, err = s.cmdSTATS(msg)
|
||||||
case "scan":
|
case "scan":
|
||||||
res, err = s.cmdScan(msg)
|
res, err = s.cmdScan(msg)
|
||||||
case "nearby":
|
case "nearby":
|
||||||
|
@ -1080,7 +1080,7 @@ func (s *Server) command(msg *Message, client *Client) (
|
|||||||
case "readonly":
|
case "readonly":
|
||||||
res, err = s.cmdReadOnly(msg)
|
res, err = s.cmdReadOnly(msg)
|
||||||
case "stats":
|
case "stats":
|
||||||
res, err = s.cmdStats(msg)
|
res, err = s.cmdSTATS(msg)
|
||||||
case "server":
|
case "server":
|
||||||
res, err = s.cmdServer(msg)
|
res, err = s.cmdServer(msg)
|
||||||
case "healthz":
|
case "healthz":
|
||||||
|
@ -45,22 +45,23 @@ func readMemStats() runtime.MemStats {
|
|||||||
return ms
|
return ms
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) cmdStats(msg *Message) (res resp.Value, err error) {
|
// STATS key [key...]
|
||||||
|
func (s *Server) cmdSTATS(msg *Message) (resp.Value, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
vs := msg.Args[1:]
|
|
||||||
var ms = []map[string]interface{}{}
|
|
||||||
|
|
||||||
if len(vs) == 0 {
|
// >> Args
|
||||||
return NOMessage, errInvalidNumberOfArguments
|
|
||||||
|
args := msg.Args
|
||||||
|
if len(args) < 2 {
|
||||||
|
return retrerr(errInvalidNumberOfArguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// >> Operation
|
||||||
|
|
||||||
var vals []resp.Value
|
var vals []resp.Value
|
||||||
var key string
|
var ms = []map[string]interface{}{}
|
||||||
var ok bool
|
for i := 1; i < len(args); i++ {
|
||||||
for {
|
key := args[i]
|
||||||
vs, key, ok = tokenval(vs)
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
col, _ := s.cols.Get(key)
|
col, _ := s.cols.Get(key)
|
||||||
if col != nil {
|
if col != nil {
|
||||||
m := make(map[string]interface{})
|
m := make(map[string]interface{})
|
||||||
@ -83,18 +84,15 @@ func (s *Server) cmdStats(msg *Message) (res resp.Value, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch msg.OutputType {
|
|
||||||
case JSON:
|
|
||||||
|
|
||||||
data, err := json.Marshal(ms)
|
// >> Response
|
||||||
if err != nil {
|
|
||||||
return NOMessage, err
|
if msg.OutputType == JSON {
|
||||||
}
|
data, _ := json.Marshal(ms)
|
||||||
res = resp.StringValue(`{"ok":true,"stats":` + string(data) + `,"elapsed":"` + time.Since(start).String() + "\"}")
|
return resp.StringValue(`{"ok":true,"stats":` + string(data) +
|
||||||
case RESP:
|
`,"elapsed":"` + time.Since(start).String() + "\"}"), nil
|
||||||
res = resp.ArrayValue(vals)
|
|
||||||
}
|
}
|
||||||
return res, nil
|
return resp.ArrayValue(vals), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) cmdHealthz(msg *Message) (res resp.Value, err error) {
|
func (s *Server) cmdHealthz(msg *Message) (res resp.Value, err error) {
|
||||||
|
@ -249,94 +249,149 @@ func keys_KEYS_test(mc *mockServer) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
func keys_PERSIST_test(mc *mockServer) error {
|
func keys_PERSIST_test(mc *mockServer) error {
|
||||||
return mc.DoBatch([][]interface{}{
|
return mc.DoBatch(
|
||||||
{"SET", "mykey", "myid", "STRING", "value"}, {"OK"},
|
Do("SET", "mykey", "myid", "STRING", "value").OK(),
|
||||||
{"EXPIRE", "mykey", "myid", 2}, {1},
|
Do("EXPIRE", "mykey", "myid", 2).Str("1"),
|
||||||
{"PERSIST", "mykey", "myid"}, {1},
|
Do("PERSIST", "mykey", "myid").Str("1"),
|
||||||
{"PERSIST", "mykey", "myid"}, {0},
|
Do("PERSIST", "mykey", "myid").Str("0"),
|
||||||
})
|
Do("PERSIST", "mykey").Err("wrong number of arguments for 'persist' command"),
|
||||||
|
Do("PERSIST", "mykey2", "myid").Str("0"),
|
||||||
|
Do("PERSIST", "mykey2", "myid").JSON().Err("key not found"),
|
||||||
|
Do("PERSIST", "mykey", "myid2").Str("0"),
|
||||||
|
Do("PERSIST", "mykey", "myid2").JSON().Err("id not found"),
|
||||||
|
Do("EXPIRE", "mykey", "myid", 2).Str("1"),
|
||||||
|
Do("PERSIST", "mykey", "myid").JSON().OK(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
func keys_SET_test(mc *mockServer) error {
|
func keys_SET_test(mc *mockServer) error {
|
||||||
return mc.DoBatch(
|
return mc.DoBatch(
|
||||||
"point", [][]interface{}{
|
// Section: point
|
||||||
{"SET", "mykey", "myid", "POINT", 33, -115}, {"OK"},
|
Do("SET", "mykey", "myid", "POINT", 33, -115).OK(),
|
||||||
{"GET", "mykey", "myid", "POINT"}, {"[33 -115]"},
|
Do("GET", "mykey", "myid", "POINT").Str("[33 -115]"),
|
||||||
{"GET", "mykey", "myid", "BOUNDS"}, {"[[33 -115] [33 -115]]"},
|
Do("GET", "mykey", "myid", "BOUNDS").Str("[[33 -115] [33 -115]]"),
|
||||||
{"GET", "mykey", "myid", "OBJECT"}, {`{"type":"Point","coordinates":[-115,33]}`},
|
Do("GET", "mykey", "myid", "OBJECT").Str(`{"type":"Point","coordinates":[-115,33]}`),
|
||||||
{"GET", "mykey", "myid", "HASH", 7}, {"9my5xp7"},
|
Do("GET", "mykey", "myid", "HASH", 7).Str("9my5xp7"),
|
||||||
{"DEL", "mykey", "myid"}, {"1"},
|
Do("DEL", "mykey", "myid").Str("1"),
|
||||||
{"GET", "mykey", "myid"}, {nil},
|
Do("GET", "mykey", "myid").Str("<nil>"),
|
||||||
},
|
Do("SET", "mykey", "myid", "point", "33", "-112", "99").OK(),
|
||||||
"object", [][]interface{}{
|
|
||||||
{"SET", "mykey", "myid", "OBJECT", `{"type":"Point","coordinates":[-115,33]}`}, {"OK"},
|
// Section: object
|
||||||
{"GET", "mykey", "myid", "POINT"}, {"[33 -115]"},
|
Do("SET", "mykey", "myid", "OBJECT", `{"type":"Point","coordinates":[-115,33]}`).OK(),
|
||||||
{"GET", "mykey", "myid", "BOUNDS"}, {"[[33 -115] [33 -115]]"},
|
Do("GET", "mykey", "myid", "POINT").Str("[33 -115]"),
|
||||||
{"GET", "mykey", "myid", "OBJECT"}, {`{"type":"Point","coordinates":[-115,33]}`},
|
Do("GET", "mykey", "myid", "BOUNDS").Str("[[33 -115] [33 -115]]"),
|
||||||
{"GET", "mykey", "myid", "HASH", 7}, {"9my5xp7"},
|
Do("GET", "mykey", "myid", "OBJECT").Str(`{"type":"Point","coordinates":[-115,33]}`),
|
||||||
{"DEL", "mykey", "myid"}, {"1"},
|
Do("GET", "mykey", "myid", "HASH", 7).Str("9my5xp7"),
|
||||||
{"GET", "mykey", "myid"}, {nil},
|
Do("DEL", "mykey", "myid").Str("1"),
|
||||||
},
|
Do("GET", "mykey", "myid").Str("<nil>"),
|
||||||
"bounds", [][]interface{}{
|
|
||||||
{"SET", "mykey", "myid", "BOUNDS", 33, -115, 33, -115}, {"OK"},
|
// Section: bounds
|
||||||
{"GET", "mykey", "myid", "POINT"}, {"[33 -115]"},
|
Do("SET", "mykey", "myid", "BOUNDS", 33, -115, 33, -115).OK(),
|
||||||
{"GET", "mykey", "myid", "BOUNDS"}, {"[[33 -115] [33 -115]]"},
|
Do("GET", "mykey", "myid", "POINT").Str("[33 -115]"),
|
||||||
{"GET", "mykey", "myid", "OBJECT"}, {`{"type":"Point","coordinates":[-115,33]}`},
|
Do("GET", "mykey", "myid", "BOUNDS").Str("[[33 -115] [33 -115]]"),
|
||||||
{"GET", "mykey", "myid", "HASH", 7}, {"9my5xp7"},
|
Do("GET", "mykey", "myid", "OBJECT").Str(`{"type":"Point","coordinates":[-115,33]}`),
|
||||||
{"DEL", "mykey", "myid"}, {"1"},
|
Do("GET", "mykey", "myid", "HASH", 7).Str("9my5xp7"),
|
||||||
{"GET", "mykey", "myid"}, {nil},
|
Do("DEL", "mykey", "myid").Str("1"),
|
||||||
},
|
Do("GET", "mykey", "myid").Str("<nil>"),
|
||||||
"hash", [][]interface{}{
|
|
||||||
{"SET", "mykey", "myid", "HASH", "9my5xp7"}, {"OK"},
|
// Section: hash
|
||||||
{"GET", "mykey", "myid", "HASH", 7}, {"9my5xp7"},
|
Do("SET", "mykey", "myid", "HASH", "9my5xp7").OK(),
|
||||||
{"DEL", "mykey", "myid"}, {"1"},
|
Do("GET", "mykey", "myid", "HASH", 7).Str("9my5xp7"),
|
||||||
{"GET", "mykey", "myid"}, {nil},
|
Do("DEL", "mykey", "myid").Str("1"),
|
||||||
},
|
Do("GET", "mykey", "myid").Str("<nil>"),
|
||||||
"field", [][]interface{}{
|
Do("SET", "mykey", "myid", "HASH", "9my5xp7").JSON().OK(),
|
||||||
{"SET", "mykey", "myid", "FIELD", "f1", 33, "FIELD", "a2", 44.5, "HASH", "9my5xp7"}, {"OK"},
|
|
||||||
{"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7 [a2 44.5 f1 33]]"},
|
// Section: field
|
||||||
{"FSET", "mykey", "myid", "f1", 0}, {1},
|
Do("SET", "mykey", "myid", "FIELD", "f1", 33, "FIELD", "a2", 44.5, "HASH", "9my5xp7").OK(),
|
||||||
{"FSET", "mykey", "myid", "f1", 0}, {0},
|
Do("GET", "mykey", "myid", "WITHFIELDS", "HASH", 7).Str("[9my5xp7 [a2 44.5 f1 33]]"),
|
||||||
{"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7 [a2 44.5]]"},
|
Do("FSET", "mykey", "myid", "f1", 0).Str("1"),
|
||||||
{"DEL", "mykey", "myid"}, {"1"},
|
Do("FSET", "mykey", "myid", "f1", 0).Str("0"),
|
||||||
{"GET", "mykey", "myid"}, {nil},
|
Do("GET", "mykey", "myid", "WITHFIELDS", "HASH", 7).Str("[9my5xp7 [a2 44.5]]"),
|
||||||
},
|
Do("DEL", "mykey", "myid").Str("1"),
|
||||||
"string", [][]interface{}{
|
Do("GET", "mykey", "myid").Str("<nil>"),
|
||||||
{"SET", "mykey", "myid", "STRING", "value"}, {"OK"},
|
|
||||||
{"GET", "mykey", "myid"}, {"value"},
|
// Section: string
|
||||||
{"SET", "mykey", "myid", "STRING", "value2"}, {"OK"},
|
Do("SET", "mykey", "myid", "STRING", "value").OK(),
|
||||||
{"GET", "mykey", "myid"}, {"value2"},
|
Do("GET", "mykey", "myid").Str("value"),
|
||||||
{"DEL", "mykey", "myid"}, {"1"},
|
Do("SET", "mykey", "myid", "STRING", "value2").OK(),
|
||||||
{"GET", "mykey", "myid"}, {nil},
|
Do("GET", "mykey", "myid").Str("value2"),
|
||||||
},
|
Do("DEL", "mykey", "myid").Str("1"),
|
||||||
|
Do("GET", "mykey", "myid").Str("<nil>"),
|
||||||
|
|
||||||
|
// Test error conditions
|
||||||
|
Do("CONFIG", "SET", "maxmemory", "1").OK(),
|
||||||
|
Do("SET", "mykey", "myid", "STRING", "value2").Err("OOM command not allowed when used memory > 'maxmemory'"),
|
||||||
|
Do("CONFIG", "SET", "maxmemory", "0").OK(),
|
||||||
|
Do("SET").Err("wrong number of arguments for 'set' command"),
|
||||||
|
Do("SET", "mykey", "myid", "FIELD", "f1").Err("wrong number of arguments for 'set' command"),
|
||||||
|
Do("SET", "mykey", "myid", "FIELD", "z", "1").Err("invalid argument 'z'"),
|
||||||
|
Do("SET", "mykey", "myid", "EX").Err("wrong number of arguments for 'set' command"),
|
||||||
|
Do("SET", "mykey", "myid", "EX", "yyy").Err("invalid argument 'yyy'"),
|
||||||
|
Do("SET", "mykey", "myid", "EX", "123").Err("wrong number of arguments for 'set' command"),
|
||||||
|
Do("SET", "mykey", "myid", "nx").Err("wrong number of arguments for 'set' command"),
|
||||||
|
Do("SET", "mykey", "myid", "nx", "xx").Err("invalid argument 'xx'"),
|
||||||
|
Do("SET", "mykey", "myid", "xx", "nx").Err("invalid argument 'nx'"),
|
||||||
|
Do("SET", "mykey", "myid", "string").Err("wrong number of arguments for 'set' command"),
|
||||||
|
Do("SET", "mykey", "myid", "point").Err("wrong number of arguments for 'set' command"),
|
||||||
|
Do("SET", "mykey", "myid", "point", "33").Err("wrong number of arguments for 'set' command"),
|
||||||
|
Do("SET", "mykey", "myid", "point", "33f", "-112").Err("invalid argument '33f'"),
|
||||||
|
Do("SET", "mykey", "myid", "point", "33", "-112f").Err("invalid argument '-112f'"),
|
||||||
|
Do("SET", "mykey", "myid", "point", "33", "-112f", "99").Err("invalid argument '-112f'"),
|
||||||
|
Do("SET", "mykey", "myid", "bounds").Err("wrong number of arguments for 'set' command"),
|
||||||
|
Do("SET", "mykey", "myid", "bounds", "fff", "1", "2", "3").Err("invalid argument 'fff'"),
|
||||||
|
Do("SET", "mykey", "myid", "hash").Err("wrong number of arguments for 'set' command"),
|
||||||
|
Do("SET", "mykey", "myid", "object").Err("wrong number of arguments for 'set' command"),
|
||||||
|
Do("SET", "mykey", "myid", "object", "asd").Err("invalid data"),
|
||||||
|
Do("SET", "mykey", "myid", "joint").Err("invalid argument 'joint'"),
|
||||||
|
Do("SET", "mykey", "myid", "XX", "HASH", "9my5xp7").Err("<nil>"),
|
||||||
|
Do("SET", "mykey", "myid", "XX", "HASH", "9my5xp7").JSON().Err("id not found"),
|
||||||
|
Do("SET", "mykey", "myid1", "HASH", "9my5xp7").OK(),
|
||||||
|
Do("SET", "mykey", "myid", "XX", "HASH", "9my5xp7").Err("<nil>"),
|
||||||
|
Do("SET", "mykey", "myid", "NX", "HASH", "9my5xp7").OK(),
|
||||||
|
Do("SET", "mykey", "myid", "XX", "HASH", "9my5xp7").OK(),
|
||||||
|
Do("SET", "mykey", "myid", "NX", "HASH", "9my5xp7").Err("<nil>"),
|
||||||
|
Do("SET", "mykey", "myid", "NX", "HASH", "9my5xp7").JSON().Err("id already exists"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func keys_STATS_test(mc *mockServer) error {
|
func keys_STATS_test(mc *mockServer) error {
|
||||||
return mc.DoBatch([][]interface{}{
|
return mc.DoBatch(
|
||||||
{"STATS", "mykey"}, {"[nil]"},
|
Do("STATS", "mykey").Str("[nil]"),
|
||||||
{"SET", "mykey", "myid", "STRING", "value"}, {"OK"},
|
Do("SET", "mykey", "myid", "STRING", "value").OK(),
|
||||||
{"STATS", "mykey"}, {"[[in_memory_size 9 num_objects 1 num_points 0 num_strings 1]]"},
|
Do("STATS", "mykey").Str("[[in_memory_size 9 num_objects 1 num_points 0 num_strings 1]]"),
|
||||||
{"SET", "mykey", "myid2", "STRING", "value"}, {"OK"},
|
Do("STATS", "mykey", "hello").JSON().Str(`{"ok":true,"stats":[{"in_memory_size":9,"num_objects":1,"num_points":0,"num_strings":1},null]}`),
|
||||||
{"STATS", "mykey"}, {"[[in_memory_size 19 num_objects 2 num_points 0 num_strings 2]]"},
|
Do("SET", "mykey", "myid2", "STRING", "value").OK(),
|
||||||
{"SET", "mykey", "myid3", "OBJECT", `{"type":"Point","coordinates":[-115,33]}`}, {"OK"},
|
Do("STATS", "mykey").Str("[[in_memory_size 19 num_objects 2 num_points 0 num_strings 2]]"),
|
||||||
{"STATS", "mykey"}, {"[[in_memory_size 40 num_objects 3 num_points 1 num_strings 2]]"},
|
Do("SET", "mykey", "myid3", "OBJECT", `{"type":"Point","coordinates":[-115,33]}`).OK(),
|
||||||
{"DEL", "mykey", "myid"}, {1},
|
Do("STATS", "mykey").Str("[[in_memory_size 40 num_objects 3 num_points 1 num_strings 2]]"),
|
||||||
{"STATS", "mykey"}, {"[[in_memory_size 31 num_objects 2 num_points 1 num_strings 1]]"},
|
Do("DEL", "mykey", "myid").Str("1"),
|
||||||
{"DEL", "mykey", "myid3"}, {1},
|
Do("STATS", "mykey").Str("[[in_memory_size 31 num_objects 2 num_points 1 num_strings 1]]"),
|
||||||
{"STATS", "mykey"}, {"[[in_memory_size 10 num_objects 1 num_points 0 num_strings 1]]"},
|
Do("DEL", "mykey", "myid3").Str("1"),
|
||||||
{"STATS", "mykey", "mykey2"}, {"[[in_memory_size 10 num_objects 1 num_points 0 num_strings 1] nil]"},
|
Do("STATS", "mykey").Str("[[in_memory_size 10 num_objects 1 num_points 0 num_strings 1]]"),
|
||||||
{"DEL", "mykey", "myid2"}, {1},
|
Do("STATS", "mykey", "mykey2").Str("[[in_memory_size 10 num_objects 1 num_points 0 num_strings 1] nil]"),
|
||||||
{"STATS", "mykey"}, {"[nil]"},
|
Do("DEL", "mykey", "myid2").Str("1"),
|
||||||
{"STATS", "mykey", "mykey2"}, {"[nil nil]"},
|
Do("STATS", "mykey").Str("[nil]"),
|
||||||
})
|
Do("STATS", "mykey", "mykey2").Str("[nil nil]"),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
func keys_TTL_test(mc *mockServer) error {
|
func keys_TTL_test(mc *mockServer) error {
|
||||||
return mc.DoBatch([][]interface{}{
|
return mc.DoBatch(
|
||||||
{"SET", "mykey", "myid", "STRING", "value"}, {"OK"},
|
Do("SET", "mykey", "myid", "STRING", "value").OK(),
|
||||||
{"EXPIRE", "mykey", "myid", 2}, {1},
|
Do("EXPIRE", "mykey", "myid", 2).Str("1"),
|
||||||
{time.Second / 4}, {}, // sleep
|
Do("EXPIRE", "mykey", "myid", 2).JSON().OK(),
|
||||||
{"TTL", "mykey", "myid"}, {1},
|
Sleep(time.Millisecond*10),
|
||||||
})
|
Do("TTL", "mykey", "myid").Str("1"),
|
||||||
|
Do("EXPIRE", "mykey", "myid", 1).Str("1"),
|
||||||
|
Sleep(time.Millisecond*10),
|
||||||
|
Do("TTL", "mykey", "myid").Str("0"),
|
||||||
|
Do("TTL", "mykey", "myid").JSON().Str(`{"ok":true,"ttl":0}`),
|
||||||
|
Do("TTL", "mykey2", "myid").Str("-2"),
|
||||||
|
Do("TTL", "mykey", "myid2").Str("-2"),
|
||||||
|
Do("TTL", "mykey").Err("wrong number of arguments for 'ttl' command"),
|
||||||
|
Do("SET", "mykey", "myid", "STRING", "value").OK(),
|
||||||
|
Do("TTL", "mykey", "myid").Str("-1"),
|
||||||
|
Do("TTL", "mykey2", "myid").JSON().Err("key not found"),
|
||||||
|
Do("TTL", "mykey", "myid2").JSON().Err("id not found"),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func keys_SET_EX_test(mc *mockServer) (err error) {
|
func keys_SET_EX_test(mc *mockServer) (err error) {
|
||||||
@ -465,7 +520,7 @@ func keys_FLUSHDB_test(mc *mockServer) error {
|
|||||||
Do("SET", "mykey2", "myid1", "POINT", 33, -115).OK(),
|
Do("SET", "mykey2", "myid1", "POINT", 33, -115).OK(),
|
||||||
Do("SETCHAN", "mychan", "INTERSECTS", "mykey1", "BOUNDS", 10, 10, 10, 10).Str("1"),
|
Do("SETCHAN", "mychan", "INTERSECTS", "mykey1", "BOUNDS", 10, 10, 10, 10).Str("1"),
|
||||||
Do("KEYS", "*").Str("[mykey1 mykey2]"),
|
Do("KEYS", "*").Str("[mykey1 mykey2]"),
|
||||||
Do("CHANS", "*").JSON().Custom(func(s string) error {
|
Do("CHANS", "*").JSON().Func(func(s string) error {
|
||||||
if gjson.Get(s, "chans.#").Int() != 1 {
|
if gjson.Get(s, "chans.#").Int() != 1 {
|
||||||
return fmt.Errorf("expected '%d', got '%d'", 1, gjson.Get(s, "chans.#").Int())
|
return fmt.Errorf("expected '%d', got '%d'", 1, gjson.Get(s, "chans.#").Int())
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ func (cmd *IO) Str(s string) *IO {
|
|||||||
cmd.out = s
|
cmd.out = s
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
func (cmd *IO) Custom(fn func(s string) error) *IO {
|
func (cmd *IO) Func(fn func(s string) error) *IO {
|
||||||
cmd.out = func(s string) error {
|
cmd.out = func(s string) error {
|
||||||
if cmd.json {
|
if cmd.json {
|
||||||
if !gjson.Valid(s) {
|
if !gjson.Valid(s) {
|
||||||
@ -47,7 +47,7 @@ func (cmd *IO) Custom(fn func(s string) error) *IO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *IO) OK() *IO {
|
func (cmd *IO) OK() *IO {
|
||||||
return cmd.Custom(func(s string) error {
|
return cmd.Func(func(s string) error {
|
||||||
if cmd.json {
|
if cmd.json {
|
||||||
if gjson.Get(s, "ok").Type != gjson.True {
|
if gjson.Get(s, "ok").Type != gjson.True {
|
||||||
return errors.New("not ok")
|
return errors.New("not ok")
|
||||||
@ -60,7 +60,7 @@ func (cmd *IO) OK() *IO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *IO) Err(msg string) *IO {
|
func (cmd *IO) Err(msg string) *IO {
|
||||||
return cmd.Custom(func(s string) error {
|
return cmd.Func(func(s string) error {
|
||||||
if cmd.json {
|
if cmd.json {
|
||||||
if gjson.Get(s, "ok").Type != gjson.False {
|
if gjson.Get(s, "ok").Type != gjson.False {
|
||||||
return errors.New("ok=true")
|
return errors.New("ok=true")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user