Files
redis-go/cluster/copy_test.go
Eriri f327000d3a Feat:Add "copy" command
Add "copy" command,also fixes the out of range error of select when the number is negative.

Move execCopy to "keys.go" ,
Add test in "keys_test.go",
Add "copy.go" and "copy_test.go" file.
2022-06-26 15:45:09 +08:00

121 lines
5.4 KiB
Go

package cluster
import (
"github.com/hdt3213/godis/lib/utils"
"github.com/hdt3213/godis/redis/connection"
"github.com/hdt3213/godis/redis/protocol/asserts"
"testing"
)
func TestCopy(t *testing.T) {
conn := new(connection.FakeConn)
testNodeA.db.Exec(conn, utils.ToCmdLine("FlushALL"))
// cross node copy
srcKey := testNodeA.self + utils.RandString(10)
value := utils.RandString(10)
destKey := testNodeB.self + utils.RandString(10)
testNodeA.db.Exec(conn, utils.ToCmdLine("SET", srcKey, value))
result := Copy(testNodeA, conn, utils.ToCmdLine("COPY", srcKey, destKey))
asserts.AssertIntReply(t, result, 1)
result = testNodeA.db.Exec(conn, utils.ToCmdLine("GET", srcKey))
asserts.AssertBulkReply(t, result, value)
result = testNodeB.db.Exec(conn, utils.ToCmdLine("GET", destKey))
asserts.AssertBulkReply(t, result, value)
// key exists
result = Copy(testNodeA, conn, utils.ToCmdLine("COPY", srcKey, destKey))
asserts.AssertErrReply(t, result, keyExistsErr)
// replace
value = utils.RandString(10)
testNodeA.db.Exec(conn, utils.ToCmdLine("SET", srcKey, value))
result = Copy(testNodeA, conn, utils.ToCmdLine("COPY", srcKey, destKey, "REPLACE"))
asserts.AssertIntReply(t, result, 1)
result = testNodeA.db.Exec(conn, utils.ToCmdLine("GET", srcKey))
asserts.AssertBulkReply(t, result, value)
result = testNodeB.db.Exec(conn, utils.ToCmdLine("GET", destKey))
asserts.AssertBulkReply(t, result, value)
// test copy expire time
testNodeA.db.Exec(conn, utils.ToCmdLine("SET", srcKey, value, "EX", "1000"))
result = Copy(testNodeA, conn, utils.ToCmdLine("COPY", srcKey, destKey, "REPLACE"))
asserts.AssertIntReply(t, result, 1)
result = testNodeA.db.Exec(conn, utils.ToCmdLine("TTL", srcKey))
asserts.AssertIntReplyGreaterThan(t, result, 0)
result = testNodeB.db.Exec(conn, utils.ToCmdLine("TTL", destKey))
asserts.AssertIntReplyGreaterThan(t, result, 0)
// same node copy
srcKey = testNodeA.self + utils.RandString(10)
value = utils.RandString(10)
destKey = srcKey + utils.RandString(2)
testNodeA.db.Exec(conn, utils.ToCmdLine("SET", srcKey, value))
result = Copy(testNodeA, conn, utils.ToCmdLine("COPY", srcKey, destKey))
asserts.AssertIntReply(t, result, 1)
result = testNodeA.db.Exec(conn, utils.ToCmdLine("GET", srcKey))
asserts.AssertBulkReply(t, result, value)
result = testNodeA.db.Exec(conn, utils.ToCmdLine("GET", destKey))
asserts.AssertBulkReply(t, result, value)
// key exists
result = Copy(testNodeA, conn, utils.ToCmdLine("COPY", srcKey, destKey))
asserts.AssertIntReply(t, result, 0)
// replace
value = utils.RandString(10)
testNodeA.db.Exec(conn, utils.ToCmdLine("SET", srcKey, value))
result = Copy(testNodeA, conn, utils.ToCmdLine("COPY", srcKey, destKey, "REPLACE"))
asserts.AssertIntReply(t, result, 1)
result = testNodeA.db.Exec(conn, utils.ToCmdLine("GET", srcKey))
asserts.AssertBulkReply(t, result, value)
result = testNodeA.db.Exec(conn, utils.ToCmdLine("GET", destKey))
asserts.AssertBulkReply(t, result, value)
// test copy expire time
testNodeA.db.Exec(conn, utils.ToCmdLine("SET", srcKey, value, "EX", "1000"))
result = Copy(testNodeA, conn, utils.ToCmdLine("COPY", srcKey, destKey, "REPLACE"))
asserts.AssertIntReply(t, result, 1)
result = testNodeA.db.Exec(conn, utils.ToCmdLine("TTL", srcKey))
asserts.AssertIntReplyGreaterThan(t, result, 0)
result = testNodeA.db.Exec(conn, utils.ToCmdLine("TTL", destKey))
asserts.AssertIntReplyGreaterThan(t, result, 0)
// test src prepare failed
*simulateATimout = true
srcKey = testNodeA.self + utils.RandString(10)
destKey = testNodeB.self + utils.RandString(10) // route to testNodeB, see mockPicker.PickNode
value = utils.RandString(10)
testNodeA.db.Exec(conn, utils.ToCmdLine("SET", srcKey, value, "ex", "1000"))
result = Rename(testNodeB, conn, utils.ToCmdLine("RENAME", srcKey, destKey))
asserts.AssertErrReply(t, result, "ERR timeout")
result = testNodeA.db.Exec(conn, utils.ToCmdLine("EXISTS", srcKey))
asserts.AssertIntReply(t, result, 1)
result = testNodeA.db.Exec(conn, utils.ToCmdLine("TTL", srcKey))
asserts.AssertIntReplyGreaterThan(t, result, 0)
result = testNodeB.db.Exec(conn, utils.ToCmdLine("EXISTS", destKey))
asserts.AssertIntReply(t, result, 0)
*simulateATimout = false
// test dest prepare failed
*simulateBTimout = true
srcKey = testNodeA.self + utils.RandString(10)
destKey = testNodeB.self + utils.RandString(10) // route to testNodeB, see mockPicker.PickNode
value = utils.RandString(10)
testNodeA.db.Exec(conn, utils.ToCmdLine("SET", srcKey, value, "ex", "1000"))
result = Rename(testNodeA, conn, utils.ToCmdLine("COPY", srcKey, destKey))
asserts.AssertErrReply(t, result, "ERR timeout")
result = testNodeA.db.Exec(conn, utils.ToCmdLine("EXISTS", srcKey))
asserts.AssertIntReply(t, result, 1)
result = testNodeA.db.Exec(conn, utils.ToCmdLine("TTL", srcKey))
asserts.AssertIntReplyGreaterThan(t, result, 0)
result = testNodeB.db.Exec(conn, utils.ToCmdLine("EXISTS", destKey))
asserts.AssertIntReply(t, result, 0)
*simulateBTimout = false
// Copying to another database
srcKey = testNodeA.self + utils.RandString(10)
value = utils.RandString(10)
destKey = srcKey + utils.RandString(2)
testNodeA.db.Exec(conn, utils.ToCmdLine("SET", srcKey, value))
result = Copy(testNodeA, conn, utils.ToCmdLine("COPY", srcKey, destKey, "db", "1"))
asserts.AssertErrReply(t, result, copyToAnotherDBErr)
result = Copy(testNodeA, conn, utils.ToCmdLine("COPY", srcKey))
asserts.AssertErrReply(t, result, "ERR wrong number of arguments for 'copy' command")
}