8000 [TestTestgresCommon] New tests are added · postgrespro/testgres@4a38b35 · GitHub
[go: up one dir, main page]

Skip to content 8000

Commit 4a38b35

Browse files
[TestTestgresCommon] New tests are added
- test_port_rereserve_during_node_start - test_port_conflict
1 parent 1d450b2 commit 4a38b35

File tree

1 file changed

+165
-2
lines changed

1 file changed

+165
-2
lines changed

tests/test_testgres_common.py

Lines changed: 165 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
from ..testgres import NodeStatus
1414
from ..testgres import IsolationLevel
1515

16+
import testgres
17+
1618
# New name prevents to collect test-functions in TestgresException and fixes
1719
# the problem with pytest warning.
1820
from ..testgres import TestgresException as testgres_TestgresException
@@ -39,6 +41,7 @@
3941
import os
4042
import re
4143
import subprocess
44+
import typing
4245

4346

4447
@contextmanager
@@ -1169,17 +1172,177 @@ def test_the_same_port(self, node_svc: PostgresNodeService):
11691172
r = node.safe_psql("SELECT 3;")
11701173
assert (__class__.helper__rm_carriage_returns(r) == b'3\n')
11711174

1175+
class tagPortManagerProxy(PortManager):
1176+
m_PrevPortManager: PortManager
1177+
1178+
m_DummyPortNumber: int
1179+
m_DummyPortMaxUsage: int
1180+
1181+
m_DummyPortCurrentUsage: int
1182+
m_DummyPortTotalUsage: int
1183+
1184+
def __init__(self, prevPortManager: PortManager, dummyPortNumber: int, dummyPortMaxUsage: int):
1185+
assert isinstance(prevPortManager, PortManager)
1186+
assert type(dummyPortNumber) == int # noqa: E721
1187+
assert type(dummyPortMaxUsage) == int # noqa: E721
1188+
assert dummyPortNumber >= 0
1189+
assert dummyPortMaxUsage >= 0
1190+
1191+
super().__init__()
1192+
1193+
self.m_PrevPortManager = prevPortManager
1194+
1195+
self.m_DummyPortNumber = dummyPortNumber
1196+
self.m_DummyPortMaxUsage = dummyPortMaxUsage
1197+
1198+
self.m_DummyPortCurrentUsage = 0
1199+
self.m_DummyPortTotalUsage = 0
8000 1200+
1201+
def __enter__(self):
1202+
return self
1203+
1204+
def __exit__(self, type, value, traceback):
1205+
assert self.m_DummyPortCurrentUsage == 0
1206+
1207+
assert self.m_PrevPortManager is not None
1208+
1209+
def reserve_port(self) -> int:
1210+
assert type(self.m_DummyPortMaxUsage) == int # noqa: E721
1211+
assert type(self.m_DummyPortTotalUsage) == int # noqa: E721
1212+
assert type(self.m_DummyPortCurrentUsage) == int # noqa: E721
1213+
assert self.m_DummyPortTotalUsage >= 0
1214+
assert self.m_DummyPortCurrentUsage >= 0
1215+
1216+
assert self.m_DummyPortTotalUsage <= self.m_DummyPortMaxUsage
1217+
assert self.m_DummyPortCurrentUsage <= self.m_DummyPortTotalUsage
1218+
1219+
assert self.m_PrevPortManager is not None
1220+
assert isinstance(self.m_PrevPortManager, PortManager)
1221+
1222+
if self.m_DummyPortTotalUsage == self.m_DummyPortMaxUsage:
1223+
return self.m_PrevPortManager.reserve_port()
1224+
1225+
self.m_DummyPortTotalUsage += 1
1226+
self.m_DummyPortCurrentUsage += 1
1227+
return self.m_DummyPortNumber
1228+
1229+
def release_port(self, dummyPortNumber: int):
1230+
assert type(dummyPortNumber) == int # noqa: E721
1231+
1232+
assert type(self.m_DummyPortMaxUsage) == int # noqa: E721
1233+
assert type(self.m_DummyPortTotalUsage) == int # noqa: E721
1234+
assert type(self.m_DummyPortCurrentUsage) == int # noqa: E721
1235+
assert self.m_DummyPortTotalUsage >= 0
1236+
assert self.m_DummyPortCurrentUsage >= 0
1237+
1238+
assert self.m_DummyPortTotalUsage <= self.m_DummyPortMaxUsage
1239+
assert self.m_DummyPortCurrentUsage <= self.m_DummyPortTotalUsage
1240+
1241+
assert self.m_PrevPortManager is not None
1242+
assert isinstance(self.m_PrevPortManager, PortManager)
1243+
1244+
if self.m_DummyPortCurrentUsage > 0 and dummyPortNumber == self.m_DummyPortNumber:
1245+
assert self.m_DummyPortTotalUsage > 0
1246+
self.m_DummyPortCurrentUsage -= 1
1247+
return
1248+
1249+
return self.m_PrevPortManager.release_port(dummyPortNumber)
1250+
1251+
def test_port_rereserve_during_node_start(self, node_svc: PostgresNodeService):
1252+
assert type(node_svc) == PostgresNodeService # noqa: E721
1253+
assert testgres.PostgresNode._C_MAX_START_ATEMPTS == 5
1254+
1255+
C_COUNT_OF_BAD_PORT_USAGE = 3
1256+
1257+
with __class__.helper__get_node(node_svc) as node1:
1258+
node1.init().start()
1259+
assert node1._should_free_port
1260+
assert type(node1.port) == int # noqa: E721
1261+
node1_port_copy = node1.port
1262+
assert __class__.helper__rm_carriage_returns(node1.safe_psql("SELECT 1;")) == b'1\n'
1263+
1264+
with __class__.tagPortManagerProxy(node_svc.port_manager, node1.port, C_COUNT_OF_BAD_PORT_USAGE) as proxy:
1265+
assert proxy.m_DummyPortNumber == node1.port
1266+
with __class__.helper__get_node(node_svc, port_manager=proxy) as node2:
1267+
assert node2._should_free_port
1268+
assert node2.port == node1.port
1269+
1270+
node2.init().start()
1271+
1272+
assert node2.port != node1.port
1273+
assert node2._should_free_port
1274+
assert proxy.m_DummyPortCurrentUsage == 0
1275+
assert proxy.m_DummyPortTotalUsage == C_COUNT_OF_BAD_PORT_USAGE
1276+
assert node2.is_started
1277+
r = node2.safe_psql("SELECT 2;")
1278+
assert __class__.helper__rm_carriage_returns(r) == b'2\n'
1279+
1280+
# node1 is still working
1281+
assert node1.port == node1_port_copy
1282+
assert node1._should_free_port
1283+
r = node1.safe_psql("SELECT 3;")
1284+
assert __class__.helper__rm_carriage_returns(r) == b'3\n'
1285+
1286+
def test_port_conflict(self, node_svc: PostgresNodeService):
1287+
assert type(node_svc) == PostgresNodeService # noqa: E721
1288+
assert testgres.PostgresNode._C_MAX_START_ATEMPTS > 1
1289+
1290+
C_COUNT_OF_BAD_PORT_USAGE = testgres.PostgresNode._C_MAX_START_ATEMPTS
1291+
1292+
with __class__.helper__get_node(node_svc) as node1:
1293+
node1.init().start()
1294+
assert node1._should_free_port
1295+
assert type(node1.port) == int # noqa: E721
1296+
node1_port_copy = node1.port
1297+
assert __class__.helper__rm_carriage_returns(node1.safe_psql("SELECT 1;")) == b'1\n'
1298+
1299+
with __class__.tagPortManagerProxy(node_svc.port_manager, node1.port, C_COUNT_OF_BAD_PORT_USAGE) as proxy:
1300+
assert proxy.m_DummyPortNumber == node1.port
1301+
with __class__.helper__get_node(node_svc, port_manager=proxy) as node2:
1302+
assert node2._should_free_port
1303+
assert node2.port == node1.port
1304+
1305+
with pytest.raises(
1306+
expected_exception=StartNodeException,
1307+
match=re.escape("Cannot start node after multiple attempts.")
1308+
):
1309+
node2.init().start()
1310+
1311+
assert node2.port == node1.port
1312+
assert node2._should_free_port
1313+
assert proxy.m_DummyPortCurrentUsage == 1
1314+
assert proxy.m_DummyPortTotalUsage == C_COUNT_OF_BAD_PORT_USAGE
1315+
assert not node2.is_started
1316+
1317+
# node2 must release our dummyPort (node1.port)
1318+
assert (proxy.m_DummyPortCurrentUsage == 0)
1319+
1320+
# node1 is still working
1321+
assert node1.port == node1_port_copy
1322+
assert node1._should_free_port
1323+
r = node1.safe_psql("SELECT 3;")
1324+
assert __class__.helper__rm_carriage_returns(r) == b'3\n'
1325+
11721326
@staticmethod
1173-
def helper__get_node(node_svc: PostgresNodeService, name=None, port=None):
1327+
def helper__get_node(
1328+
node_svc: PostgresNodeService,
1329+
name: typing.Optional[str] = None,
1330+
port: typing.Optional[int] = None,
1331+
port_manager: typing.Optional[PortManager] = None
1332+
) -> PostgresNode:
11741333
assert isinstance(node_svc, PostgresNodeService)
11751334
assert isinstance(node_svc.os_ops, OsOperations)
11761335
assert isinstance(node_svc.port_manager, PortManager)
1336+
1337+
if port_manager is None:
1338+
port_manager = node_svc.port_manager
1339+
11771340
return PostgresNode(
11781341
name,
11791342
port=port,
11801343
conn_params=None,
11811344
os_ops=node_svc.os_ops,
1182-
port_manager=node_svc.port_manager if port is None else None
1345+
port_manager=port_manager if port is None else None
11831346
)
11841347

11851348
@staticmethod

0 commit comments

Comments
 (0)
0