Files
ss-tools/backend/tests/test_scenario_live_execution_binding_migration.py

70 lines
3.4 KiB
Python

# #region Test.ScenarioExecution.LiveBindingMigration [C:3] [TYPE Module] [SEMANTICS test,scenario,execution,live-binding,migration]
# @BRIEF Verify the live-binding migration is additive and leaves historical runs nullable.
# @RELATION BINDS_TO -> [Alembic.ScenarioLiveExecutionBinding]
# @RELATION VERIFIES -> [Alembic.ScenarioLiveExecutionBinding.Upgrade]
# @RELATION VERIFIES -> [Alembic.ScenarioLiveExecutionBinding.Downgrade]
# @TEST_CONTRACT: scenario_runs legacy schema -> nullable binding reference and identity snapshot columns
# @TEST_FIXTURE: legacy_scenario_runs_044 -> INLINE_JSON nullable additive column contract
# @TEST_EDGE: no_binding -> nullable columns; downgrade -> both columns/index removed; legacy_authority_inference -> forbidden
# @TEST_INVARIANT Alembic.ScenarioLiveExecutionBinding: Existing runs remain valid with no binding and therefore fail closed as unavailable live I/O. -> VERIFIED_BY: additive_upgrade, additive_downgrade
from __future__ import annotations
import importlib.util
from pathlib import Path
from unittest.mock import Mock
# #region Test.ScenarioExecution.LiveBindingMigration.Load [C:1] [TYPE Function]
def _migration_module():
path = Path(__file__).resolve().parents[1] / "alembic" / "versions" / "c1d2e3f4a5b6_add_scenario_live_execution_binding.py"
spec = importlib.util.spec_from_file_location("scenario_live_binding_migration", path)
assert spec and spec.loader
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
# #endregion Test.ScenarioExecution.LiveBindingMigration.Load
# #region Test.ScenarioExecution.LiveBindingMigration.Upgrade [C:2] [TYPE Function]
# @BRIEF Upgrade adds only nullable identity columns and an index; it never backfills authority.
def test_upgrade_adds_nullable_binding_identity_columns(monkeypatch):
migration = _migration_module()
add_column = Mock()
create_index = Mock()
monkeypatch.setattr(migration.op, "add_column", add_column)
monkeypatch.setattr(migration.op, "create_index", create_index)
migration.upgrade()
assert [(call.args[1].name, call.args[1].nullable) for call in add_column.call_args_list] == [
("live_execution_binding_ref", True),
("live_execution_binding_snapshot", True),
]
create_index.assert_called_once_with(
"ix_scenario_runs_live_execution_binding_ref",
"scenario_runs",
["live_execution_binding_ref"],
)
# #endregion Test.ScenarioExecution.LiveBindingMigration.Upgrade
# #region Test.ScenarioExecution.LiveBindingMigration.Downgrade [C:2] [TYPE Function]
# @BRIEF Downgrade removes only the additive identity fields in reverse dependency order.
def test_downgrade_removes_only_binding_identity_columns(monkeypatch):
migration = _migration_module()
drop_index = Mock()
drop_column = Mock()
monkeypatch.setattr(migration.op, "drop_index", drop_index)
monkeypatch.setattr(migration.op, "drop_column", drop_column)
migration.downgrade()
drop_index.assert_called_once_with("ix_scenario_runs_live_execution_binding_ref", table_name="scenario_runs")
assert [call.args for call in drop_column.call_args_list] == [
("scenario_runs", "live_execution_binding_snapshot"),
("scenario_runs", "live_execution_binding_ref"),
]
# #endregion Test.ScenarioExecution.LiveBindingMigration.Downgrade
# #endregion Test.ScenarioExecution.LiveBindingMigration