/test/test_client.lua
Lua | 2645 lines | 2067 code | 536 blank | 42 comment | 135 complexity | 418ae1b497192bbfcbbdded8c45e1776 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- package.path = "../src/?.lua;src/?.lua;" .. package.path
- pcall(require, "luarocks.require")
- local unpack = _G.unpack or table.unpack
- local tsc = require "telescope"
- local redis = require "redis"
- local settings = {
- host = '127.0.0.1',
- port = 6379,
- database = 14,
- password = nil,
- }
- function table.merge(self, tbl2)
- local new_table = {}
- for k,v in pairs(self) do new_table[k] = v end
- for k,v in pairs(tbl2) do new_table[k] = v end
- return new_table
- end
- function table.keys(self)
- local keys = {}
- for k, _ in pairs(self) do table.insert(keys, k) end
- return keys
- end
- function table.values(self)
- local values = {}
- for _, v in pairs(self) do table.insert(values, v) end
- return values
- end
- function table.contains(self, value)
- for _, v in pairs(self) do
- if v == value then return true end
- end
- return false
- end
- function table.slice(self, first, length)
- -- TODO: must be improved
- local new_table = {}
- for i = first, first + length - 1 do
- table.insert(new_table, self[i])
- end
- return new_table
- end
- function table.compare(self, other)
- -- NOTE: the body of this function was taken and slightly adapted from
- -- Penlight (http://github.com/stevedonovan/Penlight)
- if #self ~= #other then return false end
- local visited = {}
- for i = 1, #self do
- local val, gotcha = self[i], nil
- for j = 1, #other do
- if not visited[j] then
- if (type(val) == 'table') then
- if (table.compare(val, other[j])) then
- gotcha = j
- break
- end
- else
- if val == other[j] then
- gotcha = j
- break
- end
- end
- end
- end
- if not gotcha then return false end
- visited[gotcha] = true
- end
- return true
- end
- function parse_version(version_str)
- local major, minor, patch, status = version_str:match('^(%d+)%.(%d+)%.(%d+)%-?(%w-)$')
- local info = {
- string = version_str,
- compare = function(self, other)
- if type(other) == 'string' then
- other = parse_version(other)
- end
- if self.unrecognized or other.unrecognized then
- error('Cannot compare versions')
- end
- for _, part in ipairs({ 'major', 'minor', 'patch' }) do
- if self[part] < other[part] then
- return -1
- end
- if self[part] > other[part] then
- return 1
- end
- end
- return 0
- end,
- is = function(self, op, other)
- local comparation = self:compare(other);
- if op == '<' then return comparation < 0 end
- if op == '<=' then return comparation <= 0 end
- if op == '=' then return comparation == 0 end
- if op == '>=' then return comparation >= 0 end
- if op == '>' then return comparation > 0 end
- error('Invalid comparison operator: '..op)
- end,
- }
- if major and minor and patch then
- info.major = tonumber(major)
- info.minor = tonumber(minor)
- info.patch = tonumber(patch)
- if status then
- info.status = status
- end
- else
- info.unrecognized = true
- end
- return info
- end
- local utils = {
- create_client = function(parameters)
- if parameters == nil then
- parameters = settings
- end
- local client = redis.connect(parameters.host, parameters.port)
- if parameters.password then client:auth(parameters.password) end
- if parameters.database then client:select(parameters.database) end
- client:flushdb()
- local info = client:info()
- local version = parse_version(info.redis_version or info.server.redis_version)
- if version:is('<', '1.2.0') then
- error("redis-lua does not support Redis < 1.2.0 (current: "..version.string..")")
- end
- return client, version
- end,
- rpush_return = function(client, key, values, wipe)
- if wipe then client:del(key) end
- for _, v in ipairs(values) do
- client:rpush(key, v)
- end
- return values
- end,
- sadd_return = function(client, key, values, wipe)
- if wipe then client:del(key) end
- for _, v in ipairs(values) do
- client:sadd(key, v)
- end
- return values
- end,
- zadd_return = function(client, key, values, wipe)
- if wipe then client:del(key) end
- for k, v in pairs(values) do
- client:zadd(key, v, k)
- end
- return values
- end,
- sleep = function(sec)
- socket.select(nil, nil, sec)
- end,
- }
- local shared = {
- kvs_table = function()
- return {
- foo = 'bar',
- hoge = 'piyo',
- foofoo = 'barbar',
- }
- end,
- kvs_ns_table = function()
- return {
- ['metavars:foo'] = 'bar',
- ['metavars:hoge'] = 'piyo',
- ['metavars:foofoo'] = 'barbar',
- }
- end,
- lang_table = function()
- return {
- italian = "ciao",
- english = "hello",
- japanese = "こんいちは!",
- }
- end,
- numbers = function()
- return { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }
- end,
- zset_sample = function()
- return { a = -10, b = 0, c = 10, d = 20, e = 20, f = 30 }
- end,
- }
- tsc.make_assertion("table_values", "'%s' to have the same values as '%s'", table.compare)
- tsc.make_assertion("response_queued", "to be queued", function(response)
- if type(response) == 'table' and response.queued == true then
- return true
- else
- return false
- end
- end)
- tsc.make_assertion("error_message", "result to be an error with the expected message", function(msg, f)
- local ok, err = pcall(f)
- return not ok and err:match(msg)
- end)
- -- ------------------------------------------------------------------------- --
- context("Client initialization", function()
- test("Can connect successfully", function()
- local client = redis.connect(settings.host, settings.port)
- assert_type(client, 'table')
- assert_true(table.contains(table.keys(client.network), 'socket'))
- client.network.socket:send("PING\r\n")
- assert_equal(client.network.socket:receive('*l'), '+PONG')
- end)
- test("Can handle connection failures", function()
- assert_error_message("could not connect to .*:%d+ %[connection refused%]", function()
- redis.connect(settings.host, settings.port + 100)
- end)
- end)
- test("Accepts an URI for connection parameters", function()
- local uri = 'redis://'..settings.host..':'..settings.port
- local client = redis.connect(uri)
- assert_type(client, 'table')
- end)
- test("Accepts a table for connection parameters", function()
- local client = redis.connect(settings)
- assert_type(client, 'table')
- end)
- test("Can use an already connected socket", function()
- local connection = require('socket').tcp()
- connection:connect(settings.host, settings.port)
- local client = redis.connect({ socket = connection })
- assert_type(client, 'table')
- assert_true(client:ping())
- end)
- test("Can specify a timeout for connecting", function()
- local time, timeout = os.time(), 2;
- assert_error_message("could not connect to .*:%d+ %[timeout%]", function()
- redis.connect({ host = '169.254.255.255', timeout = timeout })
- end)
- assert_equal(time + timeout, os.time())
- end)
- end)
- context("Client features", function()
- before(function()
- client = utils.create_client(settings)
- end)
- test("Send raw commands", function()
- assert_equal(client:raw_cmd("PING\r\n"), 'PONG')
- assert_true(client:raw_cmd("*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"))
- assert_equal(client:raw_cmd("GET foo\r\n"), 'bar')
- end)
- test("Tansform nil command arguments into empty strings", function()
- assert_true(client:set(nil, 'bar'))
- assert_equal(client:get(''), 'bar')
- end)
- test("Create a new unbound command object", function()
- local cmd = redis.command('doesnotexist')
- assert_nil(client.doesnotexist)
- assert_error(function() cmd(client) end)
- local cmd = redis.command('ping', {
- response = function(response) return response == 'PONG' end
- })
- assert_equal(cmd(client), true)
- end)
- test("Define commands at module level", function()
- redis.commands.doesnotexist = redis.command('doesnotexist')
- local client2 = utils.create_client(settings)
- redis.commands.doesnotexist = nil
- local client3 = utils.create_client(settings)
- assert_nil(client.doesnotexist)
- assert_not_nil(client2.doesnotexist)
- assert_nil(client3.doesnotexist)
- end)
- test("Define commands at module level (OLD)", function()
- redis.define_command('doesnotexist')
- local client2 = utils.create_client(settings)
- redis.undefine_command('doesnotexist')
- local client3 = utils.create_client(settings)
- assert_nil(client.doesnotexist)
- assert_not_nil(client2.doesnotexist)
- assert_nil(client3.doesnotexist)
- end)
- test("Define new commands at client instance level", function()
- client.doesnotexist = redis.command('doesnotexist')
- assert_not_nil(client.doesnotexist)
- assert_error(function() client:doesnotexist() end)
- client.doesnotexist = nil
- assert_nil(client.doesnotexist)
- client.ping = redis.command('ping')
- assert_not_nil(client.ping)
- assert_equal(client:ping(), 'PONG')
- client.ping = redis.command('ping', {
- request = client.requests.multibulk
- })
- assert_not_nil(client.ping)
- assert_equal(client:ping(), 'PONG')
- client.ping = redis.command('ping', {
- request = client.requests.multibulk,
- response = function(reply) return reply == 'PONG' end
- })
- assert_not_nil(client.ping)
- assert_true(client:ping())
- end)
- test("Define new commands at client instance level (OLD)", function()
- client:define_command('doesnotexist')
- assert_not_nil(client.doesnotexist)
- assert_error(function() client:doesnotexist() end)
- client:undefine_command('doesnotexist')
- assert_nil(client.doesnotexist)
- client:define_command('ping')
- assert_not_nil(client.ping)
- assert_equal(client:ping(), 'PONG')
- client:define_command('ping', {
- request = client.requests.multibulk
- })
- assert_not_nil(client.ping)
- assert_equal(client:ping(), 'PONG')
- client:define_command('ping', {
- request = client.requests.multibulk,
- response = function(reply) return reply == 'PONG' end
- })
- assert_not_nil(client.ping)
- assert_true(client:ping())
- end)
- test("Pipelining commands", function()
- local replies, count = client:pipeline(function(p)
- p:ping()
- p:exists('counter')
- p:incrby('counter', 10)
- p:incrby('counter', 30)
- p:exists('counter')
- p:get('counter')
- p:mset({ foo = 'bar', hoge = 'piyo'})
- p:del('foo', 'hoge')
- p:mget('does_not_exist', 'counter')
- p:info()
- p:get('nilkey')
- end)
- assert_type(replies, 'table')
- assert_equal(count, 11)
- assert_equal(#replies, 10)
- assert_true(replies[1])
- assert_type(replies[9], 'table')
- assert_equal(replies[9][2], '40')
- assert_type(replies[10], 'table')
- end)
- after(function()
- client:quit()
- end)
- end)
- context("Redis commands", function()
- before(function()
- client, version = utils.create_client(settings)
- end)
- after(function()
- client:quit()
- end)
- context("Connection related commands", function()
- test("PING (client:ping)", function()
- assert_true(client:ping())
- end)
- test("ECHO (client:echo)", function()
- local str_ascii, str_utf8 = "Can you hear me?", "聞こえますか?"
- assert_equal(client:echo(str_ascii), str_ascii)
- assert_equal(client:echo(str_utf8), str_utf8)
- end)
- test("SELECT (client:select)", function()
- if not settings.database then return end
- assert_true(client:select(0))
- assert_true(client:select(settings.database))
- assert_error(function() client:select(100) end)
- assert_error(function() client:select(-1) end)
- end)
- end)
- context("Commands operating on the key space", function()
- test("KEYS (client:keys)", function()
- local kvs_prefixed = shared.kvs_ns_table()
- local kvs_unprefixed = { aaa = 1, aba = 2, aca = 3 }
- local kvs_all = table.merge(kvs_prefixed, kvs_unprefixed)
- client:mset(kvs_all)
- assert_empty(client:keys('nokeys:*'))
- assert_table_values(
- table.values(client:keys('*')),
- table.keys(kvs_all)
- )
- assert_table_values(
- table.values(client:keys('metavars:*')),
- table.keys(kvs_prefixed)
- )
- assert_table_values(
- table.values(client:keys('a?a')),
- table.keys(kvs_unprefixed)
- )
- end)
- test("EXISTS (client:exists)", function()
- client:set('foo', 'bar')
- assert_true(client:exists('foo'))
- assert_false(client:exists('hoge'))
- end)
- test("DEL (client:del)", function()
- client:mset(shared.kvs_table())
- assert_equal(client:del('doesnotexist'), 0)
- assert_equal(client:del('foofoo'), 1)
- assert_equal(client:del('foo', 'hoge', 'doesnotexist'), 2)
- end)
- test("TYPE (client:type)", function()
- assert_equal(client:type('doesnotexist'), 'none')
- client:set('fooString', 'bar')
- assert_equal(client:type('fooString'), 'string')
- client:rpush('fooList', 'bar')
- assert_equal(client:type('fooList'), 'list')
- client:sadd('fooSet', 'bar')
- assert_equal(client:type('fooSet'), 'set')
- client:zadd('fooZSet', 0, 'bar')
- assert_equal(client:type('fooZSet'), 'zset')
- if version:is('>=', '2.0.0') then
- client:hset('fooHash', 'value', 'bar')
- assert_equal('hash', client:type('fooHash'))
- end
- end)
- test("RANDOMKEY (client:randomkey)", function()
- local kvs = shared.kvs_table()
- assert_nil(client:randomkey())
- client:mset(kvs)
- assert_true(table.contains(table.keys(kvs), client:randomkey()))
- end)
- test("RENAME (client:rename)", function()
- local kvs = shared.kvs_table()
- client:mset(kvs)
- assert_true(client:rename('hoge', 'hogehoge'))
- assert_false(client:exists('hoge'))
- assert_equal(client:get('hogehoge'), 'piyo')
- -- rename overwrites existing keys
- assert_true(client:rename('foo', 'foofoo'))
- assert_false(client:exists('foo'))
- assert_equal(client:get('foofoo'), 'bar')
- -- rename fails when the key does not exist
- assert_error(function()
- client:rename('doesnotexist', 'fuga')
- end)
- end)
- test("RENAMENX (client:renamenx)", function()
- local kvs = shared.kvs_table()
- client:mset(kvs)
- assert_true(client:renamenx('hoge', 'hogehoge'))
- assert_false(client:exists('hoge'))
- assert_equal(client:get('hogehoge'), 'piyo')
- -- rename overwrites existing keys
- assert_false(client:renamenx('foo', 'foofoo'))
- assert_true(client:exists('foo'))
- -- rename fails when the key does not exist
- assert_error(function()
- client:renamenx('doesnotexist', 'fuga')
- end)
- end)
- test("TTL (client:ttl)", function()
- client:set('foo', 'bar')
- assert_equal(client:ttl('foo'), -1)
- assert_true(client:expire('foo', 5))
- assert_lte(client:ttl('foo'), 5)
- end)
- test("PTTL (client:pttl)", function()
- if version:is('<', '2.5.0') then return end
- client:set('foo', 'bar')
- assert_equal(client:pttl('foo'), -1)
- local ttl = 5
- assert_true(client:expire('foo', ttl))
- assert_lte(client:pttl('foo'), 5 * 1000)
- assert_gte(client:pttl('foo'), 5 * 1000 - 500)
- end)
- test("EXPIRE (client:expire)", function()
- client:set('foo', 'bar')
- assert_true(client:expire('foo', 2))
- assert_true(client:exists('foo'))
- assert_lte(client:ttl('foo'), 2)
- utils.sleep(3)
- assert_false(client:exists('foo'))
- client:set('foo', 'bar')
- assert_true(client:expire('foo', 100))
- utils.sleep(3)
- assert_lte(client:ttl('foo'), 97)
- assert_true(client:expire('foo', -100))
- assert_false(client:exists('foo'))
- end)
- test("PEXPIRE (client:pexpire)", function()
- if version:is('<', '2.5.0') then return end
- local ttl = 1
- client:set('foo', 'bar')
- assert_true(client:pexpire('foo', ttl * 1000))
- assert_true(client:exists('foo'))
- assert_lte(client:pttl('foo'), ttl * 1000)
- assert_gte(client:pttl('foo'), ttl * 1000 - 500)
- utils.sleep(ttl)
- assert_false(client:exists('foo'))
- end)
- test("EXPIREAT (client:expireat)", function()
- client:set('foo', 'bar')
- assert_true(client:expireat('foo', os.time() + 2))
- assert_lte(client:ttl('foo'), 2)
- utils.sleep(3)
- assert_false(client:exists('foo'))
- client:set('foo', 'bar')
- assert_true(client:expireat('foo', os.time() - 100))
- assert_false(client:exists('foo'))
- end)
- test("PEXPIREAT (client:pexpireat)", function()
- if version:is('<', '2.5.0') then return end
- local ttl = 2
- client:set('foo', 'bar')
- assert_true(client:pexpireat('foo', os.time() + ttl * 1000))
- assert_lte(client:pttl('foo'), ttl * 1000)
- utils.sleep(ttl + 1)
- assert_false(client:exists('foo'))
- client:set('foo', 'bar')
- assert_true(client:pexpireat('foo', os.time() - 100 * 1000))
- assert_false(client:exists('foo'))
- end)
- test("MOVE (client:move)", function()
- if not settings.database then return end
- local other_db = settings.database + 1
- client:set('foo', 'bar')
- client:select(other_db)
- client:flushdb()
- client:select(settings.database)
- assert_true(client:move('foo', other_db))
- assert_false(client:move('foo', other_db))
- assert_false(client:move('doesnotexist', other_db))
- client:set('hoge', 'piyo')
- assert_error(function() client:move('hoge', 100) end)
- end)
- test("DBSIZE (client:dbsize)", function()
- assert_equal(client:dbsize(), 0)
- client:mset(shared.kvs_table())
- assert_greater_than(client:dbsize(), 0)
- end)
- test("PERSIST (client:persist)", function()
- if version:is('<', '2.1.0') then return end
- client:set('foo', 'bar')
- assert_true(client:expire('foo', 1))
- assert_equal(client:ttl('foo'), 1)
- assert_true(client:persist('foo'))
- assert_equal(client:ttl('foo'), -1)
- assert_false(client:persist('foo'))
- assert_false(client:persist('foobar'))
- end)
- test("SCAN (client:scan)", function()
- if version:is('<', '2.8.0') then return end
- client:mset(
- 'scan:1', '1',
- 'scan:2', '2',
- 'scan:3', '3',
- 'scan:4', '4'
- )
- local cursor, keys = unpack(client:scan(0, {
- match = 'scan:*', count = 10
- }))
- assert_type(cursor, 'string')
- assert_type(keys, 'table')
- assert_table_values(keys, {'scan:1','scan:2','scan:3','scan:4'})
- end)
- end)
- context("Commands operating on the key space - SORT", function()
- -- TODO: missing tests for params GET and BY
- before(function()
- -- TODO: code duplication!
- list01, list01_values = "list01", { "4","2","3","5","1" }
- for _,v in ipairs(list01_values) do client:rpush(list01,v) end
- list02, list02_values = "list02", { "1","10","2","20","3","30" }
- for _,v in ipairs(list02_values) do client:rpush(list02,v) end
- end)
- test("SORT (client:sort)", function()
- local sorted = client:sort(list01)
- assert_table_values(sorted, { "1","2","3","4","5" })
- end)
- test("SORT (client:sort) with parameter ASC/DESC", function()
- assert_table_values(client:sort(list01, { sort = 'asc'}), { "1","2","3","4","5" })
- assert_table_values(client:sort(list01, { sort = 'desc'}), { "5","4","3","2","1" })
- end)
- test("SORT (client:sort) with parameter LIMIT", function()
- assert_table_values(client:sort(list01, { limit = { 0,3 } }), { "1","2", "3" })
- assert_table_values(client:sort(list01, { limit = { 3,2 } }), { "4","5" })
- end)
- test("SORT (client:sort) with parameter ALPHA", function()
- assert_table_values(client:sort(list02, { alpha = false }), { "1","2","3","10","20","30" })
- assert_table_values(client:sort(list02, { alpha = true }), { "1","10","2","20","3","30" })
- end)
- test("SORT (client:sort) with parameter GET", function()
- client:rpush('uids', 1003)
- client:rpush('uids', 1001)
- client:rpush('uids', 1002)
- client:rpush('uids', 1000)
- local sortget = {
- ['uid:1000'] = 'foo', ['uid:1001'] = 'bar',
- ['uid:1002'] = 'hoge', ['uid:1003'] = 'piyo',
- }
- client:mset(sortget)
- assert_table_values(client:sort('uids', { get = 'uid:*' }), table.values(sortget))
- assert_table_values(client:sort('uids', { get = { 'uid:*' } }), table.values(sortget))
- end)
- test("SORT (client:sort) with multiple parameters", function()
- assert_table_values(client:sort(list02, {
- alpha = false,
- sort = 'desc',
- limit = { 1, 4 }
- }), { "20","10","3","2" })
- end)
- test("SORT (client:sort) with parameter STORE", function()
- assert_equal(client:sort(list01, { store = 'list01_ordered' }), 5)
- assert_true(client:exists('list01_ordered'))
- end)
- end)
- context("Commands operating on string values", function()
- test("SET (client:set)", function()
- assert_true(client:set('foo', 'bar'))
- assert_equal(client:get('foo'), 'bar')
- end)
- test("GET (client:get)", function()
- client:set('foo', 'bar')
- assert_equal(client:get('foo'), 'bar')
- assert_nil(client:get('hoge'))
- assert_error(function()
- client:rpush('metavars', 'foo')
- client:get('metavars')
- end)
- end)
- test("SETNX (client:setnx)", function()
- assert_true(client:setnx('foo', 'bar'))
- assert_false(client:setnx('foo', 'baz'))
- assert_equal(client:get('foo'), 'bar')
- end)
- test("SETEX (client:setex)", function()
- if version:is('<', '2.0.0') then return end
- assert_true(client:setex('foo', 10, 'bar'))
- assert_true(client:exists('foo'))
- assert_lte(client:ttl('foo'), 10)
- assert_true(client:setex('hoge', 1, 'piyo'))
- utils.sleep(2)
- assert_false(client:exists('hoge'))
- assert_error(function() client:setex('hoge', 2.5, 'piyo') end)
- assert_error(function() client:setex('hoge', 0, 'piyo') end)
- assert_error(function() client:setex('hoge', -10, 'piyo') end)
- end)
- test("PSETEX (client:psetex)", function()
- if version:is('<', '2.5.0') then return end
- local ttl = 10 * 1000
- assert_true(client:psetex('foo', ttl, 'bar'))
- assert_true(client:exists('foo'))
- assert_lte(client:pttl('foo'), ttl)
- assert_gte(client:pttl('foo'), ttl - 500)
- assert_true(client:psetex('hoge', 1 * 1000, 'piyo'))
- utils.sleep(2)
- assert_false(client:exists('hoge'))
- assert_error(function() client:psetex('hoge', 2.5, 'piyo') end)
- assert_error(function() client:psetex('hoge', 0, 'piyo') end)
- assert_error(function() client:psetex('hoge', -10, 'piyo') end)
- end)
- test("MSET (client:mset)", function()
- local kvs = shared.kvs_table()
- assert_true(client:mset(kvs))
- for k,v in pairs(kvs) do
- assert_equal(client:get(k), v)
- end
- assert_true(client:mset('a', '1', 'b', '2', 'c', '3'))
- assert_equal(client:get('a'), '1')
- assert_equal(client:get('b'), '2')
- assert_equal(client:get('c'), '3')
- end)
- test("MSETNX (client:msetnx)", function()
- assert_true(client:msetnx({ a = '1', b = '2' }))
- assert_false(client:msetnx({ c = '3', a = '100'}))
- assert_equal(client:get('a'), '1')
- assert_equal(client:get('b'), '2')
- end)
- test("MGET (client:mget)", function()
- local kvs = shared.kvs_table()
- local keys, values = table.keys(kvs), table.values(kvs)
- assert_true(client:mset(kvs))
- assert_table_values(client:mget(unpack(keys)), values)
- end)
- test("GETSET (client:getset)", function()
- assert_nil(client:getset('foo', 'bar'))
- assert_equal(client:getset('foo', 'barbar'), 'bar')
- assert_equal(client:getset('foo', 'baz'), 'barbar')
- end)
- test("INCR (client:incr)", function()
- assert_equal(client:incr('foo'), 1)
- assert_equal(client:incr('foo'), 2)
- assert_true(client:set('hoge', 'piyo'))
- if version:is('<', '2.0.0') then
- assert_equal(client:incr('hoge'), 1)
- else
- assert_error(function()
- client:incr('hoge')
- end)
- end
- end)
- test("INCRBY (client:incrby)", function()
- client:set('foo', 2)
- assert_equal(client:incrby('foo', 20), 22)
- assert_equal(client:incrby('foo', -12), 10)
- assert_equal(client:incrby('foo', -110), -100)
- end)
- test("INCRBYFLOAT (client:incrbyfloat)", function()
- if version:is('<', '2.5.0') then return end
- client:set('foo', 2)
- assert_equal(client:incrbyfloat('foo', 20.123), 22.123)
- assert_equal(client:incrbyfloat('foo', -12.123), 10)
- assert_equal(client:incrbyfloat('foo', -110.01), -100.01)
- end)
- test("DECR (client:decr)", function()
- assert_equal(client:decr('foo'), -1)
- assert_equal(client:decr('foo'), -2)
- assert_true(client:set('hoge', 'piyo'))
- if version:is('<', '2.0.0') then
- assert_equal(client:decr('hoge'), -1)
- else
- assert_error(function()
- client:decr('hoge')
- end)
- end
- end)
- test("DECRBY (client:decrby)", function()
- client:set('foo', -2)
- assert_equal(client:decrby('foo', 20), -22)
- assert_equal(client:decrby('foo', -12), -10)
- assert_equal(client:decrby('foo', -110), 100)
- end)
- test("APPEND (client:append)", function()
- if version:is('<', '2.0.0') then return end
- client:set('foo', 'bar')
- assert_equal(client:append('foo', '__'), 5)
- assert_equal(client:append('foo', 'bar'), 8)
- assert_equal(client:get('foo'), 'bar__bar')
- assert_equal(client:append('hoge', 'piyo'), 4)
- assert_equal(client:get('hoge'), 'piyo')
- assert_error(function()
- client:rpush('metavars', 'foo')
- client:append('metavars', 'bar')
- end)
- end)
- test("SUBSTR (client:substr)", function()
- if version:is('<', '2.0.0') then return end
- client:set('var', 'foobar')
- assert_equal(client:substr('var', 0, 2), 'foo')
- assert_equal(client:substr('var', 3, 5), 'bar')
- assert_equal(client:substr('var', -3, -1), 'bar')
- assert_equal(client:substr('var', 5, 0), '')
- client:set('numeric', 123456789)
- assert_equal(client:substr('numeric', 0, 4), '12345')
- assert_error(function()
- client:rpush('metavars', 'foo')
- client:substr('metavars', 0, 3)
- end)
- end)
- test("STRLEN (client:strlen)", function()
- if version:is('<', '2.1.0') then return end
- client:set('var', 'foobar')
- assert_equal(client:strlen('var'), 6)
- assert_equal(client:append('var', '___'), 9)
- assert_equal(client:strlen('var'), 9)
- assert_error(function()
- client:rpush('metavars', 'foo')
- qclient:strlen('metavars')
- end)
- end)
- test("SETRANGE (client:setrange)", function()
- if version:is('<', '2.1.0') then return end
- assert_equal(client:setrange('var', 0, 'foobar'), 6)
- assert_equal(client:get('var'), 'foobar')
- assert_equal(client:setrange('var', 3, 'foo'), 6)
- assert_equal(client:get('var'), 'foofoo')
- assert_equal(client:setrange('var', 10, 'barbar'), 16)
- assert_equal(client:get('var'), "foofoo\0\0\0\0barbar")
- assert_error(function()
- client:setrange('var', -1, 'bogus')
- end)
- assert_error(function()
- client:rpush('metavars', 'foo')
- client:setrange('metavars', 0, 'hoge')
- end)
- end)
- test("GETRANGE (client:getrange)", function()
- if version:is('<', '2.1.0') then return end
- client:set('var', 'foobar')
- assert_equal(client:getrange('var', 0, 2), 'foo')
- assert_equal(client:getrange('var', 3, 5), 'bar')
- assert_equal(client:getrange('var', -3, -1), 'bar')
- assert_equal(client:substr('var', 5, 0), '')
- client:set('numeric', 123456789)
- assert_equal(client:getrange('numeric', 0, 4), '12345')
- assert_error(function()
- client:rpush('metavars', 'foo')
- client:getrange('metavars', 0, 3)
- end)
- end)
- test("SETBIT (client:setbit)", function()
- if version:is('<', '2.1.0') then return end
- assert_equal(client:setbit('binary', 31, 1), 0)
- assert_equal(client:setbit('binary', 0, 1), 0)
- assert_equal(client:strlen('binary'), 4)
- assert_equal(client:get('binary'), "\128\0\0\1")
- assert_equal(client:setbit('binary', 0, 0), 1)
- assert_equal(client:setbit('binary', 0, 0), 0)
- assert_equal(client:get('binary'), "\0\0\0\1")
- assert_error(function()
- client:setbit('binary', -1, 1)
- end)
- assert_error(function()
- client:setbit('binary', 'invalid', 1)
- end)
- assert_error(function()
- client:setbit('binary', 'invalid', 1)
- end)
- assert_error(function()
- client:setbit('binary', 15, 255)
- end)
- assert_error(function()
- client:setbit('binary', 15, 'invalid')
- end)
- assert_error(function()
- client:rpush('metavars', 'foo')
- client:setbit('metavars', 0, 1)
- end)
- end)
- test("GETBIT (client:getbit)", function()
- if version:is('<', '2.1.0') then return end
- client:set('binary', "\128\0\0\1")
- assert_equal(client:getbit('binary', 0), 1)
- assert_equal(client:getbit('binary', 15), 0)
- assert_equal(client:getbit('binary', 31), 1)
- assert_equal(client:getbit('binary', 63), 0)
- assert_error(function()
- client:getbit('binary', -1)
- end)
- assert_error(function()
- client:getbit('binary', 'invalid')
- end)
- assert_error(function()
- client:rpush('metavars', 'foo')
- client:getbit('metavars', 0)
- end)
- end)
- test("BITOP (client:bitop)", function()
- if version:is('<', '2.5.10') then return end
- client:set('foo', 'a')
- client:set('bar', 'b')
- client:bitop('AND', 'foo&bar', 'foo', 'bar')
- client:bitop('OR', 'foo|bar', 'foo', 'bar')
- client:bitop('XOR', 'foo^bar', 'foo', 'bar')
- client:bitop('NOT', '-foo', 'foo')
- assert_equal(client:get('foo&bar'), '\96')
- assert_equal(client:get('foo|bar'), '\99')
- assert_equal(client:get('foo^bar'), '\3')
- assert_equal(client:get('-foo'), '\158')
- end)
- test("BITCOUNT (client:bitcount)", function()
- if version:is('<', '2.5.10') then return end
- client:set('foo', 'abcde')
- assert_equal(client:bitcount('foo', 1, 3), 10)
- assert_equal(client:bitcount('foo', 0, -1), 17)
- end)
- end)
- context("Commands operating on lists", function()
- test("RPUSH (client:rpush)", function()
- if version:is('<', '2.0.0') then
- assert_true(client:rpush('metavars', 'foo'))
- assert_true(client:rpush('metavars', 'hoge'))
- else
- assert_equal(client:rpush('metavars', 'foo'), 1)
- assert_equal(client:rpush('metavars', 'hoge'), 2)
- end
- assert_error(function()
- client:set('foo', 'bar')
- client:rpush('foo', 'baz')
- end)
- end)
- test("RPUSHX (client:rpushx)", function()
- if version:is('<', '2.1.0') then return end
- assert_equal(client:rpushx('numbers', 1), 0)
- assert_equal(client:rpush('numbers', 2), 1)
- assert_equal(client:rpushx('numbers', 3), 2)
- assert_equal(client:llen('numbers'), 2)
- assert_table_values(client:lrange('numbers', 0, -1), { '2', '3' })
- assert_error(function()
- client:set('foo', 'bar')
- client:rpushx('foo', 'baz')
- end)
- end)
- test("LPUSH (client:lpush)", function()
- if version:is('<', '2.0.0') then
- assert_true(client:lpush('metavars', 'foo'))
- assert_true(client:lpush('metavars', 'hoge'))
- else
- assert_equal(client:lpush('metavars', 'foo'), 1)
- assert_equal(client:lpush('metavars', 'hoge'), 2)
- end
- assert_error(function()
- client:set('foo', 'bar')
- client:lpush('foo', 'baz')
- end)
- end)
- test("LPUSHX (client:lpushx)", function()
- if version:is('<', '2.1.0') then return end
- assert_equal(client:lpushx('numbers', 1), 0)
- assert_equal(client:lpush('numbers', 2), 1)
- assert_equal(client:lpushx('numbers', 3), 2)
- assert_equal(client:llen('numbers'), 2)
- assert_table_values(client:lrange('numbers', 0, -1), { '3', '2' })
- assert_error(function()
- client:set('foo', 'bar')
- client:lpushx('foo', 'baz')
- end)
- end)
- test("LLEN (client:llen)", function()
- local kvs = shared.kvs_table()
- for _, v in pairs(kvs) do
- client:rpush('metavars', v)
- end
- assert_equal(client:llen('metavars'), 3)
- assert_equal(client:llen('doesnotexist'), 0)
- assert_error(function()
- client:set('foo', 'bar')
- client:llen('foo')
- end)
- end)
- test("LRANGE (client:lrange)", function()
- local numbers = utils.rpush_return(client, 'numbers', shared.numbers())
- assert_table_values(client:lrange('numbers', 0, 3), table.slice(numbers, 1, 4))
- assert_table_values(client:lrange('numbers', 4, 8), table.slice(numbers, 5, 5))
- assert_table_values(client:lrange('numbers', 0, 0), table.slice(numbers, 1, 1))
- assert_empty(client:lrange('numbers', 1, 0))
- assert_table_values(client:lrange('numbers', 0, -1), numbers)
- assert_table_values(client:lrange('numbers', 5, -5), { '5' })
- assert_empty(client:lrange('numbers', 7, -5))
- assert_table_values(client:lrange('numbers', -5, -2), table.slice(numbers, 6, 4))
- assert_table_values(client:lrange('numbers', -100, 100), numbers)
- end)
- test("LTRIM (client:ltrim)", function()
- local numbers = utils.rpush_return(client, 'numbers', shared.numbers(), true)
- assert_true(client:ltrim('numbers', 0, 2))
- assert_table_values(client:lrange('numbers', 0, -1), table.slice(numbers, 1, 3))
- local numbers = utils.rpush_return(client, 'numbers', shared.numbers(), true)
- assert_true(client:ltrim('numbers', 5, 9))
- assert_table_values(client:lrange('numbers', 0, -1), table.slice(numbers, 6, 5))
- local numbers = utils.rpush_return(client, 'numbers', shared.numbers(), true)
- assert_true(client:ltrim('numbers', 0, -6))
- assert_table_values(client:lrange('numbers', 0, -1), table.slice(numbers, 1, 5))
- local numbers = utils.rpush_return(client, 'numbers', shared.numbers(), true)
- assert_true(client:ltrim('numbers', -5, -3))
- assert_table_values(client:lrange('numbers', 0, -1), table.slice(numbers, 6, 3))
- local numbers = utils.rpush_return(client, 'numbers', shared.numbers(), true)
- assert_true(client:ltrim('numbers', -100, 100))
- assert_table_values(client:lrange('numbers', 0, -1), numbers)
- assert_error(function()
- client:set('foo', 'bar')
- client:ltrim('foo', 0, 1)
- end)
- end)
- test("LINDEX (client:lindex)", function()
- local numbers = utils.rpush_return(client, 'numbers', shared.numbers())
- assert_equal(client:lindex('numbers', 0), numbers[1])
- assert_equal(client:lindex('numbers', 5), numbers[6])
- assert_equal(client:lindex('numbers', 9), numbers[10])
- assert_nil(client:lindex('numbers', 100))
- assert_equal(client:lindex('numbers', -0), numbers[1])
- assert_equal(client:lindex('numbers', -1), numbers[10])
- assert_equal(client:lindex('numbers', -3), numbers[8])
- assert_nil(client:lindex('numbers', -100))
- assert_error(function()
- client:set('foo', 'bar')
- client:lindex('foo', 0)
- end)
- end)
- test("LSET (client:lset)", function()
- utils.rpush_return(client, 'numbers', shared.numbers())
- assert_true(client:lset('numbers', 5, -5))
- assert_equal(client:lindex('numbers', 5), '-5')
- assert_error(function()
- client:lset('numbers', 99, 99)
- end)
- assert_error(function()
- client:set('foo', 'bar')
- client:lset('foo', 0, 0)
- end)
- end)
- test("LREM (client:lrem)", function()
- local mixed = { '0', '_', '2', '_', '4', '_', '6', '_' }
- utils.rpush_return(client, 'mixed', mixed, true)
- assert_equal(client:lrem('mixed', 2, '_'), 2)
- assert_table_values(client:lrange('mixed', 0, -1), { '0', '2', '4', '_', '6', '_' })
- utils.rpush_return(client, 'mixed', mixed, true)
- assert_equal(client:lrem('mixed', 0, '_'), 4)
- assert_table_values(client:lrange('mixed', 0, -1), { '0', '2', '4', '6' })
- utils.rpush_return(client, 'mixed', mixed, true)
- assert_equal(client:lrem('mixed', -2, '_'), 2)
- assert_table_values(client:lrange('mixed', 0, -1), { '0', '_', '2', '_', '4', '6' })
- utils.rpush_return(client, 'mixed', mixed, true)
- assert_equal(client:lrem('mixed', 2, '|'), 0)
- assert_table_values(client:lrange('mixed', 0, -1), mixed)
- assert_equal(client:lrem('doesnotexist', 2, '_'), 0)
- assert_error(function()
- client:set('foo', 'bar')
- client:lrem('foo', 0, 0)
- end)
- end)
- test("LPOP (client:lpop)", function()
- local numbers = utils.rpush_return(client, 'numbers', { '0', '1', '2', '3', '4' })
- assert_equal(client:lpop('numbers'), numbers[1])
- assert_equal(client:lpop('numbers'), numbers[2])
- assert_equal(client:lpop('numbers'), numbers[3])
- assert_table_values(client:lrange('numbers', 0, -1), { '3', '4' })
- client:lpop('numbers')
- client:lpop('numbers')
- assert_nil(client:lpop('numbers'))
- assert_nil(client:lpop('doesnotexist'))
- assert_error(function()
- client:set('foo', 'bar')
- client:lpop('foo')
- end)
- end)
- test("RPOP (client:rpop)", function()
- local numbers = utils.rpush_return(client, 'numbers', { '0', '1', '2', '3', '4' })
- assert_equal(client:rpop('numbers'), numbers[5])
- assert_equal(client:rpop('numbers'), numbers[4])
- assert_equal(client:rpop('numbers'), numbers[3])
- assert_table_values(client:lrange('numbers', 0, -1), { '0', '1' })
- client:rpop('numbers')
- client:rpop('numbers')
- assert_nil(client:rpop('numbers'))
- assert_nil(client:rpop('doesnotexist'))
- assert_error(function()
- client:set('foo', 'bar')
- client:rpop('foo')
- end)
- end)
- test("RPOPLPUSH (client:rpoplpush)", function()
- local numbers = utils.rpush_return(client, 'numbers', { '0', '1', '2' }, true)
- assert_equal(client:llen('temporary'), 0)
- assert_equal(client:rpoplpush('numbers', 'temporary'), '2')
- assert_equal(client:rpoplpush('numbers', 'temporary'), '1')
- assert_equal(client:rpoplpush('numbers', 'temporary'), '0')
- assert_equal(client:llen('numbers'), 0)
- assert_equal(client:llen('temporary'), 3)
- local numbers = utils.rpush_return(client, 'numbers', { '0', '1', '2' }, true)
- client:rpoplpush('numbers', 'numbers')
- client:rpoplpush('numbers', 'numbers')
- client:rpoplpush('numbers', 'numbers')
- assert_table_values(client:lrange('numbers', 0, -1), numbers)
- assert_nil(client:rpoplpush('doesnotexist1', 'doesnotexist2'))
- assert_error(function()
- client:set('foo', 'bar')
- client:rpoplpush('foo', 'hoge')
- end)
- assert_error(function()
- client:set('foo', 'bar')
- client:rpoplpush('temporary', 'foo')
- end)
- end)
- test("BLPOP (client:blpop)", function()
- if version:is('<', '2.0.0') then return end
- -- TODO: implement tests
- end)
- test("BRPOP (client:brpop)", function()
- if version:is('<', '2.0.0') then return end
- -- TODO: implement tests
- end)
- test("BRPOPLPUSH (client:brpoplpush)", function()
- if version:is('<', '2.1.0') then return end
- -- TODO: implement tests
- end)
- test("LINSERT (client:linsert)", function()
- if version:is('<', '2.1.0') then return end
- utils.rpush_return(client, 'numbers', shared.numbers(), true)
- assert_equal(client:linsert('numbers', 'before', 0, -2), 11)
- assert_equal(client:linsert('numbers', 'after', -2, -1), 12)
- assert_table_values(client:lrange('numbers', 0, 3), { '-2', '-1', '0', '1' });
- assert_equal(client:linsert('numbers', 'before', 100, 200), -1)
- assert_equal(client:linsert('numbers', 'after', 100, 50), -1)
- assert_error(function()
- client:set('foo', 'bar')
- client:linsert('foo', 0, 0)
- end)
- end)
- end)
- context("Commands operating on sets", function()
- test("SADD (client:sadd)", function()
- assert_equal(client:sadd('set', 0), 1)
- assert_equal(client:sadd('set', 1), 1)
- assert_equal(client:sadd('set', 0), 0)
- assert_error(function()
- client:set('foo', 'bar')
- client:sadd('foo', 0)
- end)
- end)
- test("SREM (client:srem)", function()
- utils.sadd_return(client, 'set', { '0', '1', '2', '3', '4' })
- assert_equal(client:srem('set', 0), 1)
- assert_equal(client:srem('set', 4), 1)
- assert_equal(client:srem('set', 10), 0)
- assert_error(function()
- client:set('foo', 'bar')
- client:srem('foo', 0)
- end)
- end)
- test("SPOP (client:spop)", function()
- local set = utils.sadd_return(client, 'set', { '0', '1', '2', '3', '4' })
- assert_true(table.contains(set, client:spop('set')))
- assert_nil(client:spop('doesnotexist'))
- assert_error(function()
- client:set('foo', 'bar')
- client:spop('foo')
- end)
- end)
- test("SMOVE (client:smove)", function()
- utils.sadd_return(client, 'setA', { '0', '1', '2', '3', '4', '5' })
- utils.sadd_return(client, 'setB', { '5', '6', '7', '8', '9', '10' })
- assert_true(client:smove('setA', 'setB', 0))
- assert_equal(client:srem('setA', 0), 0)
- assert_equal(client:srem('setB', 0), 1)
- assert_true(client:smove('setA', 'setB', 5))
- assert_false(client:smove('setA', 'setB', 100))
- assert_error(function()
- client:set('foo', 'bar')
- client:smove('foo', 'setB', 5)
- end)
- assert_error(function()
- client:set('foo', 'bar')
- client:smove('setA', 'foo', 5)
- end)
- end)
- test("SCARD (client:scard)", function()
- utils.sadd_return(client, 'setA', { '0', '1', '2', '3', '4', '5' })
- assert_equal(client:scard('setA'), 6)
- -- empty set
- client:sadd('setB', 0)
- client:spop('setB')
- assert_equal(client:scard('doesnotexist'), 0)
- -- non-existent set
- assert_equal(client:scard('doesnotexist'), 0)
- assert_error(function()
- client:set('foo', 'bar')
- client:scard('foo')
- end)
- end)
- test("SISMEMBER (client:sismember)", function()
- utils.sadd_return(client, 'set', { '0', '1', '2', '3', '4', '5' })
- assert_true(client:sismember('set', 3))
- assert_false(client:sismember('set', 100))
- assert_false(client:sismember('doesnotexist', 0))
- assert_error(function()
- client:set('foo', 'bar')
- client:sismember('foo', 0)
- end)
- end)
- test("SMEMBERS (client:smembers)", function()
- local set = utils.sadd_return(client, 'set', { '0', '1', '2', '3', '4', '5' })
- assert_table_values(client:smembers('set'), set)
- if version:is('<', '2.0.0') then
- assert_nil(client:smembers('doesnotexist'))
- else
- assert_table_values(client:smembers('doesnotexist'), {})
- end
- assert_error(function()
- client:set('foo', 'bar')
- client:smembers('foo')
- end)
- end)
- test("SINTER (client:sinter)", function()
- local setA = utils.sadd_return(client, 'setA', { '0', '1', '2', '3', '4', '5', '6' })
- local setB = utils.sadd_return(client, 'setB', { '1', '3', '4', '6', '9', '10' })
- …
Large files files are truncated, but you can click here to view the full file