diff --git a/README.rst b/README.rst index 59074777..374f2223 100644 --- a/README.rst +++ b/README.rst @@ -310,8 +310,6 @@ scripting --------- * script debug - * script exists - * script flush * script kill diff --git a/fakeredis/_server.py b/fakeredis/_server.py index a9af12e4..d114a1a4 100644 --- a/fakeredis/_server.py +++ b/fakeredis/_server.py @@ -2316,8 +2316,7 @@ def time(self): return [str(now_s).encode(), str(now_us).encode()] # Script commands - # TODO: script exists, script flush - # (script debug and script kill will probably not be supported) + # script debug and script kill will probably not be supported def _convert_redis_arg(self, lua_runtime, value): # Type checks are exact to avoid issues like bool being a subclass of int. @@ -2475,6 +2474,13 @@ def script(self, subcmd, *args): sha1 = hashlib.sha1(script).hexdigest().encode() self._server.script_cache[sha1] = script return sha1 + elif casematch(subcmd, b'exists'): + return [int(sha1 in self._server.script_cache) for sha1 in args] + elif casematch(subcmd, b'flush'): + if len(args) != 0: + raise SimpleError(BAD_SUBCOMMAND_MSG.format('SCRIPT')) + self._server.script_cache = {} + return OK else: raise SimpleError(BAD_SUBCOMMAND_MSG.format('SCRIPT')) diff --git a/test/test_fakeredis.py b/test/test_fakeredis.py index 2bb41648..1541cff2 100644 --- a/test/test_fakeredis.py +++ b/test/test_fakeredis.py @@ -4486,6 +4486,46 @@ def test_script(r): assert result == b'42' +def test_script_exists(r): + # test response for no arguments by bypassing the py-redis command + # as it requires at least one argument + assert raw_command(r, "SCRIPT EXISTS") == [] + + # use single character characters for non-existing scripts, as those + # will never be equal to an actual sha1 hash digest + assert r.script_exists("a") == [0] + assert r.script_exists("a", "b", "c", "d", "e", "f") == [0, 0, 0, 0, 0, 0] + + sha1_one = r.script_load("return 'a'") + assert r.script_exists(sha1_one) == [1] + assert r.script_exists(sha1_one, "a") == [1, 0] + assert r.script_exists("a", "b", "c", sha1_one, "e") == [0, 0, 0, 1, 0] + + sha1_two = r.script_load("return 'b'") + assert r.script_exists(sha1_one, sha1_two) == [1, 1] + assert r.script_exists("a", sha1_one, "c", sha1_two, "e", "f") == [0, 1, 0, 1, 0, 0] + + +@pytest.mark.parametrize("args", [("a",), tuple("abcdefghijklmn")]) +def test_script_flush_errors_with_args(r, args): + with pytest.raises(redis.ResponseError): + raw_command(r, "SCRIPT FLUSH %s" % " ".join(args)) + + +def test_script_flush(r): + # generate/load six unique scripts and store their sha1 hash values + sha1_values = [r.script_load("return '%s'" % char) for char in "abcdef"] + + # assert the scripts all exist prior to flushing + assert r.script_exists(*sha1_values) == [1] * len(sha1_values) + + # flush and assert OK response + assert r.script_flush() is True + + # assert none of the scripts exists after flushing + assert r.script_exists(*sha1_values) == [0] * len(sha1_values) + + @fake_only def test_lua_log(r, caplog): logger = fakeredis._server.LOGGER