From a7662d1ad6af4e9476404ffe86d970a1286445b2 Mon Sep 17 00:00:00 2001 From: Dmitry Kovalenko Date: Mon, 23 Jun 2025 16:43:51 +0300 Subject: [PATCH 1/2] [#256] Port number 65535 is valid for using (#268) This patch corrects PortManager__Generic: - Valid port range is [1024, 65535]. Old range was [1024, 65535) - Strange (copy&paste) code for self._available_ports initialization is corrected - Strange (copy&paste) code for self._reserved_ports initialization is corrected - New asserts are added --- testgres/impl/port_manager__generic.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/testgres/impl/port_manager__generic.py b/testgres/impl/port_manager__generic.py index a51af2b..452b8df 100755 --- a/testgres/impl/port_manager__generic.py +++ b/testgres/impl/port_manager__generic.py @@ -9,6 +9,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? @@ -16,12 +19,21 @@ class PortManager__Generic(PortManager): _reserved_ports: typing.Set[int] 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: typing.Set[int] = set(range(1024, 65535)) - self._reserved_ports: typing.Set[int] = set() + + 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() + return def reserve_port(self) -> int: assert self._guard is not None @@ -35,9 +47,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 >= __class__._C_MIN_PORT_NUMBER + assert port <= __class__._C_MAX_PORT_NUMBER + if not self._os_ops.is_port_free(port): continue @@ -51,6 +67,8 @@ def reserve_port(self) -> int: def release_port(self, number: int) -> None: assert type(number) == int # noqa: E721 + 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 @@ -62,3 +80,4 @@ 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 + return From 2512835c05d363b15cb700bdb0cb4a26b48b922c Mon Sep 17 00:00:00 2001 From: Dmitry Kovalenko Date: Mon, 23 Jun 2025 16:44:11 +0300 Subject: [PATCH 2/2] [#264] New property PostrgsNode::port_manager (#269) This patch adds the RO-property PostgresNode::port_manager. This property returns a used port manager or None. Declaration of PostgresNode::_port_manager was corrected. New tests for PostgresNode::port_manager and PostgresNode::os_ops are added. --- testgres/node.py | 7 ++- tests/test_testgres_common.py | 82 +++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/testgres/node.py b/testgres/node.py index 9a2f4e7..a019faf 100644 --- a/testgres/node.py +++ b/testgres/node.py @@ -146,7 +146,7 @@ class PostgresNode(object): _port: typing.Optional[int] _should_free_port: bool _os_ops: OsOperations - _port_manager: PortManager + _port_manager: typing.Optional[PortManager] def __init__(self, name=None, @@ -313,6 +313,11 @@ def os_ops(self) -> OsOperations: assert isinstance(self._os_ops, OsOperations) return self._os_ops + @property + def port_manager(self) -> typing.Optional[PortManager]: + assert self._port_manager is None or isinstance(self._port_manager, PortManager) + return self._port_manager + @property def name(self) -> str: if self._name is None: diff --git a/tests/test_testgres_common.py b/tests/test_testgres_common.py index cf203a6..72873a0 100644 --- a/tests/test_testgres_common.py +++ b/tests/test_testgres_common.py @@ -1503,6 +1503,88 @@ def test_try_to_start_node_after_free_manual_port(self, node_svc: PostgresNodeSe ): node2.start() + def test_node__os_ops(self, node_svc: PostgresNodeService): + assert type(node_svc) == PostgresNodeService # noqa: E721 + + assert node_svc.os_ops is not None + assert isinstance(node_svc.os_ops, OsOperations) + + with PostgresNode(name="node", os_ops=node_svc.os_ops, port_manager=node_svc.port_manager) as node: + # retest + assert node_svc.os_ops is not None + assert isinstance(node_svc.os_ops, OsOperations) + + assert node.os_ops is node_svc.os_ops + # one more time + assert node.os_ops is node_svc.os_ops + + def test_node__port_manager(self, node_svc: PostgresNodeService): + assert type(node_svc) == PostgresNodeService # noqa: E721 + + assert node_svc.port_manager is not None + assert isinstance(node_svc.port_manager, PortManager) + + with PostgresNode(name="node", os_ops=node_svc.os_ops, port_manager=node_svc.port_manager) as node: + # retest + assert node_svc.port_manager is not None + assert isinstance(node_svc.port_manager, PortManager) + + assert node.port_manager is node_svc.port_manager + # one more time + assert node.port_manager is node_svc.port_manager + + def test_node__port_manager_and_explicit_port(self, node_svc: PostgresNodeService): + assert type(node_svc) == PostgresNodeService # noqa: E721 + + assert isinstance(node_svc.os_ops, OsOperations) + assert node_svc.port_manager is not None + assert isinstance(node_svc.port_manager, PortManager) + + port = node_svc.port_manager.reserve_port() + assert type(port) == int # noqa: E721 + + try: + with PostgresNode(name="node", port=port, os_ops=node_svc.os_ops) as node: + # retest + assert isinstance(node_svc.os_ops, OsOperations) + assert node_svc.port_manager is not None + assert isinstance(node_svc.port_manager, PortManager) + + assert node.port_manager is None + assert node.os_ops is node_svc.os_ops + + # one more time + assert node.port_manager is None + assert node.os_ops is node_svc.os_ops + finally: + node_svc.port_manager.release_port(port) + + def test_node__no_port_manager(self, node_svc: PostgresNodeService): + assert type(node_svc) == PostgresNodeService # noqa: E721 + + assert isinstance(node_svc.os_ops, OsOperations) + assert node_svc.port_manager is not None + assert isinstance(node_svc.port_manager, PortManager) + + port = node_svc.port_manager.reserve_port() + assert type(port) == int # noqa: E721 + + try: + with PostgresNode(name="node", port=port, os_ops=node_svc.os_ops, port_manager=None) as node: + # retest + assert isinstance(node_svc.os_ops, OsOperations) + assert node_svc.port_manager is not None + assert isinstance(node_svc.port_manager, PortManager) + + assert node.port_manager is None + assert node.os_ops is node_svc.os_ops + + # one more time + assert node.port_manager is None + assert node.os_ops is node_svc.os_ops + finally: + node_svc.port_manager.release_port(port) + @staticmethod def helper__get_node( node_svc: PostgresNodeService, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy