Skip to content

Commit 0f69f96

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 1091b37 commit 0f69f96

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

911
import pytest
@@ -21,6 +23,7 @@
2123
REDIS_CLUSTER_HASH_SLOTS,
2224
REPLICA,
2325
ClusterNode,
26+
LoadBalancer,
2427
NodesManager,
2528
RedisCluster,
2629
get_node_name,
@@ -812,7 +815,7 @@ def raise_error(target_node, *args, **kwargs):
812815
rc = get_mocked_redis_client(
813816
host=default_host,
814817
port=default_port,
815-
retry=Retry(ConstantBackoff(1), 3),
818+
retry=Retry(ConstantBackoff(1), 10),
816819
)
817820

818821
with pytest.raises(error):
@@ -2577,6 +2580,37 @@ def test_allow_custom_queue_class(self, queue_class):
25772580
for node in rc.nodes_manager.nodes_cache.values():
25782581
assert node.redis_connection.connection_pool.queue_class == queue_class
25792582

2583+
@pytest.mark.parametrize("invalid_index", [-10, 10])
2584+
def test_return_primary_if_invalid_node_index_is_returned(self, invalid_index):
2585+
rc = get_mocked_redis_client(
2586+
url="redis://[email protected]:7000",
2587+
cluster_slots=default_cluster_slots,
2588+
)
2589+
random_slot = random.randint(
2590+
default_cluster_slots[0][0], default_cluster_slots[0][1]
2591+
)
2592+
2593+
ports = set()
2594+
for _ in range(0, 10):
2595+
ports.add(
2596+
rc.nodes_manager.get_node_from_slot(
2597+
random_slot, read_from_replicas=True
2598+
).port
2599+
)
2600+
assert ports == {default_port, 7003}
2601+
2602+
ports = set()
2603+
with mock.patch.object(
2604+
LoadBalancer, "get_server_index", return_value=invalid_index
2605+
):
2606+
for _ in range(0, 10):
2607+
ports.add(
2608+
rc.nodes_manager.get_node_from_slot(
2609+
random_slot, read_from_replicas=True
2610+
).port
2611+
)
2612+
assert ports == {default_port}
2613+
25802614

25812615
@pytest.mark.onlycluster
25822616
class TestClusterPubSubObject:
@@ -3007,6 +3041,33 @@ def test_empty_stack(self, r):
30073041
result = p.execute()
30083042
assert result == []
30093043

3044+
@pytest.mark.parametrize("error", [ConnectionError, TimeoutError])
3045+
def test_additional_backoff_cluster_pipeline(self, r, error):
3046+
with patch.object(ConstantBackoff, "compute") as compute:
3047+
3048+
def _compute(target_node, *args, **kwargs):
3049+
return 1
3050+
3051+
compute.side_effect = _compute
3052+
with patch("redis.cluster.get_connection") as get_connection:
3053+
3054+
def raise_error(target_node, *args, **kwargs):
3055+
get_connection.failed_calls += 1
3056+
raise error("mocked error")
3057+
3058+
get_connection.side_effect = raise_error
3059+
3060+
r.set_retry(Retry(ConstantBackoff(1), 10))
3061+
pipeline = r.pipeline()
3062+
3063+
with pytest.raises(error):
3064+
pipeline.get("bar")
3065+
pipeline.get("bar")
3066+
pipeline.execute()
3067+
# cluster pipeline does one more back off than a single Redis command
3068+
# this is not required, but it's just how it's implemented as of now
3069+
assert compute.call_count == r.cluster_error_retry_attempts + 1
3070+
30103071

30113072
@pytest.mark.onlycluster
30123073
class TestReadOnlyPipeline:

0 commit comments

Comments
 (0)