Skip to content

Commit e22c208

Browse files
authored
test: improve some tests + retry others (#10239)
1 parent 3b4f4ac commit e22c208

File tree

6 files changed

+49
-51
lines changed

6 files changed

+49
-51
lines changed

test/components/audio/test_whisper_remote.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ def test_whisper_remote_transcriber(self, test_files_path):
200200
not os.environ.get("OPENAI_API_KEY", None),
201201
reason="Export an env var called OPENAI_API_KEY containing the OpenAI API key to run this test.",
202202
)
203+
@pytest.mark.flaky(reruns=3, reruns_delay=5)
203204
@pytest.mark.integration
204205
def test_whisper_remote_transcriber_pipeline_and_url_source(self):
205206
pipe = Pipeline()

test/components/connectors/test_openapi_connector.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ def test_serper_dev_integration(self):
197197
not os.environ.get("GITHUB_TOKEN", None), reason="Export an env var called GITHUB_TOKEN to run this test."
198198
)
199199
@pytest.mark.integration
200+
@pytest.mark.flaky(reruns=3, reruns_delay=5)
200201
def test_github_api_integration(self):
201202
component = OpenAPIConnector(
202203
openapi_spec="https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json",

test/components/fetchers/test_link_content_fetcher.py

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,10 @@ def test_request_headers_merging_and_ua_override(self):
182182
assert sent_headers["Accept-Language"] == "fr-FR"
183183
assert sent_headers["User-Agent"] == "ua-sync-1" # rotating UA wins
184184

185-
@pytest.mark.integration
185+
186+
@pytest.mark.flaky(reruns=3, reruns_delay=5)
187+
@pytest.mark.integration
188+
class TestLinkContentFetcherIntegration:
186189
def test_link_content_fetcher_html(self):
187190
"""
188191
Test fetching HTML content from a real URL.
@@ -195,7 +198,6 @@ def test_link_content_fetcher_html(self):
195198
assert "url" in first_stream.meta and first_stream.meta["url"] == HTML_URL
196199
assert first_stream.mime_type == "text/html"
197200

198-
@pytest.mark.integration
199201
def test_link_content_fetcher_text(self):
200202
"""
201203
Test fetching text content from a real URL.
@@ -208,7 +210,6 @@ def test_link_content_fetcher_text(self):
208210
assert "url" in first_stream.meta and first_stream.meta["url"] == TEXT_URL
209211
assert first_stream.mime_type == "text/plain"
210212

211-
@pytest.mark.integration
212213
def test_link_content_fetcher_multiple_different_content_types(self):
213214
"""
214215
This test is to ensure that the fetcher can handle a list of URLs that contain different content types.
@@ -225,7 +226,6 @@ def test_link_content_fetcher_multiple_different_content_types(self):
225226
assert len(stream.data) > 0
226227
assert stream.mime_type == "application/pdf"
227228

228-
@pytest.mark.integration
229229
def test_link_content_fetcher_multiple_html_streams(self):
230230
"""
231231
This test is to ensure that the fetcher can handle a list of URLs that contain different content types,
@@ -244,7 +244,6 @@ def test_link_content_fetcher_multiple_html_streams(self):
244244
assert len(stream.data) > 0
245245
assert stream.mime_type == "application/pdf"
246246

247-
@pytest.mark.integration
248247
def test_mix_of_good_and_failed_requests(self):
249248
"""
250249
This test is to ensure that the fetcher can handle a list of URLs that contain URLs that fail to be fetched.
@@ -259,8 +258,8 @@ def test_mix_of_good_and_failed_requests(self):
259258
assert first_stream.mime_type == "text/html"
260259

261260

261+
@pytest.mark.asyncio
262262
class TestLinkContentFetcherAsync:
263-
@pytest.mark.asyncio
264263
async def test_run_async(self):
265264
"""Test basic async fetching with a mocked response"""
266265
with patch("haystack.components.fetchers.link_content.httpx.AsyncClient.get") as mock_get:
@@ -276,7 +275,6 @@ async def test_run_async(self):
276275
assert first_stream.meta["content_type"] == "text/plain"
277276
assert first_stream.mime_type == "text/plain"
278277

279-
@pytest.mark.asyncio
280278
async def test_run_async_multiple(self):
281279
"""Test async fetching of multiple URLs with mocked responses"""
282280
with patch("haystack.components.fetchers.link_content.httpx.AsyncClient.get") as mock_get:
@@ -295,14 +293,12 @@ async def test_run_async_multiple(self):
295293
assert stream.meta["content_type"] == "text/plain"
296294
assert stream.mime_type == "text/plain"
297295

298-
@pytest.mark.asyncio
299296
async def test_run_async_empty_urls(self):
300297
"""Test async fetching with empty URL list"""
301298
fetcher = LinkContentFetcher()
302299
streams = (await fetcher.run_async(urls=[]))["streams"]
303300
assert len(streams) == 0
304301

305-
@pytest.mark.asyncio
306302
async def test_run_async_error_handling(self):
307303
"""Test error handling for async fetching"""
308304
with patch("haystack.components.fetchers.link_content.httpx.AsyncClient.get") as mock_get:
@@ -322,7 +318,6 @@ async def test_run_async_error_handling(self):
322318
with pytest.raises(httpx.HTTPStatusError):
323319
await fetcher.run_async(urls=["https://www.example.com"])
324320

325-
@pytest.mark.asyncio
326321
async def test_run_async_user_agent_rotation(self):
327322
"""Test user agent rotation in async fetching"""
328323
with (
@@ -355,34 +350,6 @@ async def test_run_async_user_agent_rotation(self):
355350

356351
mock_sleep.assert_called_once()
357352

358-
@pytest.mark.asyncio
359-
@pytest.mark.integration
360-
async def test_run_async_multiple_integration(self):
361-
"""Test async fetching of multiple URLs with real HTTP requests"""
362-
fetcher = LinkContentFetcher()
363-
streams = (await fetcher.run_async([HTML_URL, TEXT_URL]))["streams"]
364-
assert len(streams) == 2
365-
366-
for stream in streams:
367-
assert "Haystack" in stream.data.decode("utf-8")
368-
369-
if stream.meta["url"] == HTML_URL:
370-
assert stream.meta["content_type"] == "text/html"
371-
assert stream.mime_type == "text/html"
372-
elif stream.meta["url"] == TEXT_URL:
373-
assert stream.meta["content_type"] == "text/plain"
374-
assert stream.mime_type == "text/plain"
375-
376-
@pytest.mark.asyncio
377-
@pytest.mark.integration
378-
async def test_run_async_with_client_kwargs(self):
379-
"""Test async fetching with custom client kwargs"""
380-
fetcher = LinkContentFetcher(client_kwargs={"follow_redirects": True, "timeout": 10.0})
381-
streams = (await fetcher.run_async([HTML_URL]))["streams"]
382-
assert len(streams) == 1
383-
assert "Haystack" in streams[0].data.decode("utf-8")
384-
385-
@pytest.mark.asyncio
386353
async def test_request_headers_merging_and_ua_override(self):
387354
# Patch the AsyncClient class to control the instance created by LinkContentFetcher
388355
with patch("haystack.components.fetchers.link_content.httpx.AsyncClient") as AsyncClientMock:
@@ -405,7 +372,6 @@ async def test_request_headers_merging_and_ua_override(self):
405372
assert sent_headers["Accept-Language"] == "de-DE"
406373
assert sent_headers["User-Agent"] == "ua-async-1" # rotating UA wins
407374

408-
@pytest.mark.asyncio
409375
async def test_duplicated_request_headers_merging(self):
410376
# Patch the AsyncClient class to control the instance created by LinkContentFetcher
411377
with patch("haystack.components.fetchers.link_content.httpx.AsyncClient") as AsyncClientMock:
@@ -439,3 +405,31 @@ async def test_duplicated_request_headers_merging(self):
439405

440406
assert "x-test-header" in existing_keys
441407
assert existing_keys["x-test-header"] == "X-TeSt-HeAdEr"
408+
409+
410+
@pytest.mark.flaky(reruns=3, reruns_delay=5)
411+
@pytest.mark.integration
412+
@pytest.mark.asyncio
413+
class TestLinkContentFetcherAsyncIntegration:
414+
async def test_run_async_multiple_integration(self):
415+
"""Test async fetching of multiple URLs with real HTTP requests"""
416+
fetcher = LinkContentFetcher()
417+
streams = (await fetcher.run_async([HTML_URL, TEXT_URL]))["streams"]
418+
assert len(streams) == 2
419+
420+
for stream in streams:
421+
assert "Haystack" in stream.data.decode("utf-8")
422+
423+
if stream.meta["url"] == HTML_URL:
424+
assert stream.meta["content_type"] == "text/html"
425+
assert stream.mime_type == "text/html"
426+
elif stream.meta["url"] == TEXT_URL:
427+
assert stream.meta["content_type"] == "text/plain"
428+
assert stream.mime_type == "text/plain"
429+
430+
async def test_run_async_with_client_kwargs(self):
431+
"""Test async fetching with custom client kwargs"""
432+
fetcher = LinkContentFetcher(client_kwargs={"follow_redirects": True, "timeout": 10.0})
433+
streams = (await fetcher.run_async([HTML_URL]))["streams"]
434+
assert len(streams) == 1
435+
assert "Haystack" in streams[0].data.decode("utf-8")

test/components/generators/chat/test_openai.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,8 +1088,8 @@ def test_live_run_with_toolset(self, tools):
10881088
tool_call = message.tool_call
10891089
assert isinstance(tool_call, ToolCall)
10901090
assert tool_call.tool_name == "weather"
1091-
assert tool_call.arguments == {"city": "Paris"}
1092-
assert message.meta["finish_reason"] == "tool_calls"
1091+
assert tool_call.arguments.keys() == {"city"}
1092+
assert "Paris" in tool_call.arguments["city"]
10931093

10941094
@pytest.mark.skipif(
10951095
not os.environ.get("OPENAI_API_KEY", None),

test/components/generators/chat/test_openai_async.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ async def test_callback(chunk: StreamingChunk):
344344
@pytest.mark.integration
345345
@pytest.mark.asyncio
346346
async def test_run_async_cancellation_integration(self):
347-
generator = OpenAIChatGenerator(model="gpt-4")
347+
generator = OpenAIChatGenerator(model="gpt-4.1-nano")
348348
messages = [ChatMessage.from_user("Write me an essay about the history of jazz music, at least 500 words.")]
349349
received_chunks = []
350350

test/components/generators/chat/test_openai_responses.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,15 @@ def weather_function(city: str) -> dict[str, Any]:
273273
return weather_info.get(city, {"weather": "unknown", "temperature": 0, "unit": "celsius"})
274274

275275

276+
# Tool Function used in the test_live_run_with_agent_streaming_and_reasoning test
277+
def calculate(expression: str) -> dict:
278+
try:
279+
result = eval(expression, {"__builtins__": {}})
280+
return {"result": result}
281+
except Exception as e:
282+
return {"error": str(e)}
283+
284+
276285
@pytest.fixture
277286
def tools():
278287
weather_tool = Tool(
@@ -1064,7 +1073,8 @@ def test_live_run_with_toolset(self, tools):
10641073
tool_call = message.tool_call
10651074
assert isinstance(tool_call, ToolCall)
10661075
assert tool_call.tool_name == "weather"
1067-
assert tool_call.arguments == {"city": "Paris"}
1076+
assert tool_call.arguments.keys() == {"city"}
1077+
assert "Paris" in tool_call.arguments["city"]
10681078

10691079
@pytest.mark.skipif(
10701080
not os.environ.get("OPENAI_API_KEY", None),
@@ -1169,14 +1179,6 @@ def test_live_run_with_tools_streaming_and_reasoning(self, tools):
11691179
)
11701180
@pytest.mark.integration
11711181
def test_live_run_with_agent_streaming_and_reasoning(self):
1172-
# Tool Function
1173-
def calculate(expression: str) -> dict:
1174-
try:
1175-
result = eval(expression, {"__builtins__": {}})
1176-
return {"result": result}
1177-
except Exception as e:
1178-
return {"error": str(e)}
1179-
11801182
# Tool Definition
11811183
calculator_tool = Tool(
11821184
name="calculator",

0 commit comments

Comments
 (0)