@@ -2252,3 +2252,61 @@ def fast_download_stream(
22522252 results = list (result_gen )
22532253
22542254 assert results == ["result_page" ]
2255+
2256+
2257+ @pytest .mark .skipif (pandas is None , reason = "Requires `pandas`" )
2258+ @pytest .mark .skipif (isinstance (pyarrow , mock .Mock ), reason = "Requires `pyarrow`" )
2259+ def test_download_arrow_row_iterator_timeout (module_under_test ):
2260+ bq_schema = [schema .SchemaField ("name" , "STRING" )]
2261+
2262+ # Mock page with to_arrow method
2263+ mock_page = mock .Mock ()
2264+ mock_page .to_arrow .return_value = pyarrow .RecordBatch .from_pydict ({"name" : ["foo" ]})
2265+
2266+ def slow_pages ():
2267+ # First page yields quickly
2268+ yield mock_page
2269+ # Sleep to exceed timeout
2270+ time .sleep (0.1 )
2271+ yield mock_page
2272+
2273+ # Timeout of 0.05s
2274+ timeout = 0.05
2275+ iterator = module_under_test .download_arrow_row_iterator (
2276+ slow_pages (), bq_schema , timeout = timeout
2277+ )
2278+
2279+ # First item should succeed
2280+ next (iterator )
2281+
2282+ # Second item should fail with TimeoutError
2283+ with pytest .raises (concurrent .futures .TimeoutError ):
2284+ next (iterator )
2285+
2286+
2287+ @pytest .mark .skipif (pandas is None , reason = "Requires `pandas`" )
2288+ @pytest .mark .skipif (isinstance (pyarrow , mock .Mock ), reason = "Requires `pyarrow`" )
2289+ def test_download_dataframe_row_iterator_timeout (module_under_test ):
2290+ bq_schema = [schema .SchemaField ("name" , "STRING" )]
2291+ dtypes = {}
2292+
2293+ # Mock page
2294+ mock_page = mock .Mock ()
2295+ # Mock iterator for _row_iterator_page_to_dataframe checking next(iter(page))
2296+ mock_page .__iter__ = lambda self : iter (["row1" ])
2297+ mock_page ._columns = [["foo" ]]
2298+
2299+ def slow_pages ():
2300+ yield mock_page
2301+ time .sleep (0.1 )
2302+ yield mock_page
2303+
2304+ timeout = 0.05
2305+ iterator = module_under_test .download_dataframe_row_iterator (
2306+ slow_pages (), bq_schema , dtypes , timeout = timeout
2307+ )
2308+
2309+ next (iterator )
2310+
2311+ with pytest .raises (concurrent .futures .TimeoutError ):
2312+ next (iterator )
0 commit comments