Skip to content

Commit e5ed710

Browse files
majiayu000claude
andcommitted
Add tests for REPLICA alias methods
Add comprehensive tests for the new REPLICA terminology aliases: - test_replica_not_found_error_alias: Verify ReplicaNotFoundError is alias - test_replica_for_alias: Test replica_for() method - test_discover_replicas_alias: Test discover_replicas() method - test_filter_replicas_alias: Test filter_replicas() method - test_rotate_replicas_alias: Test rotate_replicas() method Tests added for both sync and async Sentinel implementations. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent b705514 commit e5ed710

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed

tests/test_asyncio/test_sentinel.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from redis import exceptions
1010
from redis.asyncio.sentinel import (
1111
MasterNotFoundError,
12+
ReplicaNotFoundError,
1213
Sentinel,
1314
SentinelConnectionPool,
1415
SlaveNotFoundError,
@@ -396,3 +397,65 @@ async def test_sentinel_commands_with_strict_redis_client(request):
396397
assert isinstance(await client.sentinel_ckquorum("redis-py-test"), bool)
397398

398399
await client.close()
400+
401+
402+
# Tests for REPLICA aliases (Redis 5.0+ terminology)
403+
@pytest.mark.onlynoncluster
404+
async def test_replica_not_found_error_alias():
405+
"""Test that ReplicaNotFoundError is an alias for SlaveNotFoundError"""
406+
assert ReplicaNotFoundError is SlaveNotFoundError
407+
408+
409+
@pytest.mark.onlynoncluster
410+
async def test_replica_for_alias(cluster, sentinel):
411+
"""Test that replica_for() is an alias for slave_for()"""
412+
cluster.slaves = [
413+
{"ip": "127.0.0.1", "port": 6379, "is_odown": False, "is_sdown": False}
414+
]
415+
async with sentinel.replica_for("mymaster", db=9) as replica:
416+
assert await replica.ping()
417+
418+
419+
@pytest.mark.onlynoncluster
420+
async def test_discover_replicas_alias(cluster, sentinel):
421+
"""Test that discover_replicas() is an alias for discover_slaves()"""
422+
cluster.slaves = [
423+
{"ip": "slave0", "port": 1234, "is_odown": False, "is_sdown": False},
424+
{"ip": "slave1", "port": 1234, "is_odown": False, "is_sdown": False},
425+
]
426+
# discover_replicas should return the same result as discover_slaves
427+
replicas = await sentinel.discover_replicas("mymaster")
428+
slaves = await sentinel.discover_slaves("mymaster")
429+
assert replicas == slaves
430+
assert replicas == [("slave0", 1234), ("slave1", 1234)]
431+
432+
433+
@pytest.mark.onlynoncluster
434+
async def test_filter_replicas_alias(cluster, sentinel):
435+
"""Test that filter_replicas() is an alias for filter_slaves()"""
436+
replicas = [
437+
{"ip": "replica0", "port": 1234, "is_odown": False, "is_sdown": False},
438+
{"ip": "replica1", "port": 1234, "is_odown": True, "is_sdown": False},
439+
]
440+
# filter_replicas should return the same result as filter_slaves
441+
filtered_replicas = sentinel.filter_replicas(replicas)
442+
filtered_slaves = sentinel.filter_slaves(replicas)
443+
assert filtered_replicas == filtered_slaves
444+
assert filtered_replicas == [("replica0", 1234)]
445+
446+
447+
@pytest.mark.onlynoncluster
448+
async def test_rotate_replicas_alias(cluster, sentinel, master_ip):
449+
"""Test that rotate_replicas() is an alias for rotate_slaves()"""
450+
cluster.slaves = [
451+
{"ip": "slave0", "port": 6379, "is_odown": False, "is_sdown": False},
452+
{"ip": "slave1", "port": 6379, "is_odown": False, "is_sdown": False},
453+
]
454+
pool = SentinelConnectionPool("mymaster", sentinel)
455+
rotator = pool.rotate_replicas()
456+
assert await rotator.__anext__() in (("slave0", 6379), ("slave1", 6379))
457+
assert await rotator.__anext__() in (("slave0", 6379), ("slave1", 6379))
458+
# Fallback to master
459+
assert await rotator.__anext__() == (master_ip, 6379)
460+
with pytest.raises(SlaveNotFoundError):
461+
await rotator.__anext__()

tests/test_sentinel.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from redis import exceptions
99
from redis.sentinel import (
1010
MasterNotFoundError,
11+
ReplicaNotFoundError,
1112
Sentinel,
1213
SentinelConnectionPool,
1314
SlaveNotFoundError,
@@ -373,3 +374,65 @@ def test_sentinel_commands_with_strict_redis_client(request):
373374
assert isinstance(client.sentinel_ckquorum("redis-py-test"), bool)
374375

375376
client.close()
377+
378+
379+
# Tests for REPLICA aliases (Redis 5.0+ terminology)
380+
@pytest.mark.onlynoncluster
381+
def test_replica_not_found_error_alias():
382+
"""Test that ReplicaNotFoundError is an alias for SlaveNotFoundError"""
383+
assert ReplicaNotFoundError is SlaveNotFoundError
384+
385+
386+
@pytest.mark.onlynoncluster
387+
def test_replica_for_alias(cluster, sentinel):
388+
"""Test that replica_for() is an alias for slave_for()"""
389+
cluster.slaves = [
390+
{"ip": "127.0.0.1", "port": 6379, "is_odown": False, "is_sdown": False}
391+
]
392+
replica = sentinel.replica_for("mymaster", db=9)
393+
assert replica.ping()
394+
395+
396+
@pytest.mark.onlynoncluster
397+
def test_discover_replicas_alias(cluster, sentinel):
398+
"""Test that discover_replicas() is an alias for discover_slaves()"""
399+
cluster.slaves = [
400+
{"ip": "slave0", "port": 1234, "is_odown": False, "is_sdown": False},
401+
{"ip": "slave1", "port": 1234, "is_odown": False, "is_sdown": False},
402+
]
403+
# discover_replicas should return the same result as discover_slaves
404+
replicas = sentinel.discover_replicas("mymaster")
405+
slaves = sentinel.discover_slaves("mymaster")
406+
assert replicas == slaves
407+
assert replicas == [("slave0", 1234), ("slave1", 1234)]
408+
409+
410+
@pytest.mark.onlynoncluster
411+
def test_filter_replicas_alias(cluster, sentinel):
412+
"""Test that filter_replicas() is an alias for filter_slaves()"""
413+
replicas = [
414+
{"ip": "replica0", "port": 1234, "is_odown": False, "is_sdown": False},
415+
{"ip": "replica1", "port": 1234, "is_odown": True, "is_sdown": False},
416+
]
417+
# filter_replicas should return the same result as filter_slaves
418+
filtered_replicas = sentinel.filter_replicas(replicas)
419+
filtered_slaves = sentinel.filter_slaves(replicas)
420+
assert filtered_replicas == filtered_slaves
421+
assert filtered_replicas == [("replica0", 1234)]
422+
423+
424+
@pytest.mark.onlynoncluster
425+
def test_rotate_replicas_alias(cluster, sentinel, master_ip):
426+
"""Test that rotate_replicas() is an alias for rotate_slaves()"""
427+
cluster.slaves = [
428+
{"ip": "slave0", "port": 6379, "is_odown": False, "is_sdown": False},
429+
{"ip": "slave1", "port": 6379, "is_odown": False, "is_sdown": False},
430+
]
431+
pool = SentinelConnectionPool("mymaster", sentinel)
432+
rotator = pool.rotate_replicas()
433+
assert next(rotator) in (("slave0", 6379), ("slave1", 6379))
434+
assert next(rotator) in (("slave0", 6379), ("slave1", 6379))
435+
# Fallback to master
436+
assert next(rotator) == (master_ip, 6379)
437+
with pytest.raises(SlaveNotFoundError):
438+
next(rotator)

0 commit comments

Comments
 (0)