|
19 | 19 | from tests.utils.object_assertions import assert_match_object, assert_object_lists_match |
20 | 20 | from typesense import exceptions |
21 | 21 | from typesense.sync.api_call import ApiCall, RequestHandler |
| 22 | +from typesense.async_.api_call import AsyncApiCall |
22 | 23 | from typesense.configuration import Configuration, Node |
23 | 24 | from typesense.logger import logger |
24 | 25 |
|
@@ -615,3 +616,52 @@ def test_max_retries_no_last_exception(fake_api_call: ApiCall) -> None: |
615 | 616 | num_retries=10, |
616 | 617 | last_exception=None, |
617 | 618 | ) |
| 619 | + |
| 620 | + |
| 621 | +def test_sleeps_retry_interval_between_retries( |
| 622 | + fake_api_call: ApiCall, |
| 623 | + mocker: MockerFixture, |
| 624 | +) -> None: |
| 625 | + """Test that it waits ``retry_interval_seconds`` between failed attempts.""" |
| 626 | + sleep_mock = mocker.patch("typesense.sync.api_call.time.sleep") |
| 627 | + |
| 628 | + with respx.mock: |
| 629 | + for host in ("nearest", "node0", "node1", "node2"): |
| 630 | + respx.get(f"http://{host}:8108/").mock( |
| 631 | + return_value=httpx.Response(503, json={"message": "unavailable"}), |
| 632 | + ) |
| 633 | + |
| 634 | + with pytest.raises(exceptions.ServiceUnavailable): |
| 635 | + fake_api_call.get("/", entity_type=typing.Dict[str, str]) |
| 636 | + |
| 637 | + # ``num_retries`` gaps for ``num_retries + 1`` attempts, and each gap must be |
| 638 | + # ``retry_interval_seconds`` long (regression: the delay was dropped entirely). |
| 639 | + assert sleep_mock.call_count == fake_api_call.config.num_retries |
| 640 | + for sleep_call in sleep_mock.call_args_list: |
| 641 | + assert sleep_call == mocker.call(fake_api_call.config.retry_interval_seconds) |
| 642 | + |
| 643 | + |
| 644 | +async def test_async_sleeps_retry_interval_between_retries( |
| 645 | + fake_async_api_call: AsyncApiCall, |
| 646 | + mocker: MockerFixture, |
| 647 | +) -> None: |
| 648 | + """Test that the async client waits ``retry_interval_seconds`` between attempts.""" |
| 649 | + sleep_mock = mocker.patch( |
| 650 | + "typesense.async_.api_call.asyncio.sleep", |
| 651 | + new_callable=mocker.AsyncMock, |
| 652 | + ) |
| 653 | + |
| 654 | + with respx.mock: |
| 655 | + for host in ("nearest", "node0", "node1", "node2"): |
| 656 | + respx.get(f"http://{host}:8108/").mock( |
| 657 | + return_value=httpx.Response(503, json={"message": "unavailable"}), |
| 658 | + ) |
| 659 | + |
| 660 | + with pytest.raises(exceptions.ServiceUnavailable): |
| 661 | + await fake_async_api_call.get("/", entity_type=typing.Dict[str, str]) |
| 662 | + |
| 663 | + assert sleep_mock.call_count == fake_async_api_call.config.num_retries |
| 664 | + for sleep_call in sleep_mock.call_args_list: |
| 665 | + assert sleep_call == mocker.call( |
| 666 | + fake_async_api_call.config.retry_interval_seconds, |
| 667 | + ) |
0 commit comments