From 2f3a91256a96e91255948c4763cc4cec2c632390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=C5=9Aliwi=C5=84ski?= Date: Tue, 17 Oct 2023 16:02:53 +0200 Subject: [PATCH] Replace pydocstyle and pycodestyle with ruff - closes #655 --- .github/workflows/linters.yml | 3 +- Pipfile | 3 +- mirakuru/__init__.py | 13 ++-- mirakuru/base.py | 73 ++++++++------------- mirakuru/base_env.py | 8 +-- mirakuru/exceptions.py | 29 +++----- mirakuru/http.py | 9 ++- mirakuru/output.py | 12 ++-- mirakuru/pid.py | 14 ++-- mirakuru/tcp.py | 14 ++-- mirakuru/unixsocket.py | 14 ++-- newsfragments/655.misc.rst | 1 + pyproject.toml | 8 +++ tests/__init__.py | 7 +- tests/executors/test_executor.py | 18 ++--- tests/executors/test_executor_kill.py | 22 +++---- tests/executors/test_http_executor.py | 26 +++----- tests/executors/test_pid_executor.py | 7 +- tests/executors/test_tcp_executor.py | 8 +-- tests/executors/test_unixsocket_executor.py | 3 +- tests/retry.py | 3 +- tests/sample_daemon.py | 8 +-- tests/server_for_tests.py | 17 ++--- tests/signals.py | 3 +- tests/test_base.py | 3 +- tests/unixsocketserver_for_tests.py | 2 +- 26 files changed, 125 insertions(+), 203 deletions(-) create mode 100644 newsfragments/655.misc.rst diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 9a6382c1..aed4f70b 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -13,6 +13,5 @@ jobs: mypy: true rst: true black: true - pydocstyle: true - pycodestyle: true + ruff: true diff --git a/Pipfile b/Pipfile index 8b88c460..a27c4808 100644 --- a/Pipfile +++ b/Pipfile @@ -12,10 +12,9 @@ pytest = "==7.4.2" pytest-cov = "==4.1.0" coverage = "==7.3.2" python-daemon = "==3.0.1" -pycodestyle = "==2.11.1" -pydocstyle = {version = "==6.3.0", extras = ["toml"]} restructuredtext-lint = "==1.4.0" mypy = "==1.6.0" black = {version = "==23.9.1", markers="python_version >= '3.8'"} pygments = "==2.16.1" tbump = "==6.11.0" +ruff = "==0.1.0" diff --git a/mirakuru/__init__.py b/mirakuru/__init__.py index b47690a0..ff8e80ac 100644 --- a/mirakuru/__init__.py +++ b/mirakuru/__init__.py @@ -21,17 +21,16 @@ import logging from mirakuru.base import Executor, SimpleExecutor -from mirakuru.output import OutputExecutor -from mirakuru.tcp import TCPExecutor -from mirakuru.http import HTTPExecutor -from mirakuru.pid import PidExecutor - from mirakuru.exceptions import ( - ExecutorError, - TimeoutExpired, AlreadyRunning, + ExecutorError, ProcessExitedWithError, + TimeoutExpired, ) +from mirakuru.http import HTTPExecutor +from mirakuru.output import OutputExecutor +from mirakuru.pid import PidExecutor +from mirakuru.tcp import TCPExecutor __version__ = "2.5.1" diff --git a/mirakuru/base.py b/mirakuru/base.py index 8147ac91..ab0b535d 100644 --- a/mirakuru/base.py +++ b/mirakuru/base.py @@ -18,40 +18,40 @@ """Executor with the core functionality.""" import atexit -from contextlib import contextmanager +import errno import logging import os +import platform import shlex import signal import subprocess import time import uuid -import errno -import platform +from contextlib import contextmanager from types import TracebackType from typing import ( - Union, IO, Any, + Callable, + Dict, + Iterator, List, - Tuple, Optional, - Dict, - TypeVar, - Type, Set, - Iterator, - Callable, + Tuple, + Type, + TypeVar, + Union, ) from mirakuru.base_env import processes_with_env +from mirakuru.compat import SIGKILL from mirakuru.exceptions import ( AlreadyRunning, ProcessExitedWithError, ProcessFinishedWithError, TimeoutExpired, ) -from mirakuru.compat import SIGKILL LOG = logging.getLogger(__name__) @@ -75,8 +75,9 @@ def cleanup_subprocesses() -> None: """On python exit: find possibly running subprocesses and kill them.""" # atexit functions tends to loose global imports sometimes so reimport # everything what is needed again here: - import os import errno + import os + from mirakuru.base_env import processes_with_env from mirakuru.compat import SIGKILL @@ -107,8 +108,7 @@ def __init__( # pylint:disable=too-many-arguments stdout: Union[None, int, IO[Any]] = subprocess.PIPE, stderr: Union[None, int, IO[Any]] = None, ) -> None: - """ - Initialize executor. + """Initialize executor. :param (str, list) command: command to be run by the subprocess :param str cwd: current working directory to be set for executor @@ -172,8 +172,7 @@ def __init__( # pylint:disable=too-many-arguments self._uuid = f"{os.getpid()}:{uuid.uuid4()}" def __enter__(self: SimpleExecutorType) -> SimpleExecutorType: - """ - Enter context manager starting the subprocess. + """Enter context manager starting the subprocess. :returns: itself :rtype: SimpleExecutor @@ -190,8 +189,7 @@ def __exit__( self.stop() def running(self) -> bool: - """ - Check if executor is running. + """Check if executor is running. :returns: True if process is running, False otherwise :rtype: bool @@ -203,8 +201,7 @@ def running(self) -> bool: @property def _popen_kwargs(self) -> Dict[str, Any]: - """ - Get kwargs for the process instance. + """Get kwargs for the process instance. .. note:: We want to open ``stdin``, ``stdout`` and ``stderr`` as text @@ -247,8 +244,7 @@ def _popen_kwargs(self) -> Dict[str, Any]: return kwargs def start(self: SimpleExecutorType) -> SimpleExecutorType: - """ - Start defined process. + """Start defined process. After process gets started, timeout countdown begins as well. @@ -270,8 +266,7 @@ def _set_timeout(self) -> None: self._endtime = time.time() + self._timeout def _clear_process(self) -> None: - """ - Close stdin/stdout of subprocess. + """Close stdin/stdout of subprocess. It is required because of ResourceWarning in Python 3. """ @@ -282,8 +277,7 @@ def _clear_process(self) -> None: self._endtime = None def _kill_all_kids(self, sig: int) -> Set[int]: - """ - Kill all subprocesses (and its subprocesses) that executor started. + """Kill all subprocesses (and its subprocesses) that executor started. This function tries to kill all leftovers in process tree that current executor may have left. It uses environment variable to recognise if @@ -313,8 +307,7 @@ def stop( stop_signal: Optional[int] = None, expected_returncode: Optional[int] = None, ) -> SimpleExecutorType: - """ - Stop process running. + """Stop process running. Wait 10 seconds for the process to end, then just kill it. @@ -378,8 +371,7 @@ def process_stopped() -> bool: @contextmanager def stopped(self: SimpleExecutorType) -> Iterator[SimpleExecutorType]: - """ - Stop process for given context and starts it afterwards. + """Stop process for given context and starts it afterwards. Allows for easier writing resistance integration tests whenever one of the service fails. @@ -394,8 +386,7 @@ def stopped(self: SimpleExecutorType) -> Iterator[SimpleExecutorType]: def kill( self: SimpleExecutorType, wait: bool = True, sig: Optional[int] = None ) -> SimpleExecutorType: - """ - Kill the process if running. + """Kill the process if running. :param bool wait: set to `True` to wait for the process to end, or False, to simply proceed after sending signal. @@ -430,8 +421,7 @@ def err_output(self) -> Optional[IO[Any]]: def wait_for( self: SimpleExecutorType, wait_for: Callable[[], bool] ) -> SimpleExecutorType: - """ - Wait for callback to return True. + """Wait for callback to return True. Simply returns if wait_for condition has been met, raises TimeoutExpired otherwise and kills the process. @@ -450,8 +440,7 @@ def wait_for( raise TimeoutExpired(self, timeout=self._timeout) def check_timeout(self) -> bool: - """ - Check if timeout has expired. + """Check if timeout has expired. Returns True if there is no timeout set or the timeout has not expired. Kills the process and raises TimeoutExpired exception otherwise. @@ -498,8 +487,7 @@ class Executor(SimpleExecutor): """Base class for executors with a pre- and after-start checks.""" def pre_start_check(self) -> bool: - """ - Check process before the start of executor. + """Check process before the start of executor. Should be overridden in order to return True when some other executor (or process) has already started with the same configuration. @@ -508,8 +496,7 @@ def pre_start_check(self) -> bool: raise NotImplementedError def start(self: ExecutorType) -> ExecutorType: - """ - Start executor with additional checks. + """Start executor with additional checks. Checks if previous executor isn't running then start process (executor) and wait until it's started. @@ -526,8 +513,7 @@ def start(self: ExecutorType) -> ExecutorType: return self def check_subprocess(self) -> bool: - """ - Make sure the process didn't exit with an error and run the checks. + """Make sure the process didn't exit with an error and run the checks. :rtype: bool :return: the actual check status or False before starting the process @@ -548,8 +534,7 @@ def check_subprocess(self) -> bool: return self.after_start_check() def after_start_check(self) -> bool: - """ - Check process after the start of executor. + """Check process after the start of executor. Should be overridden in order to return boolean value if executor can be treated as started. diff --git a/mirakuru/base_env.py b/mirakuru/base_env.py index adb32c59..20ed96bc 100644 --- a/mirakuru/base_env.py +++ b/mirakuru/base_env.py @@ -21,7 +21,7 @@ import logging import re import subprocess -from typing import Set, List +from typing import List, Set try: import psutil @@ -37,8 +37,7 @@ def processes_with_env_psutil(env_name: str, env_value: str) -> Set[int]: - """ - Find PIDs of processes having environment variable matching given one. + """Find PIDs of processes having environment variable matching given one. Internally it uses `psutil` library. @@ -65,8 +64,7 @@ def processes_with_env_psutil(env_name: str, env_value: str) -> Set[int]: def processes_with_env_ps(env_name: str, env_value: str) -> Set[int]: - """ - Find PIDs of processes having environment variable matching given one. + """Find PIDs of processes having environment variable matching given one. It uses `$ ps xe -o pid,cmd` command so it works only on systems having such command available (Linux, MacOS). If not available function diff --git a/mirakuru/exceptions.py b/mirakuru/exceptions.py index c5e870cf..4d970493 100644 --- a/mirakuru/exceptions.py +++ b/mirakuru/exceptions.py @@ -1,6 +1,6 @@ """Mirakuru exceptions.""" -from typing import Union, TYPE_CHECKING +from typing import TYPE_CHECKING, Union if TYPE_CHECKING: # pragma: no cover from mirakuru.base import SimpleExecutor # pylint:disable=cyclic-import @@ -10,8 +10,7 @@ class ExecutorError(Exception): """Base exception for executor failures.""" def __init__(self, executor: "SimpleExecutor") -> None: - """ - Exception initialization. + """Exception initialization. :param mirakuru.base.SimpleExecutor executor: for which exception occurred @@ -26,8 +25,7 @@ class TimeoutExpired(ExecutorError): def __init__( self, executor: "SimpleExecutor", timeout: Union[int, float] ) -> None: - """ - Exception initialization with an extra ``timeout`` argument. + """Exception initialization with an extra ``timeout`` argument. :param mirakuru.base.SimpleExecutor executor: for which exception occurred @@ -37,8 +35,7 @@ def __init__( self.timeout = timeout def __str__(self) -> str: - """ - Return Exception's string representation. + """Return Exception's string representation. :returns: string representation :rtype: str @@ -49,16 +46,14 @@ def __str__(self) -> str: class AlreadyRunning(ExecutorError): - """ - Is raised when the executor seems to be already running. + """Is raised when the executor seems to be already running. When some other process (not necessary executor) seems to be started with same configuration we can't bind to same port. """ def __str__(self) -> str: - """ - Return Exception's string representation. + """Return Exception's string representation. :returns: string representation :rtype: str @@ -78,8 +73,7 @@ def __str__(self) -> str: class ProcessExitedWithError(ExecutorError): - """ - Raised when the process invoked by the executor returns a non-zero code. + """Raised when the process invoked by the executor returns a non-zero code. We allow the process to exit with zero because we support daemonizing subprocesses. We assume that when double-forking, the parent process will @@ -87,8 +81,7 @@ class ProcessExitedWithError(ExecutorError): """ def __init__(self, executor: "SimpleExecutor", exit_code: int) -> None: - """ - Exception initialization with an extra ``exit_code`` argument. + """Exception initialization with an extra ``exit_code`` argument. :param mirakuru.base.SimpleExecutor executor: for which exception occurred @@ -98,8 +91,7 @@ def __init__(self, executor: "SimpleExecutor", exit_code: int) -> None: self.exit_code = exit_code def __str__(self) -> str: - """ - Return Exception's string representation. + """Return Exception's string representation. :returns: string representation :rtype: str @@ -111,8 +103,7 @@ def __str__(self) -> str: class ProcessFinishedWithError(ProcessExitedWithError): - """ - Raised when the process invoked by the executor fails when stopping. + """Raised when the process invoked by the executor fails when stopping. When a process is stopped, it should shut down cleanly and return zero as exit code. When is returns a non-zero exit code, this exception is raised. diff --git a/mirakuru/http.py b/mirakuru/http.py index bf44a84f..4a6fdc28 100644 --- a/mirakuru/http.py +++ b/mirakuru/http.py @@ -19,10 +19,10 @@ import re import socket -from logging import getLogger -from urllib.parse import urlparse, urlencode from http.client import HTTPConnection, HTTPException -from typing import Union, List, Tuple, Optional, Dict, Any +from logging import getLogger +from typing import Any, Dict, List, Optional, Tuple, Union +from urllib.parse import urlencode, urlparse from mirakuru.tcp import TCPExecutor @@ -45,8 +45,7 @@ def __init__( headers: Optional[Dict[str, str]] = None, **kwargs: Any, ) -> None: - """ - Initialize HTTPExecutor executor. + """Initialize HTTPExecutor executor. :param (str, list) command: command to be run by the subprocess :param str url: URL that executor checks to verify diff --git a/mirakuru/output.py b/mirakuru/output.py index 89db070b..68c6c237 100644 --- a/mirakuru/output.py +++ b/mirakuru/output.py @@ -19,11 +19,10 @@ import platform import re import select -from typing import Union, List, Any, TypeVar, Tuple, IO, Optional +from typing import IO, Any, List, Optional, Tuple, TypeVar, Union from mirakuru.base import SimpleExecutor - IS_DARWIN = platform.system() == "Darwin" @@ -39,8 +38,7 @@ def __init__( banner: str, **kwargs: Any, ) -> None: - """ - Initialize OutputExecutor executor. + """Initialize OutputExecutor executor. :param (str, list) command: command to be run by the subprocess :param str banner: string that has to appear in process output - @@ -63,8 +61,7 @@ def __init__( ) def start(self: OutputExecutorType) -> OutputExecutorType: - """ - Start process. + """Start process. :returns: itself :rtype: OutputExecutor @@ -137,8 +134,7 @@ def _wait_for_darwin_output(self, *fds: Optional[IO[Any]]) -> bool: return False def _wait_for_output(self, *polls: Tuple["select.poll", IO[Any]]) -> bool: - """ - Check if output matches banner. + """Check if output matches banner. .. warning:: Waiting for I/O completion. It does not work on Windows. Sorry. diff --git a/mirakuru/pid.py b/mirakuru/pid.py index e2b32ab5..96ad5c1d 100644 --- a/mirakuru/pid.py +++ b/mirakuru/pid.py @@ -18,14 +18,13 @@ """Pid executor definition.""" import os.path -from typing import Union, List, Tuple, Any +from typing import Any, List, Tuple, Union from mirakuru.base import Executor class PidExecutor(Executor): - """ - File existence checking process executor. + """File existence checking process executor. Used to start processes that create pid files (or any other for that matter). Starts the given process and waits for the given file to be @@ -38,8 +37,7 @@ def __init__( filename: str, **kwargs: Any, ) -> None: - """ - Initialize the PidExecutor executor. + """Initialize the PidExecutor executor. If the filename is empty, a ValueError is thrown. @@ -64,8 +62,7 @@ def __init__( """the name of the file which the process is to create.""" def pre_start_check(self) -> bool: - """ - Check if the specified file has been created. + """Check if the specified file has been created. .. note:: @@ -75,8 +72,7 @@ def pre_start_check(self) -> bool: return os.path.isfile(self.filename) def after_start_check(self) -> bool: - """ - Check if the process has created the specified file. + """Check if the process has created the specified file. .. note:: diff --git a/mirakuru/tcp.py b/mirakuru/tcp.py index a1265821..7972f15b 100644 --- a/mirakuru/tcp.py +++ b/mirakuru/tcp.py @@ -18,14 +18,13 @@ """TCP executor definition.""" import socket -from typing import Union, List, Tuple, Any +from typing import Any, List, Tuple, Union from mirakuru.base import Executor class TCPExecutor(Executor): - """ - TCP-listening process executor. + """TCP-listening process executor. Used to start (and wait to actually be running) processes that can accept TCP connections. @@ -38,8 +37,7 @@ def __init__( port: int, **kwargs: Any, ) -> None: - """ - Initialize TCPExecutor executor. + """Initialize TCPExecutor executor. :param (str, list) command: command to be run by the subprocess :param str host: host under which process is accessible @@ -61,8 +59,7 @@ def __init__( """Port number, process is listening on.""" def pre_start_check(self) -> bool: - """ - Check if process accepts connections. + """Check if process accepts connections. .. note:: @@ -80,8 +77,7 @@ def pre_start_check(self) -> bool: sock.close() def after_start_check(self) -> bool: - """ - Check if process accepts connections. + """Check if process accepts connections. .. note:: diff --git a/mirakuru/unixsocket.py b/mirakuru/unixsocket.py index 3dd1f9ff..a3249c60 100644 --- a/mirakuru/unixsocket.py +++ b/mirakuru/unixsocket.py @@ -18,7 +18,7 @@ """TCP Socket executor definition.""" import logging import socket -from typing import Union, List, Tuple, Any +from typing import Any, List, Tuple, Union from mirakuru import Executor @@ -26,8 +26,7 @@ class UnixSocketExecutor(Executor): - """ - Unixsocket listening process executor. + """Unixsocket listening process executor. Used to start (and wait to actually be running) processes that can accept stream Unix socket connections. @@ -39,8 +38,7 @@ def __init__( socket_name: str, **kwargs: Any, ) -> None: - """ - Initialize UnixSocketExecutor executor. + """Initialize UnixSocketExecutor executor. :param (str, list) command: command to be run by the subprocess :param str socket_name: unix socket path @@ -57,8 +55,7 @@ def __init__( self.socket = socket_name def pre_start_check(self) -> bool: - """ - Check if process accepts connections. + """Check if process accepts connections. .. note:: @@ -77,8 +74,7 @@ def pre_start_check(self) -> bool: exec_sock.close() def after_start_check(self) -> bool: - """ - Check if process accepts connections. + """Check if process accepts connections. .. note:: diff --git a/newsfragments/655.misc.rst b/newsfragments/655.misc.rst new file mode 100644 index 00000000..2565766a --- /dev/null +++ b/newsfragments/655.misc.rst @@ -0,0 +1 @@ +Replace pydocstyle, pycodestyle with ruff \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 03b9476b..75673270 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,6 +92,14 @@ line-length = 80 target-version = ['py38'] include = '.*\.pyi?$' +[tool.ruff] +line-length = 80 +select = [ + "E", # pycodestyle + "F", # pyflakes + "I", # isort + "D", # pydocstyle +] [tool.tbump] # Uncomment this if your project is hosted on GitHub: diff --git a/tests/__init__.py b/tests/__init__.py index 6105b410..ccec28d5 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,5 +1,4 @@ -""" -Package of tests for mirakuru. +"""Package of tests for mirakuru. Tests are written using py.test framework which dictates patterns that should be followed in test cases. @@ -8,7 +7,6 @@ from os import path from subprocess import check_output - TEST_PATH = path.abspath(path.dirname(__file__)) TEST_SERVER_PATH = path.join(TEST_PATH, "server_for_tests.py") @@ -19,8 +17,7 @@ def ps_aux() -> str: - """ - Return output of systems `ps aux -w` call. + """Return output of systems `ps aux -w` call. :rtype str """ diff --git a/tests/executors/test_executor.py b/tests/executors/test_executor.py index c0491249..d5bcd61c 100644 --- a/tests/executors/test_executor.py +++ b/tests/executors/test_executor.py @@ -3,17 +3,16 @@ import gc import shlex import signal -from subprocess import check_output import uuid +from subprocess import check_output +from typing import List, Union from unittest import mock -from typing import Union, List import pytest from mirakuru import Executor from mirakuru.base import SimpleExecutor from mirakuru.exceptions import ProcessExitedWithError, TimeoutExpired - from tests import SAMPLE_DAEMON_PATH, ps_aux from tests.retry import retry @@ -37,7 +36,6 @@ def test_running_process(command: Union[str, List[str]]) -> None: @pytest.mark.parametrize("command", (SLEEP_300, SLEEP_300.split())) def test_command(command: Union[str, List[str]]) -> None: """Check that the command and command parts are equivalent.""" - executor = SimpleExecutor(command) assert executor.command == SLEEP_300 assert executor.command_parts == SLEEP_300.split() @@ -143,8 +141,7 @@ def test_start_check_executor() -> None: def test_stopping_not_yet_running_executor() -> None: - """ - Test if SimpleExecutor can be stopped even it was never running. + """Test if SimpleExecutor can be stopped even it was never running. We must make sure that it's possible to call .stop() and SimpleExecutor will not raise any exception and .start() can be called afterwards. @@ -157,8 +154,7 @@ def test_stopping_not_yet_running_executor() -> None: def test_forgotten_stop() -> None: - """ - Test if SimpleExecutor subprocess is killed after an instance is deleted. + """Test if SimpleExecutor subprocess is killed after an instance is deleted. Existence can end because of context scope end or by calling 'del'. If someone forgot to stop() or kill() subprocess it should be killed @@ -185,8 +181,7 @@ def test_forgotten_stop() -> None: def test_executor_raises_if_process_exits_with_error() -> None: - """ - Test process exit detection. + """Test process exit detection. If the process exits with an error while checks are being polled, executor should raise an exception. @@ -216,8 +211,7 @@ def test_executor_raises_if_process_exits_with_error() -> None: def test_executor_ignores_processes_exiting_with_0() -> None: - """ - Test process exit detection. + """Test process exit detection. Subprocess exiting with zero should be tolerated in order to support double-forking applications. diff --git a/tests/executors/test_executor_kill.py b/tests/executors/test_executor_kill.py index ae0f8b7c..2e05e8ea 100644 --- a/tests/executors/test_executor_kill.py +++ b/tests/executors/test_executor_kill.py @@ -1,22 +1,19 @@ # mypy: no-strict-optional """Tests that check various kill behaviours.""" +import errno +import os import signal -import time import sys +import time from typing import NoReturn, Set - -import errno - -import os from unittest.mock import patch import pytest -from mirakuru import SimpleExecutor, HTTPExecutor +from mirakuru import HTTPExecutor, SimpleExecutor from mirakuru.compat import SIGKILL from mirakuru.exceptions import ProcessFinishedWithError - -from tests import SAMPLE_DAEMON_PATH, ps_aux, TEST_SERVER_PATH +from tests import SAMPLE_DAEMON_PATH, TEST_SERVER_PATH, ps_aux SLEEP_300 = "sleep 300" @@ -57,8 +54,7 @@ def process_stopped() -> bool: def test_daemons_killing() -> None: - """ - Test if all subprocesses of SimpleExecutor can be killed. + """Test if all subprocesses of SimpleExecutor can be killed. The most problematic subprocesses are daemons or other services that change the process group ID. This test verifies that daemon process @@ -77,8 +73,7 @@ def test_daemons_killing() -> None: def test_stopping_brutally() -> None: - """ - Test if SimpleExecutor is stopping insubordinate process. + """Test if SimpleExecutor is stopping insubordinate process. Check if the process that doesn't react to SIGTERM signal will be killed by executor with SIGKILL automatically. @@ -96,8 +91,7 @@ def test_stopping_brutally() -> None: def test_stopping_children_of_stopped_process() -> None: - """ - Check that children exiting between listing and killing are ignored. + """Check that children exiting between listing and killing are ignored. Given: Executor is running and it's process spawn children, diff --git a/tests/executors/test_http_executor.py b/tests/executors/test_http_executor.py index 8bd623f5..5aefc2a5 100644 --- a/tests/executors/test_http_executor.py +++ b/tests/executors/test_http_executor.py @@ -1,16 +1,15 @@ """HTTP Executor tests.""" -import sys import socket +import sys from functools import partial -from http.client import HTTPConnection, OK -from typing import Dict, Any, Union +from http.client import OK, HTTPConnection +from typing import Any, Dict, Union from unittest.mock import patch import pytest -from mirakuru import HTTPExecutor, TCPExecutor -from mirakuru import TimeoutExpired, AlreadyRunning -from tests import TEST_SERVER_PATH, HTTP_SERVER_CMD +from mirakuru import AlreadyRunning, HTTPExecutor, TCPExecutor, TimeoutExpired +from tests import HTTP_SERVER_CMD, TEST_SERVER_PATH HOST = "127.0.0.1" PORT = 7987 @@ -72,13 +71,11 @@ def test_shell_started_server_stops() -> None: @pytest.mark.parametrize("method", ("HEAD", "GET", "POST")) def test_slow_method_server_starting(method: str) -> None: - """ - Test whether or not executor awaits for slow starting servers. + """Test whether or not executor awaits for slow starting servers. Simple example. You run Gunicorn and it is working but you have to wait for worker processes. """ - http_method_slow_cmd = ( f"{sys.executable} {TEST_SERVER_PATH} {HOST}:{PORT} False {method}" ) @@ -93,13 +90,11 @@ def test_slow_method_server_starting(method: str) -> None: def test_slow_post_payload_server_starting() -> None: - """ - Test whether or not executor awaits for slow starting servers. + """Test whether or not executor awaits for slow starting servers. Simple example. You run Gunicorn and it is working but you have to wait for worker processes. """ - http_method_slow_cmd = ( f"{sys.executable} {TEST_SERVER_PATH} {HOST}:{PORT} False Key" ) @@ -117,7 +112,6 @@ def test_slow_post_payload_server_starting() -> None: @pytest.mark.parametrize("method", ("HEAD", "GET", "POST")) def test_slow_method_server_timed_out(method: str) -> None: """Check if timeout properly expires.""" - http_method_slow_cmd = ( f"{sys.executable} {TEST_SERVER_PATH} {HOST}:{PORT} False {method}" ) @@ -157,8 +151,7 @@ def test_fail_if_other_running() -> None: @patch.object(HTTPExecutor, "DEFAULT_PORT", PORT) def test_default_port() -> None: - """ - Test default port for the base TCP check. + """Test default port for the base TCP check. Check if HTTP executor fills in the default port for the TCP check from the base class if no port is provided in the URL. @@ -192,8 +185,7 @@ def test_default_port() -> None: def test_http_status_codes( accepted_status: Union[None, int, str], expected_timeout: bool ) -> None: - """ - Test how 'status' argument influences executor start. + """Test how 'status' argument influences executor start. :param int|str accepted_status: Executor 'status' value :param bool expected_timeout: if Executor raises TimeoutExpired or not diff --git a/tests/executors/test_pid_executor.py b/tests/executors/test_pid_executor.py index caf658e4..9d392d96 100644 --- a/tests/executors/test_pid_executor.py +++ b/tests/executors/test_pid_executor.py @@ -4,9 +4,7 @@ import pytest -from mirakuru import PidExecutor -from mirakuru import TimeoutExpired, AlreadyRunning - +from mirakuru import AlreadyRunning, PidExecutor, TimeoutExpired FILENAME = f"pid-test-tmp{os.getpid()}" SLEEP = f'bash -c "sleep 1 && touch {FILENAME} && sleep 1"' @@ -14,8 +12,7 @@ @pytest.fixture(autouse=True) def run_around_tests() -> Iterator[None]: - """ - Make sure the **FILENAME** file is not present. + """Make sure the **FILENAME** file is not present. This executor actually removes FILENAME as process used to test PidExecutor only creates it. diff --git a/tests/executors/test_tcp_executor.py b/tests/executors/test_tcp_executor.py index 83ee5fd7..075e1bda 100644 --- a/tests/executors/test_tcp_executor.py +++ b/tests/executors/test_tcp_executor.py @@ -1,5 +1,4 @@ -""" -TCPExecutor tests. +"""TCPExecutor tests. Some of these tests run ``nc``: when running Debian, make sure the ``netcat-openbsd`` package is used, not ``netcat-traditional``. @@ -9,12 +8,9 @@ import pytest from _pytest.logging import LogCaptureFixture -from mirakuru import TCPExecutor -from mirakuru import TimeoutExpired, AlreadyRunning - +from mirakuru import AlreadyRunning, TCPExecutor, TimeoutExpired from tests import HTTP_SERVER_CMD - PORT = 7986 HTTP_SERVER = f"{HTTP_SERVER_CMD} {PORT}" diff --git a/tests/executors/test_unixsocket_executor.py b/tests/executors/test_unixsocket_executor.py index 61befd55..2b467f69 100644 --- a/tests/executors/test_unixsocket_executor.py +++ b/tests/executors/test_unixsocket_executor.py @@ -1,5 +1,4 @@ -""" -TCPExecutor tests. +"""TCPExecutor tests. Some of these tests run ``nc``: when running Debian, make sure the ``netcat-openbsd`` package is used, not ``netcat-traditional``. diff --git a/tests/retry.py b/tests/retry.py index 6f30226c..8741a6c0 100644 --- a/tests/retry.py +++ b/tests/retry.py @@ -2,11 +2,10 @@ from datetime import datetime, timedelta, timezone from time import sleep -from typing import TypeVar, Callable, Type +from typing import Callable, Type, TypeVar from mirakuru import ExecutorError - T = TypeVar("T") diff --git a/tests/sample_daemon.py b/tests/sample_daemon.py index 79e625ad..aff22818 100644 --- a/tests/sample_daemon.py +++ b/tests/sample_daemon.py @@ -1,5 +1,4 @@ -""" -Daemon sample application for tests purposes. +"""Daemon sample application for tests purposes. Stopping this process is possible only by the SIGKILL signal. @@ -14,10 +13,9 @@ import daemon -sys.path.append(os.getcwd()) # noqa - -from tests.signals import block_signals # pylint:disable=wrong-import-position +sys.path.append(os.getcwd()) +from tests.signals import block_signals # noqa: E402 with daemon.DaemonContext(initgroups=False): block_signals() diff --git a/tests/server_for_tests.py b/tests/server_for_tests.py index 4484a04a..76d5428d 100644 --- a/tests/server_for_tests.py +++ b/tests/server_for_tests.py @@ -1,5 +1,4 @@ -""" -HTTP server that responses with delays used for tests. +"""HTTP server that responses with delays used for tests. Example usage: @@ -13,18 +12,15 @@ """ import ast -import sys import os +import sys import time -from http.server import HTTPServer, BaseHTTPRequestHandler +from http.server import BaseHTTPRequestHandler, HTTPServer from urllib.parse import parse_qs -sys.path.append(os.getcwd()) # noqa +sys.path.append(os.getcwd()) -# pylint:disable=wrong-import-position -from tests.signals import block_signals - -# pylint:enable=wrong-import-position +from tests.signals import block_signals # noqa: E402 class SlowServerHandler(BaseHTTPRequestHandler): @@ -41,8 +37,7 @@ def do_GET(self) -> None: # pylint:disable=invalid-name self.wfile.write(b"Hi. I am very slow.") def do_HEAD(self) -> None: # pylint:disable=invalid-name - """ - Serve HEAD request. + """Serve HEAD request. but count to wait and return 500 response if wait time not exceeded due to the fact that HTTPServer will hang waiting for response diff --git a/tests/signals.py b/tests/signals.py index 4e4fc192..22760c58 100644 --- a/tests/signals.py +++ b/tests/signals.py @@ -5,8 +5,7 @@ def block_signals() -> None: - """ - Catch all of the signals that it is possible. + """Catch all of the signals that it is possible. Reject their default behaviour. The process is actually mortal but the only way to kill is to send SIGKILL signal (kill -9). diff --git a/tests/test_base.py b/tests/test_base.py index a37331b1..c9777c6a 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -1,6 +1,5 @@ """General mirakuru library tests.""" -# pylint: disable=wildcard-import,unused-wildcard-import -from mirakuru import * +from mirakuru import * # noqa: F403 def test_importing_mirakuru() -> None: diff --git a/tests/unixsocketserver_for_tests.py b/tests/unixsocketserver_for_tests.py index fee73f23..3c488595 100644 --- a/tests/unixsocketserver_for_tests.py +++ b/tests/unixsocketserver_for_tests.py @@ -22,9 +22,9 @@ # POSSIBILITY OF SUCH DAMAGE. """Sample unixsocket server with small modifications.""" +import os import socket import sys -import os from time import sleep SOCKET_ADDRESS = "./uds_socket"