Skip to content

Commit

Permalink
Adding tests for modules ACL and modules config changes in 8.0
Browse files Browse the repository at this point in the history
  • Loading branch information
petyaslavova committed Jan 28, 2025
1 parent 03031a2 commit 061b55f
Show file tree
Hide file tree
Showing 2 changed files with 396 additions and 0 deletions.
199 changes: 199 additions & 0 deletions tests/test_asyncio/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
parse_info,
)
from redis.client import EMPTY_RESPONSE, NEVER_DECODE
from redis.commands.json.path import Path
from redis.commands.search.field import TextField
from redis.commands.search.query import Query
from tests.conftest import (
assert_resp_response,
assert_resp_response_in,
Expand Down Expand Up @@ -49,6 +52,12 @@ def factory(username):
return r

yield factory
try:
current_user = await r.client_info()
except exceptions.NoPermissionError:
current_user = {}
if "default" != current_user.get("user"):
await r.auth("", "default")
for username in usernames:
await r.acl_deluser(username)

Expand Down Expand Up @@ -115,12 +124,65 @@ async def test_acl_cat_no_category(self, r: redis.Redis):
assert isinstance(categories, list)
assert "read" in categories or b"read" in categories

@pytest.mark.redismod
@skip_if_server_version_lt("7.9.0")
async def test_acl_cat_contain_modules_no_category(self, r: redis.Redis):
modules_list = [
"search",
"bloom",
"json",
"cuckoo",
"timeseries",
"cms",
"topk",
"tdigest",
]
categories = await r.acl_cat()
assert isinstance(categories, list)
for module_cat in modules_list:
assert module_cat in categories or module_cat.encode() in categories

@skip_if_server_version_lt(REDIS_6_VERSION)
async def test_acl_cat_with_category(self, r: redis.Redis):
commands = await r.acl_cat("read")
assert isinstance(commands, list)
assert "get" in commands or b"get" in commands

@pytest.mark.redismod
@skip_if_server_version_lt("7.9.0")
async def test_acl_modules_cat_with_category(self, r: redis.Redis):
search_commands = await r.acl_cat("search")
assert isinstance(search_commands, list)
assert "FT.SEARCH" in search_commands or b"FT.SEARCH" in search_commands

bloom_commands = await r.acl_cat("bloom")
assert isinstance(bloom_commands, list)
assert "bf.add" in bloom_commands or b"bf.add" in bloom_commands

json_commands = await r.acl_cat("json")
assert isinstance(json_commands, list)
assert "json.get" in json_commands or b"json.get" in json_commands

cuckoo_commands = await r.acl_cat("cuckoo")
assert isinstance(cuckoo_commands, list)
assert "cf.insert" in cuckoo_commands or b"cf.insert" in cuckoo_commands

cms_commands = await r.acl_cat("cms")
assert isinstance(cms_commands, list)
assert "cms.query" in cms_commands or b"cms.query" in cms_commands

topk_commands = await r.acl_cat("topk")
assert isinstance(topk_commands, list)
assert "topk.list" in topk_commands or b"topk.list" in topk_commands

tdigest_commands = await r.acl_cat("tdigest")
assert isinstance(tdigest_commands, list)
assert "tdigest.rank" in tdigest_commands or b"tdigest.rank" in tdigest_commands

timeseries_commands = await r.acl_cat("timeseries")
assert isinstance(timeseries_commands, list)
assert "ts.range" in timeseries_commands or b"ts.range" in timeseries_commands

@skip_if_server_version_lt(REDIS_6_VERSION)
async def test_acl_deluser(self, r_teardown):
username = "redis-py-user"
Expand Down Expand Up @@ -316,6 +378,116 @@ async def test_acl_whoami(self, r: redis.Redis):
username = await r.acl_whoami()
assert isinstance(username, (str, bytes))

@pytest.mark.redismod
@skip_if_server_version_lt("7.9.0")
async def test_acl_modules_commands(self, r_teardown):
username = "redis-py-user"
password = "pass-for-test-user"

r = r_teardown(username)
await r.flushdb()

await r.ft().create_index((TextField("txt"),))
await r.hset("doc1", mapping={"txt": "foo baz"})
await r.hset("doc2", mapping={"txt": "foo bar"})

await r.acl_setuser(
username,
enabled=True,
reset=True,
passwords=[f"+{password}"],
categories=["-all"],
commands=[
"+FT.SEARCH",
"-FT.DROPINDEX",
"+json.set",
"+json.get",
"-json.clear",
"+bf.reserve",
"-bf.info",
"+cf.reserve",
"+cms.initbydim",
"+topk.reserve",
"+tdigest.create",
"+ts.create",
"-ts.info",
],
keys=["*"],
)

await r.auth(password, username)

assert await r.ft().search(Query("foo ~bar"))
with pytest.raises(exceptions.NoPermissionError):
await r.ft().dropindex()

await r.json().set("foo", Path.root_path(), "bar")
assert await r.json().get("foo") == "bar"
with pytest.raises(exceptions.NoPermissionError):
await r.json().clear("foo")

assert await r.bf().create("bloom", 0.01, 1000)
assert await r.cf().create("cuckoo", 1000)
assert await r.cms().initbydim("cmsDim", 100, 5)
assert await r.topk().reserve("topk", 5, 100, 5, 0.9)
assert await r.tdigest().create("to-tDigest", 10)
with pytest.raises(exceptions.NoPermissionError):
await r.bf().info("bloom")

assert await r.ts().create(1, labels={"Redis": "Labs"})
with pytest.raises(exceptions.NoPermissionError):
await r.ts().info(1)

@pytest.mark.redismod
@skip_if_server_version_lt("7.9.0")
async def test_acl_modules_category_commands(self, r_teardown):
username = "redis-py-user"
password = "pass-for-test-user"

r = r_teardown(username)
await r.flushdb()

# validate modules categories acl config
await r.acl_setuser(
username,
enabled=True,
reset=True,
passwords=[f"+{password}"],
categories=[
"-all",
"+@search",
"+@json",
"+@bloom",
"+@cuckoo",
"+@topk",
"+@cms",
"+@timeseries",
"+@tdigest",
],
keys=["*"],
)
await r.ft().create_index((TextField("txt"),))
await r.hset("doc1", mapping={"txt": "foo baz"})
await r.hset("doc2", mapping={"txt": "foo bar"})

await r.auth(password, username)

assert await r.ft().search(Query("foo ~bar"))
assert await r.ft().dropindex()

assert await r.json().set("foo", Path.root_path(), "bar")
assert await r.json().get("foo") == "bar"

assert await r.bf().create("bloom", 0.01, 1000)
assert await r.bf().info("bloom")
assert await r.cf().create("cuckoo", 1000)
assert await r.cms().initbydim("cmsDim", 100, 5)
assert await r.topk().reserve("topk", 5, 100, 5, 0.9)
assert await r.tdigest().create("to-tDigest", 10)

assert await r.ts().create(1, labels={"Redis": "Labs"})
assert await r.ts().info(1)

@pytest.mark.onlynoncluster
async def test_client_list(self, r: redis.Redis):
clients = await r.client_list()
Expand Down Expand Up @@ -512,6 +684,33 @@ async def test_config_set(self, r: redis.Redis):
assert await r.config_set("timeout", 0)
assert (await r.config_get())["timeout"] == "0"

@pytest.mark.redismod
@skip_if_server_version_lt("7.9.0")
async def test_config_get_for_modules(self, r: redis.Redis):
search_module_configs = await r.config_get("search-*")
assert "search-timeout" in search_module_configs

ts_module_configs = await r.config_get("ts-*")
assert "ts-num-threads" in ts_module_configs

bf_module_configs = await r.config_get("bf-*")
assert "bf-initial-size" in bf_module_configs

cf_module_configs = await r.config_get("cf-*")
assert "cf-max-iterations" in cf_module_configs

@pytest.mark.redismod
@skip_if_server_version_lt("7.9.0")
async def test_config_set_for_search_module(self, r: redis.Redis):
search_timeout_initial = (await r.config_get())["search-timeout"]
search_timeout_new = int(search_timeout_initial) + 100

assert await r.config_set("search-timeout", search_timeout_new)
assert (
int((await r.config_get("search-*"))["search-timeout"])
== search_timeout_new
)

@pytest.mark.onlynoncluster
async def test_dbsize(self, r: redis.Redis):
await r.set("a", "foo")
Expand Down
Loading

0 comments on commit 061b55f

Please sign in to comment.