From 2f3d86cfaf10a41f2d6eabb5bb67027cda54f274 Mon Sep 17 00:00:00 2001 From: holys Date: Tue, 29 Jul 2014 16:22:07 +0800 Subject: [PATCH] Merge branch 'develop' of https://github.com/siddontang/ledisdb into develop Conflicts: Makefile --- commands.json | 334 ++++++++++++++++++++++++++++++++++++++++ generate.py | 74 +++++++++ server/cmd_bit.go | 38 +++-- server/cmd_bit_test.go | 160 +++++++++++++++++++ server/cmd_zset.go | 34 ++-- server/cmd_zset_test.go | 170 ++++++++++++++++++++ server/const.go | 4 + 7 files changed, 790 insertions(+), 24 deletions(-) create mode 100644 commands.json create mode 100644 generate.py diff --git a/commands.json b/commands.json new file mode 100644 index 0000000..d060151 --- /dev/null +++ b/commands.json @@ -0,0 +1,334 @@ +{ + "DECR": { + "arguments": "key decrement", + "group": "KV" + }, + "DECRBY": { + "arguments": "key [key ...]", + "group": "KV" + }, + "DEL": { + "arguments": "key", + "group": "KV" + }, + "EXISTS": { + "arguments": "key seconds", + "group": "KV" + }, + "EXPIRE": { + "arguments": "key timestamp", + "group": "KV" + }, + "EXPIREAT": { + "arguments": "key", + "group": "KV" + }, + "GET": { + "arguments": " key value", + "group": "KV" + }, + "GETSET": { + "arguments": "key", + "group": "KV" + }, + "INCR": { + "arguments": "key increment", + "group": "KV" + }, + "INCRBY": { + "arguments": "key [key ...]", + "group": "KV" + }, + "MGET": { + "arguments": "key value [key value ...]", + "group": "KV" + }, + "MSET": { + "arguments": "key value", + "group": "KV" + }, + "SET": { + "arguments": "key value", + "group": "KV" + }, + "SETNX": { + "arguments": "key", + "group": "KV" + }, + "TTL": { + "arguments": "key", + "group": "KV" + }, + "PERSIST": { + "arguments": "key field [field ...]", + "group": "Hash" + }, + "HDEL": { + "arguments": "key field", + "group": "Hash" + }, + "HEXISTS": { + "arguments": "key field", + "group": "Hash" + }, + "HGET": { + "arguments": "key", + "group": "Hash" + }, + "HGETALL": { + "arguments": "key field increment", + "group": "Hash" + }, + "HINCRBY": { + "arguments": "key", + "group": "Hash" + }, + "HKEYS": { + "arguments": "key", + "group": "Hash" + }, + "HLEN": { + "arguments": "key field [field ...]", + "group": "Hash" + }, + "HMGET": { + "arguments": "key field value [field value ...]", + "group": "Hash" + }, + "HMSET": { + "arguments": "key field value", + "group": "Hash" + }, + "HSET": { + "arguments": "key", + "group": "Hash" + }, + "HVALS": { + "arguments": "key", + "group": "Hash" + }, + "HCLEAR": { + "arguments": "key [key ...]", + "group": "Hash" + }, + "HMCLEAR": { + "arguments": "key seconds", + "group": "Hash" + }, + "HEXPIRE": { + "arguments": "key timestamp", + "group": "Hash" + }, + "HEXPIREAT": { + "arguments": "key", + "group": "Hash" + }, + "HTTL": { + "arguments": "key", + "group": "Hash" + }, + "HPERSIST": { + "arguments": "key index", + "group": "List" + }, + "LINDEX": { + "arguments": "key", + "group": "List" + }, + "LLEN": { + "arguments": "key", + "group": "List" + }, + "LPOP": { + "arguments": "key value [value ...]", + "group": "List" + }, + "LPUSH": { + "arguments": "key start stop", + "group": "List" + }, + "LRANGE": { + "arguments": "key", + "group": "List" + }, + "RPOP": { + "arguments": "key value [value ...]", + "group": "List" + }, + "RPUSH": { + "arguments": "key", + "group": "List" + }, + "LCLEAR": { + "arguments": "key [key ...]", + "group": "List" + }, + "LMCLEAR": { + "arguments": "key seconds", + "group": "List" + }, + "LEXPIRE": { + "arguments": "key timestamp", + "group": "List" + }, + "LEXPIREAT": { + "arguments": "key", + "group": "List" + }, + "LTTL": { + "arguments": "key", + "group": "List" + }, + "LPERSIST": { + "arguments": "key score member [score member ...]", + "group": "ZSet" + }, + "ZADD": { + "arguments": "key", + "group": "ZSet" + }, + "ZCARD": { + "arguments": "key min max", + "group": "ZSet" + }, + "ZCOUNT": { + "arguments": "key increment member", + "group": "ZSet" + }, + "ZINCRBY": { + "arguments": "key start stop [WITHSCORES]", + "group": "ZSet" + }, + "ZRANGE": { + "arguments": "key min max [WITHSCORES] [LIMIT offset count]", + "group": "ZSet" + }, + "ZRANGEBYSCORE": { + "arguments": "key member", + "group": "ZSet" + }, + "ZRANK": { + "arguments": "key member [member ...]", + "group": "ZSet" + }, + "ZREM": { + "arguments": "key start stop", + "group": "ZSet" + }, + "ZREMRANGEBYRANK": { + "arguments": "key min max", + "group": "ZSet" + }, + "ZREMRANGEBYSCORE": { + "arguments": "key start stop [WITHSCORES]", + "group": "ZSet" + }, + "ZREVRANGE": { + "arguments": "key max min [WITHSCORES][LIMIT offset count]", + "group": "ZSet" + }, + "ZREVRANGEBYSCORE": { + "arguments": "key member", + "group": "ZSet" + }, + "ZREVRANK": { + "arguments": "key member", + "group": "ZSet" + }, + "ZSCORE": { + "arguments": "key", + "group": "ZSet" + }, + "ZCLEAR": { + "arguments": "key [key ...]", + "group": "ZSet" + }, + "ZMCLEAR": { + "arguments": "key seconds", + "group": "ZSet" + }, + "ZEXPIRE": { + "arguments": "key timestamp", + "group": "ZSet" + }, + "ZEXPIREAT": { + "arguments": "key", + "group": "ZSet" + }, + "ZTTL": { + "arguments": "key", + "group": "ZSet" + }, + "ZPERSIST": { + "arguments": "key", + "group": "ZSet" + }, + "BDELETE": { + "arguments": "key", + "group": "Bitmap" + }, + "BGET": { + "arguments": "key offset", + "group": "Bitmap" + }, + "BGETBIT": { + "arguments": "key offset value", + "group": "Bitmap" + }, + "BSETBIT": { + "arguments": "key offset value [offset value ...]", + "group": "Bitmap" + }, + "BMSETBIT": { + "arguments": "operation destkey key [key ...]", + "group": "Bitmap" + }, + "BOPT": { + "arguments": "key [start end]", + "group": "Bitmap" + }, + "BCOUNT": { + "arguments": "key seconds", + "group": "Bitmap" + }, + "BEXPIRE": { + "arguments": "key timestamp", + "group": "Bitmap" + }, + "BEXPIREAT": { + "arguments": "key", + "group": "Bitmap" + }, + "BTTL": { + "arguments": "key", + "group": "Bitmap" + }, + "BPERSIST": { + "arguments": "host port", + "group": "Replication" + }, + "SLAVEOF": { + "arguments": "-", + "group": "Replication" + }, + "FULLSYNC": { + "arguments": "index offset", + "group": "Replication" + }, + "SYNC": { + "arguments": "-", + "group": "Server" + }, + "PING": { + "arguments": "message", + "group": "Server" + }, + "ECHO": { + "arguments": "index", + "group": "Server" + }, + "SELECT": { + "arguments": "index", + "group": "Server" + } +} \ No newline at end of file diff --git a/generate.py b/generate.py new file mode 100644 index 0000000..beba9e5 --- /dev/null +++ b/generate.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python + +import json +import time +from collections import OrderedDict as dict + + +def go_array_to_json(path): + """Convert `./cmd/ledis-cli/const.go` to commands.json""" + fp = open(path).read() + commands_str = fp.split("string")[1] + _commands_str = commands_str.splitlines()[1:len(commands_str.splitlines())-1] + commands_d = dict() + values_d = dict() + for i in _commands_str: + t = i.split('"') + values_d.update( + { + "arguments": "%s" % t[3], + "group": "%s" % t[5] + }) + values_d = dict(sorted(values_d.items())) + d = { + "%s" % t[1]: values_d + } + commands_d.update(d) + + fp = open("commands.json", "w") + json.dump(commands_d, fp, indent=4) + fp.close() + + +def json_to_js(json_path, js_path): + """Convert `commands.json` to `commands.js`""" + keys = [] + with open(json_path) as fp: + _json = json.load(fp) + for k in _json.keys(): + keys.append(k.encode('utf-8')) + with open(js_path, "w") as fp: + generate_time(fp) + fp.write("module.exports = [\n" ) + for k in sorted(keys): + fp.write('\t"%s",\n' % k.lower()) + fp.write("]") + + +def json_to_go_array(json_path, go_path): + g_fp = open(go_path, "w") + with open(json_path) as fp: + _json = json.load(fp) + generate_time(g_fp) + g_fp.write("package main\n\nvar helpCommands = [][]string{\n") + _json_sorted = dict(sorted(_json.items(), key=lambda x: x[0])) + for k, v in _json_sorted.iteritems(): + print k, v + g_fp.write('\t{"%s", "%s", "%s"},\n' % (k, v["arguments"], v["group"])) + g_fp.write("}\n") + g_fp.close() + + +def generate_time(fp): + fp.write("//This file was generated by ./generate.py on %s \n" % \ + time.strftime('%a %b %d %Y %H:%M:%S %z')) + +if __name__ == "__main__": + path = "./cmd/ledis-cli/const.go" + # go_array_to_json(path) + json_path = "./commands.json" + js_path = "./commands.js" + json_to_js(json_path, js_path) + go_path = "const.go" + + json_to_go_array(json_path, path) diff --git a/server/cmd_bit.go b/server/cmd_bit.go index 8fdd678..cb3d593 100644 --- a/server/cmd_bit.go +++ b/server/cmd_bit.go @@ -44,13 +44,18 @@ func bsetbitCommand(c *client) error { var val int8 offset, err = ledis.StrInt32(args[1], nil) + if err != nil { - return err + return ErrOffset } val, err = ledis.StrInt8(args[2], nil) + if val != 0 && val != 1 { + return ErrBool + } + if err != nil { - return err + return ErrBool } if ori, err := c.db.BSetBit(args[0], offset, uint8(val)); err != nil { @@ -68,8 +73,9 @@ func bgetbitCommand(c *client) error { } offset, err := ledis.StrInt32(args[1], nil) + if err != nil { - return err + return ErrOffset } if v, err := c.db.BGetBit(args[0], offset); err != nil { @@ -100,13 +106,18 @@ func bmsetbitCommand(c *client) error { pairs := make([]ledis.BitPair, len(args)>>1) for i := 0; i < len(pairs); i++ { offset, err = ledis.StrInt32(args[i<<1], nil) + if err != nil { - return err + return ErrOffset } val, err = ledis.StrInt8(args[i<<1+1], nil) + if val != 0 && val != 1 { + return ErrBool + } + if err != nil { - return err + return ErrBool } pairs[i].Pos = offset @@ -137,14 +148,14 @@ func bcountCommand(c *client) error { if argCnt > 1 { start, err = ledis.StrInt32(args[1], nil) if err != nil { - return err + return ErrValue } } if argCnt > 2 { end, err = ledis.StrInt32(args[2], nil) if err != nil { - return err + return ErrValue } } @@ -180,6 +191,9 @@ func boptCommand(c *client) error { return ErrCmdParams } + if len(srcKeys) == 0 { + return ErrCmdParams + } if blen, err := c.db.BOperation(op, dstKey, srcKeys...); err != nil { return err } else { @@ -190,7 +204,7 @@ func boptCommand(c *client) error { func bexpireCommand(c *client) error { args := c.args - if len(args) == 0 { + if len(args) != 2 { return ErrCmdParams } @@ -208,9 +222,9 @@ func bexpireCommand(c *client) error { return nil } -func bexpireatCommand(c *client) error { +func bexpireAtCommand(c *client) error { args := c.args - if len(args) == 0 { + if len(args) != 2 { return ErrCmdParams } @@ -230,7 +244,7 @@ func bexpireatCommand(c *client) error { func bttlCommand(c *client) error { args := c.args - if len(args) == 0 { + if len(args) != 1 { return ErrCmdParams } @@ -267,7 +281,7 @@ func init() { register("bcount", bcountCommand) register("bopt", boptCommand) register("bexpire", bexpireCommand) - register("bexpireat", bexpireatCommand) + register("bexpireat", bexpireAtCommand) register("bttl", bttlCommand) register("bpersist", bpersistCommand) } diff --git a/server/cmd_bit_test.go b/server/cmd_bit_test.go index f5438f9..9191648 100644 --- a/server/cmd_bit_test.go +++ b/server/cmd_bit_test.go @@ -221,3 +221,163 @@ func testBitOpt(t *testing.T) { return } + +func TestBitErrorParams(t *testing.T) { + c := getTestConn() + defer c.Close() + + if _, err := c.Do("bget"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bdelete"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + // bsetbit + if _, err := c.Do("bsetbit"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bsetbit", "test_bsetbit"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bsetbit", "test_bsetbit", "o", "v"); err == nil || err.Error() != SErrOffset { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bsetbit", "test_bsetbit", "o", 1); err == nil || err.Error() != SErrOffset { + t.Fatal("invalid err of %v", err) + } + + // if _, err := c.Do("bsetbit", "test_bsetbit", -1, 1); err == nil || err.Error() != SErrOffset { + // t.Fatal("invalid err of %v", err) + // } + + if _, err := c.Do("bsetbit", "test_bsetbit", 1, "v"); err == nil || err.Error() != SErrBool { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bsetbit", "test_bsetbit", 1, 2); err == nil || err.Error() != SErrBool { + t.Fatal("invalid err of %v", err) + } + + //bgetbit + if _, err := c.Do("bgetbit", "test_bgetbit"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bgetbit", "test_bgetbit", "o"); err == nil || err.Error() != SErrOffset { + t.Fatal("invalid err of %v", err) + } + + // if _, err := c.Do("bgetbit", "test_bgetbit", -1); err == nil || err.Error() != SErrOffset { + // t.Fatal("invalid err of %v", err) + // } + + //bmsetbit + if _, err := c.Do("bmsetbit", "test_bmsetbit"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bmsetbit", "test_bmsetbit", 0, 1, 2); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bmsetbit", "test_bmsetbit", "o", "v"); err == nil || err.Error() != SErrOffset { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bmsetbit", "test_bmsetbit", "o", 1); err == nil || err.Error() != SErrOffset { + t.Fatal("invalid err of %v", err) + } + + // if _, err := c.Do("bmsetbit", "test_bmsetbit", -1, 1); err == nil || err.Error() != SErrOffset { + // t.Fatal("invalid err of %v", err) + // } + + if _, err := c.Do("bmsetbit", "test_bmsetbit", 1, "v"); err == nil || err.Error() != SErrBool { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bmsetbit", "test_bmsetbit", 1, 2); err == nil || err.Error() != SErrBool { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bmsetbit", "test_bmsetbit", 1, 0.1); err == nil || err.Error() != SErrBool { + t.Fatal("invalid err of %v", err) + } + + //bcount + + if _, err := c.Do("bcount"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bcount", "a", "b", "c"); err == nil || err.Error() != SErrValue { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bcount", 1, "a"); err == nil || err.Error() != SErrValue { + t.Fatal("invalid err of %v", err) + } + + // if _, err := c.Do("bcount", 1); err == nil || err.Error() != SErrCmdParams { + // t.Fatal("invalid err of %v", err) + // } + + //bopt + if _, err := c.Do("bopt"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bopt", "and", 1); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bopt", "x", 1); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bopt", ""); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bexpire", "test_bexpire"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bexpireat", "test_bexpireat"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bttl"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("bpersist"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //bexpire + if _, err := c.Do("bexpire", "test_bexpire"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //bexpireat + if _, err := c.Do("bexpireat", "test_bexpireat"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //bttl + if _, err := c.Do("bttl"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //bpersist + if _, err := c.Do("bpersist"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + +} diff --git a/server/cmd_zset.go b/server/cmd_zset.go index 8dc465e..868b6bd 100644 --- a/server/cmd_zset.go +++ b/server/cmd_zset.go @@ -134,6 +134,7 @@ func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err e min, err = ledis.StrInt64(minBuf, nil) if err != nil { + err = ErrValue return } @@ -164,6 +165,7 @@ func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err e max, err = ledis.StrInt64(maxBuf, nil) if err != nil { + err = ErrValue return } @@ -188,7 +190,7 @@ func zcountCommand(c *client) error { min, max, err := zparseScoreRange(args[1], args[2]) if err != nil { - return err + return ErrValue } if min > max { @@ -249,7 +251,7 @@ func zremrangebyrankCommand(c *client) error { start, stop, err := zparseRange(c, args[1], args[2]) if err != nil { - return err + return ErrValue } if n, err := c.db.ZRemRangeByRank(key, start, stop); err != nil { @@ -304,14 +306,21 @@ func zrangeGeneric(c *client, reverse bool) error { start, stop, err := zparseRange(c, args[1], args[2]) if err != nil { - return err + return ErrValue } args = args[3:] var withScores bool = false - if len(args) > 0 && strings.ToLower(ledis.String(args[0])) == "withscores" { - withScores = true + if len(args) > 0 { + if len(args) != 1 { + return ErrCmdParams + } + if strings.ToLower(ledis.String(args[0])) == "withscores" { + withScores = true + } else { + return ErrSyntax + } } if datas, err := c.db.ZRangeGeneric(key, start, stop, reverse); err != nil { @@ -356,9 +365,11 @@ func zrangebyscoreGeneric(c *client, reverse bool) error { var withScores bool = false - if len(args) > 0 && strings.ToLower(ledis.String(args[0])) == "withscores" { - withScores = true - args = args[1:] + if len(args) > 0 { + if strings.ToLower(ledis.String(args[0])) == "withscores" { + withScores = true + args = args[1:] + } } var offset int = 0 @@ -370,15 +381,15 @@ func zrangebyscoreGeneric(c *client, reverse bool) error { } if strings.ToLower(ledis.String(args[0])) != "limit" { - return ErrCmdParams + return ErrSyntax } if offset, err = strconv.Atoi(ledis.String(args[1])); err != nil { - return ErrCmdParams + return ErrValue } if count, err = strconv.Atoi(ledis.String(args[2])); err != nil { - return ErrCmdParams + return ErrValue } } @@ -472,7 +483,6 @@ func zexpireAtCommand(c *client) error { } else { c.writeInteger(v) } - return nil } diff --git a/server/cmd_zset_test.go b/server/cmd_zset_test.go index cf512c7..d26d49b 100644 --- a/server/cmd_zset_test.go +++ b/server/cmd_zset_test.go @@ -429,3 +429,173 @@ func TestZSetRange(t *testing.T) { } } + +func TestZsetErrorParams(t *testing.T) { + c := getTestConn() + defer c.Close() + + //zadd + if _, err := c.Do("zadd", "test_zadd"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zadd", "test_zadd", "a", "b", "c"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zadd", "test_zadd", "-a", "a"); err == nil || err.Error() != SErrValue { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zadd", "test_zad", "0.1", "a"); err == nil || err.Error() != SErrValue { + t.Fatal("invalid err of %v", err) + } + + //zcard + if _, err := c.Do("zcard"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zscore + if _, err := c.Do("zscore", "test_zscore"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zrem + if _, err := c.Do("zrem", "test_zrem"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zincrby + if _, err := c.Do("zincrby", "test_zincrby"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zincrby", "test_zincrby", 0.1, "a"); err == nil || err.Error() != SErrValue { + t.Fatal("invalid err of %v", err) + } + + //zcount + if _, err := c.Do("zcount", "test_zcount"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zcount", "test_zcount", "-inf", "=inf"); err == nil || err.Error() != SErrValue { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zcount", "test_zcount", 0.1, 0.1); err == nil || err.Error() != SErrValue { + t.Fatal("invalid err of %v", err) + } + + //zrank + if _, err := c.Do("zrank", "test_zrank"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zrevzrank + if _, err := c.Do("zrevrank", "test_zrevrank"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zremrangebyrank + if _, err := c.Do("zremrangebyrank", "test_zremrangebyrank"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zremrangebyrank", "test_zremrangebyrank", 0.1, 0.1); err == nil || err.Error() != SErrValue { + t.Fatal("invalid err of %v", err) + } + + //zremrangebyscore + if _, err := c.Do("zremrangebyscore", "test_zremrangebyscore"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zremrangebyscore", "test_zremrangebyscore", "-inf", "a"); err == nil || err.Error() != SErrValue { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zremrangebyscore", "test_zremrangebyscore", 0, "a"); err == nil || err.Error() != SErrValue { + t.Fatal("invalid err of %v", err) + } + + //zrange + if _, err := c.Do("zrange", "test_zrange"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zrange", "test_zrange", 0, 1, "withscore"); err == nil || err.Error() != SErrSyntax { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zrange", "test_zrange", 0, 1, "withscores", "a"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zrevrange, almost same as zrange + if _, err := c.Do("zrevrange", "test_zrevrange"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zrangebyscore + if _, err := c.Do("zrangebyscore", "test_zrangebyscore"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zrangebyscore", "test_zrangebyscore", 0, 1, "withscore"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zrangebyscore", "test_zrangebyscore", 0, 1, "withscores", "limit"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zrangebyscore", "test_zrangebyscore", 0, 1, "withscores", "limi", 1, 1); err == nil || err.Error() != SErrSyntax { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zrangebyscore", "test_zrangebyscore", 0, 1, "withscores", "limit", "a", 1); err == nil || err.Error() != SErrValue { + t.Fatal("invalid err of %v", err) + } + + if _, err := c.Do("zrangebyscore", "test_zrangebyscore", 0, 1, "withscores", "limit", 1, "a"); err == nil || err.Error() != SErrValue { + t.Fatal("invalid err of %v", err) + } + + //zrevrangebyscore, almost same as zrangebyscore + if _, err := c.Do("zrevrangebyscore", "test_zrevrangebyscore"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zclear + if _, err := c.Do("zclear"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zmclear + if _, err := c.Do("zmclear"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zexpire + if _, err := c.Do("zexpire", "test_zexpire"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zexpireat + if _, err := c.Do("zexpireat", "test_zexpireat"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zttl + if _, err := c.Do("zttl"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + + //zpersist + if _, err := c.Do("zpersist"); err == nil || err.Error() != SErrCmdParams { + t.Fatal("invalid err of %v", err) + } + +} diff --git a/server/const.go b/server/const.go index f1424d2..51c7dfe 100644 --- a/server/const.go +++ b/server/const.go @@ -10,6 +10,8 @@ var ( ErrCmdParams = errors.New("invalid command param") ErrValue = errors.New("value is not an integer or out of range") ErrSyntax = errors.New("syntax error") + ErrOffset = errors.New("offset bit is not an natural number") + ErrBool = errors.New("value is not 0 or 1") ) var ( @@ -23,4 +25,6 @@ var ( SErrCmdParams = "ERR invalid command param" SErrValue = "ERR value is not an integer or out of range" SErrSyntax = "ERR syntax error" + SErrOffset = "ERR offset bit is not an natural number" + SErrBool = "ERR value is not 0 or 1" )