"""ASV benchmarks for error recovery patterns. Measures the performance of: - Error classification - Recovery hint generation - ErrorRecord/ErrorHistory model operations - ErrorRecoveryService.record_error() with mock lifecycle """ from __future__ import annotations import sys from pathlib import Path from unittest.mock import MagicMock try: from cleveragents.application.services.error_recovery_service import ( ErrorRecoveryService, ) from cleveragents.domain.models.core.error_recovery import ( ErrorCategory, classify_error, get_recovery_hints, ) from cleveragents.domain.models.core.plan import ( PlanPhase, PlanTimestamps, ProcessingState, ) except ModuleNotFoundError: sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) from cleveragents.application.services.error_recovery_service import ( ErrorRecoveryService, ) from cleveragents.domain.models.core.error_recovery import ( ErrorCategory, classify_error, get_recovery_hints, ) from cleveragents.domain.models.core.plan import ( PlanPhase, PlanTimestamps, ProcessingState, ) _PLAN_ID = "01BENCHERR0000000000001" def _make_plan() -> MagicMock: plan = MagicMock() plan.identity.plan_id = _PLAN_ID plan.phase = PlanPhase.EXECUTE plan.processing_state = ProcessingState.ERRORED plan.is_terminal = False plan.error_message = None plan.error_details = None plan.timestamps = PlanTimestamps() return plan def _make_service(plan: MagicMock) -> ErrorRecoveryService: lifecycle = MagicMock() lifecycle.get_plan.return_value = plan lifecycle._commit_plan = MagicMock() return ErrorRecoveryService( lifecycle_service=lifecycle, auto_retry_threshold=0.0, max_retries=3, ) class ClassifySuite: """Benchmark error classification.""" def time_classify_transient(self) -> None: classify_error("Connection timed out after 30s") def time_classify_validation(self) -> None: classify_error("Schema validation failed for field X") def time_classify_unknown(self) -> None: classify_error("Something completely novel happened") def time_classify_with_exception_type(self) -> None: classify_error("failed", "RateLimitError") class HintSuite: """Benchmark recovery hint generation.""" def time_hints_transient(self) -> None: get_recovery_hints(ErrorCategory.TRANSIENT, _PLAN_ID) def time_hints_validation(self) -> None: get_recovery_hints(ErrorCategory.VALIDATION, _PLAN_ID) def time_hints_merge_conflict(self) -> None: get_recovery_hints(ErrorCategory.MERGE_CONFLICT, _PLAN_ID) class RecordSuite: """Benchmark error recording with mock service.""" def setup(self) -> None: self.plan = _make_plan() self.service = _make_service(self.plan) self._counter = 0 def time_record_error(self) -> None: self._counter += 1 self.service.record_error( plan_id=_PLAN_ID, phase="execute", message=f"Timeout #{self._counter}", ) def time_format_output_plain(self) -> None: self.service.format_error_output(_PLAN_ID, fmt="plain") def time_format_output_json(self) -> None: self.service.format_error_output(_PLAN_ID, fmt="json")