| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- from datetime import UTC, datetime, timedelta
- import pytest
- from app.core.orchestration.migration.rollout import (
- MigrationBatch,
- ObservationWindow,
- RolloutEntryGates,
- RolloutExitGates,
- RolloutPolicy,
- )
- def test_batches_are_fixed_from_low_to_high_risk():
- assert [batch.value for batch in MigrationBatch] == [
- "read_only_low_frequency",
- "idempotent_partition_write",
- "core_multi_node",
- "special_high_risk",
- ]
- def test_entry_gates_require_shadow_failure_recovery_and_capacity():
- gates = RolloutEntryGates(
- inventory_complete=True,
- workflow_spec_valid=True,
- policy_complete=True,
- rollback_target_present=True,
- shadow_runs=2,
- required_shadow_runs=3,
- failure_recovery_observed=True,
- reconciliation_passed=True,
- connection_budget_passed=True,
- peak_concurrency_passed=True,
- sla_passed=True,
- )
- with pytest.raises(ValueError, match="shadow_runs"):
- RolloutPolicy.assert_entry(gates)
- def test_observation_window_fails_closed_before_deadline_or_on_incident():
- now = datetime(2026, 7, 19, tzinfo=UTC)
- window = ObservationWindow(
- started_at=now - timedelta(hours=2),
- required_duration=timedelta(hours=4),
- unexplained_differences=0,
- duplicate_writes=0,
- critical_sla_breaches=0,
- rollback_requests=0,
- )
- with pytest.raises(ValueError, match="observation_window_complete"):
- RolloutPolicy.assert_observation(window, now=now)
- incident = ObservationWindow(
- started_at=now - timedelta(hours=5),
- required_duration=timedelta(hours=4),
- unexplained_differences=0,
- duplicate_writes=1,
- critical_sla_breaches=0,
- rollback_requests=0,
- )
- with pytest.raises(ValueError, match="duplicate_writes"):
- RolloutPolicy.assert_observation(incident, now=now)
- def test_exit_gates_require_recovery_and_unchanged_n8n_standby():
- gates = RolloutExitGates(
- observation_window_complete=True,
- no_unexplained_differences=True,
- no_duplicate_writes=True,
- sla_passed=True,
- pause_retry_rollback_exercised=False,
- n8n_standby=True,
- n8n_unauthorized_changes=0,
- )
- with pytest.raises(ValueError, match="pause_retry_rollback_exercised"):
- RolloutPolicy.assert_exit(gates)
|