"""ASV benchmarks for Plugin Architecture Framework. Measures the performance of: - PluginLoader.load_class() import overhead - PluginLoader.validate_protocol() check overhead - PluginManager registration, activation, deactivation overhead - PluginDescriptor construction overhead - Config-driven registration overhead """ from __future__ import annotations import importlib import sys from pathlib import Path # Ensure the local *source* tree is importable even when ASV has an # older build of the package installed. _SRC = str(Path(__file__).resolve().parents[1] / "src") if _SRC not in sys.path: sys.path.insert(0, _SRC) # Force-reload so ASV picks up the source tree version. import cleveragents # noqa: E402 importlib.reload(cleveragents) from cleveragents.domain.models.acms.backends import ( # noqa: E402 TextBackend, TextResult, ) from cleveragents.infrastructure.plugins.loader import PluginLoader # noqa: E402 from cleveragents.infrastructure.plugins.manager import PluginManager # noqa: E402 from cleveragents.infrastructure.plugins.types import ( # noqa: E402 ExtensionPoint, PluginDescriptor, PluginState, ) # --------------------------------------------------------------------------- # Helper classes # --------------------------------------------------------------------------- class _FakeTextBackend: """Minimal class satisfying the TextBackend protocol.""" def search( self, query: str, *, scope: frozenset[str], max_results: int = 20, ) -> list[TextResult]: return [] # --------------------------------------------------------------------------- # PluginLoader benchmarks # --------------------------------------------------------------------------- class PluginLoaderSuite: """Benchmark PluginLoader class loading overhead.""" timeout = 60 def setup(self) -> None: self.loader = PluginLoader() def time_load_class(self) -> None: self.loader.load_class( "cleveragents.domain.models.acms.stubs", "InMemoryTextBackend", ) def time_validate_protocol_pass(self) -> None: PluginLoader.validate_protocol(_FakeTextBackend, TextBackend) # --------------------------------------------------------------------------- # PluginDescriptor benchmarks # --------------------------------------------------------------------------- class PluginDescriptorSuite: """Benchmark PluginDescriptor construction overhead.""" timeout = 60 def time_create_minimal(self) -> None: PluginDescriptor(name="bench-plugin") def time_create_full(self) -> None: PluginDescriptor( name="bench-full", version="1.0.0", author="bench", description="benchmark plugin", module_path="cleveragents.test", class_name="TestClass", extension_points=["ep1", "ep2"], dependencies=["dep1"], state=PluginState.DISCOVERED, ) # --------------------------------------------------------------------------- # PluginManager benchmarks # --------------------------------------------------------------------------- class PluginManagerSuite: """Benchmark PluginManager registration and lifecycle overhead.""" timeout = 60 def setup(self) -> None: self.manager = PluginManager() self._counter = 0 def time_register_plugin(self) -> None: self._counter += 1 desc = PluginDescriptor( name=f"bench-reg-{self._counter}", module_path="cleveragents.domain.models.acms.stubs", class_name="InMemoryTextBackend", ) self.manager.register_plugin(desc) def time_register_from_config(self) -> None: self._counter += 1 config = { "custom_module": "cleveragents.domain.models.acms.stubs", "custom_class": "InMemoryTextBackend", "name": f"bench-cfg-{self._counter}", } self.manager.register_from_config(config) def time_list_plugins(self) -> None: self.manager.list_plugins() class PluginManagerLifecycleSuite: """Benchmark activate/deactivate cycle.""" timeout = 60 def setup(self) -> None: self.manager = PluginManager() self._counter = 0 def time_activate_deactivate_cycle(self) -> None: self._counter += 1 name = f"bench-life-{self._counter}" desc = PluginDescriptor( name=name, module_path="cleveragents.domain.models.acms.stubs", class_name="InMemoryTextBackend", ) self.manager.register_plugin(desc) self.manager.activate_plugin(name) self.manager.deactivate_plugin(name) # --------------------------------------------------------------------------- # ExtensionPoint benchmarks # --------------------------------------------------------------------------- class ExtensionPointSuite: """Benchmark ExtensionPoint creation overhead.""" timeout = 60 def time_create_extension_point(self) -> None: ExtensionPoint( name="bench-ep", protocol_type=TextBackend, description="Benchmark extension point", registry_key="bench_key", )