ad5f737721
CI / lint (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 25s
CI / typecheck (pull_request) Successful in 35s
CI / benchmark-publish (pull_request) Has been skipped
CI / security (pull_request) Successful in 38s
CI / build (pull_request) Successful in 21s
CI / unit_tests (pull_request) Successful in 3m42s
CI / docker (pull_request) Successful in 42s
CI / coverage (pull_request) Successful in 4m9s
CI / integration_tests (pull_request) Successful in 4m33s
CI / lint (push) Successful in 13s
CI / quality (push) Successful in 18s
CI / typecheck (push) Successful in 34s
CI / build (push) Successful in 19s
CI / benchmark-regression (push) Has been skipped
CI / security (push) Successful in 48s
CI / integration_tests (push) Successful in 2m55s
CI / unit_tests (push) Successful in 3m10s
CI / docker (push) Successful in 59s
CI / coverage (push) Successful in 4m46s
CI / benchmark-publish (push) Successful in 14m18s
CI / benchmark-regression (pull_request) Successful in 26m2s
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
148 lines
7.3 KiB
Gherkin
148 lines
7.3 KiB
Gherkin
Feature: Execution environment routing
|
|
As the tool execution engine
|
|
I need to route tool execution to host or container environments
|
|
With a priority chain: tool > plan > project > default (host)
|
|
|
|
# ── ExecutionEnvironment enum ───────────────────────────────────────
|
|
|
|
Scenario: ExecutionEnvironment enum has HOST value
|
|
Given I import ExecutionEnvironment
|
|
Then the HOST value should be "host"
|
|
|
|
Scenario: ExecutionEnvironment enum has CONTAINER value
|
|
Given I import ExecutionEnvironment
|
|
Then the CONTAINER value should be "container"
|
|
|
|
Scenario: ExecutionEnvironment is a StrEnum
|
|
Given I import ExecutionEnvironment
|
|
Then ExecutionEnvironment should be a StrEnum subclass
|
|
|
|
# ── Plan model field ────────────────────────────────────────────────
|
|
|
|
Scenario: Plan model has execution_environment field defaulting to None
|
|
Given I create a plan with default fields
|
|
Then the plan execution_environment should be None
|
|
|
|
Scenario: Plan model accepts execution_environment host
|
|
Given I create a plan with execution_environment "host"
|
|
Then the plan execution_environment should be "host"
|
|
|
|
Scenario: Plan model accepts execution_environment container
|
|
Given I create a plan with execution_environment "container"
|
|
Then the plan execution_environment should be "container"
|
|
|
|
# ── ContextConfig model field ───────────────────────────────────────
|
|
|
|
Scenario: ContextConfig has execution_environment field defaulting to None
|
|
Given I create a ContextConfig with default fields
|
|
Then the context config execution_environment should be None
|
|
|
|
Scenario: ContextConfig accepts execution_environment host
|
|
Given I create a ContextConfig with execution_environment "host"
|
|
Then the context config execution_environment should be "host"
|
|
|
|
Scenario: ContextConfig accepts execution_environment container
|
|
Given I create a ContextConfig with execution_environment "container"
|
|
Then the context config execution_environment should be "container"
|
|
|
|
# ── Resolver: default resolution ────────────────────────────────────
|
|
|
|
Scenario: Resolver defaults to host when nothing is set
|
|
Given I create an ExecutionEnvironmentResolver
|
|
When I resolve with no overrides
|
|
Then the resolved environment should be "host"
|
|
|
|
Scenario: Resolver uses explicit default
|
|
Given I create an ExecutionEnvironmentResolver
|
|
When I resolve with default "container"
|
|
Then the resolved environment should be "container"
|
|
|
|
# ── Resolver: priority chain ────────────────────────────────────────
|
|
|
|
Scenario: Project-level overrides default
|
|
Given I create an ExecutionEnvironmentResolver
|
|
When I resolve with project_env "container"
|
|
Then the resolved environment should be "container"
|
|
|
|
Scenario: Plan-level overrides project-level
|
|
Given I create an ExecutionEnvironmentResolver
|
|
When I resolve with plan_env "host" and project_env "container"
|
|
Then the resolved environment should be "host"
|
|
|
|
Scenario: Tool-level overrides plan-level
|
|
Given I create an ExecutionEnvironmentResolver
|
|
When I resolve with tool_env "container" and plan_env "host"
|
|
Then the resolved environment should be "container"
|
|
|
|
Scenario: Full priority chain tool wins
|
|
Given I create an ExecutionEnvironmentResolver
|
|
When I resolve the full chain with tool_env "container" and plan_env "host" and project_env "host"
|
|
Then the resolved environment should be "container"
|
|
|
|
# ── Resolver: validation ────────────────────────────────────────────
|
|
|
|
Scenario: Resolver raises ValueError on invalid environment
|
|
Given I create an ExecutionEnvironmentResolver
|
|
When I resolve with tool_env "invalid_env"
|
|
Then exec-env a ValueError should be raised
|
|
|
|
# ── Container availability ──────────────────────────────────────────
|
|
|
|
Scenario: validate_container_available succeeds with container resource
|
|
Given I create an ExecutionEnvironmentResolver
|
|
When I validate container available with types "devcontainer-instance,git-checkout"
|
|
Then validation should succeed
|
|
|
|
Scenario: validate_container_available raises when no container resource
|
|
Given I create an ExecutionEnvironmentResolver
|
|
When I validate container available with types "git-checkout,fs-directory"
|
|
Then a ContainerUnavailableError should be raised
|
|
|
|
Scenario: resolve_and_validate passes for host
|
|
Given I create an ExecutionEnvironmentResolver
|
|
When I resolve_and_validate with project_env "host" and types "git-checkout"
|
|
Then the resolved environment should be "host"
|
|
|
|
Scenario: resolve_and_validate raises for container without resource
|
|
Given I create an ExecutionEnvironmentResolver
|
|
When I resolve_and_validate with plan_env "container" and types "git-checkout"
|
|
Then a ContainerUnavailableError should be raised
|
|
|
|
Scenario: resolve_and_validate passes for container with resource
|
|
Given I create an ExecutionEnvironmentResolver
|
|
When I resolve_and_validate with plan_env "container" and types "devcontainer-instance"
|
|
Then the resolved environment should be "container"
|
|
|
|
# ── ToolRunner integration ──────────────────────────────────────────
|
|
|
|
Scenario: ToolRunner routes to host by default
|
|
Given I create a ToolRunner with a mock registry
|
|
When I execute a tool with no environment overrides
|
|
Then the tool should execute successfully on host
|
|
|
|
Scenario: ToolRunner returns error for container without resource
|
|
Given I create a ToolRunner with a mock registry
|
|
When I execute a tool with plan_env "container" and no container resources
|
|
Then the tool result should have an error about container unavailable
|
|
|
|
# ── Container resource types ────────────────────────────────────────
|
|
|
|
Scenario: CONTAINER_RESOURCE_TYPES includes expected types
|
|
Given I import CONTAINER_RESOURCE_TYPES
|
|
Then it should contain "container-instance"
|
|
And it should contain "devcontainer-instance"
|
|
And it should contain "devcontainer-file"
|
|
And it should not contain "git-checkout"
|
|
|
|
# ── ContainerUnavailableError ───────────────────────────────────────
|
|
|
|
Scenario: ContainerUnavailableError includes project name
|
|
When I create a ContainerUnavailableError for project "my-project"
|
|
Then exec-env the error message should contain "my-project"
|
|
And exec-env the error message should contain "Container resource unavailable"
|
|
|
|
Scenario: ContainerUnavailableError without project name
|
|
When I create a ContainerUnavailableError without project name
|
|
Then exec-env the error message should contain "Container resource unavailable"
|
|
And exec-env the error message should not contain "for project"
|