"""ORCH-042: Settings.tracker_mode config field. AC-1: tracker_mode defaults to "edit" and is read from env ORCH_TRACKER_MODE. Settings is a Pydantic BaseSettings reading env at instantiation, so each case builds a FRESH Settings() (the process-wide singleton is not mutated). """ from src.config import Settings def test_tracker_mode_defaults_to_edit(monkeypatch): # No env var -> default "edit" (TC-01 / AC-1). monkeypatch.delenv("ORCH_TRACKER_MODE", raising=False) assert Settings().tracker_mode == "edit" def test_tracker_mode_reads_env_bump(monkeypatch): # ORCH_TRACKER_MODE=bump -> "bump" (TC-01 / AC-1). monkeypatch.setenv("ORCH_TRACKER_MODE", "bump") assert Settings().tracker_mode == "bump" def test_tracker_mode_reads_env_arbitrary(monkeypatch): # The field is read verbatim from env; mode RESOLUTION (anything != "bump" # -> edit) happens in notifications, not here (AC-1/AC-2 split). monkeypatch.setenv("ORCH_TRACKER_MODE", "garbage") assert Settings().tracker_mode == "garbage" # --------------------------------------------------------------------------- # ORCH-043 / TC-25: merge-gate settings defaults + env override. # --------------------------------------------------------------------------- _MERGE_ENV = ( "ORCH_MERGE_GATE_ENABLED", "ORCH_MERGE_GATE_REPOS", "ORCH_MERGE_RETEST_TIMEOUT_S", "ORCH_MERGE_RETEST_TARGET", "ORCH_MERGE_LOCK_TIMEOUT_S", "ORCH_MERGE_DEFER_DELAY_S", "ORCH_MERGE_DEFER_MAX_ATTEMPTS", ) def test_merge_gate_settings_defaults(monkeypatch): """TC-25 / AC-10: documented defaults when no env is set.""" for name in _MERGE_ENV: monkeypatch.delenv(name, raising=False) s = Settings() assert s.merge_gate_enabled is True assert s.merge_gate_repos == "" assert s.merge_retest_timeout_s == 600 assert s.merge_retest_target == "tests/" assert s.merge_lock_timeout_s == 300 assert s.merge_defer_delay_s == 60 assert s.merge_defer_max_attempts == 5 def test_merge_gate_settings_env_override(monkeypatch): """TC-25 / AC-10: each field is read from its ORCH_* env var.""" monkeypatch.setenv("ORCH_MERGE_GATE_ENABLED", "false") monkeypatch.setenv("ORCH_MERGE_GATE_REPOS", "orchestrator,enduro-trails") monkeypatch.setenv("ORCH_MERGE_RETEST_TIMEOUT_S", "120") monkeypatch.setenv("ORCH_MERGE_RETEST_TARGET", "tests/unit") monkeypatch.setenv("ORCH_MERGE_LOCK_TIMEOUT_S", "90") monkeypatch.setenv("ORCH_MERGE_DEFER_DELAY_S", "5") monkeypatch.setenv("ORCH_MERGE_DEFER_MAX_ATTEMPTS", "9") s = Settings() assert s.merge_gate_enabled is False assert s.merge_gate_repos == "orchestrator,enduro-trails" assert s.merge_retest_timeout_s == 120 assert s.merge_retest_target == "tests/unit" assert s.merge_lock_timeout_s == 90 assert s.merge_defer_delay_s == 5 assert s.merge_defer_max_attempts == 9 # --------------------------------------------------------------------------- # ORCH-053 / TC-22: reconcile_* settings defaults + env override. # --------------------------------------------------------------------------- _RECONCILE_ENV = ( "ORCH_RECONCILE_ENABLED", "ORCH_RECONCILE_INTERVAL_S", "ORCH_RECONCILE_PLANE_ENABLED", "ORCH_RECONCILE_GRACE_DEFAULT_S", "ORCH_RECONCILE_GRACE_OVERRIDES_JSON", "ORCH_RECONCILE_NOTIFY_UNBLOCK", ) def test_reconcile_settings_defaults(monkeypatch): """TC-22 / AC-13: documented defaults when no env is set.""" for name in _RECONCILE_ENV: monkeypatch.delenv(name, raising=False) s = Settings() assert s.reconcile_enabled is True assert s.reconcile_interval_s == 120 assert s.reconcile_plane_enabled is True assert s.reconcile_grace_default_s == 600 assert s.reconcile_grace_overrides_json == "" assert s.reconcile_notify_unblock is True def test_reconcile_settings_env_override(monkeypatch): """TC-22 / AC-13: each field is read from its ORCH_* env var.""" monkeypatch.setenv("ORCH_RECONCILE_ENABLED", "false") monkeypatch.setenv("ORCH_RECONCILE_INTERVAL_S", "300") monkeypatch.setenv("ORCH_RECONCILE_PLANE_ENABLED", "false") monkeypatch.setenv("ORCH_RECONCILE_GRACE_DEFAULT_S", "900") monkeypatch.setenv("ORCH_RECONCILE_GRACE_OVERRIDES_JSON", '{"development": 300}') monkeypatch.setenv("ORCH_RECONCILE_NOTIFY_UNBLOCK", "false") s = Settings() assert s.reconcile_enabled is False assert s.reconcile_interval_s == 300 assert s.reconcile_plane_enabled is False assert s.reconcile_grace_default_s == 900 assert s.reconcile_grace_overrides_json == '{"development": 300}' assert s.reconcile_notify_unblock is False