"""ASV benchmarks for project context CLI command overhead. Measures the cost of: - Reading a context policy from the DB - Writing a context policy to the DB - Policy serialization round-trip for CLI output """ from __future__ import annotations import sys from pathlib import Path from typing import Any try: from cleveragents.domain.models.core.context_policy import ( ContextView, ProjectContextPolicy, ) from cleveragents.domain.models.core.project import ( NamespacedProject, parse_namespaced_name, ) from cleveragents.infrastructure.database.models import Base from cleveragents.infrastructure.database.repositories import ( NamespacedProjectRepository, ) except ModuleNotFoundError: sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) from cleveragents.domain.models.core.context_policy import ( ContextView, ProjectContextPolicy, ) from cleveragents.domain.models.core.project import ( NamespacedProject, parse_namespaced_name, ) from cleveragents.infrastructure.database.models import Base from cleveragents.infrastructure.database.repositories import ( NamespacedProjectRepository, ) from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker class _NoCloseSession: """Session wrapper that no-ops close().""" def __init__(self, real: object) -> None: object.__setattr__(self, "_real", real) def close(self) -> None: pass def __getattr__(self, name: str) -> Any: return getattr(object.__getattribute__(self, "_real"), name) def _make_repo_and_factory() -> tuple[NamespacedProjectRepository, Any]: engine = create_engine("sqlite:///:memory:", echo=False) Base.metadata.create_all(engine) sess = sessionmaker(bind=engine, expire_on_commit=False)() wrapper = _NoCloseSession(sess) def factory() -> Any: return wrapper repo = NamespacedProjectRepository(session_factory=factory) return repo, factory def _make_policy() -> ProjectContextPolicy: return ProjectContextPolicy( default_view=ContextView( include_resources=["db-*"], exclude_resources=["db-test"], include_paths=["src/**"], exclude_paths=["*.pyc"], max_file_size=1048576, max_total_size=10485760, ), strategize_view=ContextView( include_resources=["db-*", "cache-*"], ), execute_view=ContextView( include_paths=["src/**", "lib/**"], ), ) class ContextPolicyReadWriteSuite: """Benchmark policy read/write to DB.""" timeout = 30.0 def setup(self) -> None: from cleveragents.cli.commands.project_context import ( _write_policy, ) self.repo, self.sf = _make_repo_and_factory() parsed = parse_namespaced_name("bench-ctx") proj = NamespacedProject( name=parsed.name, namespace=parsed.namespace, ) self.repo.create(proj) _write_policy(self.sf, "local/bench-ctx", _make_policy()) def time_read_policy(self) -> None: from cleveragents.cli.commands.project_context import ( _read_policy, ) _read_policy(self.sf, "local/bench-ctx") def time_write_policy(self) -> None: from cleveragents.cli.commands.project_context import ( _write_policy, ) _write_policy(self.sf, "local/bench-ctx", _make_policy()) class ContextPolicySerializeSuite: """Benchmark policy serialization for CLI output.""" timeout = 30.0 def setup(self) -> None: self.policy = _make_policy() def time_model_dump(self) -> None: self.policy.model_dump(mode="json") def time_model_dump_json(self) -> None: self.policy.model_dump_json() def time_json_roundtrip(self) -> None: blob = self.policy.model_dump_json() ProjectContextPolicy.model_validate_json(blob) def time_resolve_and_dump(self) -> None: for phase in [ "default", "strategize", "execute", "apply", ]: v = self.policy.resolve_view(phase) v.model_dump(mode="json")