Add Redis scan_keys iterator API.
Test Python Package / unit-tests (pull_request) Successful in 14s
Code Quality Pipeline / code-quality (pull_request) Successful in 32s
Test Python Package / coverage-report (pull_request) Successful in 16s
PR Title Check / check-title (pull_request) Successful in 6s
Test Python Package / integration-tests (pull_request) Successful in 1m3s
Test Python Package / unit-tests (pull_request) Successful in 14s
Code Quality Pipeline / code-quality (pull_request) Successful in 32s
Test Python Package / coverage-report (pull_request) Successful in 16s
PR Title Check / check-title (pull_request) Successful in 6s
Test Python Package / integration-tests (pull_request) Successful in 1m3s
Provide a SCAN-based key iterator for Redis adapters so callers can enumerate large keyspaces without relying on blocking KEYS lookups. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
co-authored by
Cursor
parent
2f19fcc972
commit
50444af982
@@ -114,3 +114,53 @@ def test_connect_closes_existing_non_injected_client(
|
||||
|
||||
stale_client.close.assert_called_once()
|
||||
assert adapter._client is new_client
|
||||
|
||||
|
||||
def test_scan_keys_yields_decoded_keys() -> None:
|
||||
mock_client = MagicMock(spec=redis.Redis)
|
||||
mock_client.scan_iter.return_value = iter([b"key1", b"key2"])
|
||||
adapter = RedisAdapter(config=TEST_REDIS_CONFIG, client=mock_client)
|
||||
|
||||
keys = list(adapter.scan_keys("key*"))
|
||||
|
||||
assert keys == ["key1", "key2"]
|
||||
mock_client.scan_iter.assert_called_once_with(match="key*")
|
||||
mock_client.keys.assert_not_called()
|
||||
|
||||
|
||||
def test_scan_keys_forwards_count() -> None:
|
||||
mock_client = MagicMock(spec=redis.Redis)
|
||||
mock_client.scan_iter.return_value = iter([b"key1"])
|
||||
adapter = RedisAdapter(config=TEST_REDIS_CONFIG, client=mock_client)
|
||||
|
||||
keys = list(adapter.scan_keys("key*", count=50))
|
||||
|
||||
assert keys == ["key1"]
|
||||
mock_client.scan_iter.assert_called_once_with(match="key*", count=50)
|
||||
|
||||
|
||||
def test_list_keys_raises_value_error_on_invalid_pattern() -> None:
|
||||
mock_client = MagicMock(spec=redis.Redis)
|
||||
adapter = RedisAdapter(config=TEST_REDIS_CONFIG, client=mock_client)
|
||||
|
||||
invalid_patterns = ["", 123, None]
|
||||
for pattern in invalid_patterns:
|
||||
with pytest.raises(ValueError, match="Pattern must be a non-empty string"):
|
||||
adapter.list_keys(pattern) # type: ignore[arg-type]
|
||||
|
||||
|
||||
def test_scan_keys_raises_value_error_on_invalid_pattern() -> None:
|
||||
mock_client = MagicMock(spec=redis.Redis)
|
||||
adapter = RedisAdapter(config=TEST_REDIS_CONFIG, client=mock_client)
|
||||
|
||||
invalid_patterns = ["", 123, None]
|
||||
for pattern in invalid_patterns:
|
||||
with pytest.raises(ValueError, match="Pattern must be a non-empty string"):
|
||||
list(adapter.scan_keys(pattern)) # type: ignore[arg-type]
|
||||
|
||||
|
||||
def test_scan_keys_raises_connection_error_when_not_connected() -> None:
|
||||
adapter = RedisAdapter(config=TEST_REDIS_CONFIG)
|
||||
|
||||
with pytest.raises(ConnectionError):
|
||||
list(adapter.scan_keys("key*"))
|
||||
|
||||
Reference in New Issue
Block a user