"""ASV benchmarks for semantic validation suite runtime. Measures the performance of running entire fixture suites through the semantic validation rules, covering: - Language-porting mismatch fixtures - Dependency graph violation fixtures - API surface change fixtures - Cross-file symbol resolution fixtures - Duplicate relative import detection fixtures Uses :mod:`features.fixtures.validation.suite_helpers` for shared loading, lookup, and rule-map construction. """ from __future__ import annotations import sys from pathlib import Path from typing import Any _SRC = str(Path(__file__).resolve().parents[1] / "src") if _SRC not in sys.path: sys.path.insert(0, _SRC) _FIXTURES_DIR = str( Path(__file__).resolve().parents[1] / "features" / "fixtures" / "validation" ) if _FIXTURES_DIR not in sys.path: sys.path.insert(0, _FIXTURES_DIR) from suite_helpers import ( # noqa: E402, I001 ALL_FIXTURE_FILENAMES, API_FILENAME, CIRCULAR_FILENAME, CROSS_FILE_FILENAME, DEPENDENCY_FILENAME, PORTING_FILENAME, RULE_MAP, load_fixtures, ) from cleveragents.application.services.semantic_validation_rules import ( # noqa: E402 SemanticCheckResult, ) from cleveragents.application.services.semantic_validation_service import ( # noqa: E402 SemanticValidationService, ) # --------------------------------------------------------------------------- # Fixture runner (uses shared RULE_MAP) # --------------------------------------------------------------------------- def _run_suite(fixtures: list[dict[str, Any]]) -> list[SemanticCheckResult]: """Run all fixtures through their expected rules.""" results: list[SemanticCheckResult] = [] for fixture in fixtures: rule_name: str = fixture["expected_rule"] rule = RULE_MAP[rule_name] result = rule.check(fixture["source"], fixture["filename"]) results.append(result) return results # --------------------------------------------------------------------------- # Benchmark suites # --------------------------------------------------------------------------- class PortingFixtureSuite: """Benchmarks for language-porting mismatch fixture suite runtime.""" timeout = 60 def setup(self) -> None: self.fixtures = load_fixtures(PORTING_FILENAME) def time_run_all_porting_fixtures(self) -> None: _run_suite(self.fixtures) def time_load_porting_fixtures(self) -> None: load_fixtures(PORTING_FILENAME) class DependencyFixtureSuite: """Benchmarks for dependency graph violation fixture suite runtime.""" timeout = 60 def setup(self) -> None: self.fixtures = load_fixtures(DEPENDENCY_FILENAME) def time_run_all_dependency_fixtures(self) -> None: _run_suite(self.fixtures) def time_load_dependency_fixtures(self) -> None: load_fixtures(DEPENDENCY_FILENAME) class APISurfaceFixtureSuite: """Benchmarks for API surface change fixture suite runtime.""" timeout = 60 def setup(self) -> None: self.fixtures = load_fixtures(API_FILENAME) def time_run_all_api_fixtures(self) -> None: _run_suite(self.fixtures) def time_load_api_fixtures(self) -> None: load_fixtures(API_FILENAME) class CrossFileFixtureSuite: """Benchmarks for cross-file symbol resolution fixture suite runtime.""" timeout = 60 def setup(self) -> None: self.fixtures = load_fixtures(CROSS_FILE_FILENAME) def time_run_all_cross_file_fixtures(self) -> None: _run_suite(self.fixtures) def time_load_cross_file_fixtures(self) -> None: load_fixtures(CROSS_FILE_FILENAME) class CircularImportFixtureSuite: """Benchmarks for duplicate relative import fixture suite runtime.""" timeout = 60 def setup(self) -> None: self.fixtures = load_fixtures(CIRCULAR_FILENAME) def time_run_all_circular_fixtures(self) -> None: _run_suite(self.fixtures) def time_load_circular_fixtures(self) -> None: load_fixtures(CIRCULAR_FILENAME) class FullSuiteRuntime: """Benchmarks for running all fixture suites together.""" timeout = 120 def setup(self) -> None: self.all_fixtures: list[dict[str, Any]] = [] for filename in ALL_FIXTURE_FILENAMES: self.all_fixtures.extend(load_fixtures(filename)) # Pre-create service in setup so timing only measures validation self.service = SemanticValidationService() def time_run_all_suites(self) -> None: _run_suite(self.all_fixtures) def time_service_check_all_sources(self) -> None: self.service.cache.clear() for fixture in self.all_fixtures: self.service.check_file(fixture["source"], fixture["filename"])