"""ASV benchmarks for ``agents init --yes`` invocation time. Measures in-process execution time for the init command with the --yes flag, which should perform non-interactive initialization using defaults. These benchmarks target bug #522 and are expected to error until the fix is applied (the --yes flag does not yet exist). """ from __future__ import annotations import shutil import sys import tempfile from pathlib import Path from unittest.mock import create_autospec, patch try: from cleveragents.cli.main import app except ModuleNotFoundError: sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) from cleveragents.cli.main import app from typer.testing import CliRunner from cleveragents.application.services.project_service import ProjectService class _MockProject: """Lightweight stand-in for the Project model with spec fields. We cannot use ``create_autospec(Project)`` because the spec-required output fields (``data_dir``, ``config_path``, ``database_status``, ``directories``) do not yet exist on the legacy ``Project`` model. """ name: str path: Path data_dir: Path config_path: Path database_status: str directories: list[str] class InitYesFlagSuite: """Benchmark ``agents init --yes`` invocation.""" timeout = 30.0 def setup(self) -> None: self._runner = CliRunner() self._tmpdir = tempfile.mkdtemp() self._last_exit_code = -1 def teardown(self) -> None: shutil.rmtree(self._tmpdir, ignore_errors=True) def _invoke_with_mock(self, args: list[str], project_name: str) -> None: """Invoke the CLI with a mocked container and the given *args*. Stores the result exit code so benchmark data is only meaningful when the command succeeds (exit code 0). When ``--yes`` is not yet implemented the benchmark measures error-path latency; after the fix it measures real init latency. """ with patch( "cleveragents.application.container.get_container" ) as mock_container: mock_service = create_autospec(ProjectService, instance=True) mock_project = _MockProject() mock_project.name = project_name mock_project.path = Path(self._tmpdir) # Pre-populate spec-required fields (specification.md:1381-1386) # so benchmarks measure real output paths once #522 is fixed. mock_project.data_dir = Path(self._tmpdir) mock_project.config_path = Path(self._tmpdir) / "config.toml" mock_project.database_status = "initialized (schema v3)" mock_project.directories = ["logs", "cache", "sessions", "contexts"] mock_service.initialize_project.return_value = mock_project mock_container.return_value.project_service.return_value = mock_service result = self._runner.invoke(app, args) self._last_exit_code = result.exit_code def time_init_yes_flag(self) -> None: """Measure end-to-end latency of ``agents init --yes``.""" self._invoke_with_mock(["init", "--yes"], "bench-project") def time_init_short_y_flag(self) -> None: """Measure end-to-end latency of ``agents init -y``.""" self._invoke_with_mock(["init", "-y"], "bench-project") def time_init_yes_flag_with_path(self) -> None: """Measure latency of ``agents init --yes --path