@@ -1397,6 +1397,73 @@ async def operation() -> str:
13971397 asyncio .run (run ())
13981398
13991399
1400+ def test_async_helpers_accept_fraction_timing_values ():
1401+ async def run () -> None :
1402+ status_values = iter (["pending" , "completed" ])
1403+ status = await poll_until_terminal_status_async (
1404+ operation_name = "async poll fraction timings" ,
1405+ get_status = lambda : asyncio .sleep (0 , result = next (status_values )),
1406+ is_terminal_status = lambda value : value == "completed" ,
1407+ poll_interval_seconds = Fraction (1 , 10000 ), # type: ignore[arg-type]
1408+ max_wait_seconds = Fraction (1 , 1 ), # type: ignore[arg-type]
1409+ )
1410+ assert status == "completed"
1411+
1412+ retry_attempts = {"count" : 0 }
1413+
1414+ async def retry_operation_callback () -> str :
1415+ retry_attempts ["count" ] += 1
1416+ if retry_attempts ["count" ] < 2 :
1417+ raise ValueError ("temporary" )
1418+ return "ok"
1419+
1420+ retry_result = await retry_operation_async (
1421+ operation_name = "async retry fraction delay" ,
1422+ operation = retry_operation_callback ,
1423+ max_attempts = 2 ,
1424+ retry_delay_seconds = Fraction (1 , 10000 ), # type: ignore[arg-type]
1425+ )
1426+ assert retry_result == "ok"
1427+ assert retry_attempts ["count" ] == 2
1428+
1429+ pages = {
1430+ 1 : {"current" : 1 , "total" : 2 , "items" : ["a" ]},
1431+ 2 : {"current" : 2 , "total" : 2 , "items" : ["b" ]},
1432+ }
1433+ collected : list [str ] = []
1434+
1435+ async def get_next_page (page_batch : int ) -> dict :
1436+ return pages [page_batch ]
1437+
1438+ await collect_paginated_results_async (
1439+ operation_name = "async collect fraction delay" ,
1440+ get_next_page = get_next_page ,
1441+ get_current_page_batch = lambda response : response ["current" ],
1442+ get_total_page_batches = lambda response : response ["total" ],
1443+ on_page_success = lambda response : collected .extend (response ["items" ]),
1444+ max_wait_seconds = 1.0 ,
1445+ max_attempts = 2 ,
1446+ retry_delay_seconds = Fraction (1 , 10000 ), # type: ignore[arg-type]
1447+ )
1448+ assert collected == ["a" , "b" ]
1449+
1450+ wait_status_values = iter (["running" , "completed" ])
1451+ wait_result = await wait_for_job_result_async (
1452+ operation_name = "async wait helper fraction timings" ,
1453+ get_status = lambda : asyncio .sleep (0 , result = next (wait_status_values )),
1454+ is_terminal_status = lambda value : value == "completed" ,
1455+ fetch_result = lambda : asyncio .sleep (0 , result = {"ok" : True }),
1456+ poll_interval_seconds = Fraction (1 , 10000 ), # type: ignore[arg-type]
1457+ max_wait_seconds = Fraction (1 , 1 ), # type: ignore[arg-type]
1458+ max_status_failures = 2 ,
1459+ fetch_max_attempts = 2 ,
1460+ fetch_retry_delay_seconds = Fraction (1 , 10000 ), # type: ignore[arg-type]
1461+ )
1462+ assert wait_result == {"ok" : True }
1463+
1464+ asyncio .run (run ())
1465+
1466+
14001467def test_retry_operation_async_rejects_non_awaitable_operation_result () -> None :
14011468 async def run () -> None :
14021469 with pytest .raises (
0 commit comments