Skip to content

Commit 308c82b

Browse files
authored
[GROW-2938] additional test to redis#1 (redis#2)
* [GROW-2938] add a test for invalid index returned from load balancer * [GROW-2938] add a test for pipeline additional backoff
1 parent 94bb915 commit 308c82b

File tree

1 file changed

+62
-1
lines changed

1 file changed

+62
-1
lines changed

tests/test_cluster.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import binascii
22
import datetime
3+
import random
34
import select
45
import socket
56
import socketserver
@@ -8,6 +9,7 @@
89
import warnings
910
from queue import LifoQueue, Queue
1011
from time import sleep
12+
from unittest import mock
1113
from unittest.mock import DEFAULT, Mock, call, patch
1214

1315
import pytest
@@ -25,6 +27,7 @@
2527
REDIS_CLUSTER_HASH_SLOTS,
2628
REPLICA,
2729
ClusterNode,
30+
LoadBalancer,
2831
NodesManager,
2932
RedisCluster,
3033
get_node_name,
@@ -927,7 +930,7 @@ def raise_error(target_node, *args, **kwargs):
927930
rc = get_mocked_redis_client(
928931
host=default_host,
929932
port=default_port,
930-
retry=Retry(ConstantBackoff(1), 3),
933+
retry=Retry(ConstantBackoff(1), 10),
931934
)
932935

933936
with pytest.raises(error):
@@ -2655,6 +2658,37 @@ def test_allow_custom_queue_class(self, queue_class):
26552658
for node in rc.nodes_manager.nodes_cache.values():
26562659
assert node.redis_connection.connection_pool.queue_class == queue_class
26572660

2661+
@pytest.mark.parametrize("invalid_index", [-10, 10])
2662+
def test_return_primary_if_invalid_node_index_is_returned(self, invalid_index):
2663+
rc = get_mocked_redis_client(
2664+
url="redis://[email protected]:7000",
2665+
cluster_slots=default_cluster_slots,
2666+
)
2667+
random_slot = random.randint(
2668+
default_cluster_slots[0][0], default_cluster_slots[0][1]
2669+
)
2670+
2671+
ports = set()
2672+
for _ in range(0, 10):
2673+
ports.add(
2674+
rc.nodes_manager.get_node_from_slot(
2675+
random_slot, read_from_replicas=True
2676+
).port
2677+
)
2678+
assert ports == {default_port, 7003}
2679+
2680+
ports = set()
2681+
with mock.patch.object(
2682+
LoadBalancer, "get_server_index", return_value=invalid_index
2683+
):
2684+
for _ in range(0, 10):
2685+
ports.add(
2686+
rc.nodes_manager.get_node_from_slot(
2687+
random_slot, read_from_replicas=True
2688+
).port
2689+
)
2690+
assert ports == {default_port}
2691+
26582692

26592693
@pytest.mark.onlycluster
26602694
class TestClusterPubSubObject:
@@ -3085,6 +3119,33 @@ def test_empty_stack(self, r):
30853119
result = p.execute()
30863120
assert result == []
30873121

3122+
@pytest.mark.parametrize("error", [ConnectionError, TimeoutError])
3123+
def test_additional_backoff_cluster_pipeline(self, r, error):
3124+
with patch.object(ConstantBackoff, "compute") as compute:
3125+
3126+
def _compute(target_node, *args, **kwargs):
3127+
return 1
3128+
3129+
compute.side_effect = _compute
3130+
with patch("redis.cluster.get_connection") as get_connection:
3131+
3132+
def raise_error(target_node, *args, **kwargs):
3133+
get_connection.failed_calls += 1
3134+
raise error("mocked error")
3135+
3136+
get_connection.side_effect = raise_error
3137+
3138+
r.set_retry(Retry(ConstantBackoff(1), 10))
3139+
pipeline = r.pipeline()
3140+
3141+
with pytest.raises(error):
3142+
pipeline.get("bar")
3143+
pipeline.get("bar")
3144+
pipeline.execute()
3145+
# cluster pipeline does one more back off than a single Redis command
3146+
# this is not required, but it's just how it's implemented as of now
3147+
assert compute.call_count == r.cluster_error_retry_attempts + 1
3148+
30883149

30893150
@pytest.mark.onlycluster
30903151
class TestReadOnlyPipeline:

0 commit comments

Comments
 (0)