"""Verify the task-queue attempts migration adds the column and downgrades cleanly.""" import importlib import sqlalchemy as sa from alembic.migration import MigrationContext from alembic.operations import Operations from sqlmodel import SQLModel def _engine_with_task_table(tmp_path): from agenteval.storage import db as db_module # noqa: F401 — register tables engine = sa.create_engine(f"sqlite:///{tmp_path / 'attempts.db'}") # Build the pre-migration shape: task queue table WITHOUT the attempts column. table = db_module.IntelligentEvalTaskQueueDB.__table__ pre_columns = [sa.Column(c.name, c.type) for c in table.columns if c.name != "attempts"] pre_table = sa.Table("intelligent_eval_task_queue", sa.MetaData(), *pre_columns) with engine.begin() as connection: pre_table.create(connection) return engine def test_attempts_migration_adds_column(tmp_path, monkeypatch): engine = _engine_with_task_table(tmp_path) with engine.begin() as connection: operations = Operations(MigrationContext.configure(connection)) migration = importlib.import_module("migrations.versions.e1a2b3c4d5f6_add_task_queue_attempts") monkeypatch.setattr(migration, "op", operations) migration.upgrade() columns = {c["name"] for c in sa.inspect(connection).get_columns("intelligent_eval_task_queue")} assert "attempts" in columns def test_attempts_migration_downgrade_removes_column(tmp_path, monkeypatch): engine = _engine_with_task_table(tmp_path) with engine.begin() as connection: operations = Operations(MigrationContext.configure(connection)) migration = importlib.import_module("migrations.versions.e1a2b3c4d5f6_add_task_queue_attempts") monkeypatch.setattr(migration, "op", operations) migration.upgrade() migration.downgrade() columns = {c["name"] for c in sa.inspect(connection).get_columns("intelligent_eval_task_queue")} assert "attempts" not in columns def test_fresh_schema_parity(tmp_path): """A brand-new DB via SQLModel.metadata.create_all must include attempts.""" from agenteval.storage import db as db_module # noqa: F401 engine = sa.create_engine(f"sqlite:///{tmp_path / 'fresh.db'}") SQLModel.metadata.create_all(engine) with engine.connect() as connection: columns = {c["name"] for c in sa.inspect(connection).get_columns("intelligent_eval_task_queue")} assert "attempts" in columns