153 lines
4.2 KiB
Python
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")
|