from aarecommon.errors.exception_handler import ( LoopCenteringFailed, MountingFailed, SampleException, TellException, ) from aarecommon.recurrence_watcher import ( RecurrenceWatcher, create_default_watchers, load_watcher_threshold_overrides, redis_key_to_env_var, resolve_exception_class, ) def test_recurrence_watcher_trips_at_threshold_and_resets_on_none(): watcher = RecurrenceWatcher(name="tell", observes=TellException, threshold=2) assert watcher.observe(MountingFailed) is False assert watcher.observe(MountingFailed) is True assert watcher.streak == 2 assert watcher.observe(None) is False assert watcher.streak == 0 def test_recurrence_watcher_ignores_non_matching_exception(): watcher = RecurrenceWatcher(name="tell", observes=TellException, threshold=2) assert watcher.observe(SampleException) is False assert watcher.streak == 0 def test_load_watcher_threshold_overrides_reads_valid_values_only(): values = { "aare:watchers:mx:tell:threshold": "7", "aare:watchers:mx:alc:threshold": b"3", "aare:watchers:mx:smargon:threshold": "not-an-int", } overrides = load_watcher_threshold_overrides( beamline="mx", watcher_names=["tell", "alc", "smargon"], get_value=values.get ) assert overrides == {"tell": 7, "alc": 3} def test_create_default_watchers_applies_overrides(): watchers = {watcher.name: watcher for watcher in create_default_watchers({"alc": 4})} assert watchers["alc"].threshold == 4 assert watchers["tell"].threshold > 0 def test_resolve_exception_class_maps_known_classes(): assert resolve_exception_class("MountingFailed") is MountingFailed assert resolve_exception_class("LoopCenteringFailed") is LoopCenteringFailed assert resolve_exception_class("UnknownClass") is None def test_redis_key_to_env_var_converts_colons_and_uppercases(): assert redis_key_to_env_var("aare:watchers:default:tell:threshold") == ( "AARE_WATCHERS_DEFAULT_TELL_THRESHOLD" ) assert redis_key_to_env_var("aare:watchers:mx:alc:threshold") == ( "AARE_WATCHERS_MX_ALC_THRESHOLD" ) def test_load_watcher_threshold_overrides_through_env_var_adapter(monkeypatch): monkeypatch.setenv("AARE_WATCHERS_DEFAULT_TELL_THRESHOLD", "9") monkeypatch.setenv("AARE_WATCHERS_DEFAULT_ALC_THRESHOLD", "bad") import os overrides = load_watcher_threshold_overrides( beamline="default", watcher_names=["tell", "alc", "smargon"], get_value=lambda k: os.getenv(redis_key_to_env_var(k)), ) assert overrides == {"tell": 9}