Files
temp/features/action_repository_error_handling.feature
CoreRasurae f2f7aa5dc9 feat(core): add v3 lifecycle models, automation levels, subplan support, and security hardening
Implement multiple Stage A/B/E/SEC milestones for the v3 lifecycle system:
- Stage A5.3+A5.4: Add LifecycleActionModel and LifecyclePlanModel SQLAlchemy
  models with to_domain()/from_domain() conversion methods
- Stage A5.6: Implement ActionRepository with full CRUD, namespace/state
  queries, referential integrity checks, and retry decorator
- Stage E1: Add subplan domain models (ExecutionMode, SubplanMergeStrategy,
  SubplanConfig, SubplanStatus, SubplanAttempt, SubplanFailureHandler) with
  computed properties on Plan (is_subplan, is_root_plan, depth, has_subplans)
- Stage A6: Add AutomationLevel enum (MANUAL, REVIEW_BEFORE_APPLY,
  FULL_AUTOMATION), settings integration, PlanLifecycleService auto-progression,
  pause/resume, and CLI commands (--automation-level, set-automation-level)
- Stage SEC1: Remove eval()/exec() from stream_router.py, replace with named
  operation and transform registries; code blocks and unregistered transforms
  now raise StreamRoutingError
- Add langchain-anthropic dependency
- Update BDD tests for security changes and relax ADR directory requirement
2026-02-12 20:19:42 +00:00

97 lines
5.6 KiB
Gherkin
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@phase1 @domain @repository @action_repository @error_handling
Feature: Action Repository Transient Database Error Handling
As a system operating under unstable database conditions
I want the action repository to wrap transient database failures in a domain-specific error
So that callers receive a consistent DatabaseError regardless of the underlying driver exception
Background:
Given a clean in-memory database with the lifecycle schema
And an action repository whose session raises OperationalError on query
# ---------------------------------------------------------------------------
# ActionRepository.create non-unique IntegrityError branch (line 769→771)
# ---------------------------------------------------------------------------
@action_create @transient_error
Scenario: A non-unique integrity violation during create is wrapped in DatabaseError
Given an action repository whose session raises a non-unique IntegrityError on flush
And a valid action domain object named "local/integrity-fail"
When the action is saved and a database error is expected
Then a DatabaseError should be raised with message containing "Failed to create action"
# ---------------------------------------------------------------------------
# ActionRepository.create OperationalError branch (lines 772-774)
# ---------------------------------------------------------------------------
@action_create @transient_error
Scenario: An operational error during create is wrapped in DatabaseError
Given an action repository whose session raises OperationalError on flush
And a valid action domain object named "local/create-op-fail"
When the action is saved and a database error is expected
Then a DatabaseError should be raised with message containing "Failed to create action"
# ---------------------------------------------------------------------------
# ActionRepository.get_by_id OperationalError branch (lines 793-794)
# ---------------------------------------------------------------------------
@action_read @transient_error
Scenario: An operational error during get-by-id is wrapped in DatabaseError
When an action is retrieved by identifier and a database error is expected
Then a DatabaseError should be raised with message containing "Failed to get action"
# ---------------------------------------------------------------------------
# ActionRepository.get_by_name OperationalError branch (lines 811-812)
# ---------------------------------------------------------------------------
@action_read @transient_error
Scenario: An operational error during get-by-name is wrapped in DatabaseError
When an action is retrieved by name "local/broken" and a database error is expected
Then a DatabaseError should be raised with message containing "Failed to get action by name"
# ---------------------------------------------------------------------------
# ActionRepository.get_by_namespace OperationalError branch (lines 840-841)
# ---------------------------------------------------------------------------
@action_list @transient_error
Scenario: An operational error during namespace listing is wrapped in DatabaseError
When actions in namespace "local" are listed and a database error is expected
Then a DatabaseError should be raised with message containing "Failed to list actions in namespace"
# ---------------------------------------------------------------------------
# ActionRepository.get_by_state OperationalError branch (lines 864-865)
# ---------------------------------------------------------------------------
@action_list @transient_error
Scenario: An operational error during state listing is wrapped in DatabaseError
When actions in state "available" are listed and a database error is expected
Then a DatabaseError should be raised with message containing "Failed to list actions by state"
# ---------------------------------------------------------------------------
# ActionRepository.update OperationalError branch (lines 924-925)
# ---------------------------------------------------------------------------
@action_update @transient_error
Scenario: An operational error during update is wrapped in DatabaseError
Given a saved action named "local/update-target" in a healthy repository
And the repository session is replaced with one that raises OperationalError on query
When the saved action is updated and a database error is expected
Then a DatabaseError should be raised with message containing "Failed to update action"
# ---------------------------------------------------------------------------
# ActionRepository.list_available OperationalError branch (lines 951-952)
# ---------------------------------------------------------------------------
@action_list @transient_error
Scenario: An operational error during list-available is wrapped in DatabaseError
When available actions are listed and a database error is expected
Then a DatabaseError should be raised with message containing "Failed to list available actions"
# ---------------------------------------------------------------------------
# ActionRepository.delete OperationalError branch (lines 996-998)
# ---------------------------------------------------------------------------
@action_delete @transient_error
Scenario: An operational error during delete is wrapped in DatabaseError
When an action is deleted by identifier and a database error is expected
Then a DatabaseError should be raised with message containing "Failed to delete action"