Repository: redis/redis-py
File: tests/test_asyncio/test_connection.py (Python)

Code before:
            raise socket.timeout
        else:
            return await origin_connect()

    conn._connect.side_effect = mock_connect
    await conn.connect()
    assert conn._connect.call_count == 3
    await conn.disconnect()


async def test_connect_without_retry_on_non_retryable_error():
    """
    Test that the _connect function is not being retried in case of a CancelledError -
    error that is not in the list of retry-able errors"""
    with patch.object(Connection, "_connect") as _connect:
        _connect.side_effect = asyncio.CancelledError("")
        conn = Connection(retry_on_timeout=True, retry=Retry(NoBackoff(), 2))
        with pytest.raises(asyncio.CancelledError):
            await conn.connect()
        assert _connect.call_count == 1


async def test_connect_with_retries():
    """
    Test that the _connect function is not being retried in case of a CancelledError -
    error that is not in the list of retry-able errors"""
    with patch.object(asyncio.StreamWriter, "writelines") as writelines:
        writelines.side_effect = OSError(ECONNREFUSED)
        conn = Connection(retry_on_timeout=True, retry=Retry(NoBackoff(), 2))
        with pytest.raises(ConnectionError):
            await conn.connect()
        # the handshake commands are the failing ones
        # validate that we don't execute too many commands on each retry
        # 3 retries --> 3 commands
        assert writelines.call_count == 3


async def test_connect_timeout_error_without_retry():
    """Test that the _connect function is not being retried if retry_on_timeout is
    set to False"""
    conn = Connection(retry_on_timeout=False)
    conn._connect = mock.AsyncMock()
    conn._connect.side_effect = socket.timeout

    with pytest.raises(TimeoutError, match="Timeout connecting to server"):
        await conn.connect()
    assert conn._connect.call_count == 1


@pytest.mark.onlynoncluster
async def test_connection_parse_response_resume(r: redis.Redis):

Review comment (suggestion):
The docstring describes testing for CancelledError (a non-retryable error), but the test actually validates retry behavior with OSError during the handshake phase. The docstring should be updated to accurately describe what the test does: validating that retries occur for the entire connect+handshake flow when OSError happens during handshake.
```suggestion
    Test that retries occur for the entire connect+handshake flow when OSError happens during the handshake phase.
    """
```

Code after:
            raise socket.timeout
        else:
            return await origin_connect()

    conn._connect.side_effect = mock_connect
    await conn.connect()
    assert conn._connect.call_count == 3
    await conn.disconnect()


async def test_connect_without_retry_on_non_retryable_error():
    """
    Test that the _connect function is not being retried in case of a CancelledError -
    error that is not in the list of retry-able errors"""
    with patch.object(Connection, "_connect") as _connect:
        _connect.side_effect = asyncio.CancelledError("")
        conn = Connection(retry_on_timeout=True, retry=Retry(NoBackoff(), 2))
        with pytest.raises(asyncio.CancelledError):
            await conn.connect()
        assert _connect.call_count == 1


async def test_connect_with_retries():
    """
    Test that retries occur for the entire connect+handshake flow when OSError happens during the handshake phase.
    """
    with patch.object(asyncio.StreamWriter, "writelines") as writelines:
        writelines.side_effect = OSError(ECONNREFUSED)
        conn = Connection(retry_on_timeout=True, retry=Retry(NoBackoff(), 2))
        with pytest.raises(ConnectionError):
            await conn.connect()
        # the handshake commands are the failing ones
        # validate that we don't execute too many commands on each retry
        # 3 retries --> 3 commands
        assert writelines.call_count == 3


async def test_connect_timeout_error_without_retry():
    """Test that the _connect function is not being retried if retry_on_timeout is
    set to False"""
    conn = Connection(retry_on_timeout=False)
    conn._connect = mock.AsyncMock()
    conn._connect.side_effect = socket.timeout

    with pytest.raises(TimeoutError, match="Timeout connecting to server"):
        await conn.connect()
    assert conn._connect.call_count == 1


@pytest.mark.onlynoncluster
async def test_connection_parse_response_resume(r: redis.Redis):