Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dragonfly test support #318

Merged
merged 32 commits into from
Aug 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d92e116
tests for dragonfly
cunla Jul 30, 2024
94ff3b8
tests for dragonfly
cunla Jul 30, 2024
d8198a1
Merge branch 'refs/heads/master' into dragonfly-test-support
cunla Aug 14, 2024
3f0460e
test-dragonfly.yml
cunla Aug 14, 2024
573d374
test-dragonfly.yml
cunla Aug 14, 2024
c5b6346
test-dragonfly.yml
cunla Aug 14, 2024
9e07727
test-dragonfly.yml
cunla Aug 14, 2024
bbd5565
test-dragonfly.yml
cunla Aug 14, 2024
6e7235a
test-dragonfly.yml
cunla Aug 14, 2024
b0b8163
test-dragonfly.yml
cunla Aug 14, 2024
aff6bff
test-dragonfly.yml
cunla Aug 14, 2024
f521e8b
test-dragonfly.yml
cunla Aug 14, 2024
135a731
test-dragonfly.yml
cunla Aug 14, 2024
d4aaf59
test-dragonfly.yml
cunla Aug 14, 2024
02a6e3a
test-dragonfly.yml
cunla Aug 14, 2024
5af4c09
test-dragonfly.yml
cunla Aug 14, 2024
432a01f
test-dragonfly.yml
cunla Aug 14, 2024
701560f
test-dragonfly.yml
cunla Aug 14, 2024
692bea9
test-dragonfly.yml
cunla Aug 14, 2024
0a6d12f
test-dragonfly.yml
cunla Aug 14, 2024
3d310cb
test-dragonfly.yml
cunla Aug 14, 2024
dd09fc8
add unsupported flag
cunla Aug 14, 2024
469a723
add unsupported flag
cunla Aug 14, 2024
1abae1a
add unsupported flag
cunla Aug 14, 2024
d3622a4
add unsupported flag
cunla Aug 14, 2024
7331826
black
cunla Aug 14, 2024
e37de25
update pytest to v8
cunla Aug 24, 2024
aea814c
update reqs
cunla Aug 24, 2024
c0fc184
update reqs
cunla Aug 24, 2024
ebdd600
Merge branch 'master' into dragonfly-test-support
cunla Aug 24, 2024
0a83747
update docs
cunla Aug 24, 2024
39eb63c
update docs
cunla Aug 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions .github/workflows/test-dragonfly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
name: Test Dragonfly

on:
workflow_dispatch:


concurrency:
group: dragon-fly-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
tests:
- "test_json"
- "test_mixins"
- "test_stack"
- "test_connection.py"
- "test_asyncredis.py"
- "test_general.py"
- "test_scan.py"
- "test_zadd.py"
- "test_translations.py"
- "test_sortedset_commands.py"
permissions:
pull-requests: write
services:
redis:
image: docker.dragonflydb.io/dragonflydb/dragonfly:latest
ports:
- 6380:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
cache-dependency-path: poetry.lock
python-version: 3.12
- name: Install dependencies
env:
PYTHON_KEYRING_BACKEND: keyring.backends.null.Keyring
run: |
python -m pip --quiet install poetry
echo "$HOME/.poetry/bin" >> $GITHUB_PATH
poetry install
poetry run pip install "fakeredis[json,bf,cf,lua]"

- name: Test without coverage
run: |
poetry run pytest test/${{ matrix.tests }} \
--html=report-${{ matrix.tests }}.html \
--self-contained-html \
-v
- name: Upload Tests Result
if: always()
uses: actions/upload-artifact@v4
with:
name: tests-result-${{ matrix.tests }}
path: report-${{ matrix.tests }}.html

upload-results:
needs: test
if: always()
runs-on: ubuntu-latest
steps:
- name: Collect Tests Result
uses: actions/upload-artifact/merge@v4
with:
delete-merged: true
10 changes: 10 additions & 0 deletions docs/about/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ description: Change log of all fakeredis releases

- Support for TIME SERIES commands (no support for align arguments on some commands) #310

### 🐛 Bug Fixes

- fix:xrevrange to work with exclusive ranges @hurlenko #319

### 🧰 Maintenance

- Update all dependencies, particularly pytest to v8
- Add tests against Dragonfly server #318
- Implement decocator `unsupported_server_types` to enable excluding tests from running against certain server types #318

## v2.23.5

### 🐛 Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
mkdocs==1.6.0
mkdocs-material==9.5.31
mkdocs-material==9.5.33
208 changes: 162 additions & 46 deletions poetry.lock

Large diffs are not rendered by default.

14 changes: 9 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ packages = [
{ include = "fakeredis" },
{ include = "LICENSE" },
]
version = "2.23.5"
version = "2.24.0"
description = "Python implementation of redis API, can be used for testing purposes."
readme = "README.md"
keywords = ["redis", "RedisJson", "RedisBloom", "tests", "redis-stack"]
Expand Down Expand Up @@ -66,15 +66,16 @@ coverage = "^7"
black = { version = "^24.4.2", python = ">=3.8.1" }
flake8 = { version = "^7", python = ">=3.8.1" }
flake8-pyproject = { version = "^1", python = ">=3.8.1" }
hypothesis = "^6.70"
mypy = { version = "^1.10", python = ">=3.8.1" }

[tool.poetry.group.test.dependencies]
pytest = "^7.4"
pytest = { version = "^8.3", python = ">=3.8.1" }
hypothesis = { version = "^6.111", python = ">=3.8.1" }
pytest-timeout = "^2.3.1"
pytest-asyncio = "^0.21"
pytest-cov = "^4.1"
pytest-asyncio = { version = "^0.24", python = ">=3.8.1" }
pytest-cov = { version = "^5.0", python = ">=3.8.1" }
pytest-mock = { version = "^3.14", python = ">=3.8.1" }
pytest-html = { version = "^4.1", python = ">=3.8.1" }

[tool.poetry.group.docs.dependencies]
python-dotenv = { version = "^1", python = ">=3.8.1" }
Expand All @@ -86,6 +87,7 @@ pygithub = "^2.3"
"Documentation" = "https://fakeredis.moransoftware.ca/"

[tool.pytest.ini_options]
asyncio_default_fixture_loop_scope = "function"
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"fake: run tests only with fake redis",
Expand All @@ -94,8 +96,10 @@ markers = [
"min_server",
"max_server",
"decode_responses",
"unsupported_server_types",
]
asyncio_mode = "strict"
generate_report_on_test = true

[tool.mypy]
packages = ['fakeredis', ]
Expand Down
29 changes: 19 additions & 10 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Callable, Union
from typing import Callable, Tuple, Union, Optional

import pytest
import pytest_asyncio
Expand All @@ -18,22 +18,26 @@ def _check_lua_module_supported() -> bool:


@pytest_asyncio.fixture(scope="session")
def real_redis_version() -> Union[None, str]:
def real_redis_version() -> Tuple[str, Union[None, Tuple[int, ...]]]:
"""Returns server's version or None if server is not running"""
client = None
try:
client = redis.StrictRedis("localhost", port=6380, db=2)
server_version = client.info()["redis_version"]
return server_version
client_info = client.info()
server_type = "dragonfly" if "dragonfly_version" in client_info else "redis"
server_version = client_info["redis_version"] if server_type != "dragonfly" else (7, 0)
server_version = _create_version(server_version) or (7,)
return server_type, server_version
except redis.ConnectionError:
return None
pytest.exit("Redis is not running")
return "redis", (6,)
finally:
if hasattr(client, "close"):
client.close() # Absent in older versions of redis-py


@pytest_asyncio.fixture(name="fake_server")
def _fake_server(request):
def _fake_server(request) -> fakeredis.FakeServer:
min_server_marker = request.node.get_closest_marker("min_server")
server_version = min_server_marker.args[0] if min_server_marker else "6.2"
server = fakeredis.FakeServer(version=server_version)
Expand Down Expand Up @@ -70,10 +74,12 @@ def _marker_version_value(request, marker_name: str):
)
def _create_redis(request) -> Callable[[int], redis.Redis]:
cls_name = request.param
server_version = request.getfixturevalue("real_redis_version")
server_type, server_version = request.getfixturevalue("real_redis_version")
if not cls_name.startswith("Fake") and not server_version:
pytest.skip("Redis is not running")
server_version = _create_version(server_version) or (6,)
unsupported_server_types = request.node.get_closest_marker("unsupported_server_types")
if unsupported_server_types and server_type in unsupported_server_types.args:
pytest.skip(f"Server type {server_type} is not supported")
min_server = _marker_version_value(request, "min_server")
max_server = _marker_version_value(request, "max_server")
if server_version < min_server:
Expand Down Expand Up @@ -103,10 +109,12 @@ def factory(db=2):
params=[pytest.param("fake", marks=pytest.mark.fake), pytest.param("real", marks=pytest.mark.real)],
)
async def _req_aioredis2(request) -> redis.asyncio.Redis:
server_version = request.getfixturevalue("real_redis_version")
server_type, server_version = request.getfixturevalue("real_redis_version")
if request.param != "fake" and not server_version:
pytest.skip("Redis is not running")
server_version = _create_version(server_version) or (6,)
unsupported_server_types = request.node.get_closest_marker("unsupported_server_types")
if unsupported_server_types and server_type in unsupported_server_types.args:
pytest.skip(f"Server type {server_type} is not supported")
min_server_marker = _marker_version_value(request, "min_server")
max_server_marker = _marker_version_value(request, "max_server")
if server_version < min_server_marker:
Expand All @@ -117,6 +125,7 @@ async def _req_aioredis2(request) -> redis.asyncio.Redis:
lua_modules = set(lua_modules_marker.args) if lua_modules_marker else None
if lua_modules and not _check_lua_module_supported():
pytest.skip("LUA modules not supported by fakeredis")
fake_server: Optional[fakeredis.FakeServer]
if request.param == "fake":
fake_server = request.getfixturevalue("fake_server")
ret = fakeredis.FakeAsyncRedis(server=fake_server, lua_modules=lua_modules)
Expand Down
34 changes: 5 additions & 29 deletions test/test_json/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,14 +435,7 @@ def test_decode_response_disabaled_null(r: redis.Redis):


def test_json_get_jset(r: redis.Redis):
assert (
r.json().set(
"foo",
Path.root_path(),
"bar",
)
== 1
)
assert r.json().set("foo", Path.root_path(), "bar") == 1
assert "bar" == r.json().get("foo")
assert r.json().get("baz") is None
assert 1 == r.json().delete("foo")
Expand Down Expand Up @@ -509,19 +502,9 @@ def test_set_path(r: redis.Redis):


def test_type(r: redis.Redis):
r.json().set(
"1",
Path.root_path(),
1,
)
r.json().set("1", Path.root_path(), 1)

assert (
r.json().type(
"1",
Path.root_path(),
)
== b"integer"
)
assert r.json().type("1", Path.root_path()) == b"integer"
assert r.json().type("1") == b"integer" # noqa: E721

meta_data = {
Expand Down Expand Up @@ -553,15 +536,8 @@ def test_objlen(r: redis.Redis):

obj = {"foo": "bar", "baz": "qaz"}

r.json().set(
"obj",
Path.root_path(),
obj,
)
assert len(obj) == r.json().objlen(
"obj",
Path.root_path(),
)
r.json().set("obj", Path.root_path(), obj)
assert len(obj) == r.json().objlen("obj", Path.root_path())

r.json().set("obj", Path.root_path(), obj)
assert len(obj) == r.json().objlen("obj")
Expand Down
Loading
Loading