583e6b7ea2
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 14s
CI / build (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 17s
CI / security (pull_request) Successful in 36s
CI / typecheck (pull_request) Successful in 54s
CI / unit_tests (pull_request) Successful in 2m39s
CI / integration_tests (pull_request) Successful in 3m10s
CI / docker (pull_request) Successful in 40s
CI / coverage (pull_request) Successful in 5m0s
CI / lint (push) Successful in 14s
CI / build (push) Successful in 15s
CI / quality (push) Successful in 16s
CI / security (push) Successful in 34s
CI / typecheck (push) Successful in 35s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 2m23s
CI / docker (push) Successful in 38s
CI / integration_tests (push) Successful in 3m8s
CI / coverage (push) Successful in 5m10s
CI / benchmark-publish (push) Successful in 16m26s
CI / benchmark-regression (pull_request) Successful in 30m12s
Implement spec-mandated Layer 4 Predictive Error Prevention system: - ErrorPattern domain model with pattern text, historical failures, preventive checks, frequency tracking, and keyword-based matching. - ErrorPatternRepository with in-memory CRUD + context-matching query. - ErrorPatternService with record_failure(), match_patterns(), and get_statistics() methods. - Wire into plan execution via plan_lifecycle_service pre-execution hook. - Add error pattern statistics to CLI diagnostics output. Behave BDD: 11 scenarios covering recording, matching, formatting, stats. Robot Framework: 3 integration smoke tests. ASV benchmarks: pattern matching performance. ISSUES CLOSED: #571
159 lines
4.5 KiB
Python
159 lines
4.5 KiB
Python
"""ASV benchmarks for Layer 4 — Predictive Error Prevention.
|
|
|
|
Measures pattern matching performance with large databases,
|
|
recording throughput, and guidance generation latency.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from cleveragents.application.services.error_pattern_service import (
|
|
ErrorPatternService,
|
|
)
|
|
from cleveragents.infrastructure.database.error_pattern_repository import (
|
|
ErrorPatternRepository,
|
|
)
|
|
|
|
|
|
def _make_service(num_patterns: int = 0) -> ErrorPatternService:
|
|
"""Create a service and optionally seed it with patterns."""
|
|
repo = ErrorPatternRepository()
|
|
service = ErrorPatternService(repository=repo)
|
|
for i in range(num_patterns):
|
|
service.record_failure(
|
|
pattern_text=f"Error pattern number {i} in module_{i % 10}",
|
|
failure_description=f"Failure description {i}",
|
|
preventive_checks=(f"Check {i}-a", f"Check {i}-b"),
|
|
keywords=(f"pattern{i}", f"module_{i % 10}", "error"),
|
|
)
|
|
return service
|
|
|
|
|
|
class TimeRecordSingle:
|
|
"""Benchmark recording a single failure pattern."""
|
|
|
|
timeout = 30
|
|
|
|
def setup(self) -> None:
|
|
self.service = _make_service()
|
|
|
|
def time_record_single_failure(self) -> None:
|
|
self.service.record_failure(
|
|
pattern_text="Benchmark failure pattern",
|
|
failure_description="Test failure",
|
|
preventive_checks=("Check A", "Check B"),
|
|
keywords=("benchmark", "failure"),
|
|
)
|
|
|
|
|
|
class TimeRecordBatch:
|
|
"""Benchmark recording a batch of failure patterns."""
|
|
|
|
timeout = 60
|
|
|
|
def setup(self) -> None:
|
|
self.service = _make_service()
|
|
|
|
def time_record_100_failures(self) -> None:
|
|
for i in range(100):
|
|
self.service.record_failure(
|
|
pattern_text=f"Batch failure pattern {i}",
|
|
failure_description=f"Failure {i}",
|
|
preventive_checks=(f"Check {i}",),
|
|
keywords=(f"batch{i}",),
|
|
)
|
|
|
|
|
|
class TimeMatchSmallDB:
|
|
"""Benchmark pattern matching against a small database (10 patterns)."""
|
|
|
|
timeout = 30
|
|
|
|
def setup(self) -> None:
|
|
self.service = _make_service(num_patterns=10)
|
|
|
|
def time_match_context_small(self) -> None:
|
|
self.service.match_patterns("We need to fix error pattern number 5 in module_5")
|
|
|
|
|
|
class TimeMatchMediumDB:
|
|
"""Benchmark pattern matching against a medium database (100 patterns)."""
|
|
|
|
timeout = 60
|
|
|
|
def setup(self) -> None:
|
|
self.service = _make_service(num_patterns=100)
|
|
|
|
def time_match_context_medium(self) -> None:
|
|
self.service.match_patterns(
|
|
"We need to fix error pattern number 50 in module_5"
|
|
)
|
|
|
|
|
|
class TimeMatchLargeDB:
|
|
"""Benchmark pattern matching against a large database (1000 patterns)."""
|
|
|
|
timeout = 120
|
|
|
|
def setup(self) -> None:
|
|
self.service = _make_service(num_patterns=1000)
|
|
|
|
def time_match_context_large(self) -> None:
|
|
self.service.match_patterns(
|
|
"We need to fix error pattern number 500 in module_5"
|
|
)
|
|
|
|
def time_match_no_results_large(self) -> None:
|
|
self.service.match_patterns(
|
|
"Completely unrelated context about cooking recipes"
|
|
)
|
|
|
|
|
|
class TimeGuidanceFormatting:
|
|
"""Benchmark guidance formatting after matching."""
|
|
|
|
timeout = 30
|
|
|
|
def setup(self) -> None:
|
|
self.service = _make_service(num_patterns=50)
|
|
self.guidance = self.service.match_patterns("We need to fix error in module_5")
|
|
|
|
def time_format_guidance(self) -> None:
|
|
self.guidance.format_for_context()
|
|
|
|
|
|
class TimeStatistics:
|
|
"""Benchmark statistics computation."""
|
|
|
|
timeout = 30
|
|
|
|
def setup(self) -> None:
|
|
self.service = _make_service(num_patterns=500)
|
|
|
|
def time_get_statistics(self) -> None:
|
|
self.service.get_statistics()
|
|
|
|
def time_list_patterns(self) -> None:
|
|
self.service.list_patterns()
|
|
|
|
|
|
class TimeDuplicateRecording:
|
|
"""Benchmark recording duplicate patterns (frequency updates)."""
|
|
|
|
timeout = 60
|
|
|
|
def setup(self) -> None:
|
|
self.service = _make_service()
|
|
self.service.record_failure(
|
|
pattern_text="Recurring failure",
|
|
failure_description="Initial occurrence",
|
|
preventive_checks=("Check A",),
|
|
keywords=("recurring",),
|
|
)
|
|
|
|
def time_record_duplicate_100_times(self) -> None:
|
|
for i in range(100):
|
|
self.service.record_failure(
|
|
pattern_text="Recurring failure",
|
|
failure_description=f"Occurrence {i + 2}",
|
|
)
|