41ca082022
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Failing after 13s
CI / quality (pull_request) Successful in 17s
CI / build (pull_request) Successful in 17s
CI / typecheck (pull_request) Successful in 34s
CI / security (pull_request) Successful in 33s
CI / coverage (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 2m31s
CI / unit_tests (pull_request) Successful in 6m43s
CI / docker (pull_request) Has been skipped
210 lines
8.9 KiB
Gherkin
210 lines
8.9 KiB
Gherkin
@plan @executor @coverage
|
|
Feature: PlanExecutor coverage gaps
|
|
As a developer
|
|
I want comprehensive tests for PlanExecutor, StrategizeStubActor, and ExecuteStubActor
|
|
So that uncovered branches and lines are fully exercised
|
|
|
|
# -- PlanExecutor __init__ validation --
|
|
|
|
@init @error
|
|
Scenario: PlanExecutor raises ValidationError when lifecycle_service is None
|
|
When I construct a PlanExecutor with None lifecycle_service
|
|
Then a PE ValidationError should be raised containing "lifecycle_service"
|
|
|
|
@init
|
|
Scenario: PlanExecutor initialises successfully with valid lifecycle_service
|
|
Given a mock plan lifecycle service
|
|
When I construct a PlanExecutor with the mock lifecycle service
|
|
Then the PlanExecutor should be created without error
|
|
|
|
# -- has_runtime property --
|
|
|
|
@property
|
|
Scenario: has_runtime is True when execution_context is provided
|
|
Given a mock plan lifecycle service
|
|
And a mock execution context
|
|
When I construct a PlanExecutor with the mock lifecycle service and execution context
|
|
Then the executor has_runtime property should be True
|
|
|
|
@property
|
|
Scenario: has_runtime is False when no execution_context is provided
|
|
Given a mock plan lifecycle service
|
|
When I construct a PlanExecutor with the mock lifecycle service
|
|
Then the executor has_runtime property should be False
|
|
|
|
# -- changeset_store property --
|
|
|
|
@property
|
|
Scenario: changeset_store returns store from execution_context
|
|
Given a mock plan lifecycle service
|
|
And a mock execution context with a changeset store
|
|
When I construct a PlanExecutor with the mock lifecycle service and execution context
|
|
Then the executor changeset_store should be the mock store
|
|
|
|
@property
|
|
Scenario: changeset_store returns None when no execution_context
|
|
Given a mock plan lifecycle service
|
|
When I construct a PlanExecutor with the mock lifecycle service
|
|
Then the executor changeset_store should be None
|
|
|
|
# -- run_strategize guard: wrong phase --
|
|
|
|
@strategize @error
|
|
Scenario: run_strategize raises PlanError when plan is not in STRATEGIZE phase
|
|
Given a mock plan lifecycle service
|
|
And a PlanExecutor with the mock lifecycle service
|
|
And the lifecycle returns a plan in EXECUTE phase
|
|
When I attempt to run strategize on the executor
|
|
Then a PE PlanError should be raised containing "not in Strategize phase"
|
|
|
|
# -- run_strategize guard: empty plan_id --
|
|
|
|
@strategize @error
|
|
Scenario: run_strategize raises ValidationError for empty plan_id
|
|
Given a mock plan lifecycle service
|
|
And a PlanExecutor with the mock lifecycle service
|
|
When I attempt to run strategize with an empty plan_id
|
|
Then a PE ValidationError should be raised containing "plan_id"
|
|
|
|
# -- run_strategize exception handling (except branch) --
|
|
|
|
@strategize @error
|
|
Scenario: run_strategize calls fail_strategize when an exception occurs during execution
|
|
Given a mock plan lifecycle service
|
|
And a PlanExecutor with the mock lifecycle service
|
|
And the lifecycle returns a plan in STRATEGIZE phase
|
|
And the lifecycle start_strategize will raise a RuntimeError
|
|
When I attempt to run strategize and expect an exception
|
|
Then fail_strategize should have been called with the plan_id
|
|
And the raised exception should be a RuntimeError
|
|
|
|
@strategize @error
|
|
Scenario: run_strategize records error_details on plan when exception occurs
|
|
Given a mock plan lifecycle service
|
|
And a PlanExecutor with the mock lifecycle service
|
|
And the lifecycle returns a plan in STRATEGIZE phase that fails during actor execute
|
|
When I attempt to run strategize and expect an exception
|
|
Then the plan error_details should contain the exception_type
|
|
And fail_strategize should have been called with the plan_id
|
|
|
|
# -- _guard_execute: wrong phase --
|
|
|
|
@execute @error
|
|
Scenario: run_execute raises PlanError when plan is not in EXECUTE phase
|
|
Given a mock plan lifecycle service
|
|
And a PlanExecutor with the mock lifecycle service
|
|
And the lifecycle returns a plan in STRATEGIZE phase for execute guard
|
|
When I attempt to run execute on the executor
|
|
Then a PE PlanError should be raised containing "not in Execute phase"
|
|
|
|
# -- _guard_execute: wrong state --
|
|
|
|
@execute @error
|
|
Scenario: run_execute raises PlanError when plan state is not QUEUED
|
|
Given a mock plan lifecycle service
|
|
And a PlanExecutor with the mock lifecycle service
|
|
And the lifecycle returns a plan in EXECUTE phase with PROCESSING state
|
|
When I attempt to run execute on the executor
|
|
Then a PE PlanError should be raised containing "not queued for execution"
|
|
|
|
# -- _guard_execute: None decision_root_id --
|
|
|
|
@execute @error
|
|
Scenario: run_execute raises PlanError when decision_root_id is None
|
|
Given a mock plan lifecycle service
|
|
And a PlanExecutor with the mock lifecycle service
|
|
And the lifecycle returns a plan in EXECUTE phase with QUEUED state but no decision root
|
|
When I attempt to run execute on the executor
|
|
Then a PE PlanError should be raised containing "no decision tree"
|
|
|
|
# -- run_execute routing to stub --
|
|
|
|
@execute @stub
|
|
Scenario: run_execute routes to stub actor when no execution_context
|
|
Given a mock plan lifecycle service
|
|
And a PlanExecutor with the mock lifecycle service and no execution context
|
|
And the lifecycle returns a fully valid plan for stub execution
|
|
When I run execute on the executor
|
|
Then the plan executor result should be an ExecuteResult
|
|
And complete_execute should have been called
|
|
|
|
# -- run_execute routing to runtime --
|
|
|
|
@execute @runtime
|
|
Scenario: run_execute routes to runtime actor when execution_context is set
|
|
Given a mock plan lifecycle service
|
|
And a mock execution context
|
|
And a PlanExecutor with the mock lifecycle service and execution context and tool runner
|
|
And the lifecycle returns a fully valid plan for runtime execution
|
|
When I run execute on the executor
|
|
Then the plan executor result should be a RuntimeExecuteResult
|
|
And complete_execute should have been called
|
|
|
|
# -- StrategizeStubActor with stream_callback --
|
|
|
|
@actor @strategize
|
|
Scenario: StrategizeStubActor emits stream events when callback is provided
|
|
Given a stream event collector
|
|
When I execute the StrategizeStubActor with a plan_id and stream callback
|
|
Then the collector should contain a "strategize_started" event
|
|
And the collector should contain a "strategize_decisions" event
|
|
And the collector should contain a "strategize_complete" event
|
|
|
|
@actor @strategize
|
|
Scenario: StrategizeStubActor works without stream_callback
|
|
When I execute the StrategizeStubActor with a plan_id and no callback
|
|
Then the strategize result should have a valid decision_root_id
|
|
And the strategize result should have at least one decision
|
|
|
|
# -- ExecuteStubActor with stream_callback --
|
|
|
|
@actor @execute
|
|
Scenario: ExecuteStubActor emits stream events when callback is provided
|
|
Given a stream event collector
|
|
And a list of two strategy decisions
|
|
When I execute the ExecuteStubActor with the decisions and stream callback
|
|
Then the collector should contain an "execute_started" event
|
|
And the collector should contain an "execute_step" event
|
|
And the collector should contain an "execute_complete" event
|
|
|
|
@actor @execute
|
|
Scenario: ExecuteStubActor works without stream_callback
|
|
Given a list of two strategy decisions
|
|
When I execute the ExecuteStubActor with the decisions and no callback
|
|
Then the execute result should have a valid changeset_id
|
|
And the execute result tool_calls_count should be zero
|
|
|
|
# -- run_strategize happy path with stream_callback (lines 138-143) --
|
|
|
|
@strategize
|
|
Scenario: run_strategize succeeds with stream_callback on a valid plan
|
|
Given a mock plan lifecycle service
|
|
And a PlanExecutor with the mock lifecycle service
|
|
And the lifecycle returns a plan in STRATEGIZE phase
|
|
And a stream event collector
|
|
When I run strategize with the stream callback
|
|
Then the strategize result should have decisions
|
|
And complete_strategize should have been called
|
|
|
|
# -- run_strategize happy path sets execution_context.decision_root_id --
|
|
|
|
@strategize
|
|
Scenario: run_strategize sets decision_root_id on execution_context when present
|
|
Given a mock plan lifecycle service
|
|
And a mock execution context
|
|
And a PlanExecutor with the mock lifecycle and execution context
|
|
And the lifecycle returns a plan in STRATEGIZE phase
|
|
When I run strategize successfully
|
|
Then the execution context decision_root_id should be set
|
|
|
|
# -- run_execute with stub and exception --
|
|
|
|
@execute @error
|
|
Scenario: run_execute calls fail_execute when stub execution raises an error
|
|
Given a mock plan lifecycle service
|
|
And a PlanExecutor with the mock lifecycle service and no execution context
|
|
And the lifecycle returns a fully valid plan for stub execution
|
|
And the stub execute actor is patched to raise an error
|
|
When I attempt to run execute and expect an exception
|
|
Then fail_execute should have been called with the plan_id
|