mirror of
https://github.com/HDT3213/godis.git
synced 2025-10-05 16:57:06 +08:00
add unittests and bug fix
This commit is contained in:
@@ -8,8 +8,5 @@ before_install:
|
|||||||
- sudo apt-get install redis-server; redis-server &
|
- sudo apt-get install redis-server; redis-server &
|
||||||
- go get github.com/mattn/goveralls
|
- go get github.com/mattn/goveralls
|
||||||
script:
|
script:
|
||||||
- go test -coverprofile=coverage.txt -covermode=atomic ./...
|
- go test -covermode=atomic ./...
|
||||||
- $GOPATH/bin/goveralls -service=travis-ci
|
- $GOPATH/bin/goveralls -service=travis-ci
|
||||||
|
|
||||||
after_success:
|
|
||||||
- bash <(curl -s https://codecov.io/bash)
|
|
||||||
|
@@ -70,8 +70,8 @@ func MakeCluster() *Cluster {
|
|||||||
return cluster
|
return cluster
|
||||||
}
|
}
|
||||||
|
|
||||||
// args contains all
|
// CmdFunc represents the handler of a redis command
|
||||||
type CmdFunc func(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply
|
type CmdFunc func(cluster *Cluster, c redis.Connection, cmdAndArgs [][]byte) redis.Reply
|
||||||
|
|
||||||
func (cluster *Cluster) Close() {
|
func (cluster *Cluster) Close() {
|
||||||
cluster.db.Close()
|
cluster.db.Close()
|
||||||
|
@@ -19,20 +19,11 @@ var (
|
|||||||
// broadcast msg to all peers in cluster when receive publish command from client
|
// broadcast msg to all peers in cluster when receive publish command from client
|
||||||
func Publish(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
|
func Publish(cluster *Cluster, c redis.Connection, args [][]byte) redis.Reply {
|
||||||
var count int64 = 0
|
var count int64 = 0
|
||||||
for _, peer := range cluster.nodes {
|
results := cluster.Broadcast(c, args)
|
||||||
var re redis.Reply
|
for _, val := range results {
|
||||||
if peer == cluster.self {
|
if errReply, ok := val.(reply.ErrorReply); ok {
|
||||||
args0 := make([][]byte, len(args))
|
|
||||||
copy(args0, args)
|
|
||||||
args0[0] = publishCmd
|
|
||||||
re = cluster.db.Exec(c, args0) // let local db.hub handle publish
|
|
||||||
} else {
|
|
||||||
args[0] = publishRelayCmd
|
|
||||||
re = cluster.Relay(peer, c, args)
|
|
||||||
}
|
|
||||||
if errReply, ok := re.(reply.ErrorReply); ok {
|
|
||||||
logger.Error("publish occurs error: " + errReply.Error())
|
logger.Error("publish occurs error: " + errReply.Error())
|
||||||
} else if intReply, ok := re.(*reply.IntReply); ok {
|
} else if intReply, ok := val.(*reply.IntReply); ok {
|
||||||
count += intReply.Code
|
count += intReply.Code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
48
cluster/pubsub_test.go
Normal file
48
cluster/pubsub_test.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package cluster
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hdt3213/godis/lib/utils"
|
||||||
|
"github.com/hdt3213/godis/redis/connection"
|
||||||
|
"github.com/hdt3213/godis/redis/parser"
|
||||||
|
"github.com/hdt3213/godis/redis/reply/asserts"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPublish(t *testing.T) {
|
||||||
|
channel := utils.RandString(5)
|
||||||
|
msg := utils.RandString(5)
|
||||||
|
conn := &connection.FakeConn{}
|
||||||
|
Subscribe(testCluster, conn, utils.ToBytesList("SUBSCRIBE", channel))
|
||||||
|
conn.Clean() // clean subscribe success
|
||||||
|
Publish(testCluster, conn, utils.ToBytesList("PUBLISH", channel, msg))
|
||||||
|
data := conn.Bytes()
|
||||||
|
ret, err := parser.ParseOne(data)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
asserts.AssertMultiBulkReply(t, ret, []string{
|
||||||
|
"message",
|
||||||
|
channel,
|
||||||
|
msg,
|
||||||
|
})
|
||||||
|
|
||||||
|
// unsubscribe
|
||||||
|
UnSubscribe(testCluster, conn, utils.ToBytesList("UNSUBSCRIBE", channel))
|
||||||
|
conn.Clean()
|
||||||
|
Publish(testCluster, conn, utils.ToBytesList("PUBLISH", channel, msg))
|
||||||
|
data = conn.Bytes()
|
||||||
|
if len(data) > 0 {
|
||||||
|
t.Error("expect no msg")
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsubscribe all
|
||||||
|
Subscribe(testCluster, conn, utils.ToBytesList("SUBSCRIBE", channel))
|
||||||
|
UnSubscribe(testCluster, conn, utils.ToBytesList("UNSUBSCRIBE"))
|
||||||
|
conn.Clean()
|
||||||
|
Publish(testCluster, conn, utils.ToBytesList("PUBLISH", channel, msg))
|
||||||
|
data = conn.Bytes()
|
||||||
|
if len(data) > 0 {
|
||||||
|
t.Error("expect no msg")
|
||||||
|
}
|
||||||
|
}
|
@@ -82,7 +82,7 @@ func (db *DB) loadAof(maxBytes int) {
|
|||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
reader := utils.NewLimitedReader(file, maxBytes)
|
reader := utils.NewLimitedReader(file, maxBytes)
|
||||||
ch := parser.Parse(reader)
|
ch := parser.ParseStream(reader)
|
||||||
for p := range ch {
|
for p := range ch {
|
||||||
if p.Err != nil {
|
if p.Err != nil {
|
||||||
if p.Err == io.EOF {
|
if p.Err == io.EOF {
|
||||||
|
@@ -3,6 +3,8 @@ package db
|
|||||||
import (
|
import (
|
||||||
"github.com/hdt3213/godis/config"
|
"github.com/hdt3213/godis/config"
|
||||||
"github.com/hdt3213/godis/datastruct/utils"
|
"github.com/hdt3213/godis/datastruct/utils"
|
||||||
|
utils2 "github.com/hdt3213/godis/lib/utils"
|
||||||
|
"github.com/hdt3213/godis/redis/reply"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -32,31 +34,31 @@ func TestAof(t *testing.T) {
|
|||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
key := strconv.Itoa(cursor)
|
key := strconv.Itoa(cursor)
|
||||||
cursor++
|
cursor++
|
||||||
Set(aofWriteDB, toArgs(key, RandString(8), "EX", "10000"))
|
Set(aofWriteDB, utils2.ToBytesList(key, utils2.RandString(8), "EX", "10000"))
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
key := strconv.Itoa(cursor)
|
key := strconv.Itoa(cursor)
|
||||||
cursor++
|
cursor++
|
||||||
RPush(aofWriteDB, toArgs(key, RandString(8)))
|
RPush(aofWriteDB, utils2.ToBytesList(key, utils2.RandString(8)))
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
key := strconv.Itoa(cursor)
|
key := strconv.Itoa(cursor)
|
||||||
cursor++
|
cursor++
|
||||||
HSet(aofWriteDB, toArgs(key, RandString(8), RandString(8)))
|
HSet(aofWriteDB, utils2.ToBytesList(key, utils2.RandString(8), utils2.RandString(8)))
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
key := strconv.Itoa(cursor)
|
key := strconv.Itoa(cursor)
|
||||||
cursor++
|
cursor++
|
||||||
SAdd(aofWriteDB, toArgs(key, RandString(8)))
|
SAdd(aofWriteDB, utils2.ToBytesList(key, utils2.RandString(8)))
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
key := strconv.Itoa(cursor)
|
key := strconv.Itoa(cursor)
|
||||||
cursor++
|
cursor++
|
||||||
ZAdd(aofWriteDB, toArgs(key, "10", RandString(8)))
|
ZAdd(aofWriteDB, utils2.ToBytesList(key, "10", utils2.RandString(8)))
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
aofWriteDB.Close() // wait for aof finished
|
aofWriteDB.Close() // wait for aof finished
|
||||||
@@ -98,41 +100,49 @@ func TestRewriteAOF(t *testing.T) {
|
|||||||
aofWriteDB := MakeDB()
|
aofWriteDB := MakeDB()
|
||||||
size := 1
|
size := 1
|
||||||
keys := make([]string, 0)
|
keys := make([]string, 0)
|
||||||
|
ttlKeys := make([]string, 0)
|
||||||
cursor := 0
|
cursor := 0
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
key := "str" + strconv.Itoa(cursor)
|
key := "str" + strconv.Itoa(cursor)
|
||||||
cursor++
|
cursor++
|
||||||
Set(aofWriteDB, toArgs(key, RandString(8)))
|
Set(aofWriteDB, utils2.ToBytesList(key, utils2.RandString(8)))
|
||||||
Set(aofWriteDB, toArgs(key, RandString(8)))
|
Set(aofWriteDB, utils2.ToBytesList(key, utils2.RandString(8)))
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
|
// test ttl
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
key := "str" + strconv.Itoa(cursor)
|
||||||
|
cursor++
|
||||||
|
Set(aofWriteDB, utils2.ToBytesList(key, utils2.RandString(8), "EX", "1000"))
|
||||||
|
ttlKeys = append(ttlKeys, key)
|
||||||
|
}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
key := "list" + strconv.Itoa(cursor)
|
key := "list" + strconv.Itoa(cursor)
|
||||||
cursor++
|
cursor++
|
||||||
RPush(aofWriteDB, toArgs(key, RandString(8)))
|
RPush(aofWriteDB, utils2.ToBytesList(key, utils2.RandString(8)))
|
||||||
RPush(aofWriteDB, toArgs(key, RandString(8)))
|
RPush(aofWriteDB, utils2.ToBytesList(key, utils2.RandString(8)))
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
key := "hash" + strconv.Itoa(cursor)
|
key := "hash" + strconv.Itoa(cursor)
|
||||||
cursor++
|
cursor++
|
||||||
field := RandString(8)
|
field := utils2.RandString(8)
|
||||||
HSet(aofWriteDB, toArgs(key, field, RandString(8)))
|
HSet(aofWriteDB, utils2.ToBytesList(key, field, utils2.RandString(8)))
|
||||||
HSet(aofWriteDB, toArgs(key, field, RandString(8)))
|
HSet(aofWriteDB, utils2.ToBytesList(key, field, utils2.RandString(8)))
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
key := "set" + strconv.Itoa(cursor)
|
key := "set" + strconv.Itoa(cursor)
|
||||||
cursor++
|
cursor++
|
||||||
member := RandString(8)
|
member := utils2.RandString(8)
|
||||||
SAdd(aofWriteDB, toArgs(key, member))
|
SAdd(aofWriteDB, utils2.ToBytesList(key, member))
|
||||||
SAdd(aofWriteDB, toArgs(key, member))
|
SAdd(aofWriteDB, utils2.ToBytesList(key, member))
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
key := "zset" + strconv.Itoa(cursor)
|
key := "zset" + strconv.Itoa(cursor)
|
||||||
cursor++
|
cursor++
|
||||||
ZAdd(aofWriteDB, toArgs(key, "10", RandString(8)))
|
ZAdd(aofWriteDB, utils2.ToBytesList(key, "10", utils2.RandString(8)))
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
time.Sleep(time.Second) // wait for async goroutine finish its job
|
time.Sleep(time.Second) // wait for async goroutine finish its job
|
||||||
@@ -156,5 +166,16 @@ func TestRewriteAOF(t *testing.T) {
|
|||||||
t.Errorf("wrong value of key: %s", key)
|
t.Errorf("wrong value of key: %s", key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, key := range ttlKeys {
|
||||||
|
ret := TTL(aofReadDB, utils2.ToBytesList(key))
|
||||||
|
intResult, ok := ret.(*reply.IntReply)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("expected int reply, actually %s", ret.ToBytes())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if intResult.Code <= 0 {
|
||||||
|
t.Errorf("expect a positive integer, actual: %d", intResult.Code)
|
||||||
|
}
|
||||||
|
}
|
||||||
aofReadDB.Close()
|
aofReadDB.Close()
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/hdt3213/godis/lib/utils"
|
||||||
"github.com/hdt3213/godis/redis/reply"
|
"github.com/hdt3213/godis/redis/reply"
|
||||||
"github.com/hdt3213/godis/redis/reply/asserts"
|
"github.com/hdt3213/godis/redis/reply/asserts"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -9,52 +10,52 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestGeoHash(t *testing.T) {
|
func TestGeoHash(t *testing.T) {
|
||||||
FlushDB(testDB, toArgs())
|
FlushDB(testDB, utils.ToBytesList())
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
pos := RandString(10)
|
pos := utils.RandString(10)
|
||||||
result := GeoAdd(testDB, toArgs(key, "13.361389", "38.115556", pos))
|
result := GeoAdd(testDB, utils.ToBytesList(key, "13.361389", "38.115556", pos))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
result = GeoHash(testDB, toArgs(key, pos))
|
result = GeoHash(testDB, utils.ToBytesList(key, pos))
|
||||||
asserts.AssertMultiBulkReply(t, result, []string{"sqc8b49rnys00"})
|
asserts.AssertMultiBulkReply(t, result, []string{"sqc8b49rnys00"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGeoRadius(t *testing.T) {
|
func TestGeoRadius(t *testing.T) {
|
||||||
FlushDB(testDB, toArgs())
|
FlushDB(testDB, utils.ToBytesList())
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
pos1 := RandString(10)
|
pos1 := utils.RandString(10)
|
||||||
pos2 := RandString(10)
|
pos2 := utils.RandString(10)
|
||||||
GeoAdd(testDB, toArgs(key,
|
GeoAdd(testDB, utils.ToBytesList(key,
|
||||||
"13.361389", "38.115556", pos1,
|
"13.361389", "38.115556", pos1,
|
||||||
"15.087269", "37.502669", pos2,
|
"15.087269", "37.502669", pos2,
|
||||||
))
|
))
|
||||||
result := GeoRadius(testDB, toArgs(key, "15", "37", "200", "km"))
|
result := GeoRadius(testDB, utils.ToBytesList(key, "15", "37", "200", "km"))
|
||||||
asserts.AssertMultiBulkReplySize(t, result, 2)
|
asserts.AssertMultiBulkReplySize(t, result, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGeoRadiusByMember(t *testing.T) {
|
func TestGeoRadiusByMember(t *testing.T) {
|
||||||
FlushDB(testDB, toArgs())
|
FlushDB(testDB, utils.ToBytesList())
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
pos1 := RandString(10)
|
pos1 := utils.RandString(10)
|
||||||
pos2 := RandString(10)
|
pos2 := utils.RandString(10)
|
||||||
pivot := RandString(10)
|
pivot := utils.RandString(10)
|
||||||
GeoAdd(testDB, toArgs(key,
|
GeoAdd(testDB, utils.ToBytesList(key,
|
||||||
"13.361389", "38.115556", pos1,
|
"13.361389", "38.115556", pos1,
|
||||||
"17.087269", "38.502669", pos2,
|
"17.087269", "38.502669", pos2,
|
||||||
"13.583333", "37.316667", pivot,
|
"13.583333", "37.316667", pivot,
|
||||||
))
|
))
|
||||||
result := GeoRadiusByMember(testDB, toArgs(key, pivot, "100", "km"))
|
result := GeoRadiusByMember(testDB, utils.ToBytesList(key, pivot, "100", "km"))
|
||||||
asserts.AssertMultiBulkReplySize(t, result, 2)
|
asserts.AssertMultiBulkReplySize(t, result, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGeoPos(t *testing.T) {
|
func TestGeoPos(t *testing.T) {
|
||||||
FlushDB(testDB, toArgs())
|
FlushDB(testDB, utils.ToBytesList())
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
pos1 := RandString(10)
|
pos1 := utils.RandString(10)
|
||||||
pos2 := RandString(10)
|
pos2 := utils.RandString(10)
|
||||||
GeoAdd(testDB, toArgs(key,
|
GeoAdd(testDB, utils.ToBytesList(key,
|
||||||
"13.361389", "38.115556", pos1,
|
"13.361389", "38.115556", pos1,
|
||||||
))
|
))
|
||||||
result := GeoPos(testDB, toArgs(key, pos1, pos2))
|
result := GeoPos(testDB, utils.ToBytesList(key, pos1, pos2))
|
||||||
expected := "*2\r\n*2\r\n$18\r\n13.361386698670685\r\n$17\r\n38.11555536696687\r\n*0\r\n"
|
expected := "*2\r\n*2\r\n$18\r\n13.361386698670685\r\n$17\r\n38.11555536696687\r\n*0\r\n"
|
||||||
if string(result.ToBytes()) != expected {
|
if string(result.ToBytes()) != expected {
|
||||||
t.Error("test failed")
|
t.Error("test failed")
|
||||||
@@ -62,15 +63,15 @@ func TestGeoPos(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGeoDist(t *testing.T) {
|
func TestGeoDist(t *testing.T) {
|
||||||
FlushDB(testDB, toArgs())
|
FlushDB(testDB, utils.ToBytesList())
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
pos1 := RandString(10)
|
pos1 := utils.RandString(10)
|
||||||
pos2 := RandString(10)
|
pos2 := utils.RandString(10)
|
||||||
GeoAdd(testDB, toArgs(key,
|
GeoAdd(testDB, utils.ToBytesList(key,
|
||||||
"13.361389", "38.115556", pos1,
|
"13.361389", "38.115556", pos1,
|
||||||
"15.087269", "37.502669", pos2,
|
"15.087269", "37.502669", pos2,
|
||||||
))
|
))
|
||||||
result := GeoDist(testDB, toArgs(key, pos1, pos2, "km"))
|
result := GeoDist(testDB, utils.ToBytesList(key, pos1, pos2, "km"))
|
||||||
bulkReply, ok := result.(*reply.BulkReply)
|
bulkReply, ok := result.(*reply.BulkReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected bulk reply, actually %s", result.ToBytes()))
|
t.Error(fmt.Sprintf("expected bulk reply, actually %s", result.ToBytes()))
|
||||||
|
@@ -3,6 +3,7 @@ package db
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hdt3213/godis/datastruct/utils"
|
"github.com/hdt3213/godis/datastruct/utils"
|
||||||
|
utils2 "github.com/hdt3213/godis/lib/utils"
|
||||||
"github.com/hdt3213/godis/redis/reply"
|
"github.com/hdt3213/godis/redis/reply"
|
||||||
"github.com/hdt3213/godis/redis/reply/asserts"
|
"github.com/hdt3213/godis/redis/reply/asserts"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -14,13 +15,13 @@ func TestHSet(t *testing.T) {
|
|||||||
size := 100
|
size := 100
|
||||||
|
|
||||||
// test hset
|
// test hset
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
values := make(map[string][]byte, size)
|
values := make(map[string][]byte, size)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
field := strconv.Itoa(i)
|
field := strconv.Itoa(i)
|
||||||
values[field] = []byte(value)
|
values[field] = []byte(value)
|
||||||
result := HSet(testDB, toArgs(key, field, value))
|
result := HSet(testDB, utils2.ToBytesList(key, field, value))
|
||||||
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(1) {
|
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(1) {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code))
|
||||||
}
|
}
|
||||||
@@ -28,19 +29,19 @@ func TestHSet(t *testing.T) {
|
|||||||
|
|
||||||
// test hget and hexists
|
// test hget and hexists
|
||||||
for field, v := range values {
|
for field, v := range values {
|
||||||
actual := HGet(testDB, toArgs(key, field))
|
actual := HGet(testDB, utils2.ToBytesList(key, field))
|
||||||
expected := reply.MakeBulkReply(v)
|
expected := reply.MakeBulkReply(v)
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(actual.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(actual.ToBytes())))
|
||||||
}
|
}
|
||||||
actual = HExists(testDB, toArgs(key, field))
|
actual = HExists(testDB, utils2.ToBytesList(key, field))
|
||||||
if intResult, _ := actual.(*reply.IntReply); intResult.Code != int64(1) {
|
if intResult, _ := actual.(*reply.IntReply); intResult.Code != int64(1) {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// test hlen
|
// test hlen
|
||||||
actual := HLen(testDB, toArgs(key))
|
actual := HLen(testDB, utils2.ToBytesList(key))
|
||||||
if intResult, _ := actual.(*reply.IntReply); intResult.Code != int64(len(values)) {
|
if intResult, _ := actual.(*reply.IntReply); intResult.Code != int64(len(values)) {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", len(values), intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", len(values), intResult.Code))
|
||||||
}
|
}
|
||||||
@@ -51,24 +52,24 @@ func TestHDel(t *testing.T) {
|
|||||||
size := 100
|
size := 100
|
||||||
|
|
||||||
// set values
|
// set values
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
fields := make([]string, size)
|
fields := make([]string, size)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
field := strconv.Itoa(i)
|
field := strconv.Itoa(i)
|
||||||
fields[i] = field
|
fields[i] = field
|
||||||
HSet(testDB, toArgs(key, field, value))
|
HSet(testDB, utils2.ToBytesList(key, field, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
// test HDel
|
// test HDel
|
||||||
args := []string{key}
|
args := []string{key}
|
||||||
args = append(args, fields...)
|
args = append(args, fields...)
|
||||||
actual := HDel(testDB, toArgs(args...))
|
actual := HDel(testDB, utils2.ToBytesList(args...))
|
||||||
if intResult, _ := actual.(*reply.IntReply); intResult.Code != int64(len(fields)) {
|
if intResult, _ := actual.(*reply.IntReply); intResult.Code != int64(len(fields)) {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", len(fields), intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", len(fields), intResult.Code))
|
||||||
}
|
}
|
||||||
|
|
||||||
actual = HLen(testDB, toArgs(key))
|
actual = HLen(testDB, utils2.ToBytesList(key))
|
||||||
if intResult, _ := actual.(*reply.IntReply); intResult.Code != int64(0) {
|
if intResult, _ := actual.(*reply.IntReply); intResult.Code != int64(0) {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 0, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", 0, intResult.Code))
|
||||||
}
|
}
|
||||||
@@ -79,16 +80,16 @@ func TestHMSet(t *testing.T) {
|
|||||||
size := 100
|
size := 100
|
||||||
|
|
||||||
// test hset
|
// test hset
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
fields := make([]string, size)
|
fields := make([]string, size)
|
||||||
values := make([]string, size)
|
values := make([]string, size)
|
||||||
setArgs := []string{key}
|
setArgs := []string{key}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
fields[i] = RandString(10)
|
fields[i] = utils2.RandString(10)
|
||||||
values[i] = RandString(10)
|
values[i] = utils2.RandString(10)
|
||||||
setArgs = append(setArgs, fields[i], values[i])
|
setArgs = append(setArgs, fields[i], values[i])
|
||||||
}
|
}
|
||||||
result := HMSet(testDB, toArgs(setArgs...))
|
result := HMSet(testDB, utils2.ToBytesList(setArgs...))
|
||||||
if _, ok := result.(*reply.OkReply); !ok {
|
if _, ok := result.(*reply.OkReply); !ok {
|
||||||
t.Error(fmt.Sprintf("expected ok, actually %s", string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected ok, actually %s", string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
@@ -96,8 +97,8 @@ func TestHMSet(t *testing.T) {
|
|||||||
// test HMGet
|
// test HMGet
|
||||||
getArgs := []string{key}
|
getArgs := []string{key}
|
||||||
getArgs = append(getArgs, fields...)
|
getArgs = append(getArgs, fields...)
|
||||||
actual := HMGet(testDB, toArgs(getArgs...))
|
actual := HMGet(testDB, utils2.ToBytesList(getArgs...))
|
||||||
expected := reply.MakeMultiBulkReply(toArgs(values...))
|
expected := reply.MakeMultiBulkReply(utils2.ToBytesList(values...))
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(actual.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(actual.ToBytes())))
|
||||||
}
|
}
|
||||||
@@ -106,22 +107,22 @@ func TestHMSet(t *testing.T) {
|
|||||||
func TestHGetAll(t *testing.T) {
|
func TestHGetAll(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
size := 100
|
size := 100
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
fields := make([]string, size)
|
fields := make([]string, size)
|
||||||
valueSet := make(map[string]bool, size)
|
valueSet := make(map[string]bool, size)
|
||||||
valueMap := make(map[string]string)
|
valueMap := make(map[string]string)
|
||||||
all := make([]string, 0)
|
all := make([]string, 0)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
fields[i] = RandString(10)
|
fields[i] = utils2.RandString(10)
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
all = append(all, fields[i], value)
|
all = append(all, fields[i], value)
|
||||||
valueMap[fields[i]] = value
|
valueMap[fields[i]] = value
|
||||||
valueSet[value] = true
|
valueSet[value] = true
|
||||||
HSet(testDB, toArgs(key, fields[i], value))
|
HSet(testDB, utils2.ToBytesList(key, fields[i], value))
|
||||||
}
|
}
|
||||||
|
|
||||||
// test HGetAll
|
// test HGetAll
|
||||||
result := HGetAll(testDB, toArgs(key))
|
result := HGetAll(testDB, utils2.ToBytesList(key))
|
||||||
multiBulk, ok := result.(*reply.MultiBulkReply)
|
multiBulk, ok := result.(*reply.MultiBulkReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected MultiBulkReply, actually %s", string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected MultiBulkReply, actually %s", string(result.ToBytes())))
|
||||||
@@ -143,7 +144,7 @@ func TestHGetAll(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// test HKeys
|
// test HKeys
|
||||||
result = HKeys(testDB, toArgs(key))
|
result = HKeys(testDB, utils2.ToBytesList(key))
|
||||||
multiBulk, ok = result.(*reply.MultiBulkReply)
|
multiBulk, ok = result.(*reply.MultiBulkReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected MultiBulkReply, actually %s", string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected MultiBulkReply, actually %s", string(result.ToBytes())))
|
||||||
@@ -159,7 +160,7 @@ func TestHGetAll(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// test HVals
|
// test HVals
|
||||||
result = HVals(testDB, toArgs(key))
|
result = HVals(testDB, utils2.ToBytesList(key))
|
||||||
multiBulk, ok = result.(*reply.MultiBulkReply)
|
multiBulk, ok = result.(*reply.MultiBulkReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected MultiBulkReply, actually %s", string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected MultiBulkReply, actually %s", string(result.ToBytes())))
|
||||||
@@ -179,21 +180,21 @@ func TestHGetAll(t *testing.T) {
|
|||||||
func TestHIncrBy(t *testing.T) {
|
func TestHIncrBy(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
|
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
result := HIncrBy(testDB, toArgs(key, "a", "1"))
|
result := HIncrBy(testDB, utils2.ToBytesList(key, "a", "1"))
|
||||||
if bulkResult, _ := result.(*reply.BulkReply); string(bulkResult.Arg) != "1" {
|
if bulkResult, _ := result.(*reply.BulkReply); string(bulkResult.Arg) != "1" {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", "1", string(bulkResult.Arg)))
|
t.Error(fmt.Sprintf("expected %s, actually %s", "1", string(bulkResult.Arg)))
|
||||||
}
|
}
|
||||||
result = HIncrBy(testDB, toArgs(key, "a", "1"))
|
result = HIncrBy(testDB, utils2.ToBytesList(key, "a", "1"))
|
||||||
if bulkResult, _ := result.(*reply.BulkReply); string(bulkResult.Arg) != "2" {
|
if bulkResult, _ := result.(*reply.BulkReply); string(bulkResult.Arg) != "2" {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", "2", string(bulkResult.Arg)))
|
t.Error(fmt.Sprintf("expected %s, actually %s", "2", string(bulkResult.Arg)))
|
||||||
}
|
}
|
||||||
|
|
||||||
result = HIncrByFloat(testDB, toArgs(key, "b", "1.2"))
|
result = HIncrByFloat(testDB, utils2.ToBytesList(key, "b", "1.2"))
|
||||||
if bulkResult, _ := result.(*reply.BulkReply); string(bulkResult.Arg) != "1.2" {
|
if bulkResult, _ := result.(*reply.BulkReply); string(bulkResult.Arg) != "1.2" {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", "1.2", string(bulkResult.Arg)))
|
t.Error(fmt.Sprintf("expected %s, actually %s", "1.2", string(bulkResult.Arg)))
|
||||||
}
|
}
|
||||||
result = HIncrByFloat(testDB, toArgs(key, "b", "1.2"))
|
result = HIncrByFloat(testDB, utils2.ToBytesList(key, "b", "1.2"))
|
||||||
if bulkResult, _ := result.(*reply.BulkReply); string(bulkResult.Arg) != "2.4" {
|
if bulkResult, _ := result.(*reply.BulkReply); string(bulkResult.Arg) != "2.4" {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", "2.4", string(bulkResult.Arg)))
|
t.Error(fmt.Sprintf("expected %s, actually %s", "2.4", string(bulkResult.Arg)))
|
||||||
}
|
}
|
||||||
@@ -201,15 +202,15 @@ func TestHIncrBy(t *testing.T) {
|
|||||||
|
|
||||||
func TestHSetNX(t *testing.T) {
|
func TestHSetNX(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
field := RandString(10)
|
field := utils2.RandString(10)
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
result := HSetNX(testDB, toArgs(key, field, value))
|
result := HSetNX(testDB, utils2.ToBytesList(key, field, value))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
value2 := RandString(10)
|
value2 := utils2.RandString(10)
|
||||||
result = HSetNX(testDB, toArgs(key, field, value2))
|
result = HSetNX(testDB, utils2.ToBytesList(key, field, value2))
|
||||||
asserts.AssertIntReply(t, result, 0)
|
asserts.AssertIntReply(t, result, 0)
|
||||||
result = HGet(testDB, toArgs(key, field))
|
result = HGet(testDB, utils2.ToBytesList(key, field))
|
||||||
asserts.AssertBulkReply(t, result, value)
|
asserts.AssertBulkReply(t, result, value)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
127
db/keys_test.go
127
db/keys_test.go
@@ -2,6 +2,7 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/hdt3213/godis/lib/utils"
|
||||||
"github.com/hdt3213/godis/redis/reply"
|
"github.com/hdt3213/godis/redis/reply"
|
||||||
"github.com/hdt3213/godis/redis/reply/asserts"
|
"github.com/hdt3213/godis/redis/reply/asserts"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -11,64 +12,64 @@ import (
|
|||||||
|
|
||||||
func TestExists(t *testing.T) {
|
func TestExists(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
value := RandString(10)
|
value := utils.RandString(10)
|
||||||
Set(testDB, toArgs(key, value))
|
Set(testDB, utils.ToBytesList(key, value))
|
||||||
result := Exists(testDB, toArgs(key))
|
result := Exists(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
key = RandString(10)
|
key = utils.RandString(10)
|
||||||
result = Exists(testDB, toArgs(key))
|
result = Exists(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertIntReply(t, result, 0)
|
asserts.AssertIntReply(t, result, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestType(t *testing.T) {
|
func TestType(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
value := RandString(10)
|
value := utils.RandString(10)
|
||||||
Set(testDB, toArgs(key, value))
|
Set(testDB, utils.ToBytesList(key, value))
|
||||||
result := Type(testDB, toArgs(key))
|
result := Type(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertStatusReply(t, result, "string")
|
asserts.AssertStatusReply(t, result, "string")
|
||||||
|
|
||||||
Del(testDB, toArgs(key))
|
Del(testDB, utils.ToBytesList(key))
|
||||||
result = Type(testDB, toArgs(key))
|
result = Type(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertStatusReply(t, result, "none")
|
asserts.AssertStatusReply(t, result, "none")
|
||||||
RPush(testDB, toArgs(key, value))
|
RPush(testDB, utils.ToBytesList(key, value))
|
||||||
result = Type(testDB, toArgs(key))
|
result = Type(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertStatusReply(t, result, "list")
|
asserts.AssertStatusReply(t, result, "list")
|
||||||
|
|
||||||
Del(testDB, toArgs(key))
|
Del(testDB, utils.ToBytesList(key))
|
||||||
HSet(testDB, toArgs(key, key, value))
|
HSet(testDB, utils.ToBytesList(key, key, value))
|
||||||
result = Type(testDB, toArgs(key))
|
result = Type(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertStatusReply(t, result, "hash")
|
asserts.AssertStatusReply(t, result, "hash")
|
||||||
|
|
||||||
Del(testDB, toArgs(key))
|
Del(testDB, utils.ToBytesList(key))
|
||||||
SAdd(testDB, toArgs(key, value))
|
SAdd(testDB, utils.ToBytesList(key, value))
|
||||||
result = Type(testDB, toArgs(key))
|
result = Type(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertStatusReply(t, result, "set")
|
asserts.AssertStatusReply(t, result, "set")
|
||||||
|
|
||||||
Del(testDB, toArgs(key))
|
Del(testDB, utils.ToBytesList(key))
|
||||||
ZAdd(testDB, toArgs(key, "1", value))
|
ZAdd(testDB, utils.ToBytesList(key, "1", value))
|
||||||
result = Type(testDB, toArgs(key))
|
result = Type(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertStatusReply(t, result, "zset")
|
asserts.AssertStatusReply(t, result, "zset")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRename(t *testing.T) {
|
func TestRename(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
value := RandString(10)
|
value := utils.RandString(10)
|
||||||
newKey := key + RandString(2)
|
newKey := key + utils.RandString(2)
|
||||||
Set(testDB, toArgs(key, value, "ex", "1000"))
|
Set(testDB, utils.ToBytesList(key, value, "ex", "1000"))
|
||||||
result := Rename(testDB, toArgs(key, newKey))
|
result := Rename(testDB, utils.ToBytesList(key, newKey))
|
||||||
if _, ok := result.(*reply.OkReply); !ok {
|
if _, ok := result.(*reply.OkReply); !ok {
|
||||||
t.Error("expect ok")
|
t.Error("expect ok")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
result = Exists(testDB, toArgs(key))
|
result = Exists(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertIntReply(t, result, 0)
|
asserts.AssertIntReply(t, result, 0)
|
||||||
result = Exists(testDB, toArgs(newKey))
|
result = Exists(testDB, utils.ToBytesList(newKey))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
// check ttl
|
// check ttl
|
||||||
result = TTL(testDB, toArgs(newKey))
|
result = TTL(testDB, utils.ToBytesList(newKey))
|
||||||
intResult, ok := result.(*reply.IntReply)
|
intResult, ok := result.(*reply.IntReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes()))
|
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes()))
|
||||||
@@ -82,17 +83,17 @@ func TestRename(t *testing.T) {
|
|||||||
|
|
||||||
func TestRenameNx(t *testing.T) {
|
func TestRenameNx(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
value := RandString(10)
|
value := utils.RandString(10)
|
||||||
newKey := key + RandString(2)
|
newKey := key + utils.RandString(2)
|
||||||
Set(testDB, toArgs(key, value, "ex", "1000"))
|
Set(testDB, utils.ToBytesList(key, value, "ex", "1000"))
|
||||||
result := RenameNx(testDB, toArgs(key, newKey))
|
result := RenameNx(testDB, utils.ToBytesList(key, newKey))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
result = Exists(testDB, toArgs(key))
|
result = Exists(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertIntReply(t, result, 0)
|
asserts.AssertIntReply(t, result, 0)
|
||||||
result = Exists(testDB, toArgs(newKey))
|
result = Exists(testDB, utils.ToBytesList(newKey))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
result = TTL(testDB, toArgs(newKey))
|
result = TTL(testDB, utils.ToBytesList(newKey))
|
||||||
intResult, ok := result.(*reply.IntReply)
|
intResult, ok := result.(*reply.IntReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes()))
|
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes()))
|
||||||
@@ -106,13 +107,13 @@ func TestRenameNx(t *testing.T) {
|
|||||||
|
|
||||||
func TestTTL(t *testing.T) {
|
func TestTTL(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
value := RandString(10)
|
value := utils.RandString(10)
|
||||||
Set(testDB, toArgs(key, value))
|
Set(testDB, utils.ToBytesList(key, value))
|
||||||
|
|
||||||
result := Expire(testDB, toArgs(key, "1000"))
|
result := Expire(testDB, utils.ToBytesList(key, "1000"))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
result = TTL(testDB, toArgs(key))
|
result = TTL(testDB, utils.ToBytesList(key))
|
||||||
intResult, ok := result.(*reply.IntReply)
|
intResult, ok := result.(*reply.IntReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes()))
|
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes()))
|
||||||
@@ -123,14 +124,14 @@ func TestTTL(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result = Persist(testDB, toArgs(key))
|
result = Persist(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
result = TTL(testDB, toArgs(key))
|
result = TTL(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertIntReply(t, result, -1)
|
asserts.AssertIntReply(t, result, -1)
|
||||||
|
|
||||||
result = PExpire(testDB, toArgs(key, "1000000"))
|
result = PExpire(testDB, utils.ToBytesList(key, "1000000"))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
result = PTTL(testDB, toArgs(key))
|
result = PTTL(testDB, utils.ToBytesList(key))
|
||||||
intResult, ok = result.(*reply.IntReply)
|
intResult, ok = result.(*reply.IntReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes()))
|
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes()))
|
||||||
@@ -144,14 +145,14 @@ func TestTTL(t *testing.T) {
|
|||||||
|
|
||||||
func TestExpireAt(t *testing.T) {
|
func TestExpireAt(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
value := RandString(10)
|
value := utils.RandString(10)
|
||||||
Set(testDB, toArgs(key, value))
|
Set(testDB, utils.ToBytesList(key, value))
|
||||||
|
|
||||||
expireAt := time.Now().Add(time.Minute).Unix()
|
expireAt := time.Now().Add(time.Minute).Unix()
|
||||||
result := ExpireAt(testDB, toArgs(key, strconv.FormatInt(expireAt, 10)))
|
result := ExpireAt(testDB, utils.ToBytesList(key, strconv.FormatInt(expireAt, 10)))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
result = TTL(testDB, toArgs(key))
|
result = TTL(testDB, utils.ToBytesList(key))
|
||||||
intResult, ok := result.(*reply.IntReply)
|
intResult, ok := result.(*reply.IntReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes()))
|
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes()))
|
||||||
@@ -163,9 +164,9 @@ func TestExpireAt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expireAt = time.Now().Add(time.Minute).Unix()
|
expireAt = time.Now().Add(time.Minute).Unix()
|
||||||
result = PExpireAt(testDB, toArgs(key, strconv.FormatInt(expireAt*1000, 10)))
|
result = PExpireAt(testDB, utils.ToBytesList(key, strconv.FormatInt(expireAt*1000, 10)))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
result = TTL(testDB, toArgs(key))
|
result = TTL(testDB, utils.ToBytesList(key))
|
||||||
intResult, ok = result.(*reply.IntReply)
|
intResult, ok = result.(*reply.IntReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes()))
|
t.Error(fmt.Sprintf("expected int reply, actually %s", result.ToBytes()))
|
||||||
@@ -179,16 +180,16 @@ func TestExpireAt(t *testing.T) {
|
|||||||
|
|
||||||
func TestKeys(t *testing.T) {
|
func TestKeys(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
value := RandString(10)
|
value := utils.RandString(10)
|
||||||
Set(testDB, toArgs(key, value))
|
Set(testDB, utils.ToBytesList(key, value))
|
||||||
Set(testDB, toArgs("a:"+key, value))
|
Set(testDB, utils.ToBytesList("a:"+key, value))
|
||||||
Set(testDB, toArgs("b:"+key, value))
|
Set(testDB, utils.ToBytesList("b:"+key, value))
|
||||||
|
|
||||||
result := Keys(testDB, toArgs("*"))
|
result := Keys(testDB, utils.ToBytesList("*"))
|
||||||
asserts.AssertMultiBulkReplySize(t, result, 3)
|
asserts.AssertMultiBulkReplySize(t, result, 3)
|
||||||
result = Keys(testDB, toArgs("a:*"))
|
result = Keys(testDB, utils.ToBytesList("a:*"))
|
||||||
asserts.AssertMultiBulkReplySize(t, result, 1)
|
asserts.AssertMultiBulkReplySize(t, result, 1)
|
||||||
result = Keys(testDB, toArgs("?:*"))
|
result = Keys(testDB, utils.ToBytesList("?:*"))
|
||||||
asserts.AssertMultiBulkReplySize(t, result, 2)
|
asserts.AssertMultiBulkReplySize(t, result, 2)
|
||||||
}
|
}
|
||||||
|
157
db/list_test.go
157
db/list_test.go
@@ -3,6 +3,7 @@ package db
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hdt3213/godis/datastruct/utils"
|
"github.com/hdt3213/godis/datastruct/utils"
|
||||||
|
utils2 "github.com/hdt3213/godis/lib/utils"
|
||||||
"github.com/hdt3213/godis/redis/reply"
|
"github.com/hdt3213/godis/redis/reply"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -13,67 +14,67 @@ func TestPush(t *testing.T) {
|
|||||||
size := 100
|
size := 100
|
||||||
|
|
||||||
// rpush single
|
// rpush single
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
values := make([][]byte, size)
|
values := make([][]byte, size)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
values[i] = []byte(value)
|
values[i] = []byte(value)
|
||||||
result := RPush(testDB, toArgs(key, value))
|
result := RPush(testDB, utils2.ToBytesList(key, value))
|
||||||
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(i+1) {
|
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(i+1) {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", i+1, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", i+1, intResult.Code))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
actual := LRange(testDB, toArgs(key, "0", "-1"))
|
actual := LRange(testDB, utils2.ToBytesList(key, "0", "-1"))
|
||||||
expected := reply.MakeMultiBulkReply(values)
|
expected := reply.MakeMultiBulkReply(values)
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error("push error")
|
t.Error("push error")
|
||||||
}
|
}
|
||||||
Del(testDB, toArgs(key))
|
Del(testDB, utils2.ToBytesList(key))
|
||||||
|
|
||||||
// rpush multi
|
// rpush multi
|
||||||
key = RandString(10)
|
key = utils2.RandString(10)
|
||||||
values = make([][]byte, size+1)
|
values = make([][]byte, size+1)
|
||||||
values[0] = []byte(key)
|
values[0] = []byte(key)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
values[i+1] = []byte(value)
|
values[i+1] = []byte(value)
|
||||||
}
|
}
|
||||||
result := RPush(testDB, values)
|
result := RPush(testDB, values)
|
||||||
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(size) {
|
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(size) {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", size, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", size, intResult.Code))
|
||||||
}
|
}
|
||||||
actual = LRange(testDB, toArgs(key, "0", "-1"))
|
actual = LRange(testDB, utils2.ToBytesList(key, "0", "-1"))
|
||||||
expected = reply.MakeMultiBulkReply(values[1:])
|
expected = reply.MakeMultiBulkReply(values[1:])
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error("push error")
|
t.Error("push error")
|
||||||
}
|
}
|
||||||
Del(testDB, toArgs(key))
|
Del(testDB, utils2.ToBytesList(key))
|
||||||
|
|
||||||
// left push single
|
// left push single
|
||||||
key = RandString(10)
|
key = utils2.RandString(10)
|
||||||
values = make([][]byte, size)
|
values = make([][]byte, size)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
values[size-i-1] = []byte(value)
|
values[size-i-1] = []byte(value)
|
||||||
result = LPush(testDB, toArgs(key, value))
|
result = LPush(testDB, utils2.ToBytesList(key, value))
|
||||||
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(i+1) {
|
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(i+1) {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", i+1, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", i+1, intResult.Code))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
actual = LRange(testDB, toArgs(key, "0", "-1"))
|
actual = LRange(testDB, utils2.ToBytesList(key, "0", "-1"))
|
||||||
expected = reply.MakeMultiBulkReply(values)
|
expected = reply.MakeMultiBulkReply(values)
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error("push error")
|
t.Error("push error")
|
||||||
}
|
}
|
||||||
Del(testDB, toArgs(key))
|
Del(testDB, utils2.ToBytesList(key))
|
||||||
|
|
||||||
// left push multi
|
// left push multi
|
||||||
key = RandString(10)
|
key = utils2.RandString(10)
|
||||||
values = make([][]byte, size+1)
|
values = make([][]byte, size+1)
|
||||||
values[0] = []byte(key)
|
values[0] = []byte(key)
|
||||||
expectedValues := make([][]byte, size)
|
expectedValues := make([][]byte, size)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
values[i+1] = []byte(value)
|
values[i+1] = []byte(value)
|
||||||
expectedValues[size-i-1] = []byte(value)
|
expectedValues[size-i-1] = []byte(value)
|
||||||
}
|
}
|
||||||
@@ -81,29 +82,29 @@ func TestPush(t *testing.T) {
|
|||||||
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(size) {
|
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(size) {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", size, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", size, intResult.Code))
|
||||||
}
|
}
|
||||||
actual = LRange(testDB, toArgs(key, "0", "-1"))
|
actual = LRange(testDB, utils2.ToBytesList(key, "0", "-1"))
|
||||||
expected = reply.MakeMultiBulkReply(expectedValues)
|
expected = reply.MakeMultiBulkReply(expectedValues)
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error("push error")
|
t.Error("push error")
|
||||||
}
|
}
|
||||||
Del(testDB, toArgs(key))
|
Del(testDB, utils2.ToBytesList(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLRange(t *testing.T) {
|
func TestLRange(t *testing.T) {
|
||||||
// prepare list
|
// prepare list
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
size := 100
|
size := 100
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
values := make([][]byte, size)
|
values := make([][]byte, size)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
RPush(testDB, toArgs(key, value))
|
RPush(testDB, utils2.ToBytesList(key, value))
|
||||||
values[i] = []byte(value)
|
values[i] = []byte(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
start := "0"
|
start := "0"
|
||||||
end := "9"
|
end := "9"
|
||||||
actual := LRange(testDB, toArgs(key, start, end))
|
actual := LRange(testDB, utils2.ToBytesList(key, start, end))
|
||||||
expected := reply.MakeMultiBulkReply(values[0:10])
|
expected := reply.MakeMultiBulkReply(values[0:10])
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
|
t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
|
||||||
@@ -111,7 +112,7 @@ func TestLRange(t *testing.T) {
|
|||||||
|
|
||||||
start = "0"
|
start = "0"
|
||||||
end = "200"
|
end = "200"
|
||||||
actual = LRange(testDB, toArgs(key, start, end))
|
actual = LRange(testDB, utils2.ToBytesList(key, start, end))
|
||||||
expected = reply.MakeMultiBulkReply(values)
|
expected = reply.MakeMultiBulkReply(values)
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
|
t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
|
||||||
@@ -119,7 +120,7 @@ func TestLRange(t *testing.T) {
|
|||||||
|
|
||||||
start = "0"
|
start = "0"
|
||||||
end = "-10"
|
end = "-10"
|
||||||
actual = LRange(testDB, toArgs(key, start, end))
|
actual = LRange(testDB, utils2.ToBytesList(key, start, end))
|
||||||
expected = reply.MakeMultiBulkReply(values[0 : size-10+1])
|
expected = reply.MakeMultiBulkReply(values[0 : size-10+1])
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
|
t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
|
||||||
@@ -127,7 +128,7 @@ func TestLRange(t *testing.T) {
|
|||||||
|
|
||||||
start = "0"
|
start = "0"
|
||||||
end = "-200"
|
end = "-200"
|
||||||
actual = LRange(testDB, toArgs(key, start, end))
|
actual = LRange(testDB, utils2.ToBytesList(key, start, end))
|
||||||
expected = reply.MakeMultiBulkReply(values[0:0])
|
expected = reply.MakeMultiBulkReply(values[0:0])
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
|
t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
|
||||||
@@ -135,7 +136,7 @@ func TestLRange(t *testing.T) {
|
|||||||
|
|
||||||
start = "-10"
|
start = "-10"
|
||||||
end = "-1"
|
end = "-1"
|
||||||
actual = LRange(testDB, toArgs(key, start, end))
|
actual = LRange(testDB, utils2.ToBytesList(key, start, end))
|
||||||
expected = reply.MakeMultiBulkReply(values[90:])
|
expected = reply.MakeMultiBulkReply(values[90:])
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
|
t.Error(fmt.Sprintf("range error [%s, %s]", start, end))
|
||||||
@@ -146,21 +147,21 @@ func TestLIndex(t *testing.T) {
|
|||||||
// prepare list
|
// prepare list
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
size := 100
|
size := 100
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
values := make([][]byte, size)
|
values := make([][]byte, size)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
RPush(testDB, toArgs(key, value))
|
RPush(testDB, utils2.ToBytesList(key, value))
|
||||||
values[i] = []byte(value)
|
values[i] = []byte(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
result := LLen(testDB, toArgs(key))
|
result := LLen(testDB, utils2.ToBytesList(key))
|
||||||
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(size) {
|
if intResult, _ := result.(*reply.IntReply); intResult.Code != int64(size) {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", size, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", size, intResult.Code))
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
result = LIndex(testDB, toArgs(key, strconv.Itoa(i)))
|
result = LIndex(testDB, utils2.ToBytesList(key, strconv.Itoa(i)))
|
||||||
expected := reply.MakeBulkReply(values[i])
|
expected := reply.MakeBulkReply(values[i])
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
@@ -168,7 +169,7 @@ func TestLIndex(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i := 1; i <= size; i++ {
|
for i := 1; i <= size; i++ {
|
||||||
result = LIndex(testDB, toArgs(key, strconv.Itoa(-i)))
|
result = LIndex(testDB, utils2.ToBytesList(key, strconv.Itoa(-i)))
|
||||||
expected := reply.MakeBulkReply(values[size-i])
|
expected := reply.MakeBulkReply(values[size-i])
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
@@ -179,33 +180,33 @@ func TestLIndex(t *testing.T) {
|
|||||||
func TestLRem(t *testing.T) {
|
func TestLRem(t *testing.T) {
|
||||||
// prepare list
|
// prepare list
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
values := []string{key, "a", "b", "a", "a", "c", "a", "a"}
|
values := []string{key, "a", "b", "a", "a", "c", "a", "a"}
|
||||||
RPush(testDB, toArgs(values...))
|
RPush(testDB, utils2.ToBytesList(values...))
|
||||||
|
|
||||||
result := LRem(testDB, toArgs(key, "1", "a"))
|
result := LRem(testDB, utils2.ToBytesList(key, "1", "a"))
|
||||||
if intResult, _ := result.(*reply.IntReply); intResult.Code != 1 {
|
if intResult, _ := result.(*reply.IntReply); intResult.Code != 1 {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", 1, intResult.Code))
|
||||||
}
|
}
|
||||||
result = LLen(testDB, toArgs(key))
|
result = LLen(testDB, utils2.ToBytesList(key))
|
||||||
if intResult, _ := result.(*reply.IntReply); intResult.Code != 6 {
|
if intResult, _ := result.(*reply.IntReply); intResult.Code != 6 {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 6, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", 6, intResult.Code))
|
||||||
}
|
}
|
||||||
|
|
||||||
result = LRem(testDB, toArgs(key, "-2", "a"))
|
result = LRem(testDB, utils2.ToBytesList(key, "-2", "a"))
|
||||||
if intResult, _ := result.(*reply.IntReply); intResult.Code != 2 {
|
if intResult, _ := result.(*reply.IntReply); intResult.Code != 2 {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code))
|
||||||
}
|
}
|
||||||
result = LLen(testDB, toArgs(key))
|
result = LLen(testDB, utils2.ToBytesList(key))
|
||||||
if intResult, _ := result.(*reply.IntReply); intResult.Code != 4 {
|
if intResult, _ := result.(*reply.IntReply); intResult.Code != 4 {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 4, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", 4, intResult.Code))
|
||||||
}
|
}
|
||||||
|
|
||||||
result = LRem(testDB, toArgs(key, "0", "a"))
|
result = LRem(testDB, utils2.ToBytesList(key, "0", "a"))
|
||||||
if intResult, _ := result.(*reply.IntReply); intResult.Code != 2 {
|
if intResult, _ := result.(*reply.IntReply); intResult.Code != 2 {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code))
|
||||||
}
|
}
|
||||||
result = LLen(testDB, toArgs(key))
|
result = LLen(testDB, utils2.ToBytesList(key))
|
||||||
if intResult, _ := result.(*reply.IntReply); intResult.Code != 2 {
|
if intResult, _ := result.(*reply.IntReply); intResult.Code != 2 {
|
||||||
t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code))
|
t.Error(fmt.Sprintf("expected %d, actually %d", 2, intResult.Code))
|
||||||
}
|
}
|
||||||
@@ -213,20 +214,20 @@ func TestLRem(t *testing.T) {
|
|||||||
|
|
||||||
func TestLSet(t *testing.T) {
|
func TestLSet(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
values := []string{key, "a", "b", "c", "d", "e", "f"}
|
values := []string{key, "a", "b", "c", "d", "e", "f"}
|
||||||
RPush(testDB, toArgs(values...))
|
RPush(testDB, utils2.ToBytesList(values...))
|
||||||
|
|
||||||
// test positive index
|
// test positive index
|
||||||
size := len(values) - 1
|
size := len(values) - 1
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
indexStr := strconv.Itoa(i)
|
indexStr := strconv.Itoa(i)
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
result := LSet(testDB, toArgs(key, indexStr, value))
|
result := LSet(testDB, utils2.ToBytesList(key, indexStr, value))
|
||||||
if _, ok := result.(*reply.OkReply); !ok {
|
if _, ok := result.(*reply.OkReply); !ok {
|
||||||
t.Error(fmt.Sprintf("expected OK, actually %s", string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected OK, actually %s", string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
result = LIndex(testDB, toArgs(key, indexStr))
|
result = LIndex(testDB, utils2.ToBytesList(key, indexStr))
|
||||||
expected := reply.MakeBulkReply([]byte(value))
|
expected := reply.MakeBulkReply([]byte(value))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
@@ -234,12 +235,12 @@ func TestLSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
// test negative index
|
// test negative index
|
||||||
for i := 1; i <= size; i++ {
|
for i := 1; i <= size; i++ {
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
result := LSet(testDB, toArgs(key, strconv.Itoa(-i), value))
|
result := LSet(testDB, utils2.ToBytesList(key, strconv.Itoa(-i), value))
|
||||||
if _, ok := result.(*reply.OkReply); !ok {
|
if _, ok := result.(*reply.OkReply); !ok {
|
||||||
t.Error(fmt.Sprintf("expected OK, actually %s", string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected OK, actually %s", string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
result = LIndex(testDB, toArgs(key, strconv.Itoa(len(values)-i-1)))
|
result = LIndex(testDB, utils2.ToBytesList(key, strconv.Itoa(len(values)-i-1)))
|
||||||
expected := reply.MakeBulkReply([]byte(value))
|
expected := reply.MakeBulkReply([]byte(value))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
@@ -247,17 +248,17 @@ func TestLSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// test illegal index
|
// test illegal index
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
result := LSet(testDB, toArgs(key, strconv.Itoa(-len(values)-1), value))
|
result := LSet(testDB, utils2.ToBytesList(key, strconv.Itoa(-len(values)-1), value))
|
||||||
expected := reply.MakeErrReply("ERR index out of range")
|
expected := reply.MakeErrReply("ERR index out of range")
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
result = LSet(testDB, toArgs(key, strconv.Itoa(len(values)), value))
|
result = LSet(testDB, utils2.ToBytesList(key, strconv.Itoa(len(values)), value))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
result = LSet(testDB, toArgs(key, "a", value))
|
result = LSet(testDB, utils2.ToBytesList(key, "a", value))
|
||||||
expected = reply.MakeErrReply("ERR value is not an integer or out of range")
|
expected = reply.MakeErrReply("ERR value is not an integer or out of range")
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
@@ -266,19 +267,19 @@ func TestLSet(t *testing.T) {
|
|||||||
|
|
||||||
func TestLPop(t *testing.T) {
|
func TestLPop(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
values := []string{key, "a", "b", "c", "d", "e", "f"}
|
values := []string{key, "a", "b", "c", "d", "e", "f"}
|
||||||
RPush(testDB, toArgs(values...))
|
RPush(testDB, utils2.ToBytesList(values...))
|
||||||
size := len(values) - 1
|
size := len(values) - 1
|
||||||
|
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
result := LPop(testDB, toArgs(key))
|
result := LPop(testDB, utils2.ToBytesList(key))
|
||||||
expected := reply.MakeBulkReply([]byte(values[i+1]))
|
expected := reply.MakeBulkReply([]byte(values[i+1]))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result := RPop(testDB, toArgs(key))
|
result := RPop(testDB, utils2.ToBytesList(key))
|
||||||
expected := &reply.NullBulkReply{}
|
expected := &reply.NullBulkReply{}
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
@@ -287,19 +288,19 @@ func TestLPop(t *testing.T) {
|
|||||||
|
|
||||||
func TestRPop(t *testing.T) {
|
func TestRPop(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
values := []string{key, "a", "b", "c", "d", "e", "f"}
|
values := []string{key, "a", "b", "c", "d", "e", "f"}
|
||||||
RPush(testDB, toArgs(values...))
|
RPush(testDB, utils2.ToBytesList(values...))
|
||||||
size := len(values) - 1
|
size := len(values) - 1
|
||||||
|
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
result := RPop(testDB, toArgs(key))
|
result := RPop(testDB, utils2.ToBytesList(key))
|
||||||
expected := reply.MakeBulkReply([]byte(values[len(values)-i-1]))
|
expected := reply.MakeBulkReply([]byte(values[len(values)-i-1]))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result := RPop(testDB, toArgs(key))
|
result := RPop(testDB, utils2.ToBytesList(key))
|
||||||
expected := &reply.NullBulkReply{}
|
expected := &reply.NullBulkReply{}
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
@@ -308,24 +309,24 @@ func TestRPop(t *testing.T) {
|
|||||||
|
|
||||||
func TestRPopLPush(t *testing.T) {
|
func TestRPopLPush(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key1 := RandString(10)
|
key1 := utils2.RandString(10)
|
||||||
key2 := RandString(10)
|
key2 := utils2.RandString(10)
|
||||||
values := []string{key1, "a", "b", "c", "d", "e", "f"}
|
values := []string{key1, "a", "b", "c", "d", "e", "f"}
|
||||||
RPush(testDB, toArgs(values...))
|
RPush(testDB, utils2.ToBytesList(values...))
|
||||||
size := len(values) - 1
|
size := len(values) - 1
|
||||||
|
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
result := RPopLPush(testDB, toArgs(key1, key2))
|
result := RPopLPush(testDB, utils2.ToBytesList(key1, key2))
|
||||||
expected := reply.MakeBulkReply([]byte(values[len(values)-i-1]))
|
expected := reply.MakeBulkReply([]byte(values[len(values)-i-1]))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
result = LIndex(testDB, toArgs(key2, "0"))
|
result = LIndex(testDB, utils2.ToBytesList(key2, "0"))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result := RPop(testDB, toArgs(key1))
|
result := RPop(testDB, utils2.ToBytesList(key1))
|
||||||
expected := &reply.NullBulkReply{}
|
expected := &reply.NullBulkReply{}
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
@@ -334,22 +335,22 @@ func TestRPopLPush(t *testing.T) {
|
|||||||
|
|
||||||
func TestRPushX(t *testing.T) {
|
func TestRPushX(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
result := RPushX(testDB, toArgs(key, "1"))
|
result := RPushX(testDB, utils2.ToBytesList(key, "1"))
|
||||||
expected := reply.MakeIntReply(int64(0))
|
expected := reply.MakeIntReply(int64(0))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
|
|
||||||
RPush(testDB, toArgs(key, "1"))
|
RPush(testDB, utils2.ToBytesList(key, "1"))
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
result := RPushX(testDB, toArgs(key, value))
|
result := RPushX(testDB, utils2.ToBytesList(key, value))
|
||||||
expected := reply.MakeIntReply(int64(i + 2))
|
expected := reply.MakeIntReply(int64(i + 2))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
result = LIndex(testDB, toArgs(key, "-1"))
|
result = LIndex(testDB, utils2.ToBytesList(key, "-1"))
|
||||||
expected2 := reply.MakeBulkReply([]byte(value))
|
expected2 := reply.MakeBulkReply([]byte(value))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected2.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected2.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected2.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected2.ToBytes()), string(result.ToBytes())))
|
||||||
@@ -359,22 +360,22 @@ func TestRPushX(t *testing.T) {
|
|||||||
|
|
||||||
func TestLPushX(t *testing.T) {
|
func TestLPushX(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
result := RPushX(testDB, toArgs(key, "1"))
|
result := RPushX(testDB, utils2.ToBytesList(key, "1"))
|
||||||
expected := reply.MakeIntReply(int64(0))
|
expected := reply.MakeIntReply(int64(0))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
|
|
||||||
LPush(testDB, toArgs(key, "1"))
|
LPush(testDB, utils2.ToBytesList(key, "1"))
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
result := LPushX(testDB, toArgs(key, value))
|
result := LPushX(testDB, utils2.ToBytesList(key, value))
|
||||||
expected := reply.MakeIntReply(int64(i + 2))
|
expected := reply.MakeIntReply(int64(i + 2))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected.ToBytes()), string(result.ToBytes())))
|
||||||
}
|
}
|
||||||
result = LIndex(testDB, toArgs(key, "0"))
|
result = LIndex(testDB, utils2.ToBytesList(key, "0"))
|
||||||
expected2 := reply.MakeBulkReply([]byte(value))
|
expected2 := reply.MakeBulkReply([]byte(value))
|
||||||
if !utils.BytesEquals(result.ToBytes(), expected2.ToBytes()) {
|
if !utils.BytesEquals(result.ToBytes(), expected2.ToBytes()) {
|
||||||
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected2.ToBytes()), string(result.ToBytes())))
|
t.Error(fmt.Sprintf("expected %s, actually %s", string(expected2.ToBytes()), string(result.ToBytes())))
|
||||||
|
@@ -1,16 +1,17 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/hdt3213/godis/lib/utils"
|
||||||
"github.com/hdt3213/godis/redis/reply/asserts"
|
"github.com/hdt3213/godis/redis/reply/asserts"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPing(t *testing.T) {
|
func TestPing(t *testing.T) {
|
||||||
actual := Ping(testDB, toArgs())
|
actual := Ping(testDB, utils.ToBytesList())
|
||||||
asserts.AssertStatusReply(t, actual, "PONG")
|
asserts.AssertStatusReply(t, actual, "PONG")
|
||||||
val := RandString(5)
|
val := utils.RandString(5)
|
||||||
actual = Ping(testDB, toArgs(val))
|
actual = Ping(testDB, utils.ToBytesList(val))
|
||||||
asserts.AssertStatusReply(t, actual, val)
|
asserts.AssertStatusReply(t, actual, val)
|
||||||
actual = Ping(testDB, toArgs(val, val))
|
actual = Ping(testDB, utils.ToBytesList(val, val))
|
||||||
asserts.AssertErrReply(t, actual, "ERR wrong number of arguments for 'ping' command")
|
asserts.AssertErrReply(t, actual, "ERR wrong number of arguments for 'ping' command")
|
||||||
}
|
}
|
||||||
|
@@ -236,7 +236,7 @@ func SInterStore(db *DB, args [][]byte) redis.Reply {
|
|||||||
}
|
}
|
||||||
if set == nil {
|
if set == nil {
|
||||||
db.Remove(dest) // clean ttl and old value
|
db.Remove(dest) // clean ttl and old value
|
||||||
return &reply.EmptyMultiBulkReply{}
|
return reply.MakeIntReply(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if result == nil {
|
if result == nil {
|
||||||
@@ -437,7 +437,7 @@ func SDiffStore(db *DB, args [][]byte) redis.Reply {
|
|||||||
if i == 0 {
|
if i == 0 {
|
||||||
// early termination
|
// early termination
|
||||||
db.Remove(dest)
|
db.Remove(dest)
|
||||||
return &reply.EmptyMultiBulkReply{}
|
return reply.MakeIntReply(0)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -449,7 +449,7 @@ func SDiffStore(db *DB, args [][]byte) redis.Reply {
|
|||||||
if result.Len() == 0 {
|
if result.Len() == 0 {
|
||||||
// early termination
|
// early termination
|
||||||
db.Remove(dest)
|
db.Remove(dest)
|
||||||
return &reply.EmptyMultiBulkReply{}
|
return reply.MakeIntReply(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/hdt3213/godis/lib/utils"
|
||||||
"github.com/hdt3213/godis/redis/reply"
|
"github.com/hdt3213/godis/redis/reply"
|
||||||
"github.com/hdt3213/godis/redis/reply/asserts"
|
"github.com/hdt3213/godis/redis/reply/asserts"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -14,25 +15,25 @@ func TestSAdd(t *testing.T) {
|
|||||||
size := 100
|
size := 100
|
||||||
|
|
||||||
// test sadd
|
// test sadd
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
member := strconv.Itoa(i)
|
member := strconv.Itoa(i)
|
||||||
result := SAdd(testDB, toArgs(key, member))
|
result := SAdd(testDB, utils.ToBytesList(key, member))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
}
|
}
|
||||||
// test scard
|
// test scard
|
||||||
result := SCard(testDB, toArgs(key))
|
result := SCard(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertIntReply(t, result, size)
|
asserts.AssertIntReply(t, result, size)
|
||||||
|
|
||||||
// test is member
|
// test is member
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
member := strconv.Itoa(i)
|
member := strconv.Itoa(i)
|
||||||
result := SIsMember(testDB, toArgs(key, member))
|
result := SIsMember(testDB, utils.ToBytesList(key, member))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// test members
|
// test members
|
||||||
result = SMembers(testDB, toArgs(key))
|
result = SMembers(testDB, utils.ToBytesList(key))
|
||||||
multiBulk, ok := result.(*reply.MultiBulkReply)
|
multiBulk, ok := result.(*reply.MultiBulkReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected bulk reply, actually %s", result.ToBytes()))
|
t.Error(fmt.Sprintf("expected bulk reply, actually %s", result.ToBytes()))
|
||||||
@@ -49,15 +50,15 @@ func TestSRem(t *testing.T) {
|
|||||||
size := 100
|
size := 100
|
||||||
|
|
||||||
// mock data
|
// mock data
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
member := strconv.Itoa(i)
|
member := strconv.Itoa(i)
|
||||||
SAdd(testDB, toArgs(key, member))
|
SAdd(testDB, utils.ToBytesList(key, member))
|
||||||
}
|
}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
member := strconv.Itoa(i)
|
member := strconv.Itoa(i)
|
||||||
SRem(testDB, toArgs(key, member))
|
SRem(testDB, utils.ToBytesList(key, member))
|
||||||
result := SIsMember(testDB, toArgs(key, member))
|
result := SIsMember(testDB, utils.ToBytesList(key, member))
|
||||||
asserts.AssertIntReply(t, result, 0)
|
asserts.AssertIntReply(t, result, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,22 +71,39 @@ func TestSInter(t *testing.T) {
|
|||||||
keys := make([]string, 0)
|
keys := make([]string, 0)
|
||||||
start := 0
|
start := 0
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
for j := start; j < size+start; j++ {
|
for j := start; j < size+start; j++ {
|
||||||
member := strconv.Itoa(j)
|
member := strconv.Itoa(j)
|
||||||
SAdd(testDB, toArgs(key, member))
|
SAdd(testDB, utils.ToBytesList(key, member))
|
||||||
}
|
}
|
||||||
start += step
|
start += step
|
||||||
}
|
}
|
||||||
result := SInter(testDB, toArgs(keys...))
|
result := SInter(testDB, utils.ToBytesList(keys...))
|
||||||
asserts.AssertMultiBulkReplySize(t, result, 70)
|
asserts.AssertMultiBulkReplySize(t, result, 70)
|
||||||
|
|
||||||
destKey := RandString(10)
|
destKey := utils.RandString(10)
|
||||||
keysWithDest := []string{destKey}
|
keysWithDest := []string{destKey}
|
||||||
keysWithDest = append(keysWithDest, keys...)
|
keysWithDest = append(keysWithDest, keys...)
|
||||||
result = SInterStore(testDB, toArgs(keysWithDest...))
|
result = SInterStore(testDB, utils.ToBytesList(keysWithDest...))
|
||||||
asserts.AssertIntReply(t, result, 70)
|
asserts.AssertIntReply(t, result, 70)
|
||||||
|
|
||||||
|
// test empty set
|
||||||
|
FlushAll(testDB, [][]byte{})
|
||||||
|
key0 := utils.RandString(10)
|
||||||
|
Del(testDB, utils.ToBytesList(key0))
|
||||||
|
key1 := utils.RandString(10)
|
||||||
|
SAdd(testDB, utils.ToBytesList(key1, "a", "b"))
|
||||||
|
key2 := utils.RandString(10)
|
||||||
|
SAdd(testDB, utils.ToBytesList(key2, "1", "2"))
|
||||||
|
result = SInter(testDB, utils.ToBytesList(key0, key1, key2))
|
||||||
|
asserts.AssertMultiBulkReplySize(t, result, 0)
|
||||||
|
result = SInter(testDB, utils.ToBytesList(key1, key2))
|
||||||
|
asserts.AssertMultiBulkReplySize(t, result, 0)
|
||||||
|
result = SInterStore(testDB, utils.ToBytesList(utils.RandString(10), key0, key1, key2))
|
||||||
|
asserts.AssertIntReply(t, result, 0)
|
||||||
|
result = SInterStore(testDB, utils.ToBytesList(utils.RandString(10), key1, key2))
|
||||||
|
asserts.AssertIntReply(t, result, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSUnion(t *testing.T) {
|
func TestSUnion(t *testing.T) {
|
||||||
@@ -96,21 +114,21 @@ func TestSUnion(t *testing.T) {
|
|||||||
keys := make([]string, 0)
|
keys := make([]string, 0)
|
||||||
start := 0
|
start := 0
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
for j := start; j < size+start; j++ {
|
for j := start; j < size+start; j++ {
|
||||||
member := strconv.Itoa(j)
|
member := strconv.Itoa(j)
|
||||||
SAdd(testDB, toArgs(key, member))
|
SAdd(testDB, utils.ToBytesList(key, member))
|
||||||
}
|
}
|
||||||
start += step
|
start += step
|
||||||
}
|
}
|
||||||
result := SUnion(testDB, toArgs(keys...))
|
result := SUnion(testDB, utils.ToBytesList(keys...))
|
||||||
asserts.AssertMultiBulkReplySize(t, result, 130)
|
asserts.AssertMultiBulkReplySize(t, result, 130)
|
||||||
|
|
||||||
destKey := RandString(10)
|
destKey := utils.RandString(10)
|
||||||
keysWithDest := []string{destKey}
|
keysWithDest := []string{destKey}
|
||||||
keysWithDest = append(keysWithDest, keys...)
|
keysWithDest = append(keysWithDest, keys...)
|
||||||
result = SUnionStore(testDB, toArgs(keysWithDest...))
|
result = SUnionStore(testDB, utils.ToBytesList(keysWithDest...))
|
||||||
asserts.AssertIntReply(t, result, 130)
|
asserts.AssertIntReply(t, result, 130)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,39 +140,56 @@ func TestSDiff(t *testing.T) {
|
|||||||
keys := make([]string, 0)
|
keys := make([]string, 0)
|
||||||
start := 0
|
start := 0
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
for j := start; j < size+start; j++ {
|
for j := start; j < size+start; j++ {
|
||||||
member := strconv.Itoa(j)
|
member := strconv.Itoa(j)
|
||||||
SAdd(testDB, toArgs(key, member))
|
SAdd(testDB, utils.ToBytesList(key, member))
|
||||||
}
|
}
|
||||||
start += step
|
start += step
|
||||||
}
|
}
|
||||||
result := SDiff(testDB, toArgs(keys...))
|
result := SDiff(testDB, utils.ToBytesList(keys...))
|
||||||
asserts.AssertMultiBulkReplySize(t, result, step)
|
asserts.AssertMultiBulkReplySize(t, result, step)
|
||||||
|
|
||||||
destKey := RandString(10)
|
destKey := utils.RandString(10)
|
||||||
keysWithDest := []string{destKey}
|
keysWithDest := []string{destKey}
|
||||||
keysWithDest = append(keysWithDest, keys...)
|
keysWithDest = append(keysWithDest, keys...)
|
||||||
result = SDiffStore(testDB, toArgs(keysWithDest...))
|
result = SDiffStore(testDB, utils.ToBytesList(keysWithDest...))
|
||||||
asserts.AssertIntReply(t, result, step)
|
asserts.AssertIntReply(t, result, step)
|
||||||
|
|
||||||
|
// test empty set
|
||||||
|
FlushAll(testDB, [][]byte{})
|
||||||
|
key0 := utils.RandString(10)
|
||||||
|
Del(testDB, utils.ToBytesList(key0))
|
||||||
|
key1 := utils.RandString(10)
|
||||||
|
SAdd(testDB, utils.ToBytesList(key1, "a", "b"))
|
||||||
|
key2 := utils.RandString(10)
|
||||||
|
SAdd(testDB, utils.ToBytesList(key2, "a", "b"))
|
||||||
|
result = SDiff(testDB, utils.ToBytesList(key0, key1, key2))
|
||||||
|
asserts.AssertMultiBulkReplySize(t, result, 0)
|
||||||
|
result = SDiff(testDB, utils.ToBytesList(key1, key2))
|
||||||
|
asserts.AssertMultiBulkReplySize(t, result, 0)
|
||||||
|
result = SDiffStore(testDB, utils.ToBytesList(utils.RandString(10), key0, key1, key2))
|
||||||
|
asserts.AssertIntReply(t, result, 0)
|
||||||
|
result = SDiffStore(testDB, utils.ToBytesList(utils.RandString(10), key1, key2))
|
||||||
|
asserts.AssertIntReply(t, result, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSRandMember(t *testing.T) {
|
func TestSRandMember(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
for j := 0; j < 100; j++ {
|
for j := 0; j < 100; j++ {
|
||||||
member := strconv.Itoa(j)
|
member := strconv.Itoa(j)
|
||||||
SAdd(testDB, toArgs(key, member))
|
SAdd(testDB, utils.ToBytesList(key, member))
|
||||||
}
|
}
|
||||||
result := SRandMember(testDB, toArgs(key))
|
result := SRandMember(testDB, utils.ToBytesList(key))
|
||||||
br, ok := result.(*reply.BulkReply)
|
br, ok := result.(*reply.BulkReply)
|
||||||
if !ok && len(br.Arg) > 0 {
|
if !ok && len(br.Arg) > 0 {
|
||||||
t.Error(fmt.Sprintf("expected bulk reply, actually %s", result.ToBytes()))
|
t.Error(fmt.Sprintf("expected bulk reply, actually %s", result.ToBytes()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result = SRandMember(testDB, toArgs(key, "10"))
|
result = SRandMember(testDB, utils.ToBytesList(key, "10"))
|
||||||
asserts.AssertMultiBulkReplySize(t, result, 10)
|
asserts.AssertMultiBulkReplySize(t, result, 10)
|
||||||
multiBulk, ok := result.(*reply.MultiBulkReply)
|
multiBulk, ok := result.(*reply.MultiBulkReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -170,12 +205,12 @@ func TestSRandMember(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result = SRandMember(testDB, toArgs(key, "110"))
|
result = SRandMember(testDB, utils.ToBytesList(key, "110"))
|
||||||
asserts.AssertMultiBulkReplySize(t, result, 100)
|
asserts.AssertMultiBulkReplySize(t, result, 100)
|
||||||
|
|
||||||
result = SRandMember(testDB, toArgs(key, "-10"))
|
result = SRandMember(testDB, utils.ToBytesList(key, "-10"))
|
||||||
asserts.AssertMultiBulkReplySize(t, result, 10)
|
asserts.AssertMultiBulkReplySize(t, result, 10)
|
||||||
|
|
||||||
result = SRandMember(testDB, toArgs(key, "-110"))
|
result = SRandMember(testDB, utils.ToBytesList(key, "-110"))
|
||||||
asserts.AssertMultiBulkReplySize(t, result, 110)
|
asserts.AssertMultiBulkReplySize(t, result, 110)
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/hdt3213/godis/lib/utils"
|
||||||
"github.com/hdt3213/godis/redis/reply/asserts"
|
"github.com/hdt3213/godis/redis/reply/asserts"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -12,27 +13,27 @@ func TestZAdd(t *testing.T) {
|
|||||||
size := 100
|
size := 100
|
||||||
|
|
||||||
// add new members
|
// add new members
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
members := make([]string, size)
|
members := make([]string, size)
|
||||||
scores := make([]float64, size)
|
scores := make([]float64, size)
|
||||||
setArgs := []string{key}
|
setArgs := []string{key}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
members[i] = RandString(10)
|
members[i] = utils.RandString(10)
|
||||||
scores[i] = rand.Float64()
|
scores[i] = rand.Float64()
|
||||||
setArgs = append(setArgs, strconv.FormatFloat(scores[i], 'f', -1, 64), members[i])
|
setArgs = append(setArgs, strconv.FormatFloat(scores[i], 'f', -1, 64), members[i])
|
||||||
}
|
}
|
||||||
result := ZAdd(testDB, toArgs(setArgs...))
|
result := ZAdd(testDB, utils.ToBytesList(setArgs...))
|
||||||
asserts.AssertIntReply(t, result, size)
|
asserts.AssertIntReply(t, result, size)
|
||||||
|
|
||||||
// test zscore and zrank
|
// test zscore and zrank
|
||||||
for i, member := range members {
|
for i, member := range members {
|
||||||
result := ZScore(testDB, toArgs(key, member))
|
result := ZScore(testDB, utils.ToBytesList(key, member))
|
||||||
score := strconv.FormatFloat(scores[i], 'f', -1, 64)
|
score := strconv.FormatFloat(scores[i], 'f', -1, 64)
|
||||||
asserts.AssertBulkReply(t, result, score)
|
asserts.AssertBulkReply(t, result, score)
|
||||||
}
|
}
|
||||||
|
|
||||||
// test zcard
|
// test zcard
|
||||||
result = ZCard(testDB, toArgs(key))
|
result = ZCard(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertIntReply(t, result, size)
|
asserts.AssertIntReply(t, result, size)
|
||||||
|
|
||||||
// update members
|
// update members
|
||||||
@@ -41,12 +42,12 @@ func TestZAdd(t *testing.T) {
|
|||||||
scores[i] = rand.Float64() + 100
|
scores[i] = rand.Float64() + 100
|
||||||
setArgs = append(setArgs, strconv.FormatFloat(scores[i], 'f', -1, 64), members[i])
|
setArgs = append(setArgs, strconv.FormatFloat(scores[i], 'f', -1, 64), members[i])
|
||||||
}
|
}
|
||||||
result = ZAdd(testDB, toArgs(setArgs...))
|
result = ZAdd(testDB, utils.ToBytesList(setArgs...))
|
||||||
asserts.AssertIntReply(t, result, 0) // return number of new members
|
asserts.AssertIntReply(t, result, 0) // return number of new members
|
||||||
|
|
||||||
// test updated score
|
// test updated score
|
||||||
for i, member := range members {
|
for i, member := range members {
|
||||||
result := ZScore(testDB, toArgs(key, member))
|
result := ZScore(testDB, utils.ToBytesList(key, member))
|
||||||
score := strconv.FormatFloat(scores[i], 'f', -1, 64)
|
score := strconv.FormatFloat(scores[i], 'f', -1, 64)
|
||||||
asserts.AssertBulkReply(t, result, score)
|
asserts.AssertBulkReply(t, result, score)
|
||||||
}
|
}
|
||||||
@@ -55,23 +56,23 @@ func TestZAdd(t *testing.T) {
|
|||||||
func TestZRank(t *testing.T) {
|
func TestZRank(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
size := 100
|
size := 100
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
members := make([]string, size)
|
members := make([]string, size)
|
||||||
scores := make([]int, size)
|
scores := make([]int, size)
|
||||||
setArgs := []string{key}
|
setArgs := []string{key}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
members[i] = RandString(10)
|
members[i] = utils.RandString(10)
|
||||||
scores[i] = i
|
scores[i] = i
|
||||||
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
||||||
}
|
}
|
||||||
ZAdd(testDB, toArgs(setArgs...))
|
ZAdd(testDB, utils.ToBytesList(setArgs...))
|
||||||
|
|
||||||
// test zrank
|
// test zrank
|
||||||
for i, member := range members {
|
for i, member := range members {
|
||||||
result := ZRank(testDB, toArgs(key, member))
|
result := ZRank(testDB, utils.ToBytesList(key, member))
|
||||||
asserts.AssertIntReply(t, result, i)
|
asserts.AssertIntReply(t, result, i)
|
||||||
|
|
||||||
result = ZRevRank(testDB, toArgs(key, member))
|
result = ZRevRank(testDB, utils.ToBytesList(key, member))
|
||||||
asserts.AssertIntReply(t, result, size-i-1)
|
asserts.AssertIntReply(t, result, size-i-1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,16 +81,16 @@ func TestZRange(t *testing.T) {
|
|||||||
// prepare
|
// prepare
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
size := 100
|
size := 100
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
members := make([]string, size)
|
members := make([]string, size)
|
||||||
scores := make([]int, size)
|
scores := make([]int, size)
|
||||||
setArgs := []string{key}
|
setArgs := []string{key}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
members[i] = RandString(10)
|
members[i] = utils.RandString(10)
|
||||||
scores[i] = i
|
scores[i] = i
|
||||||
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
||||||
}
|
}
|
||||||
ZAdd(testDB, toArgs(setArgs...))
|
ZAdd(testDB, utils.ToBytesList(setArgs...))
|
||||||
reverseMembers := make([]string, size)
|
reverseMembers := make([]string, size)
|
||||||
for i, v := range members {
|
for i, v := range members {
|
||||||
reverseMembers[size-i-1] = v
|
reverseMembers[size-i-1] = v
|
||||||
@@ -97,37 +98,39 @@ func TestZRange(t *testing.T) {
|
|||||||
|
|
||||||
start := "0"
|
start := "0"
|
||||||
end := "9"
|
end := "9"
|
||||||
result := ZRange(testDB, toArgs(key, start, end))
|
result := ZRange(testDB, utils.ToBytesList(key, start, end))
|
||||||
asserts.AssertMultiBulkReply(t, result, members[0:10])
|
asserts.AssertMultiBulkReply(t, result, members[0:10])
|
||||||
result = ZRevRange(testDB, toArgs(key, start, end))
|
result = ZRange(testDB, utils.ToBytesList(key, start, end, "WITHSCORES"))
|
||||||
|
asserts.AssertMultiBulkReplySize(t, result, 20)
|
||||||
|
result = ZRevRange(testDB, utils.ToBytesList(key, start, end))
|
||||||
asserts.AssertMultiBulkReply(t, result, reverseMembers[0:10])
|
asserts.AssertMultiBulkReply(t, result, reverseMembers[0:10])
|
||||||
|
|
||||||
start = "0"
|
start = "0"
|
||||||
end = "200"
|
end = "200"
|
||||||
result = ZRange(testDB, toArgs(key, start, end))
|
result = ZRange(testDB, utils.ToBytesList(key, start, end))
|
||||||
asserts.AssertMultiBulkReply(t, result, members)
|
asserts.AssertMultiBulkReply(t, result, members)
|
||||||
result = ZRevRange(testDB, toArgs(key, start, end))
|
result = ZRevRange(testDB, utils.ToBytesList(key, start, end))
|
||||||
asserts.AssertMultiBulkReply(t, result, reverseMembers)
|
asserts.AssertMultiBulkReply(t, result, reverseMembers)
|
||||||
|
|
||||||
start = "0"
|
start = "0"
|
||||||
end = "-10"
|
end = "-10"
|
||||||
result = ZRange(testDB, toArgs(key, start, end))
|
result = ZRange(testDB, utils.ToBytesList(key, start, end))
|
||||||
asserts.AssertMultiBulkReply(t, result, members[0:size-10+1])
|
asserts.AssertMultiBulkReply(t, result, members[0:size-10+1])
|
||||||
result = ZRevRange(testDB, toArgs(key, start, end))
|
result = ZRevRange(testDB, utils.ToBytesList(key, start, end))
|
||||||
asserts.AssertMultiBulkReply(t, result, reverseMembers[0:size-10+1])
|
asserts.AssertMultiBulkReply(t, result, reverseMembers[0:size-10+1])
|
||||||
|
|
||||||
start = "0"
|
start = "0"
|
||||||
end = "-200"
|
end = "-200"
|
||||||
result = ZRange(testDB, toArgs(key, start, end))
|
result = ZRange(testDB, utils.ToBytesList(key, start, end))
|
||||||
asserts.AssertMultiBulkReply(t, result, members[0:0])
|
asserts.AssertMultiBulkReply(t, result, members[0:0])
|
||||||
result = ZRevRange(testDB, toArgs(key, start, end))
|
result = ZRevRange(testDB, utils.ToBytesList(key, start, end))
|
||||||
asserts.AssertMultiBulkReply(t, result, reverseMembers[0:0])
|
asserts.AssertMultiBulkReply(t, result, reverseMembers[0:0])
|
||||||
|
|
||||||
start = "-10"
|
start = "-10"
|
||||||
end = "-1"
|
end = "-1"
|
||||||
result = ZRange(testDB, toArgs(key, start, end))
|
result = ZRange(testDB, utils.ToBytesList(key, start, end))
|
||||||
asserts.AssertMultiBulkReply(t, result, members[90:])
|
asserts.AssertMultiBulkReply(t, result, members[90:])
|
||||||
result = ZRevRange(testDB, toArgs(key, start, end))
|
result = ZRevRange(testDB, utils.ToBytesList(key, start, end))
|
||||||
asserts.AssertMultiBulkReply(t, result, reverseMembers[90:])
|
asserts.AssertMultiBulkReply(t, result, reverseMembers[90:])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +146,7 @@ func TestZRangeByScore(t *testing.T) {
|
|||||||
// prepare
|
// prepare
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
size := 100
|
size := 100
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
members := make([]string, size)
|
members := make([]string, size)
|
||||||
scores := make([]int, size)
|
scores := make([]int, size)
|
||||||
setArgs := []string{key}
|
setArgs := []string{key}
|
||||||
@@ -152,48 +155,50 @@ func TestZRangeByScore(t *testing.T) {
|
|||||||
scores[i] = i
|
scores[i] = i
|
||||||
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
||||||
}
|
}
|
||||||
result := ZAdd(testDB, toArgs(setArgs...))
|
result := ZAdd(testDB, utils.ToBytesList(setArgs...))
|
||||||
|
|
||||||
min := "20"
|
min := "20"
|
||||||
max := "30"
|
max := "30"
|
||||||
result = ZRangeByScore(testDB, toArgs(key, min, max))
|
result = ZRangeByScore(testDB, utils.ToBytesList(key, min, max))
|
||||||
asserts.AssertMultiBulkReply(t, result, members[20:31])
|
asserts.AssertMultiBulkReply(t, result, members[20:31])
|
||||||
result = ZRevRangeByScore(testDB, toArgs(key, max, min))
|
result = ZRangeByScore(testDB, utils.ToBytesList(key, min, max, "WITHSCORES"))
|
||||||
|
asserts.AssertMultiBulkReplySize(t, result, 22)
|
||||||
|
result = ZRevRangeByScore(testDB, utils.ToBytesList(key, max, min))
|
||||||
asserts.AssertMultiBulkReply(t, result, reverse(members[20:31]))
|
asserts.AssertMultiBulkReply(t, result, reverse(members[20:31]))
|
||||||
|
|
||||||
min = "-10"
|
min = "-10"
|
||||||
max = "10"
|
max = "10"
|
||||||
result = ZRangeByScore(testDB, toArgs(key, min, max))
|
result = ZRangeByScore(testDB, utils.ToBytesList(key, min, max))
|
||||||
asserts.AssertMultiBulkReply(t, result, members[0:11])
|
asserts.AssertMultiBulkReply(t, result, members[0:11])
|
||||||
result = ZRevRangeByScore(testDB, toArgs(key, max, min))
|
result = ZRevRangeByScore(testDB, utils.ToBytesList(key, max, min))
|
||||||
asserts.AssertMultiBulkReply(t, result, reverse(members[0:11]))
|
asserts.AssertMultiBulkReply(t, result, reverse(members[0:11]))
|
||||||
|
|
||||||
min = "90"
|
min = "90"
|
||||||
max = "110"
|
max = "110"
|
||||||
result = ZRangeByScore(testDB, toArgs(key, min, max))
|
result = ZRangeByScore(testDB, utils.ToBytesList(key, min, max))
|
||||||
asserts.AssertMultiBulkReply(t, result, members[90:])
|
asserts.AssertMultiBulkReply(t, result, members[90:])
|
||||||
result = ZRevRangeByScore(testDB, toArgs(key, max, min))
|
result = ZRevRangeByScore(testDB, utils.ToBytesList(key, max, min))
|
||||||
asserts.AssertMultiBulkReply(t, result, reverse(members[90:]))
|
asserts.AssertMultiBulkReply(t, result, reverse(members[90:]))
|
||||||
|
|
||||||
min = "(20"
|
min = "(20"
|
||||||
max = "(30"
|
max = "(30"
|
||||||
result = ZRangeByScore(testDB, toArgs(key, min, max))
|
result = ZRangeByScore(testDB, utils.ToBytesList(key, min, max))
|
||||||
asserts.AssertMultiBulkReply(t, result, members[21:30])
|
asserts.AssertMultiBulkReply(t, result, members[21:30])
|
||||||
result = ZRevRangeByScore(testDB, toArgs(key, max, min))
|
result = ZRevRangeByScore(testDB, utils.ToBytesList(key, max, min))
|
||||||
asserts.AssertMultiBulkReply(t, result, reverse(members[21:30]))
|
asserts.AssertMultiBulkReply(t, result, reverse(members[21:30]))
|
||||||
|
|
||||||
min = "20"
|
min = "20"
|
||||||
max = "40"
|
max = "40"
|
||||||
result = ZRangeByScore(testDB, toArgs(key, min, max, "LIMIT", "5", "5"))
|
result = ZRangeByScore(testDB, utils.ToBytesList(key, min, max, "LIMIT", "5", "5"))
|
||||||
asserts.AssertMultiBulkReply(t, result, members[25:30])
|
asserts.AssertMultiBulkReply(t, result, members[25:30])
|
||||||
result = ZRevRangeByScore(testDB, toArgs(key, max, min, "LIMIT", "5", "5"))
|
result = ZRevRangeByScore(testDB, utils.ToBytesList(key, max, min, "LIMIT", "5", "5"))
|
||||||
asserts.AssertMultiBulkReply(t, result, reverse(members[31:36]))
|
asserts.AssertMultiBulkReply(t, result, reverse(members[31:36]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestZRem(t *testing.T) {
|
func TestZRem(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
size := 100
|
size := 100
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
members := make([]string, size)
|
members := make([]string, size)
|
||||||
scores := make([]int, size)
|
scores := make([]int, size)
|
||||||
setArgs := []string{key}
|
setArgs := []string{key}
|
||||||
@@ -202,19 +207,19 @@ func TestZRem(t *testing.T) {
|
|||||||
scores[i] = i
|
scores[i] = i
|
||||||
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
||||||
}
|
}
|
||||||
ZAdd(testDB, toArgs(setArgs...))
|
ZAdd(testDB, utils.ToBytesList(setArgs...))
|
||||||
|
|
||||||
args := []string{key}
|
args := []string{key}
|
||||||
args = append(args, members[0:10]...)
|
args = append(args, members[0:10]...)
|
||||||
result := ZRem(testDB, toArgs(args...))
|
result := ZRem(testDB, utils.ToBytesList(args...))
|
||||||
asserts.AssertIntReply(t, result, 10)
|
asserts.AssertIntReply(t, result, 10)
|
||||||
result = ZCard(testDB, toArgs(key))
|
result = ZCard(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertIntReply(t, result, size-10)
|
asserts.AssertIntReply(t, result, size-10)
|
||||||
|
|
||||||
// test ZRemRangeByRank
|
// test ZRemRangeByRank
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
size = 100
|
size = 100
|
||||||
key = RandString(10)
|
key = utils.RandString(10)
|
||||||
members = make([]string, size)
|
members = make([]string, size)
|
||||||
scores = make([]int, size)
|
scores = make([]int, size)
|
||||||
setArgs = []string{key}
|
setArgs = []string{key}
|
||||||
@@ -223,17 +228,17 @@ func TestZRem(t *testing.T) {
|
|||||||
scores[i] = i
|
scores[i] = i
|
||||||
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
||||||
}
|
}
|
||||||
ZAdd(testDB, toArgs(setArgs...))
|
ZAdd(testDB, utils.ToBytesList(setArgs...))
|
||||||
|
|
||||||
result = ZRemRangeByRank(testDB, toArgs(key, "0", "9"))
|
result = ZRemRangeByRank(testDB, utils.ToBytesList(key, "0", "9"))
|
||||||
asserts.AssertIntReply(t, result, 10)
|
asserts.AssertIntReply(t, result, 10)
|
||||||
result = ZCard(testDB, toArgs(key))
|
result = ZCard(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertIntReply(t, result, size-10)
|
asserts.AssertIntReply(t, result, size-10)
|
||||||
|
|
||||||
// test ZRemRangeByScore
|
// test ZRemRangeByScore
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
size = 100
|
size = 100
|
||||||
key = RandString(10)
|
key = utils.RandString(10)
|
||||||
members = make([]string, size)
|
members = make([]string, size)
|
||||||
scores = make([]int, size)
|
scores = make([]int, size)
|
||||||
setArgs = []string{key}
|
setArgs = []string{key}
|
||||||
@@ -242,11 +247,11 @@ func TestZRem(t *testing.T) {
|
|||||||
scores[i] = i
|
scores[i] = i
|
||||||
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
||||||
}
|
}
|
||||||
ZAdd(testDB, toArgs(setArgs...))
|
ZAdd(testDB, utils.ToBytesList(setArgs...))
|
||||||
|
|
||||||
result = ZRemRangeByScore(testDB, toArgs(key, "0", "9"))
|
result = ZRemRangeByScore(testDB, utils.ToBytesList(key, "0", "9"))
|
||||||
asserts.AssertIntReply(t, result, 10)
|
asserts.AssertIntReply(t, result, 10)
|
||||||
result = ZCard(testDB, toArgs(key))
|
result = ZCard(testDB, utils.ToBytesList(key))
|
||||||
asserts.AssertIntReply(t, result, size-10)
|
asserts.AssertIntReply(t, result, size-10)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +259,7 @@ func TestZCount(t *testing.T) {
|
|||||||
// prepare
|
// prepare
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
size := 100
|
size := 100
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
members := make([]string, size)
|
members := make([]string, size)
|
||||||
scores := make([]int, size)
|
scores := make([]int, size)
|
||||||
setArgs := []string{key}
|
setArgs := []string{key}
|
||||||
@@ -263,36 +268,37 @@ func TestZCount(t *testing.T) {
|
|||||||
scores[i] = i
|
scores[i] = i
|
||||||
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
setArgs = append(setArgs, strconv.FormatInt(int64(scores[i]), 10), members[i])
|
||||||
}
|
}
|
||||||
ZAdd(testDB, toArgs(setArgs...))
|
ZAdd(testDB, utils.ToBytesList(setArgs...))
|
||||||
|
|
||||||
min := "20"
|
min := "20"
|
||||||
max := "30"
|
max := "30"
|
||||||
result := ZCount(testDB, toArgs(key, min, max))
|
result := ZCount(testDB, utils.ToBytesList(key, min, max))
|
||||||
asserts.AssertIntReply(t, result, 11)
|
asserts.AssertIntReply(t, result, 11)
|
||||||
|
|
||||||
min = "-10"
|
min = "-10"
|
||||||
max = "10"
|
max = "10"
|
||||||
result = ZCount(testDB, toArgs(key, min, max))
|
result = ZCount(testDB, utils.ToBytesList(key, min, max))
|
||||||
asserts.AssertIntReply(t, result, 11)
|
asserts.AssertIntReply(t, result, 11)
|
||||||
|
|
||||||
min = "90"
|
min = "90"
|
||||||
max = "110"
|
max = "110"
|
||||||
result = ZCount(testDB, toArgs(key, min, max))
|
result = ZCount(testDB, utils.ToBytesList(key, min, max))
|
||||||
asserts.AssertIntReply(t, result, 10)
|
asserts.AssertIntReply(t, result, 10)
|
||||||
|
|
||||||
min = "(20"
|
min = "(20"
|
||||||
max = "(30"
|
max = "(30"
|
||||||
result = ZCount(testDB, toArgs(key, min, max))
|
result = ZCount(testDB, utils.ToBytesList(key, min, max))
|
||||||
asserts.AssertIntReply(t, result, 9)
|
asserts.AssertIntReply(t, result, 9)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestZIncrBy(t *testing.T) {
|
func TestZIncrBy(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils.RandString(10)
|
||||||
ZAdd(testDB, toArgs(key, "10", "a"))
|
result := ZIncrBy(testDB, utils.ToBytesList(key, "10", "a"))
|
||||||
result := ZIncrBy(testDB, toArgs(key, "10", "a"))
|
asserts.AssertBulkReply(t, result, "10")
|
||||||
|
result = ZIncrBy(testDB, utils.ToBytesList(key, "10", "a"))
|
||||||
asserts.AssertBulkReply(t, result, "20")
|
asserts.AssertBulkReply(t, result, "20")
|
||||||
|
|
||||||
result = ZScore(testDB, toArgs(key, "a"))
|
result = ZScore(testDB, utils.ToBytesList(key, "a"))
|
||||||
asserts.AssertBulkReply(t, result, "20")
|
asserts.AssertBulkReply(t, result, "20")
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@ package db
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hdt3213/godis/datastruct/utils"
|
"github.com/hdt3213/godis/datastruct/utils"
|
||||||
|
utils2 "github.com/hdt3213/godis/lib/utils"
|
||||||
"github.com/hdt3213/godis/redis/reply"
|
"github.com/hdt3213/godis/redis/reply"
|
||||||
"github.com/hdt3213/godis/redis/reply/asserts"
|
"github.com/hdt3213/godis/redis/reply/asserts"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -13,28 +14,28 @@ var testDB = makeTestDB()
|
|||||||
|
|
||||||
func TestSet(t *testing.T) {
|
func TestSet(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
|
|
||||||
// normal set
|
// normal set
|
||||||
Set(testDB, toArgs(key, value))
|
Set(testDB, utils2.ToBytesList(key, value))
|
||||||
actual := Get(testDB, toArgs(key))
|
actual := Get(testDB, utils2.ToBytesList(key))
|
||||||
expected := reply.MakeBulkReply([]byte(value))
|
expected := reply.MakeBulkReply([]byte(value))
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// set nx
|
// set nx
|
||||||
actual = Set(testDB, toArgs(key, value, "NX"))
|
actual = Set(testDB, utils2.ToBytesList(key, value, "NX"))
|
||||||
if _, ok := actual.(*reply.NullBulkReply); !ok {
|
if _, ok := actual.(*reply.NullBulkReply); !ok {
|
||||||
t.Error("expected true actual false")
|
t.Error("expected true actual false")
|
||||||
}
|
}
|
||||||
|
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key = RandString(10)
|
key = utils2.RandString(10)
|
||||||
value = RandString(10)
|
value = utils2.RandString(10)
|
||||||
Set(testDB, toArgs(key, value, "NX"))
|
Set(testDB, utils2.ToBytesList(key, value, "NX"))
|
||||||
actual = Get(testDB, toArgs(key))
|
actual = Get(testDB, utils2.ToBytesList(key))
|
||||||
expected = reply.MakeBulkReply([]byte(value))
|
expected = reply.MakeBulkReply([]byte(value))
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
||||||
@@ -42,25 +43,25 @@ func TestSet(t *testing.T) {
|
|||||||
|
|
||||||
// set xx
|
// set xx
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key = RandString(10)
|
key = utils2.RandString(10)
|
||||||
value = RandString(10)
|
value = utils2.RandString(10)
|
||||||
actual = Set(testDB, toArgs(key, value, "XX"))
|
actual = Set(testDB, utils2.ToBytesList(key, value, "XX"))
|
||||||
if _, ok := actual.(*reply.NullBulkReply); !ok {
|
if _, ok := actual.(*reply.NullBulkReply); !ok {
|
||||||
t.Error("expected true actually false ")
|
t.Error("expected true actually false ")
|
||||||
}
|
}
|
||||||
|
|
||||||
Set(testDB, toArgs(key, value))
|
Set(testDB, utils2.ToBytesList(key, value))
|
||||||
Set(testDB, toArgs(key, value, "XX"))
|
Set(testDB, utils2.ToBytesList(key, value, "XX"))
|
||||||
actual = Get(testDB, toArgs(key))
|
actual = Get(testDB, utils2.ToBytesList(key))
|
||||||
asserts.AssertBulkReply(t, actual, value)
|
asserts.AssertBulkReply(t, actual, value)
|
||||||
|
|
||||||
// set ex
|
// set ex
|
||||||
Del(testDB, toArgs(key))
|
Del(testDB, utils2.ToBytesList(key))
|
||||||
ttl := "1000"
|
ttl := "1000"
|
||||||
Set(testDB, toArgs(key, value, "EX", ttl))
|
Set(testDB, utils2.ToBytesList(key, value, "EX", ttl))
|
||||||
actual = Get(testDB, toArgs(key))
|
actual = Get(testDB, utils2.ToBytesList(key))
|
||||||
asserts.AssertBulkReply(t, actual, value)
|
asserts.AssertBulkReply(t, actual, value)
|
||||||
actual = TTL(testDB, toArgs(key))
|
actual = TTL(testDB, utils2.ToBytesList(key))
|
||||||
intResult, ok := actual.(*reply.IntReply)
|
intResult, ok := actual.(*reply.IntReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected int reply, actually %s", actual.ToBytes()))
|
t.Error(fmt.Sprintf("expected int reply, actually %s", actual.ToBytes()))
|
||||||
@@ -72,12 +73,12 @@ func TestSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set px
|
// set px
|
||||||
Del(testDB, toArgs(key))
|
Del(testDB, utils2.ToBytesList(key))
|
||||||
ttlPx := "1000000"
|
ttlPx := "1000000"
|
||||||
Set(testDB, toArgs(key, value, "PX", ttlPx))
|
Set(testDB, utils2.ToBytesList(key, value, "PX", ttlPx))
|
||||||
actual = Get(testDB, toArgs(key))
|
actual = Get(testDB, utils2.ToBytesList(key))
|
||||||
asserts.AssertBulkReply(t, actual, value)
|
asserts.AssertBulkReply(t, actual, value)
|
||||||
actual = TTL(testDB, toArgs(key))
|
actual = TTL(testDB, utils2.ToBytesList(key))
|
||||||
intResult, ok = actual.(*reply.IntReply)
|
intResult, ok = actual.(*reply.IntReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected int reply, actually %s", actual.ToBytes()))
|
t.Error(fmt.Sprintf("expected int reply, actually %s", actual.ToBytes()))
|
||||||
@@ -91,16 +92,16 @@ func TestSet(t *testing.T) {
|
|||||||
|
|
||||||
func TestSetNX(t *testing.T) {
|
func TestSetNX(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
SetNX(testDB, toArgs(key, value))
|
SetNX(testDB, utils2.ToBytesList(key, value))
|
||||||
actual := Get(testDB, toArgs(key))
|
actual := Get(testDB, utils2.ToBytesList(key))
|
||||||
expected := reply.MakeBulkReply([]byte(value))
|
expected := reply.MakeBulkReply([]byte(value))
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
actual = SetNX(testDB, toArgs(key, value))
|
actual = SetNX(testDB, utils2.ToBytesList(key, value))
|
||||||
expected2 := reply.MakeIntReply(int64(0))
|
expected2 := reply.MakeIntReply(int64(0))
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected2.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected2.ToBytes()) {
|
||||||
t.Error("expected: " + string(expected2.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
t.Error("expected: " + string(expected2.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
||||||
@@ -109,14 +110,14 @@ func TestSetNX(t *testing.T) {
|
|||||||
|
|
||||||
func TestSetEX(t *testing.T) {
|
func TestSetEX(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
ttl := "1000"
|
ttl := "1000"
|
||||||
|
|
||||||
SetEX(testDB, toArgs(key, ttl, value))
|
SetEX(testDB, utils2.ToBytesList(key, ttl, value))
|
||||||
actual := Get(testDB, toArgs(key))
|
actual := Get(testDB, utils2.ToBytesList(key))
|
||||||
asserts.AssertBulkReply(t, actual, value)
|
asserts.AssertBulkReply(t, actual, value)
|
||||||
actual = TTL(testDB, toArgs(key))
|
actual = TTL(testDB, utils2.ToBytesList(key))
|
||||||
intResult, ok := actual.(*reply.IntReply)
|
intResult, ok := actual.(*reply.IntReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected int reply, actually %s", actual.ToBytes()))
|
t.Error(fmt.Sprintf("expected int reply, actually %s", actual.ToBytes()))
|
||||||
@@ -130,14 +131,14 @@ func TestSetEX(t *testing.T) {
|
|||||||
|
|
||||||
func TestPSetEX(t *testing.T) {
|
func TestPSetEX(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
ttl := "1000000"
|
ttl := "1000000"
|
||||||
|
|
||||||
PSetEX(testDB, toArgs(key, ttl, value))
|
PSetEX(testDB, utils2.ToBytesList(key, ttl, value))
|
||||||
actual := Get(testDB, toArgs(key))
|
actual := Get(testDB, utils2.ToBytesList(key))
|
||||||
asserts.AssertBulkReply(t, actual, value)
|
asserts.AssertBulkReply(t, actual, value)
|
||||||
actual = PTTL(testDB, toArgs(key))
|
actual = PTTL(testDB, utils2.ToBytesList(key))
|
||||||
intResult, ok := actual.(*reply.IntReply)
|
intResult, ok := actual.(*reply.IntReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(fmt.Sprintf("expected int reply, actually %s", actual.ToBytes()))
|
t.Error(fmt.Sprintf("expected int reply, actually %s", actual.ToBytes()))
|
||||||
@@ -156,13 +157,13 @@ func TestMSet(t *testing.T) {
|
|||||||
values := make([][]byte, size)
|
values := make([][]byte, size)
|
||||||
args := make([]string, 0, size*2)
|
args := make([]string, 0, size*2)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
keys[i] = RandString(10)
|
keys[i] = utils2.RandString(10)
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
values[i] = []byte(value)
|
values[i] = []byte(value)
|
||||||
args = append(args, keys[i], value)
|
args = append(args, keys[i], value)
|
||||||
}
|
}
|
||||||
MSet(testDB, toArgs(args...))
|
MSet(testDB, utils2.ToBytesList(args...))
|
||||||
actual := MGet(testDB, toArgs(keys...))
|
actual := MGet(testDB, utils2.ToBytesList(keys...))
|
||||||
expected := reply.MakeMultiBulkReply(values)
|
expected := reply.MakeMultiBulkReply(values)
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
||||||
@@ -172,18 +173,18 @@ func TestMSet(t *testing.T) {
|
|||||||
func TestIncr(t *testing.T) {
|
func TestIncr(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
size := 10
|
size := 10
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
Incr(testDB, toArgs(key))
|
Incr(testDB, utils2.ToBytesList(key))
|
||||||
actual := Get(testDB, toArgs(key))
|
actual := Get(testDB, utils2.ToBytesList(key))
|
||||||
expected := reply.MakeBulkReply([]byte(strconv.FormatInt(int64(i+1), 10)))
|
expected := reply.MakeBulkReply([]byte(strconv.FormatInt(int64(i+1), 10)))
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
IncrBy(testDB, toArgs(key, "-1"))
|
IncrBy(testDB, utils2.ToBytesList(key, "-1"))
|
||||||
actual := Get(testDB, toArgs(key))
|
actual := Get(testDB, utils2.ToBytesList(key))
|
||||||
expected := reply.MakeBulkReply([]byte(strconv.FormatInt(int64(size-i-1), 10)))
|
expected := reply.MakeBulkReply([]byte(strconv.FormatInt(int64(size-i-1), 10)))
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
||||||
@@ -191,19 +192,19 @@ func TestIncr(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key = RandString(10)
|
key = utils2.RandString(10)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
IncrBy(testDB, toArgs(key, "1"))
|
IncrBy(testDB, utils2.ToBytesList(key, "1"))
|
||||||
actual := Get(testDB, toArgs(key))
|
actual := Get(testDB, utils2.ToBytesList(key))
|
||||||
expected := reply.MakeBulkReply([]byte(strconv.FormatInt(int64(i+1), 10)))
|
expected := reply.MakeBulkReply([]byte(strconv.FormatInt(int64(i+1), 10)))
|
||||||
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
if !utils.BytesEquals(actual.ToBytes(), expected.ToBytes()) {
|
||||||
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
t.Error("expected: " + string(expected.ToBytes()) + ", actual: " + string(actual.ToBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Del(testDB, toArgs(key))
|
Del(testDB, utils2.ToBytesList(key))
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
IncrByFloat(testDB, toArgs(key, "-1.0"))
|
IncrByFloat(testDB, utils2.ToBytesList(key, "-1.0"))
|
||||||
actual := Get(testDB, toArgs(key))
|
actual := Get(testDB, utils2.ToBytesList(key))
|
||||||
expected := -i - 1
|
expected := -i - 1
|
||||||
bulk, ok := actual.(*reply.BulkReply)
|
bulk, ok := actual.(*reply.BulkReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -225,16 +226,16 @@ func TestIncr(t *testing.T) {
|
|||||||
func TestDecr(t *testing.T) {
|
func TestDecr(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
size := 10
|
size := 10
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
Decr(testDB, toArgs(key))
|
Decr(testDB, utils2.ToBytesList(key))
|
||||||
actual := Get(testDB, toArgs(key))
|
actual := Get(testDB, utils2.ToBytesList(key))
|
||||||
asserts.AssertBulkReply(t, actual, strconv.Itoa(-i-1))
|
asserts.AssertBulkReply(t, actual, strconv.Itoa(-i-1))
|
||||||
}
|
}
|
||||||
Del(testDB, toArgs(key))
|
Del(testDB, utils2.ToBytesList(key))
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
DecrBy(testDB, toArgs(key, "1"))
|
DecrBy(testDB, utils2.ToBytesList(key, "1"))
|
||||||
actual := Get(testDB, toArgs(key))
|
actual := Get(testDB, utils2.ToBytesList(key))
|
||||||
expected := -i - 1
|
expected := -i - 1
|
||||||
bulk, ok := actual.(*reply.BulkReply)
|
bulk, ok := actual.(*reply.BulkReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -255,20 +256,20 @@ func TestDecr(t *testing.T) {
|
|||||||
|
|
||||||
func TestGetSet(t *testing.T) {
|
func TestGetSet(t *testing.T) {
|
||||||
FlushAll(testDB, [][]byte{})
|
FlushAll(testDB, [][]byte{})
|
||||||
key := RandString(10)
|
key := utils2.RandString(10)
|
||||||
value := RandString(10)
|
value := utils2.RandString(10)
|
||||||
|
|
||||||
result := GetSet(testDB, toArgs(key, value))
|
result := GetSet(testDB, utils2.ToBytesList(key, value))
|
||||||
_, ok := result.(*reply.NullBulkReply)
|
_, ok := result.(*reply.NullBulkReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Errorf("expect null bulk reply, get: %s", string(result.ToBytes()))
|
t.Errorf("expect null bulk reply, get: %s", string(result.ToBytes()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
value2 := RandString(10)
|
value2 := utils2.RandString(10)
|
||||||
result = GetSet(testDB, toArgs(key, value2))
|
result = GetSet(testDB, utils2.ToBytesList(key, value2))
|
||||||
asserts.AssertBulkReply(t, result, value)
|
asserts.AssertBulkReply(t, result, value)
|
||||||
result = Get(testDB, toArgs(key))
|
result = Get(testDB, utils2.ToBytesList(key))
|
||||||
asserts.AssertBulkReply(t, result, value2)
|
asserts.AssertBulkReply(t, result, value2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,12 +278,12 @@ func TestMSetNX(t *testing.T) {
|
|||||||
size := 10
|
size := 10
|
||||||
args := make([]string, 0, size*2)
|
args := make([]string, 0, size*2)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
str := RandString(10)
|
str := utils2.RandString(10)
|
||||||
args = append(args, str, str)
|
args = append(args, str, str)
|
||||||
}
|
}
|
||||||
result := MSetNX(testDB, toArgs(args...))
|
result := MSetNX(testDB, utils2.ToBytesList(args...))
|
||||||
asserts.AssertIntReply(t, result, 1)
|
asserts.AssertIntReply(t, result, 1)
|
||||||
|
|
||||||
result = MSetNX(testDB, toArgs(args[0:4]...))
|
result = MSetNX(testDB, utils2.ToBytesList(args[0:4]...))
|
||||||
asserts.AssertIntReply(t, result, 0)
|
asserts.AssertIntReply(t, result, 0)
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,6 @@ package db
|
|||||||
import (
|
import (
|
||||||
"github.com/hdt3213/godis/datastruct/dict"
|
"github.com/hdt3213/godis/datastruct/dict"
|
||||||
"github.com/hdt3213/godis/datastruct/lock"
|
"github.com/hdt3213/godis/datastruct/lock"
|
||||||
"math/rand"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeTestDB() *DB {
|
func makeTestDB() *DB {
|
||||||
@@ -14,20 +13,3 @@ func makeTestDB() *DB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toArgs(cmd ...string) [][]byte {
|
|
||||||
args := make([][]byte, len(cmd))
|
|
||||||
for i, s := range cmd {
|
|
||||||
args[i] = []byte(s)
|
|
||||||
}
|
|
||||||
return args
|
|
||||||
}
|
|
||||||
|
|
||||||
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
|
||||||
|
|
||||||
func RandString(n int) string {
|
|
||||||
b := make([]rune, n)
|
|
||||||
for i := range b {
|
|
||||||
b[i] = letters[rand.Intn(len(letters))]
|
|
||||||
}
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
|
20
lib/timewheel/delay_test.go
Normal file
20
lib/timewheel/delay_test.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package timewheel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDelay(t *testing.T) {
|
||||||
|
ch := make(chan time.Time)
|
||||||
|
beginTime := time.Now()
|
||||||
|
Delay(time.Second, "", func() {
|
||||||
|
ch <- time.Now()
|
||||||
|
})
|
||||||
|
execAt := <-ch
|
||||||
|
delayDuration := execAt.Sub(beginTime)
|
||||||
|
// usually 1.0~2.0 s
|
||||||
|
if delayDuration < time.Second || delayDuration > 3*time.Second {
|
||||||
|
t.Error("wrong execute time")
|
||||||
|
}
|
||||||
|
}
|
9
lib/utils/convert.go
Normal file
9
lib/utils/convert.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
func ToBytesList(cmd ...string) [][]byte {
|
||||||
|
args := make([][]byte, len(cmd))
|
||||||
|
for i, s := range cmd {
|
||||||
|
args[i] = []byte(s)
|
||||||
|
}
|
||||||
|
return args
|
||||||
|
}
|
13
lib/utils/rand_string.go
Normal file
13
lib/utils/rand_string.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import "math/rand"
|
||||||
|
|
||||||
|
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||||
|
|
||||||
|
func RandString(n int) string {
|
||||||
|
b := make([]rune, n)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = letters[rand.Intn(len(letters))]
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
@@ -3,7 +3,11 @@ package wildcard
|
|||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
func TestWildCard(t *testing.T) {
|
func TestWildCard(t *testing.T) {
|
||||||
p := CompilePattern("a")
|
p := CompilePattern("")
|
||||||
|
if !p.IsMatch("") {
|
||||||
|
t.Error("expect true actually false")
|
||||||
|
}
|
||||||
|
p = CompilePattern("a")
|
||||||
if !p.IsMatch("a") {
|
if !p.IsMatch("a") {
|
||||||
t.Error("expect true actually false")
|
t.Error("expect true actually false")
|
||||||
}
|
}
|
||||||
|
@@ -121,6 +121,7 @@ func UnSubscribe(db *Hub, c redis.Connection, args [][]byte) redis.Reply {
|
|||||||
return &reply.NoReply{}
|
return &reply.NoReply{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Publish send msg to all subscribing client
|
||||||
func Publish(hub *Hub, args [][]byte) redis.Reply {
|
func Publish(hub *Hub, args [][]byte) redis.Reply {
|
||||||
if len(args) != 2 {
|
if len(args) != 2 {
|
||||||
return &reply.ArgNumErrReply{Cmd: "publish"}
|
return &reply.ArgNumErrReply{Cmd: "publish"}
|
||||||
|
@@ -184,7 +184,7 @@ func (client *Client) finishRequest(reply redis.Reply) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) handleRead() error {
|
func (client *Client) handleRead() error {
|
||||||
ch := parser.Parse(client.conn)
|
ch := parser.ParseStream(client.conn)
|
||||||
for payload := range ch {
|
for payload := range ch {
|
||||||
if payload.Err != nil {
|
if payload.Err != nil {
|
||||||
client.finishRequest(reply.MakeErrReply(payload.Err.Error()))
|
client.finishRequest(reply.MakeErrReply(payload.Err.Error()))
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package server
|
package connection
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"github.com/hdt3213/godis/lib/sync/wait"
|
"github.com/hdt3213/godis/lib/sync/wait"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -21,6 +22,11 @@ type Connection struct {
|
|||||||
subs map[string]bool
|
subs map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoteAddr returns the remote network address
|
||||||
|
func (c *Connection) RemoteAddr() net.Addr {
|
||||||
|
return c.conn.RemoteAddr()
|
||||||
|
}
|
||||||
|
|
||||||
// Close disconnect with the client
|
// Close disconnect with the client
|
||||||
func (c *Connection) Close() error {
|
func (c *Connection) Close() error {
|
||||||
c.waitingReply.WaitWithTimeout(10 * time.Second)
|
c.waitingReply.WaitWithTimeout(10 * time.Second)
|
||||||
@@ -90,3 +96,21 @@ func (c *Connection) GetChannels() []string {
|
|||||||
}
|
}
|
||||||
return channels
|
return channels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FakeConn struct {
|
||||||
|
Connection
|
||||||
|
buf bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *FakeConn) Write(b []byte) error {
|
||||||
|
c.buf.Write(b)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *FakeConn) Clean() {
|
||||||
|
c.buf.Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *FakeConn) Bytes() []byte {
|
||||||
|
return c.buf.Bytes()
|
||||||
|
}
|
@@ -2,6 +2,7 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/hdt3213/godis/interface/redis"
|
"github.com/hdt3213/godis/interface/redis"
|
||||||
"github.com/hdt3213/godis/lib/logger"
|
"github.com/hdt3213/godis/lib/logger"
|
||||||
@@ -17,19 +18,25 @@ type Payload struct {
|
|||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func Parse(reader io.Reader) <-chan *Payload {
|
// ParseStream reads data from io.Reader and send payloads through channel
|
||||||
|
func ParseStream(reader io.Reader) <-chan *Payload {
|
||||||
ch := make(chan *Payload)
|
ch := make(chan *Payload)
|
||||||
go func() {
|
go parse0(reader, ch)
|
||||||
defer func() {
|
|
||||||
if err := recover(); err != nil {
|
|
||||||
logger.Error(debug.Stack())
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
parse0(reader, ch)
|
|
||||||
}()
|
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseOne reads data from []byte and return the first payload
|
||||||
|
func ParseOne(data []byte) (redis.Reply, error) {
|
||||||
|
ch := make(chan *Payload)
|
||||||
|
reader := bytes.NewReader(data)
|
||||||
|
go parse0(reader, ch)
|
||||||
|
payload := <-ch // parse0 will close the channel
|
||||||
|
if payload == nil {
|
||||||
|
return nil, errors.New("no reply")
|
||||||
|
}
|
||||||
|
return payload.Data, payload.Err
|
||||||
|
}
|
||||||
|
|
||||||
type readState struct {
|
type readState struct {
|
||||||
downloading bool
|
downloading bool
|
||||||
expectedArgsCount int
|
expectedArgsCount int
|
||||||
@@ -44,6 +51,11 @@ func (s *readState) finished() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parse0(reader io.Reader, ch chan<- *Payload) {
|
func parse0(reader io.Reader, ch chan<- *Payload) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
logger.Error(string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
bufReader := bufio.NewReader(reader)
|
bufReader := bufio.NewReader(reader)
|
||||||
var state readState
|
var state readState
|
||||||
var err error
|
var err error
|
||||||
|
@@ -9,7 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
func TestParseStream(t *testing.T) {
|
||||||
replies := []redis.Reply{
|
replies := []redis.Reply{
|
||||||
reply.MakeIntReply(1),
|
reply.MakeIntReply(1),
|
||||||
reply.MakeStatusReply("OK"),
|
reply.MakeStatusReply("OK"),
|
||||||
@@ -33,7 +33,7 @@ func TestParse(t *testing.T) {
|
|||||||
[]byte("set"), []byte("a"), []byte("a"),
|
[]byte("set"), []byte("a"), []byte("a"),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
ch := Parse(bytes.NewReader(reqs.Bytes()))
|
ch := ParseStream(bytes.NewReader(reqs.Bytes()))
|
||||||
i := 0
|
i := 0
|
||||||
for payload := range ch {
|
for payload := range ch {
|
||||||
if payload.Err != nil {
|
if payload.Err != nil {
|
||||||
@@ -54,3 +54,28 @@ func TestParse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseOne(t *testing.T) {
|
||||||
|
replies := []redis.Reply{
|
||||||
|
reply.MakeIntReply(1),
|
||||||
|
reply.MakeStatusReply("OK"),
|
||||||
|
reply.MakeErrReply("ERR unknown"),
|
||||||
|
reply.MakeBulkReply([]byte("a\r\nb")), // test binary safe
|
||||||
|
reply.MakeNullBulkReply(),
|
||||||
|
reply.MakeMultiBulkReply([][]byte{
|
||||||
|
[]byte("a"),
|
||||||
|
[]byte("\r\n"),
|
||||||
|
}),
|
||||||
|
reply.MakeEmptyMultiBulkReply(),
|
||||||
|
}
|
||||||
|
for _, re := range replies {
|
||||||
|
result, err := ParseOne(re.ToBytes())
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !utils.BytesEquals(result.ToBytes(), re.ToBytes()) {
|
||||||
|
t.Error("parse failed: " + string(re.ToBytes()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -115,6 +115,10 @@ func AssertMultiBulkReply(t *testing.T, actual redis.Reply, expected []string) {
|
|||||||
func AssertMultiBulkReplySize(t *testing.T, actual redis.Reply, expected int) {
|
func AssertMultiBulkReplySize(t *testing.T, actual redis.Reply, expected int) {
|
||||||
multiBulk, ok := actual.(*reply.MultiBulkReply)
|
multiBulk, ok := actual.(*reply.MultiBulkReply)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
if expected == 0 &&
|
||||||
|
utils.BytesEquals(actual.ToBytes(), reply.MakeEmptyMultiBulkReply().ToBytes()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
t.Errorf("expected bulk reply, actually %s, %s", actual.ToBytes(), printStack())
|
t.Errorf("expected bulk reply, actually %s, %s", actual.ToBytes(), printStack())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
50
redis/server/pubsub_test.go
Normal file
50
redis/server/pubsub_test.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hdt3213/godis/lib/utils"
|
||||||
|
"github.com/hdt3213/godis/pubsub"
|
||||||
|
"github.com/hdt3213/godis/redis/connection"
|
||||||
|
"github.com/hdt3213/godis/redis/parser"
|
||||||
|
"github.com/hdt3213/godis/redis/reply/asserts"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPublish(t *testing.T) {
|
||||||
|
hub := pubsub.MakeHub()
|
||||||
|
channel := utils.RandString(5)
|
||||||
|
msg := utils.RandString(5)
|
||||||
|
conn := &connection.FakeConn{}
|
||||||
|
pubsub.Subscribe(hub, conn, utils.ToBytesList(channel))
|
||||||
|
conn.Clean() // clean subscribe success
|
||||||
|
pubsub.Publish(hub, utils.ToBytesList(channel, msg))
|
||||||
|
data := conn.Bytes()
|
||||||
|
ret, err := parser.ParseOne(data)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
asserts.AssertMultiBulkReply(t, ret, []string{
|
||||||
|
"message",
|
||||||
|
channel,
|
||||||
|
msg,
|
||||||
|
})
|
||||||
|
|
||||||
|
// unsubscribe
|
||||||
|
pubsub.UnSubscribe(hub, conn, utils.ToBytesList(channel))
|
||||||
|
conn.Clean()
|
||||||
|
pubsub.Publish(hub, utils.ToBytesList(channel, msg))
|
||||||
|
data = conn.Bytes()
|
||||||
|
if len(data) > 0 {
|
||||||
|
t.Error("expect no msg")
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsubscribe all
|
||||||
|
pubsub.Subscribe(hub, conn, utils.ToBytesList(channel))
|
||||||
|
pubsub.UnSubscribe(hub, conn, utils.ToBytesList())
|
||||||
|
conn.Clean()
|
||||||
|
pubsub.Publish(hub, utils.ToBytesList(channel, msg))
|
||||||
|
data = conn.Bytes()
|
||||||
|
if len(data) > 0 {
|
||||||
|
t.Error("expect no msg")
|
||||||
|
}
|
||||||
|
}
|
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/hdt3213/godis/interface/db"
|
"github.com/hdt3213/godis/interface/db"
|
||||||
"github.com/hdt3213/godis/lib/logger"
|
"github.com/hdt3213/godis/lib/logger"
|
||||||
"github.com/hdt3213/godis/lib/sync/atomic"
|
"github.com/hdt3213/godis/lib/sync/atomic"
|
||||||
|
"github.com/hdt3213/godis/redis/connection"
|
||||||
"github.com/hdt3213/godis/redis/parser"
|
"github.com/hdt3213/godis/redis/parser"
|
||||||
"github.com/hdt3213/godis/redis/reply"
|
"github.com/hdt3213/godis/redis/reply"
|
||||||
"io"
|
"io"
|
||||||
@@ -45,7 +46,7 @@ func MakeHandler() *Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) closeClient(client *Connection) {
|
func (h *Handler) closeClient(client *connection.Connection) {
|
||||||
_ = client.Close()
|
_ = client.Close()
|
||||||
h.db.AfterClientClose(client)
|
h.db.AfterClientClose(client)
|
||||||
h.activeConn.Delete(client)
|
h.activeConn.Delete(client)
|
||||||
@@ -58,10 +59,10 @@ func (h *Handler) Handle(ctx context.Context, conn net.Conn) {
|
|||||||
_ = conn.Close()
|
_ = conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
client := NewConn(conn)
|
client := connection.NewConn(conn)
|
||||||
h.activeConn.Store(client, 1)
|
h.activeConn.Store(client, 1)
|
||||||
|
|
||||||
ch := parser.Parse(conn)
|
ch := parser.ParseStream(conn)
|
||||||
for payload := range ch {
|
for payload := range ch {
|
||||||
if payload.Err != nil {
|
if payload.Err != nil {
|
||||||
if payload.Err == io.EOF ||
|
if payload.Err == io.EOF ||
|
||||||
@@ -69,7 +70,7 @@ func (h *Handler) Handle(ctx context.Context, conn net.Conn) {
|
|||||||
strings.Contains(payload.Err.Error(), "use of closed network connection") {
|
strings.Contains(payload.Err.Error(), "use of closed network connection") {
|
||||||
// connection closed
|
// connection closed
|
||||||
h.closeClient(client)
|
h.closeClient(client)
|
||||||
logger.Info("connection closed: " + client.conn.RemoteAddr().String())
|
logger.Info("connection closed: " + client.RemoteAddr().String())
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
// protocol err
|
// protocol err
|
||||||
@@ -77,7 +78,7 @@ func (h *Handler) Handle(ctx context.Context, conn net.Conn) {
|
|||||||
err := client.Write(errReply.ToBytes())
|
err := client.Write(errReply.ToBytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.closeClient(client)
|
h.closeClient(client)
|
||||||
logger.Info("connection closed: " + client.conn.RemoteAddr().String())
|
logger.Info("connection closed: " + client.RemoteAddr().String())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@@ -107,7 +108,7 @@ func (h *Handler) Close() error {
|
|||||||
h.closing.Set(true)
|
h.closing.Set(true)
|
||||||
// TODO: concurrent wait
|
// TODO: concurrent wait
|
||||||
h.activeConn.Range(func(key interface{}, val interface{}) bool {
|
h.activeConn.Range(func(key interface{}, val interface{}) bool {
|
||||||
client := key.(*Connection)
|
client := key.(*connection.Connection)
|
||||||
_ = client.Close()
|
_ = client.Close()
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/hdt3213/godis/tcp"
|
"github.com/hdt3213/godis/tcp"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestListenAndServe(t *testing.T) {
|
func TestListenAndServe(t *testing.T) {
|
||||||
@@ -39,4 +40,5 @@ func TestListenAndServe(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
closeChan <- struct{}{}
|
closeChan <- struct{}{}
|
||||||
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestListenAndServe(t *testing.T) {
|
func TestListenAndServe(t *testing.T) {
|
||||||
@@ -42,5 +43,11 @@ func TestListenAndServe(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ = conn.Close()
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
// create idle connection
|
||||||
|
_, _ = net.Dial("tcp", addr)
|
||||||
|
}
|
||||||
closeChan <- struct{}{}
|
closeChan <- struct{}{}
|
||||||
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user