diff --git a/git_hg_sync/application.py b/git_hg_sync/application.py index cc8272c..9451382 100644 --- a/git_hg_sync/application.py +++ b/git_hg_sync/application.py @@ -1,3 +1,7 @@ +import signal +from types import FrameType +from typing import Optional + from mozlog import get_proxy_logger from git_hg_sync.events import Push, Tag @@ -22,6 +26,11 @@ def __init__( self._mappings = mappings def run(self) -> None: + def signal_handler(sig: int, frame: Optional[FrameType]) -> None: + self._worker.shoud_stop = True + logger.info("Process stopped by user") + + signal.signal(signal.SIGINT, signal_handler) self._worker.run() def _handle_push_event(self, push_event: Push) -> None: diff --git a/tests/test_pulse_worker.py b/tests/test_pulse_worker.py index 24bdb1d..a6eb5cf 100644 --- a/tests/test_pulse_worker.py +++ b/tests/test_pulse_worker.py @@ -1,8 +1,15 @@ +import signal +import time +from pathlib import Path +from subprocess import PIPE, Popen + import pytest from git_hg_sync.events import Push, Tag from git_hg_sync.pulse_worker import EntityTypeError, PulseWorker +HERE = Path(__file__).parent + def raw_push_entity(): return { @@ -39,3 +46,19 @@ def test_parse_entity_valid() -> None: def test_parse_invalid_type() -> None: with pytest.raises(EntityTypeError): PulseWorker.parse_entity({"type": "unknown"}) + + +def test_sigint_signal_interception() -> None: + config_file = HERE / "data" / "config.toml" + module_path = HERE.parent / "git_hg_sync" / "__main__.py" + process = Popen( + ["python", module_path, "-c", config_file], shell=True, stdout=PIPE, stderr=PIPE + ) + time.sleep(1) + process.send_signal(signal.SIGINT) + time.sleep(1) + try: + assert process.returncode == 0 + except AssertionError as e: + process.kill() + raise e