mirror of https://github.com/tidwall/tile38.git
Better SET/PERSIST/TTL/STATS tests
This commit is contained in:
parent
7fa2dc4419
commit
295a9c45a8
|
@ -2,7 +2,7 @@ package server
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -706,23 +706,22 @@ func (s *Server) cmdSET(msg *Message) (resp.Value, commandDetails, error) {
|
|||
return retwerr(errInvalidArgument(args[i]))
|
||||
}
|
||||
}
|
||||
if oobj == nil {
|
||||
return retwerr(errInvalidNumberOfArguments)
|
||||
}
|
||||
|
||||
// >> Operation
|
||||
|
||||
nada := func() (resp.Value, commandDetails, error) {
|
||||
// exclude operation due to 'xx' or 'nx' match
|
||||
switch msg.OutputType {
|
||||
default:
|
||||
case JSON:
|
||||
if msg.OutputType == JSON {
|
||||
if nx {
|
||||
return retwerr(errIDAlreadyExists)
|
||||
} else {
|
||||
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)
|
||||
|
@ -931,11 +930,17 @@ func (s *Server) cmdEXPIRE(msg *Message) (resp.Value, commandDetails, error) {
|
|||
// PERSIST key id
|
||||
func (s *Server) cmdPERSIST(msg *Message) (resp.Value, commandDetails, error) {
|
||||
start := time.Now()
|
||||
|
||||
// >> Args
|
||||
|
||||
args := msg.Args
|
||||
if len(args) != 3 {
|
||||
return retwerr(errInvalidNumberOfArguments)
|
||||
}
|
||||
key, id := args[1], args[2]
|
||||
|
||||
// >> Operation
|
||||
|
||||
col, _ := s.cols.Get(key)
|
||||
if col == nil {
|
||||
if msg.OutputType == RESP {
|
||||
|
@ -959,6 +964,8 @@ func (s *Server) cmdPERSIST(msg *Message) (resp.Value, commandDetails, error) {
|
|||
cleared = true
|
||||
}
|
||||
|
||||
// >> Response
|
||||
|
||||
var res resp.Value
|
||||
|
||||
var d commandDetails
|
||||
|
@ -985,62 +992,47 @@ func (s *Server) cmdPERSIST(msg *Message) (resp.Value, commandDetails, error) {
|
|||
// TTL key id
|
||||
func (s *Server) cmdTTL(msg *Message) (resp.Value, error) {
|
||||
start := time.Now()
|
||||
|
||||
// >> Args
|
||||
|
||||
args := msg.Args
|
||||
if len(args) != 3 {
|
||||
return retrerr(errInvalidNumberOfArguments)
|
||||
}
|
||||
key, id := args[1], args[2]
|
||||
var v float64
|
||||
var ok bool
|
||||
var ok2 bool
|
||||
|
||||
// >> Operation
|
||||
|
||||
col, _ := s.cols.Get(key)
|
||||
if col != nil {
|
||||
o := col.Get(id)
|
||||
ok = o != nil
|
||||
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
|
||||
}
|
||||
}
|
||||
if col == nil {
|
||||
if msg.OutputType == JSON {
|
||||
return retrerr(errKeyNotFound)
|
||||
}
|
||||
return resp.IntegerValue(-2), nil
|
||||
}
|
||||
var res resp.Value
|
||||
switch msg.OutputType {
|
||||
case JSON:
|
||||
if ok {
|
||||
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)
|
||||
}
|
||||
|
||||
o := col.Get(id)
|
||||
if o == nil {
|
||||
if msg.OutputType == JSON {
|
||||
return retrerr(errIDNotFound)
|
||||
}
|
||||
case RESP:
|
||||
if ok {
|
||||
if ok2 {
|
||||
res = resp.IntegerValue(int(v))
|
||||
} else {
|
||||
res = resp.IntegerValue(-1)
|
||||
}
|
||||
} else {
|
||||
res = resp.IntegerValue(-2)
|
||||
}
|
||||
return resp.IntegerValue(-2), nil
|
||||
}
|
||||
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":
|
||||
res, err = s.cmdTTL(msg)
|
||||
case "stats":
|
||||
res, err = s.cmdStats(msg)
|
||||
res, err = s.cmdSTATS(msg)
|
||||
case "scan":
|
||||
res, err = s.cmdScan(msg)
|
||||
case "nearby":
|
||||
|
|
|
@ -1080,7 +1080,7 @@ func (s *Server) command(msg *Message, client *Client) (
|
|||
case "readonly":
|
||||
res, err = s.cmdReadOnly(msg)
|
||||
case "stats":
|
||||
res, err = s.cmdStats(msg)
|
||||
res, err = s.cmdSTATS(msg)
|
||||
case "server":
|
||||
res, err = s.cmdServer(msg)
|
||||
case "healthz":
|
||||
|
|
|
@ -45,22 +45,23 @@ func readMemStats() runtime.MemStats {
|
|||
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()
|
||||
vs := msg.Args[1:]
|
||||
var ms = []map[string]interface{}{}
|
||||
|
||||
if len(vs) == 0 {
|
||||
return NOMessage, errInvalidNumberOfArguments
|
||||
// >> Args
|
||||
|
||||
args := msg.Args
|
||||
if len(args) < 2 {
|
||||
return retrerr(errInvalidNumberOfArguments)
|
||||
}
|
||||
|
||||
// >> Operation
|
||||
|
||||
var vals []resp.Value
|
||||
var key string
|
||||
var ok bool
|
||||
for {
|
||||
vs, key, ok = tokenval(vs)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
var ms = []map[string]interface{}{}
|
||||
for i := 1; i < len(args); i++ {
|
||||
key := args[i]
|
||||
col, _ := s.cols.Get(key)
|
||||
if col != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
return NOMessage, err
|
||||
}
|
||||
res = resp.StringValue(`{"ok":true,"stats":` + string(data) + `,"elapsed":"` + time.Since(start).String() + "\"}")
|
||||
case RESP:
|
||||
res = resp.ArrayValue(vals)
|
||||
// >> Response
|
||||
|
||||
if msg.OutputType == JSON {
|
||||
data, _ := json.Marshal(ms)
|
||||
return resp.StringValue(`{"ok":true,"stats":` + string(data) +
|
||||
`,"elapsed":"` + time.Since(start).String() + "\"}"), nil
|
||||
}
|
||||
return res, nil
|
||||
return resp.ArrayValue(vals), nil
|
||||
}
|
||||
|
||||
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 {
|
||||
return mc.DoBatch([][]interface{}{
|
||||
{"SET", "mykey", "myid", "STRING", "value"}, {"OK"},
|
||||
{"EXPIRE", "mykey", "myid", 2}, {1},
|
||||
{"PERSIST", "mykey", "myid"}, {1},
|
||||
{"PERSIST", "mykey", "myid"}, {0},
|
||||
})
|
||||
return mc.DoBatch(
|
||||
Do("SET", "mykey", "myid", "STRING", "value").OK(),
|
||||
Do("EXPIRE", "mykey", "myid", 2).Str("1"),
|
||||
Do("PERSIST", "mykey", "myid").Str("1"),
|
||||
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 {
|
||||
return mc.DoBatch(
|
||||
"point", [][]interface{}{
|
||||
{"SET", "mykey", "myid", "POINT", 33, -115}, {"OK"},
|
||||
{"GET", "mykey", "myid", "POINT"}, {"[33 -115]"},
|
||||
{"GET", "mykey", "myid", "BOUNDS"}, {"[[33 -115] [33 -115]]"},
|
||||
{"GET", "mykey", "myid", "OBJECT"}, {`{"type":"Point","coordinates":[-115,33]}`},
|
||||
{"GET", "mykey", "myid", "HASH", 7}, {"9my5xp7"},
|
||||
{"DEL", "mykey", "myid"}, {"1"},
|
||||
{"GET", "mykey", "myid"}, {nil},
|
||||
},
|
||||
"object", [][]interface{}{
|
||||
{"SET", "mykey", "myid", "OBJECT", `{"type":"Point","coordinates":[-115,33]}`}, {"OK"},
|
||||
{"GET", "mykey", "myid", "POINT"}, {"[33 -115]"},
|
||||
{"GET", "mykey", "myid", "BOUNDS"}, {"[[33 -115] [33 -115]]"},
|
||||
{"GET", "mykey", "myid", "OBJECT"}, {`{"type":"Point","coordinates":[-115,33]}`},
|
||||
{"GET", "mykey", "myid", "HASH", 7}, {"9my5xp7"},
|
||||
{"DEL", "mykey", "myid"}, {"1"},
|
||||
{"GET", "mykey", "myid"}, {nil},
|
||||
},
|
||||
"bounds", [][]interface{}{
|
||||
{"SET", "mykey", "myid", "BOUNDS", 33, -115, 33, -115}, {"OK"},
|
||||
{"GET", "mykey", "myid", "POINT"}, {"[33 -115]"},
|
||||
{"GET", "mykey", "myid", "BOUNDS"}, {"[[33 -115] [33 -115]]"},
|
||||
{"GET", "mykey", "myid", "OBJECT"}, {`{"type":"Point","coordinates":[-115,33]}`},
|
||||
{"GET", "mykey", "myid", "HASH", 7}, {"9my5xp7"},
|
||||
{"DEL", "mykey", "myid"}, {"1"},
|
||||
{"GET", "mykey", "myid"}, {nil},
|
||||
},
|
||||
"hash", [][]interface{}{
|
||||
{"SET", "mykey", "myid", "HASH", "9my5xp7"}, {"OK"},
|
||||
{"GET", "mykey", "myid", "HASH", 7}, {"9my5xp7"},
|
||||
{"DEL", "mykey", "myid"}, {"1"},
|
||||
{"GET", "mykey", "myid"}, {nil},
|
||||
},
|
||||
"field", [][]interface{}{
|
||||
{"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]]"},
|
||||
{"FSET", "mykey", "myid", "f1", 0}, {1},
|
||||
{"FSET", "mykey", "myid", "f1", 0}, {0},
|
||||
{"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7 [a2 44.5]]"},
|
||||
{"DEL", "mykey", "myid"}, {"1"},
|
||||
{"GET", "mykey", "myid"}, {nil},
|
||||
},
|
||||
"string", [][]interface{}{
|
||||
{"SET", "mykey", "myid", "STRING", "value"}, {"OK"},
|
||||
{"GET", "mykey", "myid"}, {"value"},
|
||||
{"SET", "mykey", "myid", "STRING", "value2"}, {"OK"},
|
||||
{"GET", "mykey", "myid"}, {"value2"},
|
||||
{"DEL", "mykey", "myid"}, {"1"},
|
||||
{"GET", "mykey", "myid"}, {nil},
|
||||
},
|
||||
// Section: point
|
||||
Do("SET", "mykey", "myid", "POINT", 33, -115).OK(),
|
||||
Do("GET", "mykey", "myid", "POINT").Str("[33 -115]"),
|
||||
Do("GET", "mykey", "myid", "BOUNDS").Str("[[33 -115] [33 -115]]"),
|
||||
Do("GET", "mykey", "myid", "OBJECT").Str(`{"type":"Point","coordinates":[-115,33]}`),
|
||||
Do("GET", "mykey", "myid", "HASH", 7).Str("9my5xp7"),
|
||||
Do("DEL", "mykey", "myid").Str("1"),
|
||||
Do("GET", "mykey", "myid").Str("<nil>"),
|
||||
Do("SET", "mykey", "myid", "point", "33", "-112", "99").OK(),
|
||||
|
||||
// Section: object
|
||||
Do("SET", "mykey", "myid", "OBJECT", `{"type":"Point","coordinates":[-115,33]}`).OK(),
|
||||
Do("GET", "mykey", "myid", "POINT").Str("[33 -115]"),
|
||||
Do("GET", "mykey", "myid", "BOUNDS").Str("[[33 -115] [33 -115]]"),
|
||||
Do("GET", "mykey", "myid", "OBJECT").Str(`{"type":"Point","coordinates":[-115,33]}`),
|
||||
Do("GET", "mykey", "myid", "HASH", 7).Str("9my5xp7"),
|
||||
Do("DEL", "mykey", "myid").Str("1"),
|
||||
Do("GET", "mykey", "myid").Str("<nil>"),
|
||||
|
||||
// Section: bounds
|
||||
Do("SET", "mykey", "myid", "BOUNDS", 33, -115, 33, -115).OK(),
|
||||
Do("GET", "mykey", "myid", "POINT").Str("[33 -115]"),
|
||||
Do("GET", "mykey", "myid", "BOUNDS").Str("[[33 -115] [33 -115]]"),
|
||||
Do("GET", "mykey", "myid", "OBJECT").Str(`{"type":"Point","coordinates":[-115,33]}`),
|
||||
Do("GET", "mykey", "myid", "HASH", 7).Str("9my5xp7"),
|
||||
Do("DEL", "mykey", "myid").Str("1"),
|
||||
Do("GET", "mykey", "myid").Str("<nil>"),
|
||||
|
||||
// Section: hash
|
||||
Do("SET", "mykey", "myid", "HASH", "9my5xp7").OK(),
|
||||
Do("GET", "mykey", "myid", "HASH", 7).Str("9my5xp7"),
|
||||
Do("DEL", "mykey", "myid").Str("1"),
|
||||
Do("GET", "mykey", "myid").Str("<nil>"),
|
||||
Do("SET", "mykey", "myid", "HASH", "9my5xp7").JSON().OK(),
|
||||
|
||||
// Section: field
|
||||
Do("SET", "mykey", "myid", "FIELD", "f1", 33, "FIELD", "a2", 44.5, "HASH", "9my5xp7").OK(),
|
||||
Do("GET", "mykey", "myid", "WITHFIELDS", "HASH", 7).Str("[9my5xp7 [a2 44.5 f1 33]]"),
|
||||
Do("FSET", "mykey", "myid", "f1", 0).Str("1"),
|
||||
Do("FSET", "mykey", "myid", "f1", 0).Str("0"),
|
||||
Do("GET", "mykey", "myid", "WITHFIELDS", "HASH", 7).Str("[9my5xp7 [a2 44.5]]"),
|
||||
Do("DEL", "mykey", "myid").Str("1"),
|
||||
Do("GET", "mykey", "myid").Str("<nil>"),
|
||||
|
||||
// Section: string
|
||||
Do("SET", "mykey", "myid", "STRING", "value").OK(),
|
||||
Do("GET", "mykey", "myid").Str("value"),
|
||||
Do("SET", "mykey", "myid", "STRING", "value2").OK(),
|
||||
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 {
|
||||
return mc.DoBatch([][]interface{}{
|
||||
{"STATS", "mykey"}, {"[nil]"},
|
||||
{"SET", "mykey", "myid", "STRING", "value"}, {"OK"},
|
||||
{"STATS", "mykey"}, {"[[in_memory_size 9 num_objects 1 num_points 0 num_strings 1]]"},
|
||||
{"SET", "mykey", "myid2", "STRING", "value"}, {"OK"},
|
||||
{"STATS", "mykey"}, {"[[in_memory_size 19 num_objects 2 num_points 0 num_strings 2]]"},
|
||||
{"SET", "mykey", "myid3", "OBJECT", `{"type":"Point","coordinates":[-115,33]}`}, {"OK"},
|
||||
{"STATS", "mykey"}, {"[[in_memory_size 40 num_objects 3 num_points 1 num_strings 2]]"},
|
||||
{"DEL", "mykey", "myid"}, {1},
|
||||
{"STATS", "mykey"}, {"[[in_memory_size 31 num_objects 2 num_points 1 num_strings 1]]"},
|
||||
{"DEL", "mykey", "myid3"}, {1},
|
||||
{"STATS", "mykey"}, {"[[in_memory_size 10 num_objects 1 num_points 0 num_strings 1]]"},
|
||||
{"STATS", "mykey", "mykey2"}, {"[[in_memory_size 10 num_objects 1 num_points 0 num_strings 1] nil]"},
|
||||
{"DEL", "mykey", "myid2"}, {1},
|
||||
{"STATS", "mykey"}, {"[nil]"},
|
||||
{"STATS", "mykey", "mykey2"}, {"[nil nil]"},
|
||||
})
|
||||
return mc.DoBatch(
|
||||
Do("STATS", "mykey").Str("[nil]"),
|
||||
Do("SET", "mykey", "myid", "STRING", "value").OK(),
|
||||
Do("STATS", "mykey").Str("[[in_memory_size 9 num_objects 1 num_points 0 num_strings 1]]"),
|
||||
Do("STATS", "mykey", "hello").JSON().Str(`{"ok":true,"stats":[{"in_memory_size":9,"num_objects":1,"num_points":0,"num_strings":1},null]}`),
|
||||
Do("SET", "mykey", "myid2", "STRING", "value").OK(),
|
||||
Do("STATS", "mykey").Str("[[in_memory_size 19 num_objects 2 num_points 0 num_strings 2]]"),
|
||||
Do("SET", "mykey", "myid3", "OBJECT", `{"type":"Point","coordinates":[-115,33]}`).OK(),
|
||||
Do("STATS", "mykey").Str("[[in_memory_size 40 num_objects 3 num_points 1 num_strings 2]]"),
|
||||
Do("DEL", "mykey", "myid").Str("1"),
|
||||
Do("STATS", "mykey").Str("[[in_memory_size 31 num_objects 2 num_points 1 num_strings 1]]"),
|
||||
Do("DEL", "mykey", "myid3").Str("1"),
|
||||
Do("STATS", "mykey").Str("[[in_memory_size 10 num_objects 1 num_points 0 num_strings 1]]"),
|
||||
Do("STATS", "mykey", "mykey2").Str("[[in_memory_size 10 num_objects 1 num_points 0 num_strings 1] nil]"),
|
||||
Do("DEL", "mykey", "myid2").Str("1"),
|
||||
Do("STATS", "mykey").Str("[nil]"),
|
||||
Do("STATS", "mykey", "mykey2").Str("[nil nil]"),
|
||||
)
|
||||
}
|
||||
func keys_TTL_test(mc *mockServer) error {
|
||||
return mc.DoBatch([][]interface{}{
|
||||
{"SET", "mykey", "myid", "STRING", "value"}, {"OK"},
|
||||
{"EXPIRE", "mykey", "myid", 2}, {1},
|
||||
{time.Second / 4}, {}, // sleep
|
||||
{"TTL", "mykey", "myid"}, {1},
|
||||
})
|
||||
return mc.DoBatch(
|
||||
Do("SET", "mykey", "myid", "STRING", "value").OK(),
|
||||
Do("EXPIRE", "mykey", "myid", 2).Str("1"),
|
||||
Do("EXPIRE", "mykey", "myid", 2).JSON().OK(),
|
||||
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) {
|
||||
|
@ -465,7 +520,7 @@ func keys_FLUSHDB_test(mc *mockServer) error {
|
|||
Do("SET", "mykey2", "myid1", "POINT", 33, -115).OK(),
|
||||
Do("SETCHAN", "mychan", "INTERSECTS", "mykey1", "BOUNDS", 10, 10, 10, 10).Str("1"),
|
||||
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 {
|
||||
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
|
||||
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 {
|
||||
if cmd.json {
|
||||
if !gjson.Valid(s) {
|
||||
|
@ -47,7 +47,7 @@ func (cmd *IO) Custom(fn func(s string) error) *IO {
|
|||
}
|
||||
|
||||
func (cmd *IO) OK() *IO {
|
||||
return cmd.Custom(func(s string) error {
|
||||
return cmd.Func(func(s string) error {
|
||||
if cmd.json {
|
||||
if gjson.Get(s, "ok").Type != gjson.True {
|
||||
return errors.New("not ok")
|
||||
|
@ -60,7 +60,7 @@ func (cmd *IO) OK() *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 gjson.Get(s, "ok").Type != gjson.False {
|
||||
return errors.New("ok=true")
|
||||
|
|
Loading…
Reference in New Issue