Files
cleveragents-core/benchmarks/apply_pipeline_bench.py
T
2026-02-25 10:01:57 +00:00

170 lines
4.7 KiB
Python

"""ASV benchmarks for the validation-gated apply pipeline.
Measures the performance of:
- ApplyResult model construction
- Validation count extraction
- apply_with_validation_gate() with mock lifecycle
"""
from __future__ import annotations
import sys
from pathlib import Path
from typing import Any
from unittest.mock import MagicMock
try:
from cleveragents.application.services.plan_apply_service import (
ApplyOutcome,
ApplyResult,
PlanApplyService,
)
from cleveragents.domain.models.core.change import (
ChangeEntry,
ChangeOperation,
SpecChangeSet,
)
from cleveragents.domain.models.core.plan import (
PlanPhase,
PlanTimestamps,
ProcessingState,
)
except ModuleNotFoundError:
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from cleveragents.application.services.plan_apply_service import (
ApplyOutcome,
ApplyResult,
PlanApplyService,
)
from cleveragents.domain.models.core.change import (
ChangeEntry,
ChangeOperation,
SpecChangeSet,
)
from cleveragents.domain.models.core.plan import (
PlanPhase,
PlanTimestamps,
ProcessingState,
)
_PLAN_ID = "01BENCHPLAN0000000000001"
def _make_plan(
*,
changeset_id: str = "CS001",
validation_summary: dict[str, Any] | None = None,
) -> MagicMock:
plan = MagicMock()
plan.identity.plan_id = _PLAN_ID
plan.phase = PlanPhase.EXECUTE
plan.processing_state = ProcessingState.COMPLETE
plan.changeset_id = changeset_id
plan.validation_summary = validation_summary
plan.is_terminal = False
plan.error_details = None
plan.timestamps = PlanTimestamps()
return plan
def _make_changeset(n: int = 10) -> SpecChangeSet:
cs = SpecChangeSet(plan_id=_PLAN_ID)
for i in range(n):
cs.add_change(
ChangeEntry(
plan_id=_PLAN_ID,
resource_id="RES001",
tool_name="builtin/bench-tool",
operation=ChangeOperation.MODIFY,
path=f"src/mod_{i:04d}.py",
before_hash=f"b{i}",
after_hash=f"a{i}",
)
)
return cs
def _make_service(plan: MagicMock, changeset: SpecChangeSet) -> PlanApplyService:
lifecycle = MagicMock()
lifecycle.get_plan.return_value = plan
lifecycle.complete_apply.return_value = plan
lifecycle._commit_plan = MagicMock()
store = MagicMock()
store.get.return_value = changeset
return PlanApplyService(lifecycle_service=lifecycle, changeset_store=store)
class ApplyResultSuite:
"""Benchmark ApplyResult model construction."""
def time_result_construction_applied(self) -> None:
ApplyResult(
outcome=ApplyOutcome.APPLIED,
plan_id=_PLAN_ID,
message="applied ok",
files_changed=10,
validations_total=5,
validations_passed=5,
validations_failed=0,
)
def time_result_construction_constrained(self) -> None:
ApplyResult(
outcome=ApplyOutcome.CONSTRAINED,
plan_id=_PLAN_ID,
message="blocked",
validations_total=5,
validations_passed=3,
validations_failed=2,
)
class ApplyValidationCountSuite:
"""Benchmark validation count extraction."""
def setup(self) -> None:
self.summary: dict[str, Any] = {
"total": 100,
"required_passed": 80,
"required_failed": 20,
}
self.empty_summary: dict[str, Any] | None = None
def time_extract_counts(self) -> None:
PlanApplyService._extract_validation_counts(self.summary)
def time_extract_counts_none(self) -> None:
PlanApplyService._extract_validation_counts(self.empty_summary)
class ApplyGateSuite:
"""Benchmark the full apply_with_validation_gate flow."""
def setup(self) -> None:
cs = _make_changeset(20)
self.plan_pass = _make_plan(
changeset_id=cs.changeset_id,
validation_summary={
"total": 5,
"required_passed": 5,
"required_failed": 0,
},
)
self.plan_fail = _make_plan(
changeset_id=cs.changeset_id,
validation_summary={
"total": 5,
"required_passed": 3,
"required_failed": 2,
},
)
self.svc_pass = _make_service(self.plan_pass, cs)
self.svc_fail = _make_service(self.plan_fail, cs)
def time_apply_gate_pass(self) -> None:
self.svc_pass.apply_with_validation_gate(_PLAN_ID)
def time_apply_gate_fail(self) -> None:
self.svc_fail.apply_with_validation_gate(_PLAN_ID)