From 99e645e8bcce52ac85d4dabdc6ae1e4bdceb4a17 Mon Sep 17 00:00:00 2001 From: "d.kovalenko" Date: Tue, 6 May 2025 15:52:11 +0300 Subject: [PATCH 1/7] [#247] PortManager__Generic uses lock-dirs for reserved ports --- testgres/consts.py | 4 +++ testgres/impl/port_manager__generic.py | 44 ++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/testgres/consts.py b/testgres/consts.py index 89c49ab7..d3589205 100644 --- a/testgres/consts.py +++ b/testgres/consts.py @@ -10,6 +10,10 @@ TMP_CACHE = 'tgsc_' TMP_BACKUP = 'tgsb_' +TMP_TESTGRES = "testgres" + +TMP_TESTGRES_PORTS = TMP_TESTGRES + "/ports" + # path to control file XLOG_CONTROL_FILE = "global/pg_control" diff --git a/testgres/impl/port_manager__generic.py b/testgres/impl/port_manager__generic.py index a51af2bd..07cc2122 100755 --- a/testgres/impl/port_manager__generic.py +++ b/testgres/impl/port_manager__generic.py @@ -2,7 +2,9 @@ from ..port_manager import PortManager from ..exceptions import PortForException +from .. import consts +import os import threading import random import typing @@ -15,6 +17,8 @@ class PortManager__Generic(PortManager): _available_ports: typing.Set[int] _reserved_ports: typing.Set[int] + _lock_dir: str + def __init__(self, os_ops: OsOperations): assert os_ops is not None assert isinstance(os_ops, OsOperations) @@ -23,6 +27,12 @@ def __init__(self, os_ops: OsOperations): self._available_ports: typing.Set[int] = set(range(1024, 65535)) self._reserved_ports: typing.Set[int] = set() + temp_dir = os_ops.get_tempdir() + assert type(temp_dir) == str # noqa: E721 + self._lock_dir = os.path.join(temp_dir, consts.TMP_TESTGRES_PORTS) + assert type(self._lock_dir) == str # noqa: E721 + os_ops.makedirs(self._lock_dir) + def reserve_port(self) -> int: assert self._guard is not None assert type(self._available_ports) == set # noqa: E721t @@ -41,9 +51,23 @@ def reserve_port(self) -> int: if not self._os_ops.is_port_free(port): continue - self._reserved_ports.add(port) - self._available_ports.discard(port) + try: + lock_path = self.helper__make_lock_path(port) + self._os_ops.makedir(lock_path) + except: # noqa: 722 + continue + + assert self._os_ops.path_exists(lock_path) + + try: + self._reserved_ports.add(port) + except: # noqa: 722 + assert not (port in self._reserved_ports) + self._os_ops.rmdir(lock_path) + raise + assert port in self._reserved_ports + self._available_ports.discard(port) assert not (port in self._available_ports) return port @@ -55,6 +79,8 @@ def release_port(self, number: int) -> None: assert self._guard is not None assert type(self._reserved_ports) == set # noqa: E721 + lock_path = self.helper__make_lock_path(number) + with self._guard: assert number in self._reserved_ports assert not (number in self._available_ports) @@ -62,3 +88,17 @@ def release_port(self, number: int) -> None: self._reserved_ports.discard(number) assert not (number in self._reserved_ports) assert number in self._available_ports + + assert isinstance(self._os_ops, OsOperations) + assert self._os_ops.path_exists(lock_path) + self._os_ops.rmdir(lock_path) + + return + + def helper__make_lock_path(self, port_number: int) -> str: + assert type(port_number) == int # noqa: E721 + assert type(self._lock_dir) == str # noqa: E721 + + result = os.path.join(self._lock_dir, str(port_number) + ".lock") + assert type(result) == str # noqa: E721 + return result From c6f4b4df046aa37e3a72b5677a721f3ce6a60142 Mon Sep 17 00:00:00 2001 From: "d.kovalenko" Date: Wed, 7 May 2025 09:07:17 +0300 Subject: [PATCH 2/7] PortManager__Generic is refactored - [FIX] A creation of self._log_dir is moved to reserve_port method - Code normalization [copy&paste mistakes] - New asserts are added - New comments are added --- testgres/impl/port_manager__generic.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/testgres/impl/port_manager__generic.py b/testgres/impl/port_manager__generic.py index 07cc2122..cf60fa84 100755 --- a/testgres/impl/port_manager__generic.py +++ b/testgres/impl/port_manager__generic.py @@ -24,21 +24,28 @@ def __init__(self, os_ops: OsOperations): assert isinstance(os_ops, OsOperations) self._os_ops = os_ops self._guard = threading.Lock() - self._available_ports: typing.Set[int] = set(range(1024, 65535)) - self._reserved_ports: typing.Set[int] = set() - - temp_dir = os_ops.get_tempdir() - assert type(temp_dir) == str # noqa: E721 - self._lock_dir = os.path.join(temp_dir, consts.TMP_TESTGRES_PORTS) - assert type(self._lock_dir) == str # noqa: E721 - os_ops.makedirs(self._lock_dir) + self._available_ports = set(range(1024, 65535)) + self._reserved_ports = set() + self._lock_dir = None def reserve_port(self) -> int: assert self._guard is not None assert type(self._available_ports) == set # noqa: E721t assert type(self._reserved_ports) == set # noqa: E721 + assert isinstance(self._os_ops, OsOperations) with self._guard: + if self._lock_dir is None: + temp_dir = self._os_ops.get_tempdir() + assert type(temp_dir) == str # noqa: E721 + lock_dir = os.path.join(temp_dir, consts.TMP_TESTGRES_PORTS) + assert type(lock_dir) == str # noqa: E721 + self._os_ops.makedirs(lock_dir) + self._lock_dir = lock_dir + + assert self._lock_dir is not None + assert type(self._lock_dir) == str # noqa: E721 + t = tuple(self._available_ports) assert len(t) == len(self._available_ports) sampled_ports = random.sample(t, min(len(t), 100)) @@ -53,7 +60,7 @@ def reserve_port(self) -> int: try: lock_path = self.helper__make_lock_path(port) - self._os_ops.makedir(lock_path) + self._os_ops.makedir(lock_path) # raise except: # noqa: 722 continue @@ -97,6 +104,7 @@ def release_port(self, number: int) -> None: def helper__make_lock_path(self, port_number: int) -> str: assert type(port_number) == int # noqa: E721 + # You have to call the reserve_port at first! assert type(self._lock_dir) == str # noqa: E721 result = os.path.join(self._lock_dir, str(port_number) + ".lock") From f085b70d52922b4f7ac3af9e064ae1296f725621 Mon Sep 17 00:00:00 2001 From: "d.kovalenko" Date: Wed, 7 May 2025 09:37:43 +0300 Subject: [PATCH 3/7] [#256] A used port range is [1024 ... 65535] PortManager__Generic is updated. --- testgres/impl/port_manager__generic.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/testgres/impl/port_manager__generic.py b/testgres/impl/port_manager__generic.py index cf60fa84..fdf9e7a5 100755 --- a/testgres/impl/port_manager__generic.py +++ b/testgres/impl/port_manager__generic.py @@ -24,7 +24,7 @@ def __init__(self, os_ops: OsOperations): assert isinstance(os_ops, OsOperations) self._os_ops = os_ops self._guard = threading.Lock() - self._available_ports = set(range(1024, 65535)) + self._available_ports = set(range(1024, 65536)) self._reserved_ports = set() self._lock_dir = None @@ -52,9 +52,13 @@ def reserve_port(self) -> int: t = None for port in sampled_ports: + assert type(port) == int # noqa: E721 assert not (port in self._reserved_ports) assert port in self._available_ports + assert port >= 0 + assert port <= 65535 + if not self._os_ops.is_port_free(port): continue @@ -82,6 +86,8 @@ def reserve_port(self) -> int: def release_port(self, number: int) -> None: assert type(number) == int # noqa: E721 + assert number >= 0 + assert number <= 65535 assert self._guard is not None assert type(self._reserved_ports) == set # noqa: E721 From c9b4bbf9a84b2f4f041e12afa8669f00287f9ec0 Mon Sep 17 00:00:00 2001 From: "d.kovalenko" Date: Wed, 7 May 2025 10:10:54 +0300 Subject: [PATCH 4/7] PortManager__Generic is refactored [consts, asserts] --- testgres/impl/port_manager__generic.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/testgres/impl/port_manager__generic.py b/testgres/impl/port_manager__generic.py index fdf9e7a5..3f312c13 100755 --- a/testgres/impl/port_manager__generic.py +++ b/testgres/impl/port_manager__generic.py @@ -11,6 +11,9 @@ class PortManager__Generic(PortManager): + C_MIN_PORT_NUMBER = 1024 + C_MAX_PORT_NUMBER = 65535 + _os_ops: OsOperations _guard: object # TODO: is there better to use bitmap fot _available_ports? @@ -20,11 +23,20 @@ class PortManager__Generic(PortManager): _lock_dir: str def __init__(self, os_ops: OsOperations): + assert __class__.C_MIN_PORT_NUMBER <= __class__.C_MAX_PORT_NUMBER + assert os_ops is not None assert isinstance(os_ops, OsOperations) self._os_ops = os_ops self._guard = threading.Lock() - self._available_ports = set(range(1024, 65536)) + + self._available_ports = set( + range(__class__.C_MIN_PORT_NUMBER, __class__.C_MAX_PORT_NUMBER + 1) + ) + assert len(self._available_ports) == ( + (__class__.C_MAX_PORT_NUMBER - __class__.C_MIN_PORT_NUMBER) + 1 + ) + self._reserved_ports = set() self._lock_dir = None @@ -56,8 +68,8 @@ def reserve_port(self) -> int: assert not (port in self._reserved_ports) assert port in self._available_ports - assert port >= 0 - assert port <= 65535 + assert port >= __class__.C_MIN_PORT_NUMBER + assert port <= __class__.C_MAX_PORT_NUMBER if not self._os_ops.is_port_free(port): continue @@ -86,8 +98,8 @@ def reserve_port(self) -> int: def release_port(self, number: int) -> None: assert type(number) == int # noqa: E721 - assert number >= 0 - assert number <= 65535 + assert number >= __class__.C_MIN_PORT_NUMBER + assert number <= __class__.C_MAX_PORT_NUMBER assert self._guard is not None assert type(self._reserved_ports) == set # noqa: E721 From d15ecdba09aecb65e117f0aad8b03238ed363684 Mon Sep 17 00:00:00 2001 From: "d.kovalenko" Date: Thu, 29 May 2025 17:22:24 +0300 Subject: [PATCH 5/7] PortManager__Generic sends debug messages about its operations. This idea was taken from PgBouncer tests. --- testgres/impl/port_manager__generic.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/testgres/impl/port_manager__generic.py b/testgres/impl/port_manager__generic.py index 3f312c13..cbf4aa12 100755 --- a/testgres/impl/port_manager__generic.py +++ b/testgres/impl/port_manager__generic.py @@ -8,6 +8,7 @@ import threading import random import typing +import logging class PortManager__Generic(PortManager): @@ -76,22 +77,29 @@ def reserve_port(self) -> int: try: lock_path = self.helper__make_lock_path(port) + __class__.helper__send_debug_msg("Attempting to create lock object {}.", lock_path) self._os_ops.makedir(lock_path) # raise except: # noqa: 722 + __class__.helper__send_debug_msg("Lock object {} is not created.", lock_path) continue assert self._os_ops.path_exists(lock_path) try: + __class__.helper__send_debug_msg("Lock object {} is created.", lock_path) self._reserved_ports.add(port) except: # noqa: 722 assert not (port in self._reserved_ports) self._os_ops.rmdir(lock_path) + __class__.helper__send_debug_msg("Lock object {} was deleted during processing of failure.", lock_path) raise assert port in self._reserved_ports self._available_ports.discard(port) assert not (port in self._available_ports) + + __class__.helper__send_debug_msg("Port {} is reserved.".format(port)) + return port raise PortForException("Can't select a port.") @@ -117,9 +125,22 @@ def release_port(self, number: int) -> None: assert isinstance(self._os_ops, OsOperations) assert self._os_ops.path_exists(lock_path) self._os_ops.rmdir(lock_path) + __class__.helper__send_debug_msg("Lock object {} was deleted.", lock_path) + __class__.helper__send_debug_msg("Port {} is released.", number) return + @staticmethod + def helper__send_debug_msg(msg_template: str, *args) -> None: + assert msg_template is not None + assert str is not None + assert type(msg_template) == str # noqa: E721 + assert type(args) == tuple # noqa: E721 + assert msg_template != "" + s = "[port manager] " + s += msg_template.format(*args) + logging.debug(s) + def helper__make_lock_path(self, port_number: int) -> str: assert type(port_number) == int # noqa: E721 # You have to call the reserve_port at first! From 8e0869d498d7dd894e25f64dc65f26b4e939b1da Mon Sep 17 00:00:00 2001 From: "d.kovalenko" Date: Sat, 31 May 2025 23:25:31 +0300 Subject: [PATCH 6/7] [attention] OsOperations::create_lock_fs_obj is added 1) PortManager__Generic uses OsOperations::create_lock_fs_obj to create a lock object 2) utils.bound_ports is removed - TestTestgresLocal.test_ports_management is deleted - TestOsOpsCommon.test_create_lock_fs_obj is added --- testgres/__init__.py | 7 +++--- testgres/impl/port_manager__generic.py | 33 +++++++++--------------- testgres/operations/local_ops.py | 22 ++++++++++++++++ testgres/operations/os_ops.py | 9 +++++++ testgres/operations/remote_ops.py | 32 +++++++++++++++++++++++ testgres/utils.py | 5 +--- tests/test_os_ops_common.py | 35 ++++++++++++++++++++++++++ tests/test_testgres_local.py | 35 -------------------------- 8 files changed, 115 insertions(+), 63 deletions(-) diff --git a/testgres/__init__.py b/testgres/__init__.py index 339ae62e..959aaa41 100644 --- a/testgres/__init__.py +++ b/testgres/__init__.py @@ -39,7 +39,6 @@ from .utils import \ reserve_port, \ release_port, \ - bound_ports, \ get_bin_path, \ get_pg_config, \ get_pg_version @@ -51,6 +50,7 @@ from .config import testgres_config from .operations.os_ops import OsOperations, ConnectionParams +from .operations.os_ops import OsLockObj from .operations.local_ops import LocalOperations from .operations.remote_ops import RemoteOperations @@ -64,7 +64,8 @@ "XLogMethod", "IsolationLevel", "NodeStatus", "ProcessType", "DumpFormat", "PostgresNode", "NodeApp", "PortManager", - "reserve_port", "release_port", "bound_ports", "get_bin_path", "get_pg_config", "get_pg_version", + "reserve_port", "release_port", "get_bin_path", "get_pg_config", "get_pg_version", "First", "Any", - "OsOperations", "LocalOperations", "RemoteOperations", "ConnectionParams" + "OsOperations", "LocalOperations", "RemoteOperations", "ConnectionParams", + "OsLockObj", ] diff --git a/testgres/impl/port_manager__generic.py b/testgres/impl/port_manager__generic.py index cbf4aa12..67949104 100755 --- a/testgres/impl/port_manager__generic.py +++ b/testgres/impl/port_manager__generic.py @@ -1,4 +1,5 @@ from ..operations.os_ops import OsOperations +from ..operations.os_ops import OsLockObj from ..port_manager import PortManager from ..exceptions import PortForException @@ -19,7 +20,7 @@ class PortManager__Generic(PortManager): _guard: object # TODO: is there better to use bitmap fot _available_ports? _available_ports: typing.Set[int] - _reserved_ports: typing.Set[int] + _reserved_ports: typing.Dict[int, OsLockObj] _lock_dir: str @@ -38,13 +39,13 @@ def __init__(self, os_ops: OsOperations): (__class__.C_MAX_PORT_NUMBER - __class__.C_MIN_PORT_NUMBER) + 1 ) - self._reserved_ports = set() + self._reserved_ports = dict() self._lock_dir = None def reserve_port(self) -> int: assert self._guard is not None assert type(self._available_ports) == set # noqa: E721t - assert type(self._reserved_ports) == set # noqa: E721 + assert type(self._reserved_ports) == dict # noqa: E721 assert isinstance(self._os_ops, OsOperations) with self._guard: @@ -77,29 +78,24 @@ def reserve_port(self) -> int: try: lock_path = self.helper__make_lock_path(port) - __class__.helper__send_debug_msg("Attempting to create lock object {}.", lock_path) - self._os_ops.makedir(lock_path) # raise + lock_obj = self._os_ops.create_lock_fs_obj(lock_path) # raise except: # noqa: 722 - __class__.helper__send_debug_msg("Lock object {} is not created.", lock_path) continue + assert isinstance(lock_obj, OsLockObj) assert self._os_ops.path_exists(lock_path) try: - __class__.helper__send_debug_msg("Lock object {} is created.", lock_path) - self._reserved_ports.add(port) + self._reserved_ports[port] = lock_obj except: # noqa: 722 assert not (port in self._reserved_ports) - self._os_ops.rmdir(lock_path) - __class__.helper__send_debug_msg("Lock object {} was deleted during processing of failure.", lock_path) + lock_obj.release() raise assert port in self._reserved_ports self._available_ports.discard(port) assert not (port in self._available_ports) - __class__.helper__send_debug_msg("Port {} is reserved.".format(port)) - return port raise PortForException("Can't select a port.") @@ -110,22 +106,17 @@ def release_port(self, number: int) -> None: assert number <= __class__.C_MAX_PORT_NUMBER assert self._guard is not None - assert type(self._reserved_ports) == set # noqa: E721 - - lock_path = self.helper__make_lock_path(number) + assert type(self._reserved_ports) == dict # noqa: E721 with self._guard: assert number in self._reserved_ports assert not (number in self._available_ports) self._available_ports.add(number) - self._reserved_ports.discard(number) + lock_obj = self._reserved_ports.pop(number) assert not (number in self._reserved_ports) assert number in self._available_ports - - assert isinstance(self._os_ops, OsOperations) - assert self._os_ops.path_exists(lock_path) - self._os_ops.rmdir(lock_path) - __class__.helper__send_debug_msg("Lock object {} was deleted.", lock_path) + assert isinstance(lock_obj, OsLockObj) + lock_obj.release() __class__.helper__send_debug_msg("Port {} is released.", number) return diff --git a/testgres/operations/local_ops.py b/testgres/operations/local_ops.py index ccf1ab82..67c75d01 100644 --- a/testgres/operations/local_ops.py +++ b/testgres/operations/local_ops.py @@ -15,6 +15,7 @@ from ..exceptions import ExecUtilException from ..exceptions import InvalidOperationException from .os_ops import ConnectionParams, OsOperations, get_default_encoding +from .os_ops import OsLockObj from .raise_error import RaiseError from .helpers import Helpers @@ -28,6 +29,23 @@ CMD_TIMEOUT_SEC = 60 +class LocalOsLockFsObj(OsLockObj): + m_path: str + + def __init__(self, path: str): + assert type(path) == str # noqa: str + self.m_path = path + os.mkdir(path) # throw + assert os.path.exists(path) + self.m_path = path + + def release(self) -> None: + assert type(self.m_path) == str # noqa: str + assert os.path.exists(self.m_path) + os.rmdir(self.m_path) + self.m_path = None + + class LocalOperations(OsOperations): sm_single_instance: OsOperations = None sm_single_instance_guard = threading.Lock() @@ -535,3 +553,7 @@ def get_tempdir(self) -> str: assert type(r) == str # noqa: E721 assert os.path.exists(r) return r + + def create_lock_fs_obj(self, path: str) -> OsLockObj: + assert type(path) == str # noqa: E721 + return LocalOsLockFsObj(path) diff --git a/testgres/operations/os_ops.py b/testgres/operations/os_ops.py index 45e4f71c..891c99b3 100644 --- a/testgres/operations/os_ops.py +++ b/testgres/operations/os_ops.py @@ -16,6 +16,11 @@ def get_default_encoding(): return locale.getencoding() or 'UTF-8' +class OsLockObj: + def release(self) -> None: + raise NotImplementedError() + + class OsOperations: def __init__(self, username=None): self.ssh_key = None @@ -133,3 +138,7 @@ def is_port_free(self, number: int): def get_tempdir(self) -> str: raise NotImplementedError() + + def create_lock_fs_obj(self, path: str) -> OsLockObj: + assert type(path) == str # noqa: E721 + raise NotImplementedError() diff --git a/testgres/operations/remote_ops.py b/testgres/operations/remote_ops.py index a478b453..2478ab08 100644 --- a/testgres/operations/remote_ops.py +++ b/testgres/operations/remote_ops.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import getpass import os import platform @@ -10,6 +12,7 @@ from ..exceptions import ExecUtilException from ..exceptions import InvalidOperationException from .os_ops import OsOperations, ConnectionParams, get_default_encoding +from .os_ops import OsLockObj from .raise_error import RaiseError from .helpers import Helpers @@ -40,6 +43,31 @@ def cmdline(self): return cmdline.split() +class RemoteOsLockFsObj(OsLockObj): + m_os_ops: RemoteOperations + m_path: str + + def __init__(self, os_ops: RemoteOperations, path: str): + assert isinstance(os_ops, RemoteOperations) + assert type(path) == str # noqa: str + + os_ops.makedir(path) # throw + assert os_ops.path_exists(path) + + self.m_os_ops = os_ops + self.m_path = path + + def release(self) -> None: + assert type(self.m_path) == str # noqa: str + assert isinstance(self.m_os_ops, RemoteOperations) + assert self.m_os_ops.path_exists(self.m_path) + + self.m_os_ops.rmdir(self.m_path) # throw + + self.m_path = None + self.m_os_ops = None + + class RemoteOperations(OsOperations): def __init__(self, conn_params: ConnectionParams): if not platform.system().lower() == "linux": @@ -687,6 +715,10 @@ def get_tempdir(self) -> str: assert type(temp_dir) == str # noqa: E721 return temp_dir + def create_lock_fs_obj(self, path: str) -> OsLockObj: + assert type(path) == str # noqa: E721 + return RemoteOsLockFsObj(self, path) + @staticmethod def _is_port_free__process_0(error: str) -> bool: assert type(error) == str # noqa: E721 diff --git a/testgres/utils.py b/testgres/utils.py index d231eec3..d8086655 100644 --- a/testgres/utils.py +++ b/testgres/utils.py @@ -30,9 +30,6 @@ # _old_port_manager = PortManager__Generic(LocalOperations.get_single_instance()) -# ports used by nodes -bound_ports = _old_port_manager._reserved_ports - # re-export version type class PgVer(Version): @@ -46,7 +43,7 @@ def __init__(self, version: str) -> None: def internal__reserve_port(): """ - Generate a new port and add it to 'bound_ports'. + Reserve a port. """ return _old_port_manager.reserve_port() diff --git a/tests/test_os_ops_common.py b/tests/test_os_ops_common.py index 5ae3a61f..c999f44e 100644 --- a/tests/test_os_ops_common.py +++ b/tests/test_os_ops_common.py @@ -17,6 +17,7 @@ from testgres import InvalidOperationException from testgres import ExecUtilException +from testgres.operations.os_ops import OsLockObj from concurrent.futures import ThreadPoolExecutor from concurrent.futures import Future as ThreadFuture @@ -1113,3 +1114,37 @@ class tadWorkerData: logging.info("Test is finished! Total error count is {}.".format(nErrors)) return + + def test_create_lock_fs_obj(self, os_ops: OsOperations): + assert isinstance(os_ops, OsOperations) + + tmp = os_ops.mkdtemp() + assert type(tmp) == str # noqa: E721 + assert os_ops.path_exists(tmp) + logging.info("tmp dir is [{}]".format(tmp)) + + p1 = os.path.join(tmp, "a.lock") + obj1 = os_ops.create_lock_fs_obj(p1) + assert obj1 is not None + assert isinstance(obj1, OsLockObj) + assert os_ops.path_exists(tmp) + assert os_ops.path_exists(p1) + + while True: + try: + os_ops.create_lock_fs_obj(p1) + except Exception as e: + logging.info("OK. We got the error ({}): {}".format(type(e).__name__, e)) + break + raise Exception("We wait the exception!") + + assert isinstance(obj1, OsLockObj) + assert os_ops.path_exists(tmp) + assert os_ops.path_exists(p1) + + obj1.release() + assert not os_ops.path_exists(p1) + + assert os_ops.path_exists(tmp) + os_ops.rmdir(tmp) + assert not os_ops.path_exists(tmp) diff --git a/tests/test_testgres_local.py b/tests/test_testgres_local.py index 63e5f37e..d8765f86 100644 --- a/tests/test_testgres_local.py +++ b/tests/test_testgres_local.py @@ -19,7 +19,6 @@ from testgres import get_pg_version # NOTE: those are ugly imports -from testgres.utils import bound_ports from testgres.utils import PgVer from testgres.node import ProcessProxy @@ -90,40 +89,6 @@ def test_pg_config(self): b = get_pg_config() assert (id(a) != id(b)) - def test_ports_management(self): - assert bound_ports is not None - assert type(bound_ports) == set # noqa: E721 - - if len(bound_ports) != 0: - logging.warning("bound_ports is not empty: {0}".format(bound_ports)) - - stage0__bound_ports = bound_ports.copy() - - with get_new_node() as node: - assert bound_ports is not None - assert type(bound_ports) == set # noqa: E721 - - assert node.port is not None - assert type(node.port) == int # noqa: E721 - - logging.info("node port is {0}".format(node.port)) - - assert node.port in bound_ports - assert node.port not in stage0__bound_ports - - assert stage0__bound_ports <= bound_ports - assert len(stage0__bound_ports) + 1 == len(bound_ports) - - stage1__bound_ports = stage0__bound_ports.copy() - stage1__bound_ports.add(node.port) - - assert stage1__bound_ports == bound_ports - - # check that port has been freed successfully - assert bound_ports is not None - assert type(bound_ports) == set # noqa: E721 - assert bound_ports == stage0__bound_ports - def test_child_process_dies(self): # test for FileNotFound exception during child_processes() function cmd = ["timeout", "60"] if os.name == 'nt' else ["sleep", "60"] From 82b46b3594237c991cbb5dd9a8c061f46afd64cb Mon Sep 17 00:00:00 2001 From: "d.kovalenko" Date: Sun, 1 Jun 2025 13:14:40 +0300 Subject: [PATCH 7/7] Code style is fixed --- testgres/operations/local_ops.py | 14 +++++++------- testgres/operations/remote_ops.py | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/testgres/operations/local_ops.py b/testgres/operations/local_ops.py index 67c75d01..e7945078 100644 --- a/testgres/operations/local_ops.py +++ b/testgres/operations/local_ops.py @@ -30,20 +30,20 @@ class LocalOsLockFsObj(OsLockObj): - m_path: str + _path: str def __init__(self, path: str): assert type(path) == str # noqa: str - self.m_path = path + self._path = path os.mkdir(path) # throw assert os.path.exists(path) - self.m_path = path + self._path = path def release(self) -> None: - assert type(self.m_path) == str # noqa: str - assert os.path.exists(self.m_path) - os.rmdir(self.m_path) - self.m_path = None + assert type(self._path) == str # noqa: str + assert os.path.exists(self._path) + os.rmdir(self._path) + self._path = None class LocalOperations(OsOperations): diff --git a/testgres/operations/remote_ops.py b/testgres/operations/remote_ops.py index 2478ab08..9ecfed51 100644 --- a/testgres/operations/remote_ops.py +++ b/testgres/operations/remote_ops.py @@ -44,8 +44,8 @@ def cmdline(self): class RemoteOsLockFsObj(OsLockObj): - m_os_ops: RemoteOperations - m_path: str + _os_ops: RemoteOperations + _path: str def __init__(self, os_ops: RemoteOperations, path: str): assert isinstance(os_ops, RemoteOperations) @@ -54,18 +54,18 @@ def __init__(self, os_ops: RemoteOperations, path: str): os_ops.makedir(path) # throw assert os_ops.path_exists(path) - self.m_os_ops = os_ops - self.m_path = path + self._os_ops = os_ops + self._path = path def release(self) -> None: - assert type(self.m_path) == str # noqa: str - assert isinstance(self.m_os_ops, RemoteOperations) - assert self.m_os_ops.path_exists(self.m_path) + assert type(self._path) == str # noqa: str + assert isinstance(self._os_ops, RemoteOperations) + assert self._os_ops.path_exists(self._path) - self.m_os_ops.rmdir(self.m_path) # throw + self._os_ops.rmdir(self._path) # throw - self.m_path = None - self.m_os_ops = None + self._path = None + self._os_ops = None class RemoteOperations(OsOperations):