Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

PortManager#234

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Changes from1 commit
Commits
Show all changes
32 commits
Select commitHold shift + click to select a range
09dab31
PostgresNode refactoring [PostgresNodePortManager and RO-properties]
dmitry-lipetskApr 3, 2025
ef095d3
[FIX] clone_with_new_name_and_base_dir did not respect port_manager
dmitry-lipetskApr 4, 2025
0f842fd
PostgresNodePortManager__ThisHost is defined (was: PostgresNodePortMa…
dmitry-lipetskApr 4, 2025
e1e609e
PostgresNodePortManager__Generic is added
dmitry-lipetskApr 4, 2025
285e5b7
PostgresNodePortManager is added in public API
dmitry-lipetskApr 4, 2025
a974866
Test structures were refactored (local, local2, remote)
dmitry-lipetskApr 4, 2025
110947d
CI files are updated
dmitry-lipetskApr 4, 2025
4f49dde
TestTestgresCommon.test_pgbench is added
dmitry-lipetskApr 4, 2025
4fbf51d
PostgresNodePortManager is updated [error messages]
dmitry-lipetskApr 4, 2025
17c73cb
PostgresNodePortManager(+company) was moved in own file - port_manage…
dmitry-lipetskApr 4, 2025
b1cee19
PortManager was deleted [amen]
dmitry-lipetskApr 4, 2025
c5ad907
PostgresNodePortManager was renamed with PortManager
dmitry-lipetskApr 4, 2025
0967057
TestTestgresCommon.test_unix_sockets is added
dmitry-lipetskApr 4, 2025
1d450b2
TestTestgresCommon.test_the_same_port is added
dmitry-lipetskApr 4, 2025
4a38b35
[TestTestgresCommon] New tests are added
dmitry-lipetskApr 4, 2025
322fb23
RemoteOperations::is_port_free is updated
dmitry-lipetskApr 4, 2025
94da63e
Tests for OsOps::is_port_free are added
dmitry-lipetskApr 4, 2025
88f9b73
TestTestgresCommon is corrected [python problems]
dmitry-lipetskApr 4, 2025
d9558ce
The call of RaiseError.CommandExecutionError is fixed [message, not m…
dmitry-lipetskApr 4, 2025
0da4c21
[CI] ubuntu 24.04 does not have nc
dmitry-lipetskApr 4, 2025
0058508
RemoteOperations is update [private method names]
dmitry-lipetskApr 5, 2025
8f3a566
test_is_port_free__true is updated
dmitry-lipetskApr 5, 2025
d8ebdb7
RemoteOperations::is_port_free is updated (comments)
dmitry-lipetskApr 5, 2025
30e472c
setup.py is updated [testgres.helpers was deleted]
dmitry-lipetskApr 5, 2025
c94bbb5
Comment in node.py is updated
dmitry-lipetskApr 5, 2025
04f88c7
PostgresNode::_node was deleted [use self._os_ops.host]
dmitry-lipetskApr 5, 2025
0a3442a
PostgresNode::start is corrected [error message]
dmitry-lipetskApr 5, 2025
30124f3
Merge branch 'master' into D20250403_001--port_manager
dmitry-lipetskApr 5, 2025
13e71d8
[FIX] PostgresNode.__init__ must not test "os_ops.host" attribute.
dmitry-lipetskApr 5, 2025
9e14f4a
PostgresNode.free_port always set a port to None
dmitry-lipetskApr 6, 2025
739ef61
[FIX] flake8 (noqa: E721)
dmitry-lipetskApr 6, 2025
696cc1e
PortManager__Generic is refactored
dmitry-lipetskApr 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
NextNext commit
PostgresNode refactoring [PostgresNodePortManager and RO-properties]
PostgresNode uses PostgresNodePortManager to reserve/release port numberNew PostgresNode RO-properties are added: - name - host - port - ssh_key
  • Loading branch information
@dmitry-lipetsk
dmitry-lipetsk committedApr 3, 2025
commit09dab3139a3cdc88afc1f3a1e39c07a4aaeedbc4
163 changes: 141 additions & 22 deletionstestgres/node.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,6 +10,7 @@
from queue import Queue

import time
import typing

try:
from collections.abc import Iterable
Expand DownExpand Up@@ -131,12 +132,47 @@ def __repr__(self):
repr(self.process))


class PostgresNodePortManager:
def reserve_port(self) -> int:
raise NotImplementedError("PostManager::reserve_port is not implemented.")

def release_port(self, number: int) -> None:
assert type(number) == int # noqa: E721
raise NotImplementedError("PostManager::release_port is not implemented.")


class PostgresNodePortManager__Global(PostgresNodePortManager):
def __init__(self):
pass

def reserve_port(self) -> int:
return utils.reserve_port()

def release_port(self, number: int) -> None:
assert type(number) == int # noqa: E721
return utils.release_port(number)


class PostgresNode(object):
# a max number of node start attempts
_C_MAX_START_ATEMPTS = 5

def __init__(self, name=None, base_dir=None, port=None, conn_params: ConnectionParams = ConnectionParams(),
bin_dir=None, prefix=None, os_ops=None):
_name: typing.Optional[str]
_host: typing.Optional[str]
_port: typing.Optional[int]
_should_free_port: bool
_os_ops: OsOperations
_port_manager: PostgresNodePortManager

def __init__(self,
name=None,
base_dir=None,
port: typing.Optional[int] = None,
conn_params: ConnectionParams = ConnectionParams(),
bin_dir=None,
prefix=None,
os_ops: typing.Optional[OsOperations] = None,
port_manager: typing.Optional[PostgresNodePortManager] = None):
"""
PostgresNode constructor.

Expand All@@ -145,34 +181,57 @@ def __init__(self, name=None, base_dir=None, port=None, conn_params: ConnectionP
port: port to accept connections.
base_dir: path to node's data directory.
bin_dir: path to node's binary directory.
os_ops: None or correct OS operation object.
port_manager: None or correct port manager object.
"""
assert port is None or type(port) == int # noqa: E721
assert os_ops is None or isinstance(os_ops, OsOperations)
assert port_manager is None or isinstance(port_manager, PostgresNodePortManager)

# private
if os_ops is None:
os_ops = __class__._get_os_ops(conn_params)
self._os_ops = __class__._get_os_ops(conn_params)
else:
assert conn_params is None
assert isinstance(os_ops, OsOperations)
self._os_ops = os_ops
pass

assert os_ops is not None
assert isinstance(os_ops, OsOperations)
self._os_ops = os_ops
assert self._os_ops is not None
assert isinstance(self._os_ops, OsOperations)

self._pg_version = PgVer(get_pg_version2(os_ops, bin_dir))
self._should_free_port = port is None
self._pg_version = PgVer(get_pg_version2(self._os_ops, bin_dir))
self._base_dir = base_dir
self._bin_dir = bin_dir
self._prefix = prefix
self._logger = None
self._master = None

# basic
self.name = name or generate_app_name()
self._name = name or generate_app_name()
self._host = self._os_ops.host

self.host = os_ops.host
self.port = port or utils.reserve_port()
if port is not None:
assert type(port) == int # noqa: E721
assert port_manager is None
self._port = port
self._should_free_port = False
self._port_manager = None
else:
if port_manager is not None:
assert isinstance(port_manager, PostgresNodePortManager)
self._port_manager = port_manager
else:
self._port_manager = __class__._get_port_manager(self._os_ops)

assert self._port_manager is not None
assert isinstance(self._port_manager, PostgresNodePortManager)

self._port = self._port_manager.reserve_port() # raises
assert type(self._port) == int # noqa: E721
self._should_free_port = True

self.ssh_key = os_ops.ssh_key
assert type(self._port) == int # noqa: E721

# defaults for __exit__()
self.cleanup_on_good_exit = testgres_config.node_cleanup_on_good_exit
Expand DownExpand Up@@ -207,7 +266,11 @@ def __exit__(self, type, value, traceback):

def __repr__(self):
return "{}(name='{}', port={}, base_dir='{}')".format(
self.__class__.__name__, self.name, self.port, self.base_dir)
self.__class__.__name__,
self.name,
str(self._port) if self._port is not None else "None",
self.base_dir
)

@staticmethod
def _get_os_ops(conn_params: ConnectionParams) -> OsOperations:
Expand All@@ -221,12 +284,28 @@ def _get_os_ops(conn_params: ConnectionParams) -> OsOperations:

return LocalOperations(conn_params)

@staticmethod
def _get_port_manager(os_ops: OsOperations) -> PostgresNodePortManager:
assert os_ops is not None
assert isinstance(os_ops, OsOperations)

# [2025-04-03] It is our old, incorrected behaviour
return PostgresNodePortManager__Global()

def clone_with_new_name_and_base_dir(self, name: str, base_dir: str):
assert name is None or type(name) == str # noqa: E721
assert base_dir is None or type(base_dir) == str # noqa: E721

assert __class__ == PostgresNode

if self._port_manager is None:
raise InvalidOperationException("PostgresNode without PortManager can't be cloned.")

assert self._port_manager is not None
assert isinstance(self._port_manager, PostgresNodePortManager)
assert self._os_ops is not None
assert isinstance(self._os_ops, OsOperations)

node = PostgresNode(
name=name,
base_dir=base_dir,
Expand All@@ -243,6 +322,34 @@ def os_ops(self) -> OsOperations:
assert isinstance(self._os_ops, OsOperations)
return self._os_ops

@property
def name(self) -> str:
if self._name is None:
raise InvalidOperationException("PostgresNode name is not defined.")
assert type(self._name) == str # noqa: E721
return self._name

@property
def host(self) -> str:
if self._host is None:
raise InvalidOperationException("PostgresNode host is not defined.")
assert type(self._host) == str # noqa: E721
return self._host

@property
def port(self) -> int:
if self._port is None:
raise InvalidOperationException("PostgresNode port is not defined.")

assert type(self._port) == int # noqa: E721
return self._port

@property
def ssh_key(self) -> typing.Optional[str]:
assert self._os_ops is not None
assert isinstance(self._os_ops, OsOperations)
return self._os_ops.ssh_key

@property
def pid(self):
"""
Expand DownExpand Up@@ -993,6 +1100,11 @@ def start(self, params=[], wait=True):
if self.is_started:
return self

if self._port is None:
raise InvalidOperationException("Can't start PostgresNode. Port is node defined.")

assert type(self._port) == int # noqa: E721

_params = [self._get_bin_path("pg_ctl"),
"-D", self.data_dir,
"-l", self.pg_log_file,
Expand DownExpand Up@@ -1023,6 +1135,8 @@ def LOCAL__raise_cannot_start_node__std(from_exception):
LOCAL__raise_cannot_start_node__std(e)
else:
assert self._should_free_port
assert self._port_manager is not None
assert isinstance(self._port_manager, PostgresNodePortManager)
assert __class__._C_MAX_START_ATEMPTS > 1

log_files0 = self._collect_log_files()
Expand All@@ -1048,20 +1162,20 @@ def LOCAL__raise_cannot_start_node__std(from_exception):

log_files0 = log_files1
logging.warning(
"Detected a conflict with using the port {0}. Trying another port after a {1}-second sleep...".format(self.port, timeout)
"Detected a conflict with using the port {0}. Trying another port after a {1}-second sleep...".format(self._port, timeout)
)
time.sleep(timeout)
timeout = min(2 * timeout, 5)
cur_port = self.port
new_port =utils.reserve_port() # can raise
cur_port = self._port
new_port =self._port_manager.reserve_port() # can raise
try:
options = {'port': new_port}
self.set_auto_conf(options)
except: # noqa: E722
utils.release_port(new_port)
self._port_manager.release_port(new_port)
raise
self.port = new_port
utils.release_port(cur_port)
self._port = new_port
self._port_manager.release_port(cur_port)
continue
break
self._maybe_start_logger()
Expand DownExpand Up@@ -1226,10 +1340,15 @@ def free_port(self):
"""

if self._should_free_port:
port = self.port
assert type(self._port) == int # noqa: E721

assert self._port_manager is not None
assert isinstance(self._port_manager, PostgresNodePortManager)

port = self._port
self._should_free_port = False
self.port = None
utils.release_port(port)
self._port = None
self._port_manager.release_port(port)

def cleanup(self, max_attempts=3, full=False):
"""
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp