forked from redis/redis-py
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* [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)
- Loading branch information
Showing
1 changed file
with
62 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,10 @@ | ||
import binascii | ||
import datetime | ||
import random | ||
import uuid | ||
import warnings | ||
from time import sleep | ||
from unittest import mock | ||
from unittest.mock import DEFAULT, Mock, call, patch | ||
|
||
import pytest | ||
|
@@ -20,6 +22,7 @@ | |
REDIS_CLUSTER_HASH_SLOTS, | ||
REPLICA, | ||
ClusterNode, | ||
LoadBalancer, | ||
NodesManager, | ||
RedisCluster, | ||
get_node_name, | ||
|
@@ -810,7 +813,7 @@ def raise_error(target_node, *args, **kwargs): | |
rc = get_mocked_redis_client( | ||
host=default_host, | ||
port=default_port, | ||
retry=Retry(ConstantBackoff(1), 3), | ||
retry=Retry(ConstantBackoff(1), 10), | ||
) | ||
|
||
with pytest.raises(error): | ||
|
@@ -2519,6 +2522,37 @@ def test_connection_pool_class(self, connection_pool_class): | |
node.redis_connection.connection_pool, connection_pool_class | ||
) | ||
|
||
@pytest.mark.parametrize("invalid_index", [-10, 10]) | ||
def test_return_primary_if_invalid_node_index_is_returned(self, invalid_index): | ||
rc = get_mocked_redis_client( | ||
url="redis://[email protected]:7000", | ||
cluster_slots=default_cluster_slots, | ||
) | ||
random_slot = random.randint( | ||
default_cluster_slots[0][0], default_cluster_slots[0][1] | ||
) | ||
|
||
ports = set() | ||
for _ in range(0, 10): | ||
ports.add( | ||
rc.nodes_manager.get_node_from_slot( | ||
random_slot, read_from_replicas=True | ||
).port | ||
) | ||
assert ports == {default_port, 7003} | ||
|
||
ports = set() | ||
with mock.patch.object( | ||
LoadBalancer, "get_server_index", return_value=invalid_index | ||
): | ||
for _ in range(0, 10): | ||
ports.add( | ||
rc.nodes_manager.get_node_from_slot( | ||
random_slot, read_from_replicas=True | ||
).port | ||
) | ||
assert ports == {default_port} | ||
|
||
|
||
@pytest.mark.onlycluster | ||
class TestClusterPubSubObject: | ||
|
@@ -2930,6 +2964,33 @@ def test_empty_stack(self, r): | |
result = p.execute() | ||
assert result == [] | ||
|
||
@pytest.mark.parametrize("error", [ConnectionError, TimeoutError]) | ||
def test_additional_backoff_cluster_pipeline(self, r, error): | ||
with patch.object(ConstantBackoff, "compute") as compute: | ||
|
||
def _compute(target_node, *args, **kwargs): | ||
return 1 | ||
|
||
compute.side_effect = _compute | ||
with patch("redis.cluster.get_connection") as get_connection: | ||
|
||
def raise_error(target_node, *args, **kwargs): | ||
get_connection.failed_calls += 1 | ||
raise error("mocked error") | ||
|
||
get_connection.side_effect = raise_error | ||
|
||
r.set_retry(Retry(ConstantBackoff(1), 10)) | ||
pipeline = r.pipeline() | ||
|
||
with pytest.raises(error): | ||
pipeline.get("bar") | ||
pipeline.get("bar") | ||
pipeline.execute() | ||
# cluster pipeline does one more back off than a single Redis command | ||
# this is not required, but it's just how it's implemented as of now | ||
assert compute.call_count == r.cluster_error_retry_attempts + 1 | ||
|
||
|
||
@pytest.mark.onlycluster | ||
class TestReadOnlyPipeline: | ||
|