Skip to content

Commit 9e3ef4b

Browse files
committed
Adding tests for modules ACL and modules config changes in 8.0
1 parent 2427365 commit 9e3ef4b

File tree

2 files changed

+400
-0
lines changed

2 files changed

+400
-0
lines changed

tests/test_asyncio/test_commands.py

+202
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
parse_info,
2121
)
2222
from redis.client import EMPTY_RESPONSE, NEVER_DECODE
23+
from redis.commands.json.path import Path
24+
from redis.commands.search.field import TextField
25+
from redis.commands.search.query import Query
2326
from tests.conftest import (
2427
assert_resp_response,
2528
assert_resp_response_in,
@@ -49,6 +52,12 @@ def factory(username):
4952
return r
5053

5154
yield factory
55+
try:
56+
current_user = await r.client_info()
57+
except exceptions.NoPermissionError:
58+
current_user = {}
59+
if "default" != current_user.get("user"):
60+
await r.auth("", "default")
5261
for username in usernames:
5362
await r.acl_deluser(username)
5463

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

127+
@pytest.mark.redismod
128+
@skip_if_server_version_lt("7.9.0")
129+
async def test_acl_cat_contain_modules_no_category(self, r: redis.Redis):
130+
modules_list = [
131+
"search",
132+
"bloom",
133+
"json",
134+
"cuckoo",
135+
"timeseries",
136+
"cms",
137+
"topk",
138+
"tdigest",
139+
]
140+
categories = await r.acl_cat()
141+
assert isinstance(categories, list)
142+
for module_cat in modules_list:
143+
assert module_cat in categories or module_cat.encode() in categories
144+
118145
@skip_if_server_version_lt(REDIS_6_VERSION)
119146
async def test_acl_cat_with_category(self, r: redis.Redis):
120147
commands = await r.acl_cat("read")
121148
assert isinstance(commands, list)
122149
assert "get" in commands or b"get" in commands
123150

151+
@pytest.mark.redismod
152+
@skip_if_server_version_lt("7.9.0")
153+
async def test_acl_modules_cat_with_category(self, r: redis.Redis):
154+
search_commands = await r.acl_cat("search")
155+
assert isinstance(search_commands, list)
156+
assert "FT.SEARCH" in search_commands or b"FT.SEARCH" in search_commands
157+
158+
bloom_commands = await r.acl_cat("bloom")
159+
assert isinstance(bloom_commands, list)
160+
assert "bf.add" in bloom_commands or b"bf.add" in bloom_commands
161+
162+
json_commands = await r.acl_cat("json")
163+
assert isinstance(json_commands, list)
164+
assert "json.get" in json_commands or b"json.get" in json_commands
165+
166+
cuckoo_commands = await r.acl_cat("cuckoo")
167+
assert isinstance(cuckoo_commands, list)
168+
assert "cf.insert" in cuckoo_commands or b"cf.insert" in cuckoo_commands
169+
170+
cms_commands = await r.acl_cat("cms")
171+
assert isinstance(cms_commands, list)
172+
assert "cms.query" in cms_commands or b"cms.query" in cms_commands
173+
174+
topk_commands = await r.acl_cat("topk")
175+
assert isinstance(topk_commands, list)
176+
assert "topk.list" in topk_commands or b"topk.list" in topk_commands
177+
178+
tdigest_commands = await r.acl_cat("tdigest")
179+
assert isinstance(tdigest_commands, list)
180+
assert "tdigest.rank" in tdigest_commands or b"tdigest.rank" in tdigest_commands
181+
182+
timeseries_commands = await r.acl_cat("timeseries")
183+
assert isinstance(timeseries_commands, list)
184+
assert "ts.range" in timeseries_commands or b"ts.range" in timeseries_commands
185+
124186
@skip_if_server_version_lt(REDIS_6_VERSION)
125187
async def test_acl_deluser(self, r_teardown):
126188
username = "redis-py-user"
@@ -316,6 +378,116 @@ async def test_acl_whoami(self, r: redis.Redis):
316378
username = await r.acl_whoami()
317379
assert isinstance(username, (str, bytes))
318380

381+
@pytest.mark.redismod
382+
@skip_if_server_version_lt("7.9.0")
383+
async def test_acl_modules_commands(self, r_teardown):
384+
username = "redis-py-user"
385+
password = "pass-for-test-user"
386+
387+
r = r_teardown(username)
388+
await r.flushdb()
389+
390+
await r.ft().create_index((TextField("txt"),))
391+
await r.hset("doc1", mapping={"txt": "foo baz"})
392+
await r.hset("doc2", mapping={"txt": "foo bar"})
393+
394+
await r.acl_setuser(
395+
username,
396+
enabled=True,
397+
reset=True,
398+
passwords=[f"+{password}"],
399+
categories=["-all"],
400+
commands=[
401+
"+FT.SEARCH",
402+
"-FT.DROPINDEX",
403+
"+json.set",
404+
"+json.get",
405+
"-json.clear",
406+
"+bf.reserve",
407+
"-bf.info",
408+
"+cf.reserve",
409+
"+cms.initbydim",
410+
"+topk.reserve",
411+
"+tdigest.create",
412+
"+ts.create",
413+
"-ts.info",
414+
],
415+
keys=["*"],
416+
)
417+
418+
await r.auth(password, username)
419+
420+
assert await r.ft().search(Query("foo ~bar"))
421+
with pytest.raises(exceptions.NoPermissionError):
422+
await r.ft().dropindex()
423+
424+
await r.json().set("foo", Path.root_path(), "bar")
425+
assert await r.json().get("foo") == "bar"
426+
with pytest.raises(exceptions.NoPermissionError):
427+
await r.json().clear("foo")
428+
429+
assert await r.bf().create("bloom", 0.01, 1000)
430+
assert await r.cf().create("cuckoo", 1000)
431+
assert await r.cms().initbydim("cmsDim", 100, 5)
432+
assert await r.topk().reserve("topk", 5, 100, 5, 0.9)
433+
assert await r.tdigest().create("to-tDigest", 10)
434+
with pytest.raises(exceptions.NoPermissionError):
435+
await r.bf().info("bloom")
436+
437+
assert await r.ts().create(1, labels={"Redis": "Labs"})
438+
with pytest.raises(exceptions.NoPermissionError):
439+
await r.ts().info(1)
440+
441+
@pytest.mark.redismod
442+
@skip_if_server_version_lt("7.9.0")
443+
async def test_acl_modules_category_commands(self, r_teardown):
444+
username = "redis-py-user"
445+
password = "pass-for-test-user"
446+
447+
r = r_teardown(username)
448+
await r.flushdb()
449+
450+
# validate modules categories acl config
451+
await r.acl_setuser(
452+
username,
453+
enabled=True,
454+
reset=True,
455+
passwords=[f"+{password}"],
456+
categories=[
457+
"-all",
458+
"+@search",
459+
"+@json",
460+
"+@bloom",
461+
"+@cuckoo",
462+
"+@topk",
463+
"+@cms",
464+
"+@timeseries",
465+
"+@tdigest",
466+
],
467+
keys=["*"],
468+
)
469+
await r.ft().create_index((TextField("txt"),))
470+
await r.hset("doc1", mapping={"txt": "foo baz"})
471+
await r.hset("doc2", mapping={"txt": "foo bar"})
472+
473+
await r.auth(password, username)
474+
475+
assert await r.ft().search(Query("foo ~bar"))
476+
assert await r.ft().dropindex()
477+
478+
assert await r.json().set("foo", Path.root_path(), "bar")
479+
assert await r.json().get("foo") == "bar"
480+
481+
assert await r.bf().create("bloom", 0.01, 1000)
482+
assert await r.bf().info("bloom")
483+
assert await r.cf().create("cuckoo", 1000)
484+
assert await r.cms().initbydim("cmsDim", 100, 5)
485+
assert await r.topk().reserve("topk", 5, 100, 5, 0.9)
486+
assert await r.tdigest().create("to-tDigest", 10)
487+
488+
assert await r.ts().create(1, labels={"Redis": "Labs"})
489+
assert await r.ts().info(1)
490+
319491
@pytest.mark.onlynoncluster
320492
async def test_client_list(self, r: redis.Redis):
321493
clients = await r.client_list()
@@ -512,6 +684,36 @@ async def test_config_set(self, r: redis.Redis):
512684
assert await r.config_set("timeout", 0)
513685
assert (await r.config_get())["timeout"] == "0"
514686

687+
@pytest.mark.redismod
688+
@skip_if_server_version_lt("7.9.0")
689+
async def test_config_get_for_modules(self, r: redis.Redis):
690+
search_module_configs = await r.config_get("search-*")
691+
assert "search-timeout" in search_module_configs
692+
693+
ts_module_configs = await r.config_get("ts-*")
694+
assert "ts-num-threads" in ts_module_configs
695+
696+
bf_module_configs = await r.config_get("bf-*")
697+
assert "bf-initial-size" in bf_module_configs
698+
699+
cf_module_configs = await r.config_get("cf-*")
700+
assert "cf-max-iterations" in cf_module_configs
701+
702+
@pytest.mark.redismod
703+
@skip_if_server_version_lt("7.9.0")
704+
async def test_config_set_for_search_module(self, r: redis.Redis):
705+
search_timeout_initial = (await r.config_get())["search-timeout"]
706+
search_timeout_new = int(search_timeout_initial) + 100
707+
708+
assert await r.config_set("search-timeout", search_timeout_new)
709+
assert (
710+
int((await r.config_get("search-*"))["search-timeout"])
711+
== search_timeout_new
712+
)
713+
assert (
714+
int((await r.ft().config_get("TIMEOUT"))[b"TIMEOUT"]) == search_timeout_new
715+
)
716+
515717
@pytest.mark.onlynoncluster
516718
async def test_dbsize(self, r: redis.Redis):
517719
await r.set("a", "foo")

0 commit comments

Comments
 (0)