"""ASV benchmarks for custom sandbox strategy registration. Measures the performance of: - SandboxRef creation - DiffView / DiffEntry model creation - SandboxStrategyRegistry registration and lookup - BuiltInSandboxStrategyAdapter create/write/read cycle - Protocol runtime checking via isinstance """ from __future__ import annotations import importlib import os import sys import tempfile from datetime import datetime 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.core.resource import ( # noqa: E402 PhysVirt, Resource, ResourceCapabilities, ) from cleveragents.domain.models.core.resource import ( # noqa: E402 SandboxStrategy as SandboxStrategyEnum, ) from cleveragents.domain.models.core.sandbox_strategy import ( # noqa: E402 DiffEntry, DiffView, SandboxRef, SandboxStrategyProtocol, ) from cleveragents.infrastructure.sandbox.strategy_adapter import ( # noqa: E402 BuiltInSandboxStrategyAdapter, ) from cleveragents.infrastructure.sandbox.strategy_registry import ( # noqa: E402 SandboxStrategyRegistry, ) # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- _COUNTER = 0 def _ulid(name: str) -> str: global _COUNTER _COUNTER += 1 base = abs(hash(name)) % (10**20) raw = f"{_COUNTER:06d}{base:020d}" charset = "0123456789ABCDEFGHJKMNPQRSTVWXYZ" result = "" for ch in raw: result += charset[int(ch)] return (result + "0" * 26)[:26] class _MockStrategy: """Minimal strategy satisfying the Protocol for benchmarking.""" def create(self, plan_id, resource): return None def read(self, ref, path): return b"" def write(self, ref, path, content): return None def diff(self, ref): return None def commit(self, ref): pass def rollback(self, ref): pass def checkpoint(self, ref, checkpoint_id): pass def restore_checkpoint(self, ref, checkpoint_id): pass def cleanup(self, ref): pass # --------------------------------------------------------------------------- # SandboxRef benchmarks # --------------------------------------------------------------------------- class TimeSandboxRef: """Benchmark SandboxRef creation.""" def time_create_ref(self) -> None: SandboxRef( sandbox_id="bench-ref", plan_id="bench-plan", resource_id="bench-res", created_at=datetime.now(), ) def time_create_ref_with_metadata(self) -> None: SandboxRef( sandbox_id="bench-ref-meta", plan_id="bench-plan", resource_id="bench-res", created_at=datetime.now(), metadata={"key": "value", "num": 42}, ) # --------------------------------------------------------------------------- # DiffEntry / DiffView benchmarks # --------------------------------------------------------------------------- class TimeDiffModels: """Benchmark DiffEntry and DiffView creation.""" def time_create_diff_entry(self) -> None: DiffEntry(path="bench.txt", operation="modified") def time_create_diff_entry_with_content(self) -> None: DiffEntry( path="bench.txt", operation="modified", before=b"old", after=b"new", ) def time_create_diff_view_10_entries(self) -> None: entries = [ DiffEntry(path=f"file{i}.txt", operation="modified") for i in range(10) ] DiffView(sandbox_id="bench-dv", entries=entries) # --------------------------------------------------------------------------- # Protocol checking benchmarks # --------------------------------------------------------------------------- class TimeProtocolCheck: """Benchmark SandboxStrategyProtocol isinstance checks.""" def setup(self) -> None: self.good = _MockStrategy() def time_isinstance_check_pass(self) -> None: isinstance(self.good, SandboxStrategyProtocol) def time_isinstance_check_fail(self) -> None: isinstance("not a strategy", SandboxStrategyProtocol) # --------------------------------------------------------------------------- # SandboxStrategyRegistry benchmarks # --------------------------------------------------------------------------- class TimeStrategyRegistry: """Benchmark registry operations.""" def setup(self) -> None: self.registry = SandboxStrategyRegistry( allowed_prefixes=("cleveragents.",), ) self.registry.register( "bench_adapter", "cleveragents.infrastructure.sandbox.strategy_adapter", "BuiltInSandboxStrategyAdapter", ) def time_lookup_hit(self) -> None: self.registry.get("bench_adapter") def time_lookup_miss(self) -> None: self.registry.get("nonexistent") def time_has_check(self) -> None: self.registry.has("bench_adapter") def time_list_strategies(self) -> None: self.registry.list_strategies() # --------------------------------------------------------------------------- # BuiltInSandboxStrategyAdapter benchmarks # --------------------------------------------------------------------------- class TimeAdapterLifecycle: """Benchmark adapter create/write/read cycle.""" def setup(self) -> None: self.tmpdir = tempfile.mkdtemp(prefix="ca-bench-adapter-") with open(os.path.join(self.tmpdir, "seed.txt"), "w") as f: f.write("seed") self.adapter = BuiltInSandboxStrategyAdapter(strategy_name="copy_on_write") self.resource = Resource( resource_id=_ulid("bench-adapter"), name="bench-adapter", resource_type_name="fs-directory", classification=PhysVirt.PHYSICAL, sandbox_strategy=SandboxStrategyEnum.COPY_ON_WRITE, location=self.tmpdir, capabilities=ResourceCapabilities( readable=True, writable=True, sandboxable=True, checkpointable=False, ), ) def time_create_and_cleanup(self) -> None: ref = self.adapter.create("bench-plan", self.resource) self.adapter.cleanup(ref) def time_write_read_cycle(self) -> None: ref = self.adapter.create("bench-plan-wr", self.resource) self.adapter.write(ref, "bench.txt", b"bench content") self.adapter.read(ref, "bench.txt") self.adapter.cleanup(ref) def teardown(self) -> None: import shutil shutil.rmtree(self.tmpdir, ignore_errors=True)