Files
cleveragents-core/benchmarks/project_context_cli_bench.py

153 lines
4.2 KiB
Python

"""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")