import tempfile import time from contextlib import contextmanager from os import path from shutil import rmtree import pytest from galaxy.tool_util.toolbox import watcher from galaxy.util import bunch from galaxy.util.watcher import can_watch @pytest.mark.skipif(not can_watch, reason="watchdog not available") def test_watcher(): with __test_directory() as t: tool_path = path.join(t, "test.xml") toolbox = Toolbox() with open(tool_path, "w") as f: f.write("a") tool_watcher = watcher.get_tool_watcher(toolbox, bunch.Bunch(watch_tools=True)) tool_watcher.start() tool_watcher.watch_file(tool_path, "cool_tool") time.sleep(2) assert not toolbox.was_reloaded("cool_tool") with open(tool_path, "w") as f: f.write("b") wait_for_reload(lambda: toolbox.was_reloaded("cool_tool")) tool_watcher.shutdown() assert tool_watcher.observer is None @pytest.mark.skipif(not can_watch, reason="watchdog not available") def test_tool_conf_watcher(): callback = CallbackRecorder() conf_watcher = watcher.get_tool_conf_watcher(callback.call) conf_watcher.start() with __test_directory() as t: tool_conf_path = path.join(t, "test_conf.xml") with open(tool_conf_path, "w") as f: f.write("a") conf_watcher.watch_file(tool_conf_path) time.sleep(2) with open(tool_conf_path, "w") as f: f.write("b") wait_for_reload(lambda: callback.called) conf_watcher.shutdown() assert conf_watcher.thread is None def wait_for_reload(check): reloaded = False for _ in range(10): reloaded = check() if reloaded: break time.sleep(0.2) assert reloaded class Toolbox: def __init__(self): self.reloaded = {} def reload_tool_by_id(self, tool_id): self.reloaded[tool_id] = True def was_reloaded(self, tool_id): return self.reloaded.get(tool_id, False) class CallbackRecorder: def __init__(self): self.called = False def call(self): self.called = True @contextmanager def __test_directory(): base_path = tempfile.mkdtemp() try: yield base_path finally: rmtree(base_path)