feat(session): add session persistence and repositories
CI / lint (pull_request) Successful in 17s
CI / typecheck (pull_request) Successful in 29s
CI / security (pull_request) Has been cancelled
CI / quality (pull_request) Has been cancelled
CI / unit_tests (pull_request) Has been cancelled
CI / integration_tests (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
CI / docker (pull_request) Has been cancelled
CI / coverage (pull_request) Has been cancelled
CI / lint (pull_request) Successful in 17s
CI / typecheck (pull_request) Successful in 29s
CI / security (pull_request) Has been cancelled
CI / quality (pull_request) Has been cancelled
CI / unit_tests (pull_request) Has been cancelled
CI / integration_tests (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
CI / docker (pull_request) Has been cancelled
CI / coverage (pull_request) Has been cancelled
This commit is contained in:
@@ -0,0 +1,431 @@
|
||||
@phase1 @domain @repository @coverage
|
||||
Feature: Repository Error Resilience and Edge-Case Coverage
|
||||
As a system operating under varying database conditions
|
||||
I want all repositories to handle transient failures and edge-case inputs
|
||||
So that callers receive consistent domain errors regardless of driver exceptions
|
||||
|
||||
# ==========================================================================
|
||||
# Session Repository — conditional logic and error branches
|
||||
# ==========================================================================
|
||||
|
||||
# ---- list_all with actor_name filter (line 3131) ----
|
||||
|
||||
@session_repo @filter
|
||||
Scenario: Listing sessions filtered by actor name returns only matching sessions
|
||||
Given a clean in-memory database for repository coverage
|
||||
And a session repository backed by the coverage database
|
||||
When two sessions are created with actor "local/orchestrator"
|
||||
And one session is created with actor "local/planner"
|
||||
And sessions are listed filtered by actor "local/orchestrator"
|
||||
Then the filtered session list should contain 2 entries
|
||||
|
||||
# ---- update on non-existent session (line 3184) ----
|
||||
|
||||
@session_repo @error
|
||||
Scenario: Updating a non-existent session raises a database error
|
||||
Given a clean in-memory database for repository coverage
|
||||
And a session repository backed by the coverage database
|
||||
When a session update is attempted for a non-existent session identifier
|
||||
Then a DatabaseError should be raised mentioning "not found for update"
|
||||
|
||||
# ---- create OperationalError branch (lines 3095-3097) ----
|
||||
|
||||
@session_repo @transient_error
|
||||
Scenario: A transient database failure during session creation is wrapped in DatabaseError
|
||||
Given a session repository whose session raises OperationalError on flush
|
||||
When a session is created and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to create session"
|
||||
|
||||
# ---- create IntegrityError non-unique branch (lines 3092-3094) ----
|
||||
|
||||
@session_repo @transient_error
|
||||
Scenario: A non-unique integrity violation during session creation is wrapped in DatabaseError
|
||||
Given a session repository whose session raises a non-unique IntegrityError on flush
|
||||
When a session is created and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to create session"
|
||||
|
||||
# ---- get_by_id OperationalError branch (lines 3114-3115) ----
|
||||
|
||||
@session_repo @transient_error
|
||||
Scenario: A transient database failure during session retrieval is wrapped in DatabaseError
|
||||
Given a session repository whose session raises OperationalError on query
|
||||
When a session is retrieved by identifier and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to get session"
|
||||
|
||||
# ---- list_all OperationalError branch (lines 3134-3135) ----
|
||||
|
||||
@session_repo @transient_error
|
||||
Scenario: A transient database failure during session listing is wrapped in DatabaseError
|
||||
Given a session repository whose session raises OperationalError on query
|
||||
When sessions are listed and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to list sessions"
|
||||
|
||||
# ---- delete OperationalError branch (lines 3157-3159) ----
|
||||
|
||||
@session_repo @transient_error
|
||||
Scenario: A transient database failure during session deletion is wrapped in DatabaseError
|
||||
Given a session repository whose session raises OperationalError on query
|
||||
When a session is deleted and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to delete session"
|
||||
|
||||
# ---- update OperationalError branch (lines 3209-3211) ----
|
||||
|
||||
@session_repo @transient_error
|
||||
Scenario: A transient database failure during session update is wrapped in DatabaseError
|
||||
Given a session repository whose session raises OperationalError on query
|
||||
When a session is updated and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to update session"
|
||||
|
||||
# ==========================================================================
|
||||
# Session Message Repository — error branches
|
||||
# ==========================================================================
|
||||
|
||||
# ---- append OperationalError branch (lines 3254-3256) ----
|
||||
|
||||
@session_msg_repo @transient_error
|
||||
Scenario: A transient database failure during message append is wrapped in DatabaseError
|
||||
Given a session message repository whose session raises OperationalError on flush
|
||||
When a message is appended and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to append message"
|
||||
|
||||
# ---- get_for_session OperationalError branch (lines 3289-3290) ----
|
||||
|
||||
@session_msg_repo @transient_error
|
||||
Scenario: A transient database failure during message retrieval is wrapped in DatabaseError
|
||||
Given a session message repository whose session raises OperationalError on query
|
||||
When messages are retrieved and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to get messages"
|
||||
|
||||
# ---- count_for_session OperationalError branch (lines 3311-3312) ----
|
||||
|
||||
@session_msg_repo @transient_error
|
||||
Scenario: A transient database failure during message counting is wrapped in DatabaseError
|
||||
Given a session message repository whose session raises OperationalError on query
|
||||
When messages are counted and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to count messages"
|
||||
|
||||
# ==========================================================================
|
||||
# Tool Registry Repository — update not-found and error branches
|
||||
# ==========================================================================
|
||||
|
||||
# ---- update on non-existent tool (line 2778) ----
|
||||
|
||||
@tool_repo @error
|
||||
Scenario: Updating a non-existent tool raises a database error
|
||||
Given a clean in-memory database for repository coverage
|
||||
And a tool registry repository backed by the coverage database
|
||||
When a tool update is attempted for non-existent tool "local/phantom"
|
||||
Then a DatabaseError should be raised mentioning "not found for update"
|
||||
|
||||
# ---- create OperationalError branch (lines 2701-2703) ----
|
||||
|
||||
@tool_repo @transient_error
|
||||
Scenario: A transient database failure during tool creation is wrapped in DatabaseError
|
||||
Given a tool registry repository whose session raises OperationalError on flush
|
||||
When a tool is created and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to create tool"
|
||||
|
||||
# ---- create non-unique IntegrityError (line 2700) ----
|
||||
|
||||
@tool_repo @transient_error
|
||||
Scenario: A non-unique integrity violation during tool creation is wrapped in DatabaseError
|
||||
Given a tool registry repository whose session raises a non-unique IntegrityError on flush
|
||||
When a tool is created and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to create tool"
|
||||
|
||||
# ---- get_by_name OperationalError (lines 2718-2719) ----
|
||||
|
||||
@tool_repo @transient_error
|
||||
Scenario: A transient database failure during tool retrieval is wrapped in DatabaseError
|
||||
Given a tool registry repository whose session raises OperationalError on query
|
||||
When a tool is retrieved by name and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to get tool"
|
||||
|
||||
# ---- list_all OperationalError (lines 2749-2750) ----
|
||||
|
||||
@tool_repo @transient_error
|
||||
Scenario: A transient database failure during tool listing is wrapped in DatabaseError
|
||||
Given a tool registry repository whose session raises OperationalError on query
|
||||
When tools are listed and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to list tools"
|
||||
|
||||
# ---- update OperationalError (lines 2821-2823) ----
|
||||
|
||||
@tool_repo @transient_error
|
||||
Scenario: A transient database failure during tool update is wrapped in DatabaseError
|
||||
Given a tool registry repository whose session raises OperationalError on query
|
||||
When a tool is updated and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to update tool"
|
||||
|
||||
# ---- delete OperationalError (lines 2860-2862) ----
|
||||
|
||||
@tool_repo @transient_error
|
||||
Scenario: A transient database failure during tool deletion is wrapped in DatabaseError
|
||||
Given a tool registry repository whose session raises OperationalError on query
|
||||
When a tool is deleted and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to delete tool"
|
||||
|
||||
# ==========================================================================
|
||||
# Validation Attachment Repository — args serialisation and error branches
|
||||
# ==========================================================================
|
||||
|
||||
# ---- attach with args (line 2913) ----
|
||||
|
||||
@validation_repo @logic
|
||||
Scenario: Attaching a validation with arguments serialises them to JSON
|
||||
Given a clean in-memory database for repository coverage
|
||||
And a tool registry repository backed by the coverage database
|
||||
And a validation attachment repository backed by the coverage database
|
||||
And a registered validation tool named "local/schema-check"
|
||||
When a validation is attached to resource "res-001" with arguments
|
||||
Then the attachment should store the arguments as JSON
|
||||
|
||||
# ---- get_by_id returns None (line 3033) ----
|
||||
|
||||
@validation_repo @logic
|
||||
Scenario: Retrieving a non-existent attachment by identifier returns nothing
|
||||
Given a clean in-memory database for repository coverage
|
||||
And a validation attachment repository backed by the coverage database
|
||||
When an attachment is retrieved by non-existent identifier
|
||||
Then the attachment result should be empty
|
||||
|
||||
# ---- attach OperationalError (lines 2937-2939) ----
|
||||
|
||||
@validation_repo @transient_error
|
||||
Scenario: A transient database failure during validation attach is wrapped in DatabaseError
|
||||
Given a validation attachment repository whose session raises OperationalError on flush
|
||||
When a validation is attached and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to attach validation"
|
||||
|
||||
# ---- detach OperationalError (lines 2963-2965) ----
|
||||
|
||||
@validation_repo @transient_error
|
||||
Scenario: A transient database failure during validation detach is wrapped in DatabaseError
|
||||
Given a validation attachment repository whose session raises OperationalError on query
|
||||
When a validation is detached and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to detach"
|
||||
|
||||
# ---- list_for_resource OperationalError (lines 3013-3014) ----
|
||||
|
||||
@validation_repo @transient_error
|
||||
Scenario: A transient database failure during attachment listing is wrapped in DatabaseError
|
||||
Given a validation attachment repository whose session raises OperationalError on query
|
||||
When attachments are listed and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to list"
|
||||
|
||||
# ---- get_by_id OperationalError (lines 3044-3045) ----
|
||||
|
||||
@validation_repo @transient_error
|
||||
Scenario: A transient database failure during attachment retrieval is wrapped in DatabaseError
|
||||
Given a validation attachment repository whose session raises OperationalError on query
|
||||
When an attachment is retrieved and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to get attachment"
|
||||
|
||||
# ==========================================================================
|
||||
# Lifecycle Plan Repository — error branches
|
||||
# ==========================================================================
|
||||
|
||||
# ---- create non-unique IntegrityError (line 1202) ----
|
||||
|
||||
@lifecycle_plan_repo @transient_error
|
||||
Scenario: A non-unique integrity violation during lifecycle plan creation is wrapped in DatabaseError
|
||||
Given a lifecycle plan repository whose session raises a non-unique IntegrityError on flush
|
||||
When a lifecycle plan is created and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to create plan"
|
||||
|
||||
# ---- create OperationalError (lines 1203-1205) ----
|
||||
|
||||
@lifecycle_plan_repo @transient_error
|
||||
Scenario: A transient database failure during lifecycle plan creation is wrapped in DatabaseError
|
||||
Given a lifecycle plan repository whose session raises OperationalError on flush
|
||||
When a lifecycle plan is created and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to create plan"
|
||||
|
||||
# ---- get OperationalError (lines 1220-1221) ----
|
||||
|
||||
@lifecycle_plan_repo @transient_error
|
||||
Scenario: A transient database failure during lifecycle plan get is wrapped in DatabaseError
|
||||
Given a lifecycle plan repository whose session raises OperationalError on query
|
||||
When a lifecycle plan is retrieved and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to get plan"
|
||||
|
||||
# ---- get_by_name OperationalError (lines 1240-1241) ----
|
||||
|
||||
@lifecycle_plan_repo @transient_error
|
||||
Scenario: A transient database failure during lifecycle plan get-by-name is wrapped in DatabaseError
|
||||
Given a lifecycle plan repository whose session raises OperationalError on query
|
||||
When a lifecycle plan is retrieved by name and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to get plan by name"
|
||||
|
||||
# ---- update OperationalError (lines 1395-1397) ----
|
||||
|
||||
@lifecycle_plan_repo @transient_error
|
||||
Scenario: A transient database failure during lifecycle plan update is wrapped in DatabaseError
|
||||
Given a lifecycle plan repository whose session raises OperationalError on query
|
||||
When a lifecycle plan is updated and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to update plan"
|
||||
|
||||
# ---- delete OperationalError (lines 1420-1422) ----
|
||||
|
||||
@lifecycle_plan_repo @transient_error
|
||||
Scenario: A transient database failure during lifecycle plan deletion is wrapped in DatabaseError
|
||||
Given a lifecycle plan repository whose session raises OperationalError on query
|
||||
When a lifecycle plan is deleted and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to delete plan"
|
||||
|
||||
# ---- list_plans OperationalError (lines 1471-1472) ----
|
||||
|
||||
@lifecycle_plan_repo @transient_error
|
||||
Scenario: A transient database failure during lifecycle plan listing is wrapped in DatabaseError
|
||||
Given a lifecycle plan repository whose session raises OperationalError on query
|
||||
When lifecycle plans are listed and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to list plans"
|
||||
|
||||
# ---- count OperationalError (lines 1499-1500) ----
|
||||
|
||||
@lifecycle_plan_repo @transient_error
|
||||
Scenario: A transient database failure during lifecycle plan count is wrapped in DatabaseError
|
||||
Given a lifecycle plan repository whose session raises OperationalError on query
|
||||
When lifecycle plans are counted and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to count plans"
|
||||
|
||||
# ==========================================================================
|
||||
# Resource Repository — namespace filter and error branches
|
||||
# ==========================================================================
|
||||
|
||||
# ---- list_resources with namespace filter (line 2068) ----
|
||||
|
||||
@resource_repo @filter
|
||||
Scenario: Listing resources filtered by namespace returns only matching resources
|
||||
Given a clean in-memory database for repository coverage
|
||||
And a resource type and resource repository backed by the coverage database
|
||||
And a seeded resource type "bench/filter-type"
|
||||
And a resource "bench/res-a" of type "bench/filter-type"
|
||||
And a resource "other/res-b" of type "bench/filter-type"
|
||||
When resources are listed filtered by namespace "bench"
|
||||
Then the filtered resource list should contain 1 entry
|
||||
|
||||
# ---- create OperationalError (lines 1997-1999) ----
|
||||
|
||||
@resource_repo @transient_error
|
||||
Scenario: A transient database failure during resource creation is wrapped in DatabaseError
|
||||
Given a resource repository whose session raises OperationalError on flush
|
||||
When a resource is created and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to create resource"
|
||||
|
||||
# ---- create non-unique IntegrityError (lines 1990-1993) ----
|
||||
|
||||
@resource_repo @transient_error
|
||||
Scenario: A non-unique integrity violation during resource creation is wrapped in DatabaseError
|
||||
Given a resource repository whose session raises a non-unique IntegrityError on flush
|
||||
When a resource is created and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to create resource"
|
||||
|
||||
# ---- get OperationalError (lines 2016-2017) ----
|
||||
|
||||
@resource_repo @transient_error
|
||||
Scenario: A transient database failure during resource get is wrapped in DatabaseError
|
||||
Given a resource repository whose session raises OperationalError on query
|
||||
When a resource is retrieved and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to get resource"
|
||||
|
||||
# ---- get_by_name OperationalError (lines 2038-2039) ----
|
||||
|
||||
@resource_repo @transient_error
|
||||
Scenario: A transient database failure during resource get-by-name is wrapped in DatabaseError
|
||||
Given a resource repository whose session raises OperationalError on query
|
||||
When a resource is retrieved by name and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to get resource by name"
|
||||
|
||||
# ---- list_resources OperationalError (lines 2076-2077) ----
|
||||
|
||||
@resource_repo @transient_error
|
||||
Scenario: A transient database failure during resource listing is wrapped in DatabaseError
|
||||
Given a resource repository whose session raises OperationalError on query
|
||||
When resources are listed and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to list resources"
|
||||
|
||||
# ---- update OperationalError (lines 2126-2128) ----
|
||||
|
||||
@resource_repo @transient_error
|
||||
Scenario: A transient database failure during resource update is wrapped in DatabaseError
|
||||
Given a resource repository whose session raises OperationalError on query
|
||||
When a resource is updated and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to update resource"
|
||||
|
||||
# ---- delete OperationalError (lines 2171-2173) ----
|
||||
|
||||
@resource_repo @transient_error
|
||||
Scenario: A transient database failure during resource deletion is wrapped in DatabaseError
|
||||
Given a resource repository whose session raises OperationalError on query
|
||||
When a resource is deleted and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to delete resource"
|
||||
|
||||
# ---- resolve OperationalError (lines 2215-2216) ----
|
||||
|
||||
@resource_repo @transient_error
|
||||
Scenario: A transient database failure during resource resolution is wrapped in DatabaseError
|
||||
Given a resource repository whose session raises OperationalError on query
|
||||
When a resource is resolved and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to resolve resource"
|
||||
|
||||
# ==========================================================================
|
||||
# Resource Type Repository — equivalence_json and error branches
|
||||
# ==========================================================================
|
||||
|
||||
# ---- _to_domain with equivalence_json (line 1877) ----
|
||||
|
||||
@resource_type_repo @logic
|
||||
Scenario: A resource type with equivalence metadata is correctly round-tripped
|
||||
Given a clean in-memory database for repository coverage
|
||||
And a resource type and resource repository backed by the coverage database
|
||||
When a resource type with equivalence metadata is created and retrieved
|
||||
Then the retrieved resource type should have the equivalence data
|
||||
|
||||
# ---- create OperationalError (lines 1665-1666) ----
|
||||
|
||||
@resource_type_repo @transient_error
|
||||
Scenario: A transient database failure during resource type creation is wrapped in DatabaseError
|
||||
Given a resource type repository whose session raises OperationalError on flush
|
||||
When a resource type is created and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to create resource type"
|
||||
|
||||
# ---- create IntegrityError non-unique (lines 1660-1663) ----
|
||||
|
||||
@resource_type_repo @transient_error
|
||||
Scenario: A non-unique integrity violation during resource type creation is wrapped in DatabaseError
|
||||
Given a resource type repository whose session raises a non-unique IntegrityError on flush
|
||||
When a resource type is created and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to create resource type"
|
||||
|
||||
# ---- get OperationalError (lines 1681-1682) ----
|
||||
|
||||
@resource_type_repo @transient_error
|
||||
Scenario: A transient database failure during resource type get is wrapped in DatabaseError
|
||||
Given a resource type repository whose session raises OperationalError on query
|
||||
When a resource type is retrieved and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to get resource type"
|
||||
|
||||
# ---- list_types OperationalError (lines 1708-1709) ----
|
||||
|
||||
@resource_type_repo @transient_error
|
||||
Scenario: A transient database failure during resource type listing is wrapped in DatabaseError
|
||||
Given a resource type repository whose session raises OperationalError on query
|
||||
When resource types are listed and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to list resource types"
|
||||
|
||||
# ---- update OperationalError (lines 1795-1797) ----
|
||||
|
||||
@resource_type_repo @transient_error
|
||||
Scenario: A transient database failure during resource type update is wrapped in DatabaseError
|
||||
Given a resource type repository whose session raises OperationalError on query
|
||||
When a resource type is updated and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to update resource type"
|
||||
|
||||
# ---- delete OperationalError (lines 1835-1837) ----
|
||||
|
||||
@resource_type_repo @transient_error
|
||||
Scenario: A transient database failure during resource type deletion is wrapped in DatabaseError
|
||||
Given a resource type repository whose session raises OperationalError on query
|
||||
When a resource type is deleted and a database error is expected
|
||||
Then a DatabaseError should be raised mentioning "Failed to delete resource type"
|
||||
Reference in New Issue
Block a user