|
13 | 13 | from ..testgresimportNodeStatus
|
14 | 14 | from ..testgresimportIsolationLevel
|
15 | 15 |
|
| 16 | +importtestgres |
| 17 | + |
16 | 18 | # New name prevents to collect test-functions in TestgresException and fixes
|
17 | 19 | # the problem with pytest warning.
|
18 | 20 | from ..testgresimportTestgresExceptionastestgres_TestgresException
|
|
39 | 41 | importos
|
40 | 42 | importre
|
41 | 43 | importsubprocess
|
| 44 | +importtyping |
42 | 45 |
|
43 | 46 |
|
44 | 47 | @contextmanager
|
@@ -1169,17 +1172,177 @@ def test_the_same_port(self, node_svc: PostgresNodeService):
|
1169 | 1172 | r=node.safe_psql("SELECT 3;")
|
1170 | 1173 | assert (__class__.helper__rm_carriage_returns(r)==b'3\n')
|
1171 | 1174 |
|
| 1175 | +classtagPortManagerProxy(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 | +assertisinstance(prevPortManager,PortManager) |
| 1186 | +asserttype(dummyPortNumber)==int# noqa: E721 |
| 1187 | +asserttype(dummyPortMaxUsage)==int# noqa: E721 |
| 1188 | +assertdummyPortNumber>=0 |
| 1189 | +assertdummyPortMaxUsage>=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 |
| 1200 | + |
| 1201 | +def__enter__(self): |
| 1202 | +returnself |
| 1203 | + |
| 1204 | +def__exit__(self,type,value,traceback): |
| 1205 | +assertself.m_DummyPortCurrentUsage==0 |
| 1206 | + |
| 1207 | +assertself.m_PrevPortManagerisnotNone |
| 1208 | + |
| 1209 | +defreserve_port(self)->int: |
| 1210 | +asserttype(self.m_DummyPortMaxUsage)==int# noqa: E721 |
| 1211 | +asserttype(self.m_DummyPortTotalUsage)==int# noqa: E721 |
| 1212 | +asserttype(self.m_DummyPortCurrentUsage)==int# noqa: E721 |
| 1213 | +assertself.m_DummyPortTotalUsage>=0 |
| 1214 | +assertself.m_DummyPortCurrentUsage>=0 |
| 1215 | + |
| 1216 | +assertself.m_DummyPortTotalUsage<=self.m_DummyPortMaxUsage |
| 1217 | +assertself.m_DummyPortCurrentUsage<=self.m_DummyPortTotalUsage |
| 1218 | + |
| 1219 | +assertself.m_PrevPortManagerisnotNone |
| 1220 | +assertisinstance(self.m_PrevPortManager,PortManager) |
| 1221 | + |
| 1222 | +ifself.m_DummyPortTotalUsage==self.m_DummyPortMaxUsage: |
| 1223 | +returnself.m_PrevPortManager.reserve_port() |
| 1224 | + |
| 1225 | +self.m_DummyPortTotalUsage+=1 |
| 1226 | +self.m_DummyPortCurrentUsage+=1 |
| 1227 | +returnself.m_DummyPortNumber |
| 1228 | + |
| 1229 | +defrelease_port(self,dummyPortNumber:int): |
| 1230 | +asserttype(dummyPortNumber)==int# noqa: E721 |
| 1231 | + |
| 1232 | +asserttype(self.m_DummyPortMaxUsage)==int# noqa: E721 |
| 1233 | +asserttype(self.m_DummyPortTotalUsage)==int# noqa: E721 |
| 1234 | +asserttype(self.m_DummyPortCurrentUsage)==int# noqa: E721 |
| 1235 | +assertself.m_DummyPortTotalUsage>=0 |
| 1236 | +assertself.m_DummyPortCurrentUsage>=0 |
| 1237 | + |
| 1238 | +assertself.m_DummyPortTotalUsage<=self.m_DummyPortMaxUsage |
| 1239 | +assertself.m_DummyPortCurrentUsage<=self.m_DummyPortTotalUsage |
| 1240 | + |
| 1241 | +assertself.m_PrevPortManagerisnotNone |
| 1242 | +assertisinstance(self.m_PrevPortManager,PortManager) |
| 1243 | + |
| 1244 | +ifself.m_DummyPortCurrentUsage>0anddummyPortNumber==self.m_DummyPortNumber: |
| 1245 | +assertself.m_DummyPortTotalUsage>0 |
| 1246 | +self.m_DummyPortCurrentUsage-=1 |
| 1247 | +return |
| 1248 | + |
| 1249 | +returnself.m_PrevPortManager.release_port(dummyPortNumber) |
| 1250 | + |
| 1251 | +deftest_port_rereserve_during_node_start(self,node_svc:PostgresNodeService): |
| 1252 | +asserttype(node_svc)==PostgresNodeService# noqa: E721 |
| 1253 | +asserttestgres.PostgresNode._C_MAX_START_ATEMPTS==5 |
| 1254 | + |
| 1255 | +C_COUNT_OF_BAD_PORT_USAGE=3 |
| 1256 | + |
| 1257 | +with__class__.helper__get_node(node_svc)asnode1: |
| 1258 | +node1.init().start() |
| 1259 | +assertnode1._should_free_port |
| 1260 | +asserttype(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)asproxy: |
| 1265 | +assertproxy.m_DummyPortNumber==node1.port |
| 1266 | +with__class__.helper__get_node(node_svc,port_manager=proxy)asnode2: |
| 1267 | +assertnode2._should_free_port |
| 1268 | +assertnode2.port==node1.port |
| 1269 | + |
| 1270 | +node2.init().start() |
| 1271 | + |
| 1272 | +assertnode2.port!=node1.port |
| 1273 | +assertnode2._should_free_port |
| 1274 | +assertproxy.m_DummyPortCurrentUsage==0 |
| 1275 | +assertproxy.m_DummyPortTotalUsage==C_COUNT_OF_BAD_PORT_USAGE |
| 1276 | +assertnode2.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 | +assertnode1.port==node1_port_copy |
| 1282 | +assertnode1._should_free_port |
| 1283 | +r=node1.safe_psql("SELECT 3;") |
| 1284 | +assert__class__.helper__rm_carriage_returns(r)==b'3\n' |
| 1285 | + |
| 1286 | +deftest_port_conflict(self,node_svc:PostgresNodeService): |
| 1287 | +asserttype(node_svc)==PostgresNodeService# noqa: E721 |
| 1288 | +asserttestgres.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)asnode1: |
| 1293 | +node1.init().start() |
| 1294 | +assertnode1._should_free_port |
| 1295 | +asserttype(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)asproxy: |
| 1300 | +assertproxy.m_DummyPortNumber==node1.port |
| 1301 | +with__class__.helper__get_node(node_svc,port_manager=proxy)asnode2: |
| 1302 | +assertnode2._should_free_port |
| 1303 | +assertnode2.port==node1.port |
| 1304 | + |
| 1305 | +withpytest.raises( |
| 1306 | +expected_exception=StartNodeException, |
| 1307 | +match=re.escape("Cannot start node after multiple attempts.") |
| 1308 | + ): |
| 1309 | +node2.init().start() |
| 1310 | + |
| 1311 | +assertnode2.port==node1.port |
| 1312 | +assertnode2._should_free_port |
| 1313 | +assertproxy.m_DummyPortCurrentUsage==1 |
| 1314 | +assertproxy.m_DummyPortTotalUsage==C_COUNT_OF_BAD_PORT_USAGE |
| 1315 | +assertnotnode2.is_started |
| 1316 | + |
| 1317 | +# node2 must release our dummyPort (node1.port) |
| 1318 | +assert (proxy.m_DummyPortCurrentUsage==0) |
| 1319 | + |
| 1320 | +# node1 is still working |
| 1321 | +assertnode1.port==node1_port_copy |
| 1322 | +assertnode1._should_free_port |
| 1323 | +r=node1.safe_psql("SELECT 3;") |
| 1324 | +assert__class__.helper__rm_carriage_returns(r)==b'3\n' |
| 1325 | + |
1172 | 1326 | @staticmethod
|
1173 |
| -defhelper__get_node(node_svc:PostgresNodeService,name=None,port=None): |
| 1327 | +defhelper__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: |
1174 | 1333 | assertisinstance(node_svc,PostgresNodeService)
|
1175 | 1334 | assertisinstance(node_svc.os_ops,OsOperations)
|
1176 | 1335 | assertisinstance(node_svc.port_manager,PortManager)
|
| 1336 | + |
| 1337 | +ifport_managerisNone: |
| 1338 | +port_manager=node_svc.port_manager |
| 1339 | + |
1177 | 1340 | returnPostgresNode(
|
1178 | 1341 | name,
|
1179 | 1342 | port=port,
|
1180 | 1343 | conn_params=None,
|
1181 | 1344 | os_ops=node_svc.os_ops,
|
1182 |
| -port_manager=node_svc.port_managerifportisNoneelseNone |
| 1345 | +port_manager=port_managerifportisNoneelseNone |
1183 | 1346 | )
|
1184 | 1347 |
|
1185 | 1348 | @staticmethod
|
|