forked from cleveragents/cleveragents-core
f8233000cc
Align resource_links, checkpoint_metadata, and decisions schema behavior with the spec DDL. Add SQLite runtime trigger guards for checkpoint foreign-key semantics and migration-focused Behave/Robot checks that orphan checkpoint references are rejected. ISSUES CLOSED: #922
154 lines
7.4 KiB
Gherkin
154 lines
7.4 KiB
Gherkin
Feature: Database migration lifecycle
|
|
As a CleverAgents administrator
|
|
I want to manage database schema via Alembic migrations
|
|
So that I can safely evolve the schema with rollback capability
|
|
|
|
Background:
|
|
Given a fresh in-memory database for migration lifecycle testing
|
|
|
|
Scenario: Apply all migrations forward on a fresh database
|
|
When I run all migrations forward to head
|
|
Then the database should have all expected tables
|
|
And the current revision should be the head revision
|
|
|
|
Scenario: Spec-parity schema details are present after migration
|
|
Given all migrations have been applied
|
|
Then the "resource_links" table should include "link_type" with default "contains"
|
|
And checkpoint_metadata should enforce decision and resource foreign keys
|
|
And checkpoint_metadata foreign keys should reject orphan references
|
|
And checkpoint_metadata should reject orphan decision_id independently
|
|
And checkpoint_metadata should reject orphan resource_id independently
|
|
And checkpoint_metadata should accept valid decision and resource references
|
|
And the "decisions" table should have partial index "idx_decisions_superseded" on "superseded_by"
|
|
|
|
Scenario: Roll back all migrations to base
|
|
Given all migrations have been applied
|
|
When I downgrade all migrations to base
|
|
Then the current revision should be None
|
|
And the database should have no application tables
|
|
|
|
Scenario: Round-trip forward then rollback to initial
|
|
Given all migrations have been applied
|
|
When I downgrade to the initial migration "001_initial_schema"
|
|
Then the current revision should be "001_initial_schema"
|
|
When I upgrade back to head
|
|
Then the current revision should be the head revision
|
|
|
|
Scenario: CLI db upgrade command applies migrations
|
|
When I invoke the db upgrade CLI command
|
|
Then the CLI should report a successful upgrade
|
|
And the database should have all expected tables
|
|
|
|
Scenario: CLI db current command shows revision
|
|
Given all migrations have been applied
|
|
When I invoke the db current CLI command
|
|
Then the CLI should display the current revision
|
|
|
|
Scenario: CLI db downgrade command rolls back
|
|
Given all migrations have been applied
|
|
When I invoke the db downgrade CLI command with revision "m6_004_container_metadata_column"
|
|
Then the CLI should report a successful downgrade
|
|
|
|
Scenario: Stamp logic detects pre-Alembic database
|
|
Given a database with legacy tables but no alembic_version
|
|
When I run init_or_upgrade on the legacy database
|
|
Then the database should be stamped with alembic_version
|
|
And the database revision should be at head
|
|
|
|
Scenario: Migration orphan cleanup nullifies stale checkpoint references
|
|
Given migrations applied up to "m4_003_plan_env_columns"
|
|
And checkpoint_metadata contains orphan decision and resource references
|
|
When I upgrade to the next migration revision
|
|
Then the orphan decision_id values should be NULL
|
|
And the orphan resource_id values should be NULL
|
|
And checkpoint_metadata should enforce decision and resource foreign keys
|
|
|
|
Scenario: resource_links.link_type accepts spec-defined non-default values
|
|
Given all migrations have been applied
|
|
Then resource_links should accept link_type "references"
|
|
And resource_links should accept link_type "derived_from"
|
|
|
|
Scenario: resource_links.link_type rejects NULL values
|
|
Given all migrations have been applied
|
|
Then resource_links should reject NULL link_type
|
|
|
|
Scenario: resource_links.link_type rejects invalid values
|
|
Given all migrations have been applied
|
|
Then resource_links should reject link_type "invalid_type"
|
|
|
|
Scenario: Deleting a decision sets checkpoint decision_id to NULL
|
|
Given all migrations have been applied
|
|
And a checkpoint references a valid decision
|
|
When the referenced decision is deleted
|
|
Then the checkpoint decision_id should be NULL
|
|
|
|
Scenario: Deleting a resource sets checkpoint resource_id to NULL
|
|
Given all migrations have been applied
|
|
And a checkpoint references a valid resource
|
|
When the referenced resource is deleted
|
|
Then the checkpoint resource_id should be NULL
|
|
|
|
Scenario: Spec-parity m4_004 downgrade removes added schema objects
|
|
Given all migrations have been applied
|
|
When I downgrade to revision "m4_003_plan_env_columns"
|
|
Then the "resource_links" table should not include "link_type"
|
|
And the "decisions" table should not have index "idx_decisions_superseded"
|
|
And checkpoint_metadata should not have foreign key "fk_checkpoint_metadata_decision"
|
|
And checkpoint_metadata should not have foreign key "fk_checkpoint_metadata_resource"
|
|
And checkpoint_metadata should not have SQLite triggers for FK enforcement
|
|
|
|
Scenario: Migration idempotency: existing link_type column gains CHECK constraint
|
|
Given migrations applied up to "m4_003_plan_env_columns"
|
|
And resource_links already has a link_type column without CHECK constraint
|
|
When I upgrade to the next migration revision
|
|
Then the "resource_links" table should include "link_type" with default "contains"
|
|
And resource_links should reject link_type "invalid_type"
|
|
|
|
Scenario: Migration idempotency: existing link_type column with wrong default is corrected
|
|
Given migrations applied up to "m4_003_plan_env_columns"
|
|
And resource_links already has a link_type column with a non-contains default
|
|
When I upgrade to the next migration revision
|
|
Then the "resource_links" table should include "link_type" with default "contains"
|
|
And resource_links should reject link_type "invalid_type"
|
|
|
|
Scenario: Positive checkpoint FK test verifies persisted row
|
|
Given all migrations have been applied
|
|
And valid decision and resource rows exist
|
|
When I insert a checkpoint with valid FK references
|
|
Then the checkpoint row should be persisted in the database
|
|
|
|
Scenario: UPDATE trigger rejects orphan decision_id on checkpoint_metadata
|
|
Given all migrations have been applied
|
|
And a checkpoint exists with valid FK references
|
|
When I update the checkpoint decision_id to a non-existent value
|
|
Then the update should be rejected with an integrity error
|
|
|
|
Scenario: UPDATE trigger rejects orphan resource_id on checkpoint_metadata
|
|
Given all migrations have been applied
|
|
And a checkpoint exists with valid FK references
|
|
When I update the checkpoint resource_id to a non-existent value
|
|
Then the update should be rejected with an integrity error
|
|
|
|
Scenario: resource_links.link_type rejects empty string values
|
|
Given all migrations have been applied
|
|
Then resource_links should reject empty string link_type
|
|
|
|
Scenario: init_database creates a valid schema
|
|
When I call init_database with an in-memory URL
|
|
Then the resulting engine should have a valid schema
|
|
|
|
@issue_4180 @alembic_packaging
|
|
Scenario: MigrationRunner locates alembic.ini from packaged location
|
|
Given the MigrationRunner class is available
|
|
When I call _find_alembic_ini() to locate the configuration file
|
|
Then it should find alembic.ini at the package location
|
|
And the alembic.ini should be readable and valid
|
|
|
|
@issue_4180 @alembic_packaging
|
|
Scenario: Database initialization succeeds with packaged alembic files
|
|
Given a fresh in-memory database for migration lifecycle testing
|
|
When I run all migrations forward to head
|
|
Then the database should have all expected tables
|
|
And the database should be stamped with alembic_version
|
|
And the database revision should be at head
|