Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c05777a

Browse files
committedMay 9, 2025·
make sync test cases reusable for cluster
1 parent 524919c commit c05777a

File tree

8 files changed

+169
-1231
lines changed

8 files changed

+169
-1231
lines changed
 

‎tests/conftest.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1+
import copy
12
from collections.abc import Iterable
3+
from typing import cast
24

35
import pytest
46
import pytest_asyncio
7+
from pytest_django.fixtures import SettingsWrapper
58

69
from asgiref.compatibility import iscoroutinefunction
7-
from django.core.cache import cache as default_cache
10+
from django.core.cache import cache as default_cache, caches
811

912
from django_valkey.base import BaseValkeyCache
10-
13+
from django_valkey.cache import ValkeyCache
1114

1215
# for some reason `isawaitable` doesn't work here
1316
if iscoroutinefunction(default_cache.clear):
@@ -23,3 +26,20 @@ async def cache():
2326
def cache() -> Iterable[BaseValkeyCache]:
2427
yield default_cache
2528
default_cache.clear()
29+
30+
31+
@pytest.fixture
32+
def key_prefix_cache(
33+
cache: ValkeyCache, settings: SettingsWrapper
34+
) -> Iterable[ValkeyCache]:
35+
caches_setting = copy.deepcopy(settings.CACHES)
36+
caches_setting["default"]["KEY_PREFIX"] = "*"
37+
settings.CACHES = caches_setting
38+
yield cache
39+
40+
41+
@pytest.fixture
42+
def with_prefix_cache() -> Iterable[ValkeyCache]:
43+
with_prefix = cast(ValkeyCache, caches["with_prefix"])
44+
yield with_prefix
45+
with_prefix.clear()

‎tests/test_backend.py

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
from django_valkey.cache import ValkeyCache
1717
from django_valkey.client import ShardClient, herd
18+
from django_valkey.cluster_cache.client import DefaultClusterClient
1819
from django_valkey.serializers.json import JSONSerializer
1920
from django_valkey.serializers.msgpack import MSGPackSerializer
2021
from django_valkey.serializers.pickle import PickleSerializer
@@ -99,7 +100,7 @@ def test_unicode_keys(self, cache: ValkeyCache):
99100
res = cache.get("ключ")
100101
assert res == "value"
101102

102-
def test_save_and_integer(self, cache: ValkeyCache):
103+
def test_save_an_integer(self, cache: ValkeyCache):
103104
cache.set("test_key", 2)
104105
res = cache.get("test_key", "Foo")
105106

@@ -223,7 +224,9 @@ def test_get_many(self, cache: ValkeyCache):
223224
assert res == {"a": 1, "b": 2, "c": 3}
224225

225226
def test_mget(self, cache: ValkeyCache):
226-
if isinstance(cache.client, ShardClient):
227+
if isinstance(cache.client, ShardClient) or isinstance(
228+
cache.client, DefaultClusterClient
229+
):
227230
pytest.skip()
228231
cache.set("a", 1)
229232
cache.set("b", 2)
@@ -240,13 +243,28 @@ def test_get_many_unicode(self, cache: ValkeyCache):
240243
res = cache.get_many(["a", "ب", "c"])
241244
assert res == {"a": "1", "ب": "2", "c": "الف"}
242245

246+
def test_mget_unicode(self, cache: ValkeyCache):
247+
if isinstance(cache.client, ShardClient) or isinstance(
248+
cache.client, DefaultClusterClient
249+
):
250+
pytest.skip()
251+
252+
cache.set("fooa", "1")
253+
cache.set("fooب", "2")
254+
cache.set("fooc", "الف")
255+
256+
res = cache.mget(["fooa", "fooب", "fooc"])
257+
assert res == {"fooa": "1", "fooب": "2", "fooc": "الف"}
258+
243259
def test_set_many(self, cache: ValkeyCache):
244260
cache.set_many({"a": 1, "b": 2, "c": 3})
245261
res = cache.get_many(["a", "b", "c"])
246262
assert res == {"a": 1, "b": 2, "c": 3}
247263

248264
def test_mset(self, cache: ValkeyCache):
249-
if isinstance(cache.client, ShardClient):
265+
if isinstance(cache.client, ShardClient) or isinstance(
266+
cache.client, DefaultClusterClient
267+
):
250268
pytest.skip()
251269
cache.mset({"a": 1, "b": 2, "c": 3})
252270
res = cache.mget(["a", "b", "c"])
@@ -518,6 +536,9 @@ def test_ttl_incr_version_no_timeout(self, cache: ValkeyCache):
518536
assert my_value == "hello world!"
519537

520538
def test_delete_pattern(self, cache: ValkeyCache):
539+
if isinstance(cache.client, DefaultClusterClient):
540+
pytest.skip("cluster client has a specific test")
541+
521542
for key in ["foo-aa", "foo-ab", "foo-bb", "foo-bc"]:
522543
cache.set(key, "foo")
523544

@@ -532,6 +553,9 @@ def test_delete_pattern(self, cache: ValkeyCache):
532553

533554
@patch("django_valkey.cache.ValkeyCache.client")
534555
def test_delete_pattern_with_custom_count(self, client_mock, cache: ValkeyCache):
556+
if isinstance(cache.client, DefaultClusterClient):
557+
pytest.skip("cluster client has a specific test")
558+
535559
for key in ["foo-aa", "foo-ab", "foo-bb", "foo-bc"]:
536560
cache.set(key, "foo")
537561

@@ -547,6 +571,9 @@ def test_delete_pattern_with_settings_default_scan_count(
547571
cache: ValkeyCache,
548572
settings: SettingsWrapper,
549573
):
574+
if isinstance(cache.client, DefaultClusterClient):
575+
pytest.skip("cluster client has a specific test")
576+
550577
for key in ["foo-aa", "foo-ab", "foo-bb", "foo-bc"]:
551578
cache.set(key, "foo")
552579
expected_count = settings.DJANGO_VALKEY_SCAN_ITERSIZE
@@ -715,6 +742,11 @@ def test_lock(self, cache: ValkeyCache):
715742
lock.release()
716743
assert not cache.has_key("foobar")
717744

745+
def test_lock_context_manager(self, cache: ValkeyCache):
746+
with cache.lock("foobar"):
747+
assert cache.has_key("foobar")
748+
assert not cache.has_key("foobar")
749+
718750
def test_lock_released_by_thread(self, cache: ValkeyCache):
719751
lock = cache.lock("foobar", thread_local=False)
720752
lock.acquire(blocking=True)
@@ -918,6 +950,9 @@ def test_sdiff(self, cache: ValkeyCache):
918950
if isinstance(cache.client, ShardClient):
919951
pytest.skip("ShardClient doesn't support sdiff")
920952

953+
if isinstance(cache.client, DefaultClusterClient):
954+
pytest.skip("cluster client has a specific test")
955+
921956
cache.sadd("foo1", "bar1", "bar2")
922957
cache.sadd("foo2", "bar2", "bar3")
923958
assert cache.sdiff("foo1", "foo2") == {"bar1"}
@@ -926,6 +961,9 @@ def test_sdiffstore(self, cache: ValkeyCache):
926961
if isinstance(cache.client, ShardClient):
927962
pytest.skip("ShardClient doesn't support sdiffstore")
928963

964+
if isinstance(cache.client, DefaultClusterClient):
965+
pytest.skip("cluster client has a specific test")
966+
929967
cache.sadd("foo1", "bar1", "bar2")
930968
cache.sadd("foo2", "bar2", "bar3")
931969
assert cache.sdiffstore("foo3", "foo1", "foo2") == 1
@@ -935,6 +973,9 @@ def test_sdiffstore_with_keys_version(self, cache: ValkeyCache):
935973
if isinstance(cache.client, ShardClient):
936974
pytest.skip("ShardClient doesn't support sdiffstore")
937975

976+
if isinstance(cache.client, DefaultClusterClient):
977+
pytest.skip("cluster client has a specific test")
978+
938979
cache.sadd("foo1", "bar1", "bar2", version=2)
939980
cache.sadd("foo2", "bar2", "bar3", version=2)
940981
assert cache.sdiffstore("foo3", "foo1", "foo2", version_keys=2) == 1
@@ -946,6 +987,9 @@ def test_sdiffstore_with_different_keys_versions_without_initial_set_in_version(
946987
if isinstance(cache.client, ShardClient):
947988
pytest.skip("ShardClient doesn't support sdiffstore")
948989

990+
if isinstance(cache.client, DefaultClusterClient):
991+
pytest.skip("cluster client has a specific test")
992+
949993
cache.sadd("foo1", "bar1", "bar2", version=1)
950994
cache.sadd("foo2", "bar2", "bar3", version=2)
951995
assert cache.sdiffstore("foo3", "foo1", "foo2", version_keys=2) == 0
@@ -956,6 +1000,9 @@ def test_sdiffstore_with_different_keys_versions_with_initial_set_in_version(
9561000
if isinstance(cache.client, ShardClient):
9571001
pytest.skip("ShardClient doesn't support sdiffstore")
9581002

1003+
if isinstance(cache.client, DefaultClusterClient):
1004+
pytest.skip("cluster client has a specific test")
1005+
9591006
cache.sadd("foo1", "bar1", "bar2", version=2)
9601007
cache.sadd("foo2", "bar2", "bar3", version=1)
9611008
assert cache.sdiffstore("foo3", "foo1", "foo2", version_keys=2) == 2
@@ -964,14 +1011,20 @@ def test_sinter(self, cache: ValkeyCache):
9641011
if isinstance(cache.client, ShardClient):
9651012
pytest.skip("ShardClient doesn't support sinter")
9661013

1014+
if isinstance(cache.client, DefaultClusterClient):
1015+
pytest.skip("cluster client has a specific test")
1016+
9671017
cache.sadd("foo1", "bar1", "bar2")
9681018
cache.sadd("foo2", "bar2", "bar3")
9691019
assert cache.sinter("foo1", "foo2") == {"bar2"}
9701020

971-
def test_interstore(self, cache: ValkeyCache):
1021+
def test_sinterstore(self, cache: ValkeyCache):
9721022
if isinstance(cache.client, ShardClient):
9731023
pytest.skip("ShardClient doesn't support sinterstore")
9741024

1025+
if isinstance(cache.client, DefaultClusterClient):
1026+
pytest.skip("cluster client has a specific test")
1027+
9751028
cache.sadd("foo1", "bar1", "bar2")
9761029
cache.sadd("foo2", "bar2", "bar3")
9771030
assert cache.sinterstore("foo3", "foo1", "foo2") == 1
@@ -1066,6 +1119,9 @@ def test_smove(self, cache: ValkeyCache):
10661119
# if isinstance(cache.client, ShardClient):
10671120
# pytest.skip("ShardClient doesn't support get_client")
10681121

1122+
if isinstance(cache.client, DefaultClusterClient):
1123+
pytest.skip("cluster client has a specific test")
1124+
10691125
cache.sadd("foo1", "bar1", "bar2")
10701126
cache.sadd("foo2", "bar2", "bar3")
10711127
assert cache.smove("foo1", "foo2", "bar1") is True
@@ -1130,6 +1186,9 @@ def test_sunion(self, cache: ValkeyCache):
11301186
if isinstance(cache.client, ShardClient):
11311187
pytest.skip("ShardClient doesn't support sunion")
11321188

1189+
if isinstance(cache.client, DefaultClusterClient):
1190+
pytest.skip("cluster client has a specific test")
1191+
11331192
cache.sadd("foo1", "bar1", "bar2")
11341193
cache.sadd("foo2", "bar2", "bar3")
11351194
assert cache.sunion("foo1", "foo2") == {"bar1", "bar2", "bar3"}
@@ -1138,6 +1197,9 @@ def test_sunionstore(self, cache: ValkeyCache):
11381197
if isinstance(cache.client, ShardClient):
11391198
pytest.skip("ShardClient doesn't support sunionstore")
11401199

1200+
if isinstance(cache.client, DefaultClusterClient):
1201+
pytest.skip("cluster client has a specific test")
1202+
11411203
cache.sadd("foo1", "bar1", "bar2")
11421204
cache.sadd("foo2", "bar2", "bar3")
11431205
assert cache.sunionstore("foo3", "foo1", "foo2") == 3

‎tests/test_cache_options.py

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import copy
2-
from collections.abc import Iterable
32
from typing import cast
43

54
import pytest
6-
from django.core.cache import caches
75
from pytest import LogCaptureFixture
86
from pytest_django.fixtures import SettingsWrapper
7+
8+
from django.core.cache import caches, cache as default_cache
9+
910
from valkey.exceptions import ConnectionError
1011

1112
from django_valkey.cache import ValkeyCache
1213
from django_valkey.client import ShardClient
14+
from django_valkey.cluster_cache.client import DefaultClusterClient
1315

1416

1517
def make_key(key: str, prefix: str, version: str) -> str:
@@ -31,13 +33,21 @@ def ignore_exceptions_cache(settings: SettingsWrapper) -> ValkeyCache:
3133
return cast(ValkeyCache, caches["doesnotexist"])
3234

3335

36+
@pytest.mark.skipif(
37+
isinstance(default_cache.client, DefaultClusterClient),
38+
reason="cluster client doesn't support ignore exception",
39+
)
3440
def test_get_django_omit_exceptions_many_returns_default_arg(
3541
ignore_exceptions_cache: ValkeyCache,
3642
):
3743
assert ignore_exceptions_cache._ignore_exceptions is True
3844
assert ignore_exceptions_cache.get_many(["key1", "key2", "key3"]) == {}
3945

4046

47+
@pytest.mark.skipif(
48+
isinstance(default_cache.client, DefaultClusterClient),
49+
reason="cluster client doesn't support ignore exception",
50+
)
4151
def test_get_django_omit_exceptions(
4252
caplog: LogCaptureFixture, ignore_exceptions_cache: ValkeyCache
4353
):
@@ -55,6 +65,10 @@ def test_get_django_omit_exceptions(
5565
)
5666

5767

68+
@pytest.mark.skipif(
69+
isinstance(default_cache.client, DefaultClusterClient),
70+
reason="cluster client doesn't support ignore exception",
71+
)
5872
def test_get_django_omit_exceptions_priority_1(settings: SettingsWrapper):
5973
caches_setting = copy.deepcopy(settings.CACHES)
6074
caches_setting["doesnotexist"]["OPTIONS"]["IGNORE_EXCEPTIONS"] = True
@@ -65,6 +79,10 @@ def test_get_django_omit_exceptions_priority_1(settings: SettingsWrapper):
6579
assert cache.get("key") is None
6680

6781

82+
@pytest.mark.skipif(
83+
isinstance(default_cache.client, DefaultClusterClient),
84+
reason="cluster client doesn't support ignore exception",
85+
)
6886
def test_get_django_omit_exceptions_priority_2(settings: SettingsWrapper):
6987
caches_setting = copy.deepcopy(settings.CACHES)
7088
caches_setting["doesnotexist"]["OPTIONS"]["IGNORE_EXCEPTIONS"] = False
@@ -76,23 +94,6 @@ def test_get_django_omit_exceptions_priority_2(settings: SettingsWrapper):
7694
cache.get("key")
7795

7896

79-
@pytest.fixture
80-
def key_prefix_cache(
81-
cache: ValkeyCache, settings: SettingsWrapper
82-
) -> Iterable[ValkeyCache]:
83-
caches_setting = copy.deepcopy(settings.CACHES)
84-
caches_setting["default"]["KEY_PREFIX"] = "*"
85-
settings.CACHES = caches_setting
86-
yield cache
87-
88-
89-
@pytest.fixture
90-
def with_prefix_cache() -> Iterable[ValkeyCache]:
91-
with_prefix = cast(ValkeyCache, caches["with_prefix"])
92-
yield with_prefix
93-
with_prefix.clear()
94-
95-
9697
class TestDjangoValkeyCacheEscapePrefix:
9798
def test_delete_pattern(
9899
self, key_prefix_cache: ValkeyCache, with_prefix_cache: ValkeyCache
@@ -113,6 +114,10 @@ def test_iter_keys(
113114
with_prefix_cache.set("b", "2")
114115
assert list(key_prefix_cache.iter_keys("*")) == ["a"]
115116

117+
@pytest.mark.skipif(
118+
isinstance(default_cache.client, DefaultClusterClient),
119+
reason="cluster client doesn't support ignore exception",
120+
)
116121
def test_keys(self, key_prefix_cache: ValkeyCache, with_prefix_cache: ValkeyCache):
117122
key_prefix_cache.set("a", "1")
118123
with_prefix_cache.set("b", "2")
@@ -121,6 +126,10 @@ def test_keys(self, key_prefix_cache: ValkeyCache, with_prefix_cache: ValkeyCach
121126
assert "b" not in keys
122127

123128

129+
@pytest.mark.skipif(
130+
isinstance(default_cache.client, DefaultClusterClient),
131+
reason="cluster client doesn't support ignore exception",
132+
)
124133
def test_custom_key_function(cache: ValkeyCache, settings: SettingsWrapper):
125134
caches_setting = copy.deepcopy(settings.CACHES)
126135
caches_setting["default"]["KEY_FUNCTION"] = "tests.test_cache_options.make_key"

‎tests/test_client.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
from unittest.mock import Mock, call, patch
33

44
import pytest
5-
from django.core.cache import DEFAULT_CACHE_ALIAS
65
from pytest_django.fixtures import SettingsWrapper
76
from pytest_mock import MockerFixture
87

8+
from django.core.cache import DEFAULT_CACHE_ALIAS, cache as default_cache
9+
910
from django_valkey.cache import ValkeyCache
1011
from django_valkey.client import DefaultClient, ShardClient
1112

@@ -58,9 +59,12 @@ def test_close_disconnect_client_options(
5859
assert mock.called
5960

6061

62+
@pytest.mark.skipif(
63+
not isinstance(default_cache.client, DefaultClient), reason="shard only test"
64+
)
6165
class TestDefaultClient:
62-
@patch("tests.test_client.DefaultClient.get_client")
63-
@patch("tests.test_client.DefaultClient.__init__", return_value=None)
66+
@patch("django_valkey.base_client.ClientCommands.get_client")
67+
@patch("django_valkey.base_client.BaseClient.__init__", return_value=None)
6468
def test_delete_pattern_calls_get_client_given_no_client(
6569
self, init_mock, get_client_mock
6670
):
@@ -71,9 +75,9 @@ def test_delete_pattern_calls_get_client_given_no_client(
7175
client.delete_pattern(pattern="foo*")
7276
get_client_mock.assert_called_once_with(write=True, tried=None)
7377

74-
@patch("tests.test_client.DefaultClient.make_pattern")
75-
@patch("tests.test_client.DefaultClient.get_client", return_value=Mock())
76-
@patch("tests.test_client.DefaultClient.__init__", return_value=None)
78+
@patch("django_valkey.base_client.BaseClient.make_pattern")
79+
@patch("django_valkey.base_client.ClientCommands.get_client", return_value=Mock())
80+
@patch("django_valkey.base_client.BaseClient.__init__", return_value=None)
7781
def test_delete_pattern_calls_make_pattern(
7882
self, init_mock, get_client_mock, make_pattern_mock
7983
):
@@ -87,9 +91,9 @@ def test_delete_pattern_calls_make_pattern(
8791
kwargs = {"version": None, "prefix": None}
8892
make_pattern_mock.assert_called_once_with("foo*", **kwargs)
8993

90-
@patch("tests.test_client.DefaultClient.make_pattern")
91-
@patch("tests.test_client.DefaultClient.get_client", return_value=Mock())
92-
@patch("tests.test_client.DefaultClient.__init__", return_value=None)
94+
@patch("django_valkey.base_client.BaseClient.make_pattern")
95+
@patch("django_valkey.base_client.ClientCommands.get_client", return_value=Mock())
96+
@patch("django_valkey.base_client.BaseClient.__init__", return_value=None)
9397
def test_delete_pattern_calls_scan_iter_with_count_if_itersize_given(
9498
self, init_mock, get_client_mock, make_pattern_mock
9599
):
@@ -104,9 +108,9 @@ def test_delete_pattern_calls_scan_iter_with_count_if_itersize_given(
104108
count=90210, match=make_pattern_mock.return_value
105109
)
106110

107-
@patch("tests.test_client.DefaultClient.make_pattern")
108-
@patch("tests.test_client.DefaultClient.get_client", return_value=Mock())
109-
@patch("tests.test_client.DefaultClient.__init__", return_value=None)
111+
@patch("django_valkey.base_client.BaseClient.make_pattern")
112+
@patch("django_valkey.base_client.ClientCommands.get_client", return_value=Mock())
113+
@patch("django_valkey.base_client.BaseClient.__init__", return_value=None)
110114
def test_delete_pattern_calls_pipeline_delete_and_execute(
111115
self, init_mock, get_client_mock, make_pattern_mock
112116
):
@@ -127,6 +131,9 @@ def test_delete_pattern_calls_pipeline_delete_and_execute(
127131
get_client_mock.return_value.pipeline.return_value.execute.assert_called_once()
128132

129133

134+
@pytest.mark.skipif(
135+
not isinstance(default_cache.client, ShardClient), reason="shard only test"
136+
)
130137
class TestShardClient:
131138
CLIENT_METHODS_FOR_MOCK = {
132139
"add",
@@ -166,8 +173,8 @@ def connection(self, mocker):
166173

167174
yield connection
168175

169-
@patch("tests.test_client.ShardClient.make_pattern")
170-
@patch("tests.test_client.ShardClient.__init__", return_value=None)
176+
@patch("django_valkey.base_client.BaseClient.make_pattern")
177+
@patch("django_valkey.client.sharded.ShardClient.__init__", return_value=None)
171178
def test_delete_pattern_calls_scan_iter_with_count_if_itersize_given(
172179
self,
173180
init_mock,

‎tests/test_session.py

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,12 @@
33
from datetime import timedelta
44
from typing import Optional, Type
55

6-
import django
7-
import pytest
86
from django.conf import settings
97
from django.contrib.sessions.backends.base import SessionBase
108
from django.contrib.sessions.backends.cache import SessionStore as CacheSession
11-
from django.core.cache import DEFAULT_CACHE_ALIAS, caches
129
from django.test import override_settings
1310
from django.utils import timezone
1411

15-
from django_valkey.serializers.msgpack import MSGPackSerializer
1612

1713
SessionType = Type[SessionBase]
1814

@@ -304,27 +300,23 @@ def test_decode_failure_logged_to_security(self):
304300
self.assertIn("corrupted", cm.output[0])
305301

306302
def test_actual_expiry(self):
307-
# this doesn't work with JSONSerializer (serializing timedelta)
308-
with override_settings(
309-
SESSION_SERIALIZER="django.contrib.sessions.serializers.PickleSerializer"
310-
):
311-
self.session = self.backend() # reinitialize after overriding settings
312-
313-
# Regression test for #19200
314-
old_session_key = None
315-
new_session_key = None
316-
try:
317-
self.session["foo"] = "bar"
318-
self.session.set_expiry(-timedelta(seconds=10))
319-
self.session.save()
320-
old_session_key = self.session.session_key
321-
# With an expiry date in the past, the session expires instantly.
322-
new_session = self.backend(self.session.session_key)
323-
new_session_key = new_session.session_key
324-
self.assertNotIn("foo", new_session)
325-
finally:
326-
self.session.delete(old_session_key)
327-
self.session.delete(new_session_key)
303+
self.session = self.backend() # reinitialize after overriding settings
304+
305+
# Regression test for #19200
306+
old_session_key = None
307+
new_session_key = None
308+
try:
309+
self.session["foo"] = "bar"
310+
self.session.set_expiry(-timedelta(seconds=10))
311+
self.session.save()
312+
old_session_key = self.session.session_key
313+
# With an expiry date in the past, the session expires instantly.
314+
new_session = self.backend(self.session.session_key)
315+
new_session_key = new_session.session_key
316+
self.assertNotIn("foo", new_session)
317+
finally:
318+
self.session.delete(old_session_key)
319+
self.session.delete(new_session_key)
328320

329321
def test_session_load_does_not_create_record(self):
330322
"""
@@ -366,14 +358,3 @@ def test_session_save_does_not_resurrect_session_logged_out_in_other_context(sel
366358

367359
class SessionTests(SessionTestsMixin, unittest.TestCase):
368360
backend = CacheSession
369-
370-
@pytest.mark.skipif(
371-
django.VERSION >= (4, 2),
372-
reason="PickleSerializer is removed as of https://code.djangoproject.com/ticket/29708",
373-
)
374-
def test_actual_expiry(self):
375-
if isinstance(
376-
caches[DEFAULT_CACHE_ALIAS].client._serializer, MSGPackSerializer
377-
):
378-
self.skipTest("msgpack serializer doesn't support datetime serialization")
379-
super().test_actual_expiry()

‎tests/tests_cluster/test_backend.py

Lines changed: 1 addition & 972 deletions
Large diffs are not rendered by default.

‎tests/tests_cluster/test_cache_options.py

Lines changed: 3 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,17 @@
11
import copy
2-
from collections.abc import Iterable
3-
from typing import cast
42

5-
import pytest
6-
from django.core.cache import caches
73
from pytest_django.fixtures import SettingsWrapper
4+
85
from valkey import ValkeyCluster
96

10-
from django_valkey.cache import ValkeyCache
117
from django_valkey.cluster_cache.cache import ClusterValkeyCache
128

139

14-
def make_key(key: str, prefix: str, version: str) -> str:
15-
return f"{prefix}#{version}#{key}"
16-
17-
18-
def reverse_key(key: str) -> str:
19-
return key.split("#", 2)[2]
20-
21-
22-
# TODO: cluster doesn't ignore exceptions, see if there's a fix
23-
# @pytest.fixture
24-
# def ignore_exceptions_cache(settings: SettingsWrapper) -> ValkeyCache:
25-
# caches_setting = copy.deepcopy(settings.CACHES)
26-
# caches_setting["doesnotexist"]["OPTIONS"]["IGNORE_EXCEPTIONS"] = True
27-
# caches_setting["doesnotexist"]["OPTIONS"]["LOG_IGNORED_EXCEPTIONS"] = True
28-
# settings.CACHES = caches_setting
29-
# settings.DJANGO_VALKEY_IGNORE_EXCEPTIONS = True
30-
# settings.DJANGO_VALKEY_LOG_IGNORED_EXCEPTIONS = True
31-
# return cast(ValkeyCache, caches["doesnotexist"])
32-
33-
34-
# def test_get_django_omit_exceptions_many_returns_default_arg(
35-
# ignore_exceptions_cache: ValkeyCache,
36-
# ):
37-
# assert ignore_exceptions_cache._ignore_exceptions is True
38-
# assert ignore_exceptions_cache.get_many(["key1", "key2", "key3"]) == {}
39-
40-
41-
# def test_get_django_omit_exceptions(
42-
# caplog: LogCaptureFixture, ignore_exceptions_cache: ValkeyCache
43-
# ):
44-
# assert ignore_exceptions_cache._ignore_exceptions is True
45-
# assert ignore_exceptions_cache._log_ignored_exceptions is True
46-
#
47-
# assert ignore_exceptions_cache.get("key") is None
48-
# assert ignore_exceptions_cache.get("key", "default") == "default"
49-
# assert ignore_exceptions_cache.get("key", default="default") == "default"
50-
#
51-
# assert len(caplog.records) == 3
52-
# assert all(
53-
# record.levelname == "ERROR" and record.msg == "Exception ignored"
54-
# for record in caplog.records
55-
# )
56-
#
57-
#
58-
# def test_get_django_omit_exceptions_priority_1(settings: SettingsWrapper):
59-
# caches_setting = copy.deepcopy(settings.CACHES)
60-
# caches_setting["doesnotexist"]["OPTIONS"]["IGNORE_EXCEPTIONS"] = True
61-
# settings.CACHES = caches_setting
62-
# settings.DJANGO_VALKEY_IGNORE_EXCEPTIONS = False
63-
# cache = cast(ValkeyCache, caches["doesnotexist"])
64-
# assert cache._ignore_exceptions is True
65-
# assert cache.get("key") is None
66-
#
67-
#
68-
# def test_get_django_omit_exceptions_priority_2(settings: SettingsWrapper):
69-
# caches_setting = copy.deepcopy(settings.CACHES)
70-
# caches_setting["doesnotexist"]["OPTIONS"]["IGNORE_EXCEPTIONS"] = False
71-
# settings.CACHES = caches_setting
72-
# settings.DJANGO_VALKEY_IGNORE_EXCEPTIONS = True
73-
# cache = cast(ValkeyCache, caches["doesnotexist"])
74-
# assert cache._ignore_exceptions is False
75-
# with pytest.raises(ConnectionError):
76-
# cache.get("key")
77-
78-
79-
@pytest.fixture
80-
def key_prefix_cache(
81-
cache: ValkeyCache, settings: SettingsWrapper
82-
) -> Iterable[ClusterValkeyCache]:
83-
caches_setting = copy.deepcopy(settings.CACHES)
84-
caches_setting["default"]["KEY_PREFIX"] = "*"
85-
settings.CACHES = caches_setting
86-
yield cache
87-
88-
89-
@pytest.fixture
90-
def with_prefix_cache() -> Iterable[ClusterValkeyCache]:
91-
with_prefix = cast(ClusterValkeyCache, caches["with_prefix"])
92-
yield with_prefix
93-
with_prefix.clear()
94-
95-
9610
class TestDjangoValkeyCacheEscapePrefix:
97-
def test_delete_pattern(
98-
self,
99-
key_prefix_cache: ClusterValkeyCache,
100-
with_prefix_cache: ClusterValkeyCache,
101-
):
102-
key_prefix_cache.set("a", "1")
103-
with_prefix_cache.set("b", "2")
104-
key_prefix_cache.delete_pattern("*")
105-
assert key_prefix_cache.has_key("a") is False
106-
assert with_prefix_cache.get("b") == "2"
107-
108-
def test_iter_keys(
109-
self,
110-
key_prefix_cache: ClusterValkeyCache,
111-
with_prefix_cache: ClusterValkeyCache,
112-
):
113-
key_prefix_cache.set("a", "1")
114-
with_prefix_cache.set("b", "2")
115-
assert list(key_prefix_cache.iter_keys("*")) == ["a"]
116-
11711
def test_keys(
11812
self,
119-
key_prefix_cache: ClusterValkeyCache,
120-
with_prefix_cache: ClusterValkeyCache,
13+
key_prefix_cache: ClusterValkeyCache, # noqa: F811
14+
with_prefix_cache: ClusterValkeyCache, # noqa: F811
12115
):
12216
key_prefix_cache.set("a", "1")
12317
with_prefix_cache.set("b", "2")

‎tests/tests_cluster/test_client.py

Lines changed: 11 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
from unittest.mock import Mock, call, patch
33

44
import pytest
5-
from django.core.cache import DEFAULT_CACHE_ALIAS
6-
from pytest_django.fixtures import SettingsWrapper
7-
from pytest_mock import MockerFixture
85

96
from django_valkey.cluster_cache.cache import ClusterValkeyCache
107
from django_valkey.cluster_cache.client import DefaultClusterClient
@@ -18,52 +15,9 @@ def cache_client(cache: ClusterValkeyCache) -> Iterable[DefaultClusterClient]:
1815
client.delete("TestClientClose")
1916

2017

21-
class TestClientClose:
22-
def test_close_client_disconnect_default(
23-
self, cache_client: DefaultClusterClient, mocker: MockerFixture
24-
):
25-
mock = mocker.patch.object(cache_client.connection_factory, "disconnect")
26-
cache_client.close()
27-
assert not mock.called
28-
29-
def test_close_disconnect_settings(
30-
self,
31-
cache_client: DefaultClusterClient,
32-
settings: SettingsWrapper,
33-
mocker: MockerFixture,
34-
):
35-
settings.DJANGO_VALKEY_CLOSE_CONNECTION = True
36-
mock = mocker.patch.object(cache_client.connection_factory, "disconnect")
37-
cache_client.close()
38-
assert mock.called
39-
40-
def test_close_disconnect_settings_cache(
41-
self,
42-
cache_client: DefaultClusterClient,
43-
mocker: MockerFixture,
44-
settings: SettingsWrapper,
45-
):
46-
settings.CACHES[DEFAULT_CACHE_ALIAS]["OPTIONS"]["CLOSE_CONNECTION"] = True
47-
cache_client.set("TestClientClose", 0)
48-
mock = mocker.patch.object(cache_client.connection_factory, "disconnect")
49-
cache_client.close()
50-
assert mock.called
51-
52-
def test_close_disconnect_client_options(
53-
self, cache_client: DefaultClusterClient, mocker: MockerFixture
54-
):
55-
cache_client._options["CLOSE_CONNECTION"] = True
56-
mock = mocker.patch.object(cache_client.connection_factory, "disconnect")
57-
cache_client.close()
58-
assert mock.called
59-
60-
6118
class TestDefaultClusterClient:
62-
@patch("tests.tests_cluster.test_client.DefaultClusterClient.get_client")
63-
@patch(
64-
"tests.tests_cluster.test_client.DefaultClusterClient.__init__",
65-
return_value=None,
66-
)
19+
@patch("django_valkey.base_client.ClientCommands.get_client")
20+
@patch("django_valkey.base_client.BaseClient.__init__", return_value=None)
6721
def test_delete_pattern_calls_get_client_given_no_client(
6822
self, init_mock, get_client_mock
6923
):
@@ -74,15 +28,9 @@ def test_delete_pattern_calls_get_client_given_no_client(
7428
client.delete_pattern(pattern="{foo}*")
7529
get_client_mock.assert_called_once_with(write=True, tried=None)
7630

77-
@patch("tests.tests_cluster.test_client.DefaultClusterClient.make_pattern")
78-
@patch(
79-
"tests.tests_cluster.test_client.DefaultClusterClient.get_client",
80-
return_value=Mock(),
81-
)
82-
@patch(
83-
"tests.tests_cluster.test_client.DefaultClusterClient.__init__",
84-
return_value=None,
85-
)
31+
@patch("django_valkey.base_client.BaseClient.make_pattern")
32+
@patch("django_valkey.base_client.ClientCommands.get_client", return_value=Mock())
33+
@patch("django_valkey.base_client.BaseClient.__init__", return_value=None)
8634
def test_delete_pattern_calls_make_pattern(
8735
self, init_mock, get_client_mock, make_pattern_mock
8836
):
@@ -96,15 +44,9 @@ def test_delete_pattern_calls_make_pattern(
9644
kwargs = {"version": None, "prefix": None}
9745
make_pattern_mock.assert_called_once_with("{foo}*", **kwargs)
9846

99-
@patch("tests.tests_cluster.test_client.DefaultClusterClient.make_pattern")
100-
@patch(
101-
"tests.tests_cluster.test_client.DefaultClusterClient.get_client",
102-
return_value=Mock(),
103-
)
104-
@patch(
105-
"tests.tests_cluster.test_client.DefaultClusterClient.__init__",
106-
return_value=None,
107-
)
47+
@patch("django_valkey.base_client.BaseClient.make_pattern")
48+
@patch("django_valkey.base_client.ClientCommands.get_client", return_value=Mock())
49+
@patch("django_valkey.base_client.BaseClient.__init__", return_value=None)
10850
def test_delete_pattern_calls_scan_iter_with_count_if_itersize_given(
10951
self, init_mock, get_client_mock, make_pattern_mock
11052
):
@@ -119,15 +61,9 @@ def test_delete_pattern_calls_scan_iter_with_count_if_itersize_given(
11961
count=90210, match=make_pattern_mock.return_value
12062
)
12163

122-
@patch("tests.tests_cluster.test_client.DefaultClusterClient.make_pattern")
123-
@patch(
124-
"tests.tests_cluster.test_client.DefaultClusterClient.get_client",
125-
return_value=Mock(),
126-
)
127-
@patch(
128-
"tests.tests_cluster.test_client.DefaultClusterClient.__init__",
129-
return_value=None,
130-
)
64+
@patch("django_valkey.base_client.BaseClient.make_pattern")
65+
@patch("django_valkey.base_client.ClientCommands.get_client", return_value=Mock())
66+
@patch("django_valkey.base_client.BaseClient.__init__", return_value=None)
13167
def test_delete_pattern_calls_pipeline_delete_and_execute(
13268
self, init_mock, get_client_mock, make_pattern_mock
13369
):

0 commit comments

Comments
 (0)
Please sign in to comment.