Skip to content

Commit

Permalink
Add valkey to CI/tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alisaifee committed Apr 20, 2024
1 parent 0179c65 commit 6645b22
Show file tree
Hide file tree
Showing 17 changed files with 77 additions and 10 deletions.
18 changes: 11 additions & 7 deletions .github/workflows/compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
matrix:
python-version: [3.8, 3.9, "3.10", "3.11", "3.12"]
redis-version: ["6.2", "7.0", "7.2", "latest"]
test_params: ["-m '(not (keydb or dragonfly))'"]
test_params: ["-m '(not (keydb or dragonfly or valkey))'"]
orjson: ["False"]
uvloop: ["True", "False"]
runtime_type_checks: ["True"]
Expand All @@ -72,24 +72,24 @@ jobs:
include:
- python-version: "3.11"
redis-version: next
test_params: "-m '(not (keydb or dragonfly))'"
test_params: "-m '(not (keydb or dragonfly or valkey))'"
runtime_type_checks: "True"
label: ""
- python-version: "3.11"
redis-version: latest
test_params: "-m '(not (keydb or dragonfly))'"
test_params: "-m '(not (keydb or dragonfly or valkey))'"
extensions: "False"
runtime_type_checks: "True"
label: ""
- python-version: "3.11"
redis-version: latest
test_params: "-m '(not (keydb or dragonfly))'"
test_params: "-m '(not (keydb or dragonfly or valkey))'"
runtime_type_checks: "True"
orjson: "True"
label: ""
- python-version: "3.11"
redis-version: 7.0
test_params: "-m '(not (keydb or dragonfly))'"
test_params: "-m '(not (keydb or dragonfly or valkey))'"
runtime_type_checks: "False"
label: ""
- python-version: "3.11"
Expand All @@ -101,16 +101,20 @@ jobs:
redis-version: 7.0
test_params: "-m dragonfly"
label: "Dragonfly"
- python-version: "3.11"
redis-version: 7.0
test_params: "-m valkey"
label: "Valkey"
- python-version: "pypy-3.8"
redis-version: 7.0
test_params: "-m '(not (keydb or dragonfly))' tests/commands tests/test_tracking_cache.py"
test_params: "-m '(not (keydb or dragonfly or valkey))' tests/commands tests/test_tracking_cache.py"
runtime_type_checks: "False"
extensions: "False"
uvloop: "False"
label: ""
- python-version: "pypy-3.9"
redis-version: 7.0
test_params: "-m '(not (keydb or dragonfly))' tests/commands tests/test_tracking_cache.py"
test_params: "-m '(not (keydb or dragonfly or valkey))' tests/commands tests/test_tracking_cache.py"
runtime_type_checks: "False"
extensions: "False"
uvloop: "False"
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
matrix:
python-version: ["3.10", "3.11", "3.12"]
redis-version: ["6.2", "7.0", "7.2", "latest"]
test_params: ["-m '(not (keydb or dragonfly))'"]
test_params: ["-m '(not (keydb or dragonfly or valkey))'"]
uvloop: ["True", "False"]
orjson: ["False"]
runtime_type_checks: ["True"]
Expand All @@ -66,7 +66,7 @@ jobs:
include:
- python-version: "3.11"
redis-version: "latest"
test_params: "-m '(not (keydb or dragonfly))'"
test_params: "-m '(not (keydb or dragonfly or valkey))'"
runtime_type_checks: "True"
extensions: "False"
- python-version: "3.11"
Expand All @@ -77,9 +77,13 @@ jobs:
redis-version: "7.0"
test_params: "-m dragonfly"
label: "Dragonfly"
- python-version: "3.11"
redis-version: "7.0"
test_params: "-m valkey"
label: "Valkey"
- python-version: "pypy-3.9"
redis-version: "7.0"
test_params: "-m '(not (keydb or dragonfly))' tests/commands tests/test_tracking_cache.py"
test_params: "-m '(not (keydb or dragonfly or valkey))' tests/commands tests/test_tracking_cache.py"
runtime_type_checks: "False"
extensions: "False"
uvloop: "False"
Expand Down
4 changes: 4 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -320,3 +320,7 @@ services:
- '11379:6379'
ulimits:
memlock: -1
valkey:
image: "valkey/valkey:${VALKEY_VERSION:-unstable}"
ports:
- '12379:6379'
2 changes: 2 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ markers =
nokeydb
keydb
nodragonfly
novalkey
dragonfly
sentinel
stack
valkey
ssl
uds
nocluster
Expand Down
1 change: 1 addition & 0 deletions tests/commands/test_acl.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ async def teardown(client):
"redis_cluster_blocking",
"redis_cluster_raw",
"keydb",
"valkey",
)
@pytest.mark.min_server_version("6.0.0")
class TestACL:
Expand Down
1 change: 1 addition & 0 deletions tests/commands/test_bitmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"redis_cluster_blocking",
"redis_cluster_raw",
"keydb",
"valkey",
)
class TestBitmap:
async def test_bitcount(self, client, _s):
Expand Down
1 change: 1 addition & 0 deletions tests/commands/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ async def simple_library(client):
"redis_cluster_blocking",
"redis_cluster_raw",
"keydb",
"valkey",
)
@pytest.mark.min_server_version("7.0.0")
class TestFunctions:
Expand Down
7 changes: 7 additions & 0 deletions tests/commands/test_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"redis_cached_resp2",
"redis_cluster_cached",
"keydb",
"valkey",
)
class TestGeneric:
async def test_sort_basic(self, client, _s):
Expand Down Expand Up @@ -186,6 +187,7 @@ async def test_delete_with_multiple_keys(self, client, _s):
assert await client.get("b{foo}") is None

@pytest.mark.xfail
@pytest.mark.novalkey
async def test_dump_and_restore_with_ttl(self, client, _s):
await client.set("a", "foo")
dumped = await client.dump("a")
Expand Down Expand Up @@ -216,6 +218,7 @@ async def test_dump_and_restore_with_freq(self, client, _s):
freq_now = await client.object_freq("a")
assert freq + 1 == freq_now

@pytest.mark.novalkey
async def test_dump_and_restore_with_idle_time(self, client, _s):
await client.set("a", "foo")
idle = await client.object_idletime("a")
Expand All @@ -236,6 +239,7 @@ async def test_dump_and_restore_and_replace(self, client, _s):
assert await client.get("a") == _s("bar")

@pytest.mark.nocluster
@pytest.mark.novalkey
async def test_migrate_single_key_with_auth(self, client, redis_auth, _s):
auth_connection = await redis_auth.connection_pool.get_connection()
await client.set("a", "1")
Expand Down Expand Up @@ -312,6 +316,7 @@ async def test_migrate_single_key_with_auth(self, client, redis_auth, _s):
)

@pytest.mark.nocluster
@pytest.mark.novalkey
async def test_migrate_multiple_keys_with_auth(self, client, redis_auth, _s):
auth_connection = await redis_auth.connection_pool.get_connection()
await client.set("a", "1")
Expand Down Expand Up @@ -369,13 +374,15 @@ async def test_object_encoding_listpack(self, client, _s):
assert await client.object_encoding("a") == _s("embstr")
assert await client.object_encoding("b") == _s("listpack")

@pytest.mark.novalkey
async def test_object_freq(self, client, _s):
await client.set("a", "foo")
with pytest.raises(ResponseError):
await client.object_freq("a"),
await client.config_set({"maxmemory-policy": "allkeys-lfu"})
assert isinstance(await client.object_freq("a"), int)

@pytest.mark.novalkey
async def test_object_idletime(self, client, _s):
await client.set("a", "foo")
assert isinstance(await client.object_idletime("a"), int)
Expand Down
1 change: 1 addition & 0 deletions tests/commands/test_geo.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"redis_cluster_blocking",
"redis_cluster_raw",
"keydb",
"valkey",
)
class TestGeo:
async def test_geoadd(self, client, _s):
Expand Down
1 change: 1 addition & 0 deletions tests/commands/test_hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"redis_cluster_cached",
"keydb",
"dragonfly",
"valkey",
)
class TestHash:
async def test_hget_and_hset(self, client, _s):
Expand Down
1 change: 1 addition & 0 deletions tests/commands/test_hyperloglog.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"redis_cluster_blocking",
"redis_cluster_raw",
"keydb",
"valkey",
)
class TestHyperLogLog:
async def test_pfadd(self, client, _s):
Expand Down
1 change: 1 addition & 0 deletions tests/commands/test_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"redis_cluster_cached",
"keydb",
"dragonfly",
"valkey",
)
class TestList:
async def test_blpop(self, client, _s):
Expand Down
1 change: 1 addition & 0 deletions tests/commands/test_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"redis_cluster_cached",
"keydb",
"dragonfly",
"valkey",
)
class TestSet:
async def test_sadd(self, client, _s):
Expand Down
1 change: 1 addition & 0 deletions tests/commands/test_sorted_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"redis_cluster_cached",
"keydb",
"dragonfly",
"valkey",
)
class TestSortedSet:
async def test_zadd(self, client, _s):
Expand Down
1 change: 1 addition & 0 deletions tests/commands/test_streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ async def get_stream_message(client, stream, message_id):
"redis_cluster_blocking",
"redis_cluster_raw",
"keydb",
"valkey",
)
class TestStreams:
async def test_xadd_with_wrong_id(self, client, _s):
Expand Down
1 change: 1 addition & 0 deletions tests/commands/test_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"keydb",
"keydb_resp2",
"dragonfly",
"valkey",
)
class TestString:
async def test_append(self, client, _s):
Expand Down
35 changes: 35 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ async def get_version(client):

if "dragonfly_version" in client_info:
SERVER_TYPES[str(client)] = "dragonfly"
if "valkey" == client_info.get("server_name"):
SERVER_TYPES[str(client)] = "valkey"

version_string = client_info["redis_version"]
REDIS_VERSIONS[str(client)] = version.parse(version_string)
Expand Down Expand Up @@ -205,6 +207,9 @@ async def check_test_constraints(request, client, protocol=3):
):
return pytest.skip("Skipped for Dragonfly")

if marker.name == "novalkey" and SERVER_TYPES.get(str(client)) == "valkey":
return pytest.skip("Skipped for Valkey")

if marker.name == "nopypy" and PY_IMPLEMENTATION == "PyPy":
return pytest.skip("Skipped for PyPy")

Expand Down Expand Up @@ -473,6 +478,13 @@ def dragonfly_server(docker_services):
yield ["localhost", 11379]


@pytest.fixture(scope="session")
def valkey_server(docker_services):
docker_services.start("valkey")
docker_services.wait_for_service("valkey", 6379, ping_socket)
yield ["localhost", 12379]


@pytest.fixture(scope="session")
def keydb_cluster_server(docker_services):
docker_services.start("keydb-cluster-init")
Expand Down Expand Up @@ -1205,6 +1217,23 @@ async def dragonfly(dragonfly_server, request):
client.connection_pool.disconnect()


@pytest.fixture
async def valkey(valkey_server, request):
client = coredis.Redis(
"localhost",
12379,
decode_responses=True,
**get_client_test_args(request),
)
await client.flushall()
await check_test_constraints(request, client)
await set_default_test_config(client, variant="valkey")

yield client

client.connection_pool.disconnect()


@pytest.fixture(scope="session")
def docker_services_project_name():
return "coredis"
Expand Down Expand Up @@ -1328,5 +1357,11 @@ def pytest_collection_modifyitems(items):
item.add_marker(getattr(pytest.mark, "dragonfly"))
tokens = client_name.replace("dragonfly_", "").split("_")

for token in tokens:
item.add_marker(getattr(pytest.mark, token))
elif client_name.startswith("valkey"):
item.add_marker(getattr(pytest.mark, "valkey"))
tokens = client_name.replace("valkey_", "").split("_")

for token in tokens:
item.add_marker(getattr(pytest.mark, token))

0 comments on commit 6645b22

Please sign in to comment.