@phase1 @domain @repository @error_handling_coverage Feature: Repository error handling coverage for major repository classes As a system operating under unstable database conditions I want all repository error-handling paths to be covered So that OperationalError, IntegrityError, and DatabaseError paths are exercised # ========================================================================== # NamespacedProjectRepository error handling # ========================================================================== # --- create: IntegrityError (UNIQUE) -> DatabaseError "already exists" ---- @project_repo @transient_error Scenario: NamespacedProjectRepository create raises DatabaseError on UNIQUE IntegrityError Given a namespaced project repository with session raising UNIQUE IntegrityError on flush When a namespaced project is created and a repo error is expected Then a repo DatabaseError should be raised containing "already exists" # --- create: IntegrityError (non-UNIQUE) -> DatabaseError ----------------- @project_repo @transient_error Scenario: NamespacedProjectRepository create raises DatabaseError on non-UNIQUE IntegrityError Given a namespaced project repository with session raising non-UNIQUE IntegrityError on flush When a namespaced project is created and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to create project" # --- create: OperationalError -> DatabaseError ---------------------------- @project_repo @transient_error Scenario: NamespacedProjectRepository create raises DatabaseError on OperationalError Given a namespaced project repository with session raising OperationalError on flush When a namespaced project is created and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to create project" # --- get: OperationalError -> DatabaseError ------------------------------- @project_repo @transient_error Scenario: NamespacedProjectRepository get raises DatabaseError on OperationalError Given a namespaced project repository with session raising OperationalError on query When a namespaced project is fetched by name and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to get project" # --- list_projects: OperationalError -> DatabaseError --------------------- @project_repo @transient_error Scenario: NamespacedProjectRepository list_projects raises DatabaseError on OperationalError Given a namespaced project repository with session raising OperationalError on query When namespaced projects are listed and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to list projects" # --- update: OperationalError -> DatabaseError ---------------------------- @project_repo @transient_error Scenario: NamespacedProjectRepository update raises DatabaseError on OperationalError Given a namespaced project repository with session raising OperationalError on query When a namespaced project is updated and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to update project" # --- delete: OperationalError -> DatabaseError ---------------------------- @project_repo @transient_error Scenario: NamespacedProjectRepository delete raises DatabaseError on OperationalError Given a namespaced project repository with session raising OperationalError on query When a namespaced project is deleted and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to delete project" # ========================================================================== # ToolRepository error handling # ========================================================================== # --- add: IntegrityError (UNIQUE) -> DuplicateToolError ------------------- @tool_repo @transient_error Scenario: ToolRepository add raises DuplicateToolError on UNIQUE IntegrityError Given a tool repository with session raising UNIQUE IntegrityError on flush When a tool is added and a repo error is expected Then a repo DuplicateToolError should be raised # --- add: IntegrityError (non-UNIQUE) -> DatabaseError -------------------- @tool_repo @transient_error Scenario: ToolRepository add raises DatabaseError on non-UNIQUE IntegrityError Given a tool repository with session raising non-UNIQUE IntegrityError on flush When a tool is added and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to create tool" # --- add: OperationalError -> DatabaseError ------------------------------- @tool_repo @transient_error Scenario: ToolRepository add raises DatabaseError on OperationalError Given a tool repository with session raising OperationalError on flush When a tool is added and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to create tool" # --- get_by_name: OperationalError -> DatabaseError ----------------------- @tool_repo @transient_error Scenario: ToolRepository get_by_name raises DatabaseError on OperationalError Given a tool repository with session raising OperationalError on query When a tool is fetched by name and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to get tool" # --- list_all: OperationalError -> DatabaseError -------------------------- @tool_repo @transient_error Scenario: ToolRepository list_all raises DatabaseError on OperationalError Given a tool repository with session raising OperationalError on query When all tools are listed and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to list tools" # --- update: ToolNotFoundError (not found) -------------------------------- @tool_repo @not_found Scenario: ToolRepository update raises ToolNotFoundError when tool not found Given a tool repository backed by a clean in-memory database When a non-existent tool is updated and a repo error is expected Then a repo ToolNotFoundError should be raised # --- update: OperationalError -> DatabaseError ---------------------------- @tool_repo @transient_error Scenario: ToolRepository update raises DatabaseError on OperationalError Given a tool repository with session raising OperationalError on query When a non-existent tool is updated and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to update tool" # --- remove: ToolNotFoundError (not found) -------------------------------- @tool_repo @not_found Scenario: ToolRepository remove raises ToolNotFoundError when tool not found Given a tool repository backed by a clean in-memory database When a non-existent tool is removed and a repo error is expected Then a repo ToolNotFoundError should be raised # --- remove: OperationalError -> DatabaseError ---------------------------- @tool_repo @transient_error Scenario: ToolRepository remove raises DatabaseError on OperationalError Given a tool repository with session raising OperationalError on query When a non-existent tool is removed and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to delete tool" # ========================================================================== # AutomationProfileRepository error handling # ========================================================================== # --- get_by_name: OperationalError -> DatabaseError ----------------------- @profile_repo @transient_error Scenario: AutomationProfileRepository get_by_name raises DatabaseError on OperationalError Given an automation profile repository with session raising OperationalError on query When an automation profile is fetched by name and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to get profile" # --- list_all: OperationalError -> DatabaseError -------------------------- @profile_repo @transient_error Scenario: AutomationProfileRepository list_all raises DatabaseError on OperationalError Given an automation profile repository with session raising OperationalError on query When all automation profiles are listed and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to list profiles" # --- upsert: OperationalError -> DatabaseError ---------------------------- @profile_repo @transient_error Scenario: AutomationProfileRepository upsert raises DatabaseError on OperationalError Given an automation profile repository with session raising OperationalError on query When an automation profile is upserted and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to upsert profile" # --- delete: OperationalError -> DatabaseError ---------------------------- @profile_repo @transient_error Scenario: AutomationProfileRepository delete raises DatabaseError on OperationalError Given an automation profile repository with session raising OperationalError on query When an automation profile is deleted and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to delete profile" # ========================================================================== # ResourceTypeRepository error handling # ========================================================================== # --- create: IntegrityError (non-UNIQUE) -> DatabaseError ----------------- @resource_type_repo @transient_error Scenario: ResourceTypeRepository create raises DatabaseError on non-UNIQUE IntegrityError Given a resource type repository with session that passes query but raises non-UNIQUE IntegrityError on flush When a resource type is created and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to create resource type" # --- create: OperationalError -> DatabaseError ---------------------------- @resource_type_repo @transient_error Scenario: ResourceTypeRepository create raises DatabaseError on OperationalError Given a resource type repository with session raising OperationalError on flush When a resource type is created and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to create resource type" # --- get: OperationalError -> DatabaseError ------------------------------- @resource_type_repo @transient_error Scenario: ResourceTypeRepository get raises DatabaseError on OperationalError Given a resource type repository with session raising OperationalError on query When a resource type is fetched by name and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to get resource type" # --- list_types: OperationalError -> DatabaseError ------------------------ @resource_type_repo @transient_error Scenario: ResourceTypeRepository list_types raises DatabaseError on OperationalError Given a resource type repository with session raising OperationalError on query When resource types are listed and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to list resource types" # --- update: OperationalError -> DatabaseError ---------------------------- @resource_type_repo @transient_error Scenario: ResourceTypeRepository update raises DatabaseError on OperationalError Given a resource type repository with session raising OperationalError on query When a resource type is updated and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to update resource type" # --- delete: OperationalError -> DatabaseError ---------------------------- @resource_type_repo @transient_error Scenario: ResourceTypeRepository delete raises DatabaseError on OperationalError Given a resource type repository with session raising OperationalError on query When a resource type is deleted and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to delete resource type" # ========================================================================== # ResourceRepository error handling # ========================================================================== # --- create: IntegrityError (UNIQUE) -> DuplicateResourceError ------------ @resource_repo @transient_error Scenario: ResourceRepository create raises DuplicateResourceError on UNIQUE IntegrityError Given a resource repository with session that passes initial queries but raises UNIQUE IntegrityError on flush When a resource is created and a repo error is expected Then a repo DuplicateResourceError should be raised # --- create: IntegrityError (non-UNIQUE) -> DatabaseError ----------------- @resource_repo @transient_error Scenario: ResourceRepository create raises DatabaseError on non-UNIQUE IntegrityError Given a resource repository with session that passes initial queries but raises non-UNIQUE IntegrityError on flush When a resource is created and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to create resource" # --- create: OperationalError -> DatabaseError ---------------------------- @resource_repo @transient_error Scenario: ResourceRepository create raises DatabaseError on OperationalError Given a resource repository with session raising OperationalError on flush When a resource is created and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to create resource" # --- get: OperationalError -> DatabaseError ------------------------------- @resource_repo @transient_error Scenario: ResourceRepository get raises DatabaseError on OperationalError Given a resource repository with session raising OperationalError on query When a resource is fetched by ID and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to get resource" # --- get_by_name: OperationalError -> DatabaseError ----------------------- @resource_repo @transient_error Scenario: ResourceRepository get_by_name raises DatabaseError on OperationalError Given a resource repository with session raising OperationalError on query When a resource is fetched by name and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to get resource by name" # --- list_resources: OperationalError -> DatabaseError -------------------- @resource_repo @transient_error Scenario: ResourceRepository list_resources raises DatabaseError on OperationalError Given a resource repository with session raising OperationalError on query When resources are listed and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to list resources" # --- update: OperationalError -> DatabaseError ---------------------------- @resource_repo @transient_error Scenario: ResourceRepository update raises DatabaseError on OperationalError Given a resource repository with session raising OperationalError on query When a resource is updated and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to update resource" # --- delete: OperationalError -> DatabaseError ---------------------------- @resource_repo @transient_error Scenario: ResourceRepository delete raises DatabaseError on OperationalError Given a resource repository with session raising OperationalError on query When a resource is deleted and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to delete resource" # --- resolve_namespaced_name: OperationalError -> DatabaseError ----------- @resource_repo @transient_error Scenario: ResourceRepository resolve_namespaced_name raises DatabaseError on OperationalError Given a resource repository with session raising OperationalError on query When a resource is resolved by name-or-id and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to resolve resource" # ========================================================================== # ProjectResourceLinkRepository error handling # ========================================================================== # --- create_link: IntegrityError -> DatabaseError ------------------------- @link_repo @transient_error Scenario: ProjectResourceLinkRepository create_link raises DatabaseError on IntegrityError Given a project resource link repository with session that passes query but raises IntegrityError on flush When a project resource link is created and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to create link" # --- create_link: OperationalError -> DatabaseError ----------------------- @link_repo @transient_error Scenario: ProjectResourceLinkRepository create_link raises DatabaseError on OperationalError Given a project resource link repository with session raising OperationalError on flush When a project resource link is created and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to create link" # --- list_links: OperationalError -> DatabaseError ------------------------ @link_repo @transient_error Scenario: ProjectResourceLinkRepository list_links raises DatabaseError on OperationalError Given a project resource link repository with session raising OperationalError on query When project resource links are listed and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to list links" # --- get_link: OperationalError -> DatabaseError -------------------------- @link_repo @transient_error Scenario: ProjectResourceLinkRepository get_link raises DatabaseError on OperationalError Given a project resource link repository with session raising OperationalError on query When a project resource link is fetched and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to get link" # --- remove_link: OperationalError -> DatabaseError ----------------------- @link_repo @transient_error Scenario: ProjectResourceLinkRepository remove_link raises DatabaseError on OperationalError Given a project resource link repository with session raising OperationalError on query When a project resource link is removed and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to remove link" # ========================================================================== # ValidationAttachmentRepository error handling # ========================================================================== # --- attach: IntegrityError (UNIQUE) -> DuplicateValidationAttachmentError @validation_repo @transient_error Scenario: ValidationAttachmentRepository attach raises DuplicateValidationAttachmentError on UNIQUE IntegrityError Given a validation attachment repository with session that passes query but raises UNIQUE IntegrityError on flush When a validation is attached and a repo error is expected Then a repo DuplicateValidationAttachmentError should be raised # --- attach: IntegrityError (non-UNIQUE) -> DatabaseError ----------------- @validation_repo @transient_error Scenario: ValidationAttachmentRepository attach raises DatabaseError on non-UNIQUE IntegrityError Given a validation attachment repository with session that passes query but raises non-UNIQUE IntegrityError on flush When a validation is attached and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to attach validation" # --- attach: OperationalError -> DatabaseError ---------------------------- @validation_repo @transient_error Scenario: ValidationAttachmentRepository attach raises DatabaseError on OperationalError Given a validation attachment repository with session raising OperationalError on flush When a validation is attached and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to attach validation" # --- detach: OperationalError -> DatabaseError ---------------------------- @validation_repo @transient_error Scenario: ValidationAttachmentRepository detach raises DatabaseError on OperationalError Given a validation attachment repository with session raising OperationalError on query When a validation is detached and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to detach validation" # --- list_for_resource: OperationalError -> DatabaseError ----------------- @validation_repo @transient_error Scenario: ValidationAttachmentRepository list_for_resource raises DatabaseError on OperationalError Given a validation attachment repository with session raising OperationalError on query When validation attachments are listed and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to list attachments" # ========================================================================== # LifecyclePlanRepository error handling # ========================================================================== # --- create: IntegrityError (non-UNIQUE) -> DatabaseError ----------------- @plan_repo @transient_error Scenario: LifecyclePlanRepository create raises DatabaseError on non-UNIQUE IntegrityError Given a lifecycle plan repository with session raising non-UNIQUE IntegrityError on flush When a lifecycle plan is created and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to create plan" # --- create: OperationalError -> DatabaseError ---------------------------- @plan_repo @transient_error Scenario: LifecyclePlanRepository create raises DatabaseError on OperationalError Given a lifecycle plan repository with session raising OperationalError on flush When a lifecycle plan is created and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to create plan" # --- get: OperationalError -> DatabaseError ------------------------------- @plan_repo @transient_error Scenario: LifecyclePlanRepository get raises DatabaseError on OperationalError Given a lifecycle plan repository with session raising OperationalError on query When a lifecycle plan is fetched by ID and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to get plan" # --- get_by_name: OperationalError -> DatabaseError ----------------------- @plan_repo @transient_error Scenario: LifecyclePlanRepository get_by_name raises DatabaseError on OperationalError Given a lifecycle plan repository with session raising OperationalError on query When a lifecycle plan is fetched by name and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to get plan by name" # --- update: OperationalError -> DatabaseError ---------------------------- @plan_repo @transient_error Scenario: LifecyclePlanRepository update raises DatabaseError on OperationalError Given a lifecycle plan repository with session raising OperationalError on query When a lifecycle plan is updated and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to update plan" # --- delete: OperationalError -> DatabaseError ---------------------------- @plan_repo @transient_error Scenario: LifecyclePlanRepository delete raises DatabaseError on OperationalError Given a lifecycle plan repository with session raising OperationalError on query When a lifecycle plan is deleted and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to delete plan" # --- list_plans: OperationalError -> DatabaseError ------------------------ @plan_repo @transient_error Scenario: LifecyclePlanRepository list_plans raises DatabaseError on OperationalError Given a lifecycle plan repository with session raising OperationalError on query When lifecycle plans are listed and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to list plans" # --- count: OperationalError -> DatabaseError ----------------------------- @plan_repo @transient_error Scenario: LifecyclePlanRepository count raises DatabaseError on OperationalError Given a lifecycle plan repository with session raising OperationalError on query When lifecycle plans are counted and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to count plans" # ========================================================================== # ResourceRepository DAG operations error handling # ========================================================================== # --- link_child: IntegrityError -> DatabaseError -------------------------- @resource_repo @dag @transient_error Scenario: ResourceRepository link_child raises DatabaseError on IntegrityError Given a resource repository with session that has resources but raises IntegrityError on link flush When a resource child is linked and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to link" # --- link_child: OperationalError -> DatabaseError ------------------------ @resource_repo @dag @transient_error Scenario: ResourceRepository link_child raises DatabaseError on OperationalError during link Given a resource repository with session that has resources but raises OperationalError on link flush When a resource child is linked and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to link" # --- unlink_child: OperationalError -> DatabaseError ---------------------- @resource_repo @dag @transient_error Scenario: ResourceRepository unlink_child raises DatabaseError on OperationalError Given a resource repository with session raising OperationalError on query When a resource child is unlinked and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to unlink" # --- get_children: OperationalError -> DatabaseError ---------------------- @resource_repo @dag @transient_error Scenario: ResourceRepository get_children raises DatabaseError on OperationalError Given a resource repository with session raising OperationalError on query When resource children are fetched and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to get children" # --- get_parents: OperationalError -> DatabaseError ----------------------- @resource_repo @dag @transient_error Scenario: ResourceRepository get_parents raises DatabaseError on OperationalError Given a resource repository with session raising OperationalError on query When resource parents are fetched and a repo error is expected Then a repo DatabaseError should be raised containing "Failed to get parents"