From cb83787e63256cecf81631b4eed8a4e35f56c4db Mon Sep 17 00:00:00 2001 From: Amotz Getzov Date: Thu, 23 Jun 2016 11:12:54 +0300 Subject: [PATCH 1/2] Add status_reply and error_reply helpers to Lua's global 'redis' table. --- mockredis/script.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mockredis/script.py b/mockredis/script.py index c0a3d48..50c20d2 100644 --- a/mockredis/script.py +++ b/mockredis/script.py @@ -47,7 +47,11 @@ def _call(*call_args): response = client.call(*call_args) return self._python_to_lua(response) - lua_globals.redis = {"call": _call} + lua_globals.redis = {"call": _call, + # TODO wrap _call with try to implement "pcall": _pcall, + "status_reply": lambda status: self._python_to_lua({"ok": status}), + "error_reply": lambda error: self._python_to_lua({"err": error}) + } return self._lua_to_python(lua.execute(self.script), return_status=True) @staticmethod From 8673ddddf690e73bf581ab1d3178a13cf8a5028e Mon Sep 17 00:00:00 2001 From: Amotz Getzov Date: Mon, 5 Dec 2016 01:56:39 +0200 Subject: [PATCH 2/2] Fixed status reply type to Lua table, not list. And added tests. --- mockredis/script.py | 7 +++++-- mockredis/tests/fixtures.py | 17 ++++++++++++++++- mockredis/tests/test_constants.py | 3 +++ mockredis/tests/test_script.py | 17 ++++++++++++++--- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/mockredis/script.py b/mockredis/script.py index 50c20d2..4031c28 100644 --- a/mockredis/script.py +++ b/mockredis/script.py @@ -47,10 +47,13 @@ def _call(*call_args): response = client.call(*call_args) return self._python_to_lua(response) + def reply_table(field, msg): + return lua.eval("{{{}='{}'}}".format(field, msg)) + lua_globals.redis = {"call": _call, # TODO wrap _call with try to implement "pcall": _pcall, - "status_reply": lambda status: self._python_to_lua({"ok": status}), - "error_reply": lambda error: self._python_to_lua({"err": error}) + "status_reply": lambda status: reply_table('ok', status), + "error_reply": lambda error: reply_table('err', error) } return self._lua_to_python(lua.execute(self.script), return_status=True) diff --git a/mockredis/tests/fixtures.py b/mockredis/tests/fixtures.py index 980c07b..b0a9102 100644 --- a/mockredis/tests/fixtures.py +++ b/mockredis/tests/fixtures.py @@ -3,7 +3,7 @@ """ from contextlib import contextmanager -from nose.tools import assert_raises, raises +from nose.tools import assert_raises, raises, assert_raises_regexp, make_decorator from mockredis.noseplugin import WithRedis @@ -39,6 +39,21 @@ def raises_response_error(func): return raises(WithRedis.ResponseError)(func) +def raises_response_error_regex(regex): + """ + Test decorator that handles ResponseError or its mock equivalent + (currently ValueError) and verify it's message. + + mockredis does not currently raise redis-py's exceptions because it + does not current depend on redis-py strictly. + """ + def real_decorator(func): + def assert_func(*arg, **kw): + return assert_raises_regexp(WithRedis.ResponseError, regex, func, *arg, **kw) + return make_decorator(func)(assert_func) + return real_decorator + + @contextmanager def assert_raises_redis_error(): """ diff --git a/mockredis/tests/test_constants.py b/mockredis/tests/test_constants.py index 3d9030d..1c2fa5c 100644 --- a/mockredis/tests/test_constants.py +++ b/mockredis/tests/test_constants.py @@ -9,6 +9,9 @@ VAL3 = "val3" VAL4 = "val4" +OK_REPLY = "Good" +ERR_REPLY = "Bad" + LPOP_SCRIPT = "return redis.call('LPOP', KEYS[1])" bVAL1 = VAL1.encode('utf8') diff --git a/mockredis/tests/test_script.py b/mockredis/tests/test_script.py index bb000b6..e79e1d5 100644 --- a/mockredis/tests/test_script.py +++ b/mockredis/tests/test_script.py @@ -15,9 +15,9 @@ LIST1, LIST2, SET1, VAL1, VAL2, VAL3, VAL4, - LPOP_SCRIPT -) -from mockredis.tests.fixtures import raises_response_error + LPOP_SCRIPT, + OK_REPLY, ERR_REPLY) +from mockredis.tests.fixtures import raises_response_error, raises_response_error_regex if sys.version_info >= (3, 0): @@ -389,6 +389,17 @@ def test_lua_err_return(self): script = self.redis.register_script(script_content) script() + def test_lua_status_reply(self): + script_content = "return redis.status_reply('{}')".format(OK_REPLY) + script = self.redis.register_script(script_content) + eq_(OK_REPLY, script()) + + @raises_response_error_regex(ERR_REPLY) + def test_lua_err_reply(self): + script_content = "return redis.error_reply('{}')".format(ERR_REPLY) + script = self.redis.register_script(script_content) + script() + def test_concurrent_lua(self): script_content = """ local entry = redis.call('HGETALL', ARGV[1])