Files
cleveragents-core/benchmarks/execution_environment_bench.py
T
freemo ad5f737721 feat(execution): add execution environment routing
Add ExecutionEnvironment enum (host/container) to domain models, implement
execution environment resolution with priority chain (tool > plan > project
> default), wire the tool runner to check execution_environment before
execution, and add CLI flags to plan use/execute and project context set.

When container is selected but no container resource is available, a clear
ContainerUnavailableError is raised with an actionable message.

Closes #512
2026-03-03 14:48:55 -05:00

120 lines
3.6 KiB
Python

"""ASV benchmarks for execution environment routing.
Measures the performance of:
- ExecutionEnvironmentResolver.resolve() overhead
- ExecutionEnvironmentResolver.validate_container_available() overhead
- ExecutionEnvironmentResolver.resolve_and_validate() overhead
- ExecutionEnvironment enum instantiation
"""
from __future__ import annotations
import importlib
import sys
from pathlib import Path
# Ensure the local source tree is importable
_SRC = str(Path(__file__).resolve().parents[1] / "src")
if _SRC not in sys.path:
sys.path.insert(0, _SRC)
import cleveragents # noqa: E402
importlib.reload(cleveragents)
from cleveragents.application.services.execution_environment_resolver import ( # noqa: E402
ContainerUnavailableError,
ExecutionEnvironmentResolver,
)
from cleveragents.domain.models.core.plan import ExecutionEnvironment # noqa: E402
# ---------------------------------------------------------------------------
# Resolver resolution benchmarks
# ---------------------------------------------------------------------------
class ResolverResolutionSuite:
"""Benchmark resolution overhead."""
timeout = 60
def setup(self) -> None:
self.resolver = ExecutionEnvironmentResolver()
def time_resolve_default(self) -> None:
self.resolver.resolve()
def time_resolve_tool_override(self) -> None:
self.resolver.resolve(tool_env="container")
def time_resolve_full_chain(self) -> None:
self.resolver.resolve(
tool_env="host",
plan_env="container",
project_env="container",
default="host",
)
def time_resolve_plan_only(self) -> None:
self.resolver.resolve(plan_env="container")
def time_resolve_project_only(self) -> None:
self.resolver.resolve(project_env="host")
# ---------------------------------------------------------------------------
# Container validation benchmarks
# ---------------------------------------------------------------------------
class ContainerValidationSuite:
"""Benchmark container availability validation overhead."""
timeout = 60
def setup(self) -> None:
self.resolver = ExecutionEnvironmentResolver()
self.container_types = ["devcontainer-instance", "git-checkout"]
self.no_container_types = ["git-checkout", "fs-directory"]
def time_validate_with_container(self) -> None:
self.resolver.validate_container_available(self.container_types)
def time_validate_without_container_exception(self) -> None:
try:
self.resolver.validate_container_available(self.no_container_types)
except ContainerUnavailableError:
pass
def time_resolve_and_validate_host(self) -> None:
self.resolver.resolve_and_validate(
linked_resource_types=self.container_types,
project_env="host",
)
def time_resolve_and_validate_container(self) -> None:
self.resolver.resolve_and_validate(
linked_resource_types=self.container_types,
plan_env="container",
)
# ---------------------------------------------------------------------------
# Enum instantiation benchmarks
# ---------------------------------------------------------------------------
class EnumInstantiationSuite:
"""Benchmark ExecutionEnvironment enum overhead."""
timeout = 60
def time_create_host(self) -> None:
ExecutionEnvironment("host")
def time_create_container(self) -> None:
ExecutionEnvironment("container")
def time_resolver_instantiation(self) -> None:
ExecutionEnvironmentResolver()