haystack/test/conftest.py
Abdelrahman Kaseb 5f3c37d287
chore: adopt PEP 585 type hints (#9678)
* chore(lint): enforce and apply PEP 585 type hinting

* Run fmt fixes

* Fix all typing imports using some regex

* Fix all typing written in string in tests

* undo changes in the e2e tests

* make e2e test use list instead of List

* type fixes

* remove type:ignore

* pylint

* Remove typing from Usage example comments

* Remove typing from most of comments

* try to fix e2e tests on comm PRs

* fix

* Add tests typing.List in to adjust test compatiplity
- test/components/agents/test_state_class.py
- test/components/converters/test_output_adapter.py
- test/components/joiners/test_list_joiner.py

* simplify pyproject

* improve relnote

---------

Co-authored-by: anakin87 <stefanofiorucci@gmail.com>
2025-08-07 10:23:14 +02:00

119 lines
3.6 KiB
Python

# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
import asyncio
import time
from pathlib import Path
from typing import Generator
from unittest.mock import Mock
import pytest
from haystack import component, tracing
from haystack.core.pipeline.breakpoint import load_pipeline_snapshot
from haystack.testing.test_utils import set_all_seeds
from test.tracing.utils import SpyingTracer
set_all_seeds(0)
# Tracing is disable by default to avoid failures in CI
tracing.disable_tracing()
@pytest.fixture()
def waiting_component():
@component
class Waiter:
@component.output_types(waited_for=int)
def run(self, wait_for: int) -> dict[str, int]:
time.sleep(wait_for)
return {"waited_for": wait_for}
@component.output_types(waited_for=int)
async def run_async(self, wait_for: int) -> dict[str, int]:
await asyncio.sleep(wait_for)
return {"waited_for": wait_for}
return Waiter
@pytest.fixture()
def mock_tokenizer():
"""
Tokenizes the string by splitting on spaces.
"""
tokenizer = Mock()
tokenizer.encode = lambda text: text.split()
tokenizer.decode = lambda tokens: " ".join(tokens)
return tokenizer
@pytest.fixture()
def test_files_path():
return Path(__file__).parent / "test_files"
@pytest.fixture(autouse=True)
def request_blocker(request: pytest.FixtureRequest, monkeypatch):
"""
This fixture is applied automatically to all tests.
Those that are not marked as integration will have the requests module
monkeypatched to avoid making HTTP requests by mistake.
"""
marker = request.node.get_closest_marker("integration")
if marker is not None:
return
def urlopen_mock(self, method, url, *args, **kwargs):
raise RuntimeError(f"The test was about to {method} {self.scheme}://{self.host}{url}")
monkeypatch.setattr("urllib3.connectionpool.HTTPConnectionPool.urlopen", urlopen_mock)
@pytest.fixture()
def spying_tracer() -> Generator[SpyingTracer, None, None]:
tracer = SpyingTracer()
tracing.enable_tracing(tracer)
tracer.is_content_tracing_enabled = True
yield tracer
# Make sure to disable tracing after the test to avoid affecting other tests
tracing.disable_tracing()
def load_and_resume_pipeline_snapshot(pipeline, output_directory: Path, component_name: str, data: dict = None) -> dict:
"""
Utility function to load and resume pipeline snapshot from a breakpoint file.
:param pipeline: The pipeline instance to resume
:param output_directory: Directory containing the breakpoint files
:param component_name: Component name to look for in breakpoint files
:param data: Data to pass to the pipeline run (defaults to empty dict)
:returns:
Dict containing the pipeline run results
:raises:
ValueError: If no breakpoint file is found for the given component
"""
data = data or {}
all_files = list(output_directory.glob("*"))
file_found = False
for full_path in all_files:
f_name = Path(full_path).name
if str(f_name).startswith(component_name):
pipeline_snapshot = load_pipeline_snapshot(full_path)
return pipeline.run(data=data, pipeline_snapshot=pipeline_snapshot)
if not file_found:
msg = f"No files found for {component_name} in {output_directory}."
raise ValueError(msg)
@pytest.fixture()
def base64_image_string():
return "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII="