Skip to content

Commit 05bf98c

Browse files
committed
[GROW-2938] additional test to #1 (#2)
* [GROW-2938] add a test for invalid index returned from load balancer * [GROW-2938] add a test for pipeline additional backoff (cherry picked from commit 308c82b)
1 parent 36ef785 commit 05bf98c

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,8 +1,10 @@
11
import binascii
22
import datetime
3+
import random
34
import uuid
45
import warnings
56
from time import sleep
7+
from unittest import mock
68
from unittest.mock import DEFAULT, Mock, call, patch
79

810
import pytest
@@ -20,6 +22,7 @@
2022
REDIS_CLUSTER_HASH_SLOTS,
2123
REPLICA,
2224
ClusterNode,
25+
LoadBalancer,
2326
NodesManager,
2427
RedisCluster,
2528
get_node_name,
@@ -810,7 +813,7 @@ def raise_error(target_node, *args, **kwargs):
810813
rc = get_mocked_redis_client(
811814
host=default_host,
812815
port=default_port,
813-
retry=Retry(ConstantBackoff(1), 3),
816+
retry=Retry(ConstantBackoff(1), 10),
814817
)
815818

816819
with pytest.raises(error):
@@ -2519,6 +2522,37 @@ def test_connection_pool_class(self, connection_pool_class):
25192522
node.redis_connection.connection_pool, connection_pool_class
25202523
)
25212524

2525+
@pytest.mark.parametrize("invalid_index", [-10, 10])
2526+
def test_return_primary_if_invalid_node_index_is_returned(self, invalid_index):
2527+
rc = get_mocked_redis_client(
2528+
url="redis://[email protected]:7000",
2529+
cluster_slots=default_cluster_slots,
2530+
)
2531+
random_slot = random.randint(
2532+
default_cluster_slots[0][0], default_cluster_slots[0][1]
2533+
)
2534+
2535+
ports = set()
2536+
for _ in range(0, 10):
2537+
ports.add(
2538+
rc.nodes_manager.get_node_from_slot(
2539+
random_slot, read_from_replicas=True
2540+
).port
2541+
)
2542+
assert ports == {default_port, 7003}
2543+
2544+
ports = set()
2545+
with mock.patch.object(
2546+
LoadBalancer, "get_server_index", return_value=invalid_index
2547+
):
2548+
for _ in range(0, 10):
2549+
ports.add(
2550+
rc.nodes_manager.get_node_from_slot(
2551+
random_slot, read_from_replicas=True
2552+
).port
2553+
)
2554+
assert ports == {default_port}
2555+
25222556

25232557
@pytest.mark.onlycluster
25242558
class TestClusterPubSubObject:
@@ -2930,6 +2964,33 @@ def test_empty_stack(self, r):
29302964
result = p.execute()
29312965
assert result == []
29322966

2967+
@pytest.mark.parametrize("error", [ConnectionError, TimeoutError])
2968+
def test_additional_backoff_cluster_pipeline(self, r, error):
2969+
with patch.object(ConstantBackoff, "compute") as compute:
2970+
2971+
def _compute(target_node, *args, **kwargs):
2972+
return 1
2973+
2974+
compute.side_effect = _compute
2975+
with patch("redis.cluster.get_connection") as get_connection:
2976+
2977+
def raise_error(target_node, *args, **kwargs):
2978+
get_connection.failed_calls += 1
2979+
raise error("mocked error")
2980+
2981+
get_connection.side_effect = raise_error
2982+
2983+
r.set_retry(Retry(ConstantBackoff(1), 10))
2984+
pipeline = r.pipeline()
2985+
2986+
with pytest.raises(error):
2987+
pipeline.get("bar")
2988+
pipeline.get("bar")
2989+
pipeline.execute()
2990+
# cluster pipeline does one more back off than a single Redis command
2991+
# this is not required, but it's just how it's implemented as of now
2992+
assert compute.call_count == r.cluster_error_retry_attempts + 1
2993+
29332994

29342995
@pytest.mark.onlycluster
29352996
class TestReadOnlyPipeline:

0 commit comments

Comments
 (0)