1
- from unittest .mock import ANY , AsyncMock , create_autospec , patch
1
+ from unittest .mock import ANY , AsyncMock , patch
2
2
3
3
import pytest
4
4
5
- from glide import Transaction , Script
5
+ from glide import ConditionalChange , ExpirySet , ExpiryType , Transaction , Script
6
6
from glide .exceptions import RequestError
7
7
8
8
from aiocache .backends .valkey import ValkeyBackend , ValkeyCache
@@ -30,20 +30,12 @@ def valkey(valkey_client):
30
30
):
31
31
setattr (m , method , AsyncMock (return_value = None , spec_set = ()))
32
32
m .mget = AsyncMock (return_value = [None ], spec_set = ())
33
- m .set = AsyncMock (return_value = True , spec_set = ())
33
+ m .set = AsyncMock (return_value = "OK" , spec_set = ())
34
34
35
35
yield valkey
36
36
37
37
38
38
class TestValkeyBackend :
39
- # async def test_valkey_backend_requires_client_decode_responses(self, valkey_client):
40
- # with pytest.raises(ValueError) as ve:
41
- # ValkeyBackend(client=valkey_client)
42
- #
43
- # assert str(ve.value) == (
44
- # "valkey client must be constructed with decode_responses set to False"
45
- # )
46
-
47
39
async def test_get (self , valkey ):
48
40
valkey .client .get .return_value = b"value"
49
41
assert await valkey ._get (Keys .KEY ) == "value"
@@ -62,54 +54,68 @@ async def test_set(self, valkey):
62
54
valkey .client .set .assert_called_once
63
55
64
56
async def test_set_cas_token (self , mocker , valkey ):
65
- mocker .spy (valkey , "_cas" )
66
- await valkey ._set (Keys .KEY , "value" , _cas_token = "old_value" , _conn = valkey .client )
57
+ mocker .patch .object (valkey , "_cas" )
58
+ await valkey ._set (
59
+ Keys .KEY , "value" , _cas_token = "old_value" , _conn = valkey .client
60
+ )
67
61
valkey ._cas .assert_called_with (
68
62
Keys .KEY , "value" , "old_value" , ttl = None , _conn = valkey .client
69
63
)
70
64
71
65
async def test_cas (self , mocker , valkey ):
72
- mocker .spy (valkey , "_script" )
66
+ mocker .spy (valkey , "_get" )
67
+ mocker .spy (valkey , "_cas" )
73
68
await valkey ._cas (Keys .KEY , "value" , "old_value" , ttl = 10 , _conn = valkey .client )
74
- valkey ._script .assert_called_with (
75
- valkey .CAS_SCRIPT ,
76
- * [[Keys .KEY ], "value" , "old_value" , "EX" , "10" ],
77
- )
69
+ valkey ._get .assert_called_with (Keys .KEY )
70
+ assert valkey ._cas .spy_return == 0
78
71
79
72
async def test_cas_float_ttl (self , mocker , valkey ):
80
- mocker .spy (valkey , "_script " )
73
+ spy = mocker .spy (valkey , "_get " )
81
74
await valkey ._cas (Keys .KEY , "value" , "old_value" , ttl = 0.1 , _conn = valkey .client )
82
- valkey ._script .assert_called_with (
83
- valkey .CAS_SCRIPT ,
84
- * [[Keys .KEY ], "value" , "old_value" , "PX" , "100" ],
85
- )
75
+ spy .assert_called_with (Keys .KEY )
76
+ mocker .stop (spy )
77
+ mock = mocker .patch .object (valkey , "_get" , return_value = "old_value" )
78
+ await valkey ._cas (Keys .KEY , "value" , "old_value" , ttl = 0.1 , _conn = valkey .client )
79
+ mock .assert_called_once ()
80
+ valkey .client .set .assert_called_with (Keys .KEY , "value" , expiry = 0.1 )
86
81
87
82
async def test_multi_get (self , valkey ):
88
83
await valkey ._multi_get ([Keys .KEY , Keys .KEY_1 ])
89
- valkey .client .mget .assert_called_with (Keys .KEY , Keys .KEY_1 )
84
+ valkey .client .mget .assert_called_with ([ Keys .KEY , Keys .KEY_1 ] )
90
85
91
86
async def test_multi_set (self , valkey ):
92
87
await valkey ._multi_set ([(Keys .KEY , "value" ), (Keys .KEY_1 , "random" )])
93
88
valkey .client .mset .assert_called_with ({Keys .KEY : "value" , Keys .KEY_1 : "random" })
94
89
95
90
async def test_multi_set_with_ttl (self , valkey , mocker ):
96
- spy_mset = mocker .spy (Transaction , "mset" )
97
- spy_expire = mocker .spy (Transaction , "expire" )
91
+ mock_mset = mocker .patch . object (Transaction , "mset" )
92
+ mock_expire = mocker .patch . object (Transaction , "expire" )
98
93
await valkey ._multi_set ([(Keys .KEY , "value" ), (Keys .KEY_1 , "random" )], ttl = 1 )
99
94
100
95
valkey .client .exec .assert_called ()
101
96
102
- assert spy_mset .call_count == 1
103
- assert spy_expire .call_count == 2
104
- spy_expire .assert_any_call (valkey . client . exec . call_args . args [ 0 ], Keys .KEY , 1 )
105
- spy_expire .assert_any_call (valkey . client . exec . call_args . args [ 0 ], Keys .KEY_1 , 1 )
97
+ assert mock_mset .call_count == 1
98
+ assert mock_expire .call_count == 2
99
+ mock_expire .assert_any_call (Keys .KEY , 1 )
100
+ mock_expire .assert_any_call (Keys .KEY_1 , 1 )
106
101
107
102
async def test_add (self , valkey ):
108
103
await valkey ._add (Keys .KEY , "value" )
109
- valkey .client .set .assert_called_with (Keys .KEY , "value" , nx = True , ex = None )
104
+ valkey .client .set .assert_called_with (
105
+ Keys .KEY , "value" , conditional_set = ConditionalChange .ONLY_IF_DOES_NOT_EXIST
106
+ )
110
107
111
108
await valkey ._add (Keys .KEY , "value" , 1 )
112
- valkey .client .set .assert_called_with (Keys .KEY , "value" , nx = True , ex = 1 )
109
+ # TODO: change this to `assert_called_with` once ExpirySet support `__eq__`
110
+ assert valkey .client .set .call_args .args [0 ] == Keys .KEY
111
+ assert (
112
+ valkey .client .set .call_args .kwargs ["conditional_set" ]
113
+ == ConditionalChange .ONLY_IF_DOES_NOT_EXIST
114
+ )
115
+ assert (
116
+ valkey .client .set .call_args .kwargs ["expiry" ].get_cmd_args ()
117
+ == ExpirySet (ExpiryType .SEC , 1 ).get_cmd_args ()
118
+ )
113
119
114
120
async def test_add_existing (self , valkey ):
115
121
valkey .client .set .return_value = False
@@ -118,7 +124,15 @@ async def test_add_existing(self, valkey):
118
124
119
125
async def test_add_float_ttl (self , valkey ):
120
126
await valkey ._add (Keys .KEY , "value" , 0.1 )
121
- valkey .client .set .assert_called_with (Keys .KEY , "value" , nx = True , px = 100 )
127
+ assert valkey .client .set .call_args .args [0 ] == Keys .KEY
128
+ assert (
129
+ valkey .client .set .call_args .kwargs ["conditional_set" ]
130
+ == ConditionalChange .ONLY_IF_DOES_NOT_EXIST
131
+ )
132
+ assert (
133
+ valkey .client .set .call_args .kwargs ["expiry" ].get_cmd_args ()
134
+ == ExpirySet (ExpiryType .MILLSEC , 100 ).get_cmd_args ()
135
+ )
122
136
123
137
async def test_exists (self , valkey ):
124
138
valkey .client .exists .return_value = 1
@@ -151,7 +165,7 @@ async def test_delete(self, valkey):
151
165
async def test_clear (self , valkey ):
152
166
valkey .client .scan .return_value = [b"0" , ["nm:a" , "nm:b" ]]
153
167
await valkey ._clear ("nm" )
154
- valkey .client .delete .assert_called_with ("nm:a" , "nm:b" )
168
+ valkey .client .delete .assert_called_with ([ "nm:a" , "nm:b" ] )
155
169
156
170
async def test_clear_no_keys (self , valkey ):
157
171
valkey .client .scan .return_value = [b"0" , []]
@@ -168,9 +182,10 @@ async def test_script(self, valkey):
168
182
valkey .client .invoke_script .assert_called_with (script , Keys .KEY , ())
169
183
170
184
async def test_redlock_release (self , mocker , valkey ):
171
- mocker .spy (valkey , "_script " )
185
+ mocker .patch . object (valkey , "_get" , return_value = "random " )
172
186
await valkey ._redlock_release (Keys .KEY , "random" )
173
- valkey ._script .assert_called_with (valkey .RELEASE_SCRIPT , Keys .KEY , "random" )
187
+ valkey ._get .assert_called_once_with (Keys .KEY )
188
+ valkey .client .delete .assert_called_once_with ([Keys .KEY ])
174
189
175
190
176
191
class TestValkeyCache :
@@ -190,7 +205,8 @@ def test_default_serializer(self, valkey_client):
190
205
assert isinstance (ValkeyCache (client = valkey_client ).serializer , JsonSerializer )
191
206
192
207
@pytest .mark .parametrize (
193
- "path,expected" , [("" , {}), ("/" , {}), ("/1" , {"db" : "1" }), ("/1/2/3" , {"db" : "1" })]
208
+ "path,expected" ,
209
+ [("" , {}), ("/" , {}), ("/1" , {"db" : "1" }), ("/1/2/3" , {"db" : "1" })],
194
210
)
195
211
def test_parse_uri_path (self , path , expected , valkey_client ):
196
212
assert ValkeyCache (client = valkey_client ).parse_uri_path (path ) == expected
@@ -203,7 +219,9 @@ def test_parse_uri_path(self, path, expected, valkey_client):
203
219
["my_ns" , "my_ns:" + ensure_key (Keys .KEY )],
204
220
), # noqa: B950
205
221
)
206
- def test_build_key_double_dot (self , set_test_namespace , valkey_cache , namespace , expected ):
222
+ def test_build_key_double_dot (
223
+ self , set_test_namespace , valkey_cache , namespace , expected
224
+ ):
207
225
assert valkey_cache .build_key (Keys .KEY , namespace ) == expected
208
226
209
227
def test_build_key_no_namespace (self , valkey_cache ):
0 commit comments