testgres 1.12.1__tar.gz → 1.12.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. {testgres-1.12.1/testgres.egg-info → testgres-1.12.2}/PKG-INFO +2 -2
  2. {testgres-1.12.1 → testgres-1.12.2}/setup.py +2 -2
  3. {testgres-1.12.1 → testgres-1.12.2}/src/node.py +7 -5
  4. {testgres-1.12.1 → testgres-1.12.2/testgres.egg-info}/PKG-INFO +2 -2
  5. {testgres-1.12.1 → testgres-1.12.2}/testgres.egg-info/requires.txt +1 -1
  6. {testgres-1.12.1 → testgres-1.12.2}/tests/test_os_ops_common.py +199 -0
  7. {testgres-1.12.1 → testgres-1.12.2}/LICENSE +0 -0
  8. {testgres-1.12.1 → testgres-1.12.2}/MANIFEST.in +0 -0
  9. {testgres-1.12.1 → testgres-1.12.2}/README.md +0 -0
  10. {testgres-1.12.1 → testgres-1.12.2}/setup.cfg +0 -0
  11. {testgres-1.12.1 → testgres-1.12.2}/src/__init__.py +0 -0
  12. {testgres-1.12.1 → testgres-1.12.2}/src/api.py +0 -0
  13. {testgres-1.12.1 → testgres-1.12.2}/src/backup.py +0 -0
  14. {testgres-1.12.1 → testgres-1.12.2}/src/cache.py +0 -0
  15. {testgres-1.12.1 → testgres-1.12.2}/src/config.py +0 -0
  16. {testgres-1.12.1 → testgres-1.12.2}/src/connection.py +0 -0
  17. {testgres-1.12.1 → testgres-1.12.2}/src/consts.py +0 -0
  18. {testgres-1.12.1 → testgres-1.12.2}/src/decorators.py +0 -0
  19. {testgres-1.12.1 → testgres-1.12.2}/src/defaults.py +0 -0
  20. {testgres-1.12.1 → testgres-1.12.2}/src/enums.py +0 -0
  21. {testgres-1.12.1 → testgres-1.12.2}/src/exceptions.py +0 -0
  22. {testgres-1.12.1 → testgres-1.12.2}/src/impl/port_manager__generic.py +0 -0
  23. {testgres-1.12.1 → testgres-1.12.2}/src/impl/port_manager__this_host.py +0 -0
  24. {testgres-1.12.1 → testgres-1.12.2}/src/logger.py +0 -0
  25. {testgres-1.12.1 → testgres-1.12.2}/src/node_app.py +0 -0
  26. {testgres-1.12.1 → testgres-1.12.2}/src/port_manager.py +0 -0
  27. {testgres-1.12.1 → testgres-1.12.2}/src/pubsub.py +0 -0
  28. {testgres-1.12.1 → testgres-1.12.2}/src/standby.py +0 -0
  29. {testgres-1.12.1 → testgres-1.12.2}/src/utils.py +0 -0
  30. {testgres-1.12.1 → testgres-1.12.2}/testgres.egg-info/SOURCES.txt +0 -0
  31. {testgres-1.12.1 → testgres-1.12.2}/testgres.egg-info/dependency_links.txt +0 -0
  32. {testgres-1.12.1 → testgres-1.12.2}/testgres.egg-info/top_level.txt +0 -0
  33. {testgres-1.12.1 → testgres-1.12.2}/tests/__init__.py +0 -0
  34. {testgres-1.12.1 → testgres-1.12.2}/tests/conftest.py +0 -0
  35. {testgres-1.12.1 → testgres-1.12.2}/tests/helpers/__init__.py +0 -0
  36. {testgres-1.12.1 → testgres-1.12.2}/tests/helpers/global_data.py +0 -0
  37. {testgres-1.12.1 → testgres-1.12.2}/tests/helpers/run_conditions.py +0 -0
  38. {testgres-1.12.1 → testgres-1.12.2}/tests/test_config.py +0 -0
  39. {testgres-1.12.1 → testgres-1.12.2}/tests/test_os_ops_local.py +0 -0
  40. {testgres-1.12.1 → testgres-1.12.2}/tests/test_os_ops_remote.py +0 -0
  41. {testgres-1.12.1 → testgres-1.12.2}/tests/test_testgres_common.py +0 -0
  42. {testgres-1.12.1 → testgres-1.12.2}/tests/test_testgres_local.py +0 -0
  43. {testgres-1.12.1 → testgres-1.12.2}/tests/test_testgres_remote.py +0 -0
  44. {testgres-1.12.1 → testgres-1.12.2}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: testgres
3
- Version: 1.12.1
3
+ Version: 1.12.2
4
4
  Summary: Testing utility for PostgreSQL and its extensions
5
5
  Home-page: https://github.com/postgrespro/testgres
6
6
  Author: Postgres Professional
@@ -14,7 +14,7 @@ Requires-Dist: port-for>=0.4
14
14
  Requires-Dist: six>=1.9.0
15
15
  Requires-Dist: psutil
16
16
  Requires-Dist: packaging
17
- Requires-Dist: testgres.os_ops<1.0.0,>=0.0.2
17
+ Requires-Dist: testgres.os_ops<2.0.0,>=1.0.0
18
18
  Dynamic: author
19
19
  Dynamic: author-email
20
20
  Dynamic: description
@@ -12,7 +12,7 @@ install_requires = [
12
12
  "six>=1.9.0",
13
13
  "psutil",
14
14
  "packaging",
15
- "testgres.os_ops>=0.0.2,<1.0.0"
15
+ "testgres.os_ops>=1.0.0,<2.0.0"
16
16
  ]
17
17
 
18
18
  # Add compatibility enum class
@@ -28,7 +28,7 @@ with open('README.md', 'r') as f:
28
28
  readme = f.read()
29
29
 
30
30
  setup(
31
- version='1.12.1',
31
+ version='1.12.2',
32
32
  name='testgres',
33
33
  packages=['testgres', 'testgres.impl'],
34
34
  package_dir={"testgres": "src"},
@@ -1206,11 +1206,12 @@ class PostgresNode(object):
1206
1206
  If None, the main PostgreSQL node process will be killed. Defaults to None.
1207
1207
  """
1208
1208
  if self.is_started:
1209
+ assert isinstance(self._os_ops, OsOperations)
1209
1210
  sig = signal.SIGKILL if os.name != 'nt' else signal.SIGBREAK
1210
1211
  if someone is None:
1211
- os.kill(self.pid, sig)
1212
+ self._os_ops.kill(self.pid, sig)
1212
1213
  else:
1213
- os.kill(self.auxiliary_pids[someone][0], sig)
1214
+ self._os_ops.kill(self.auxiliary_pids[someone][0], sig)
1214
1215
  self.is_started = False
1215
1216
 
1216
1217
  def restart(self, params=[]):
@@ -2119,10 +2120,11 @@ class PostgresNode(object):
2119
2120
  Args:
2120
2121
  old_node: An instance of PostgresNode representing the old node.
2121
2122
  """
2122
- if not os.path.exists(old_node.data_dir):
2123
+ assert isinstance(self._os_ops, OsOperations)
2124
+ if not self._os_ops.path_exists(old_node.data_dir):
2123
2125
  raise Exception("Old node must be initialized")
2124
2126
 
2125
- if not os.path.exists(self.data_dir):
2127
+ if not self._os_ops.path_exists(self.data_dir):
2126
2128
  self.init()
2127
2129
 
2128
2130
  if not options:
@@ -2130,7 +2132,7 @@ class PostgresNode(object):
2130
2132
 
2131
2133
  pg_upgrade_binary = self._get_bin_path("pg_upgrade")
2132
2134
 
2133
- if not os.path.exists(pg_upgrade_binary):
2135
+ if not self._os_ops.path_exists(pg_upgrade_binary):
2134
2136
  raise Exception("pg_upgrade does not exist in the new node's binary path")
2135
2137
 
2136
2138
  upgrade_command = [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: testgres
3
- Version: 1.12.1
3
+ Version: 1.12.2
4
4
  Summary: Testing utility for PostgreSQL and its extensions
5
5
  Home-page: https://github.com/postgrespro/testgres
6
6
  Author: Postgres Professional
@@ -14,7 +14,7 @@ Requires-Dist: port-for>=0.4
14
14
  Requires-Dist: six>=1.9.0
15
15
  Requires-Dist: psutil
16
16
  Requires-Dist: packaging
17
- Requires-Dist: testgres.os_ops<1.0.0,>=0.0.2
17
+ Requires-Dist: testgres.os_ops<2.0.0,>=1.0.0
18
18
  Dynamic: author
19
19
  Dynamic: author-email
20
20
  Dynamic: description
@@ -3,4 +3,4 @@ port-for>=0.4
3
3
  six>=1.9.0
4
4
  psutil
5
5
  packaging
6
- testgres.os_ops<1.0.0,>=0.0.2
6
+ testgres.os_ops<2.0.0,>=1.0.0
@@ -5,6 +5,7 @@ from .helpers.global_data import OsOperations
5
5
  from .helpers.run_conditions import RunConditions
6
6
 
7
7
  import os
8
+ import sys
8
9
 
9
10
  import pytest
10
11
  import re
@@ -14,6 +15,10 @@ import socket
14
15
  import threading
15
16
  import typing
16
17
  import uuid
18
+ import subprocess
19
+ import psutil
20
+ import time
21
+ import signal as os_signal
17
22
 
18
23
  from src import InvalidOperationException
19
24
  from src import ExecUtilException
@@ -1137,3 +1142,197 @@ class TestOsOpsCommon:
1137
1142
 
1138
1143
  logging.info("Test is finished! Total error count is {}.".format(nErrors))
1139
1144
  return
1145
+
1146
+ T_KILL_SIGNAL_DESCR = typing.Tuple[
1147
+ str,
1148
+ typing.Union[int, os_signal.Signals],
1149
+ str
1150
+ ]
1151
+
1152
+ sm_kill_signal_ids: typing.List[T_KILL_SIGNAL_DESCR] = [
1153
+ ("SIGINT", os_signal.SIGINT, "2"),
1154
+ # ("SIGQUIT", os_signal.SIGQUIT, "3"), # it creates coredump
1155
+ ("SIGKILL", os_signal.SIGKILL, "9"),
1156
+ ("SIGTERM", os_signal.SIGTERM, "15"),
1157
+ ("2", 2, "2"),
1158
+ # ("3", 3, "3"), # it creates coredump
1159
+ ("9", 9, "9"),
1160
+ ("15", 15, "15"),
1161
+ ]
1162
+
1163
+ @pytest.fixture(
1164
+ params=sm_kill_signal_ids,
1165
+ ids=["signal: {}".format(x[0]) for x in sm_kill_signal_ids],
1166
+ )
1167
+ def kill_signal_id(self, request: pytest.FixtureRequest) -> T_KILL_SIGNAL_DESCR:
1168
+ assert isinstance(request, pytest.FixtureRequest)
1169
+ assert type(request.param) == tuple # noqa: E721
1170
+ return request.param
1171
+
1172
+ def test_kill_signal(
1173
+ self,
1174
+ kill_signal_id: T_KILL_SIGNAL_DESCR,
1175
+ ):
1176
+ assert type(kill_signal_id) == tuple # noqa: E721
1177
+ assert "{}".format(kill_signal_id[1]) == kill_signal_id[2]
1178
+ assert "{}".format(int(kill_signal_id[1])) == kill_signal_id[2]
1179
+
1180
+ def test_kill(
1181
+ self,
1182
+ os_ops: OsOperations,
1183
+ kill_signal_id: T_KILL_SIGNAL_DESCR,
1184
+ ):
1185
+ """
1186
+ Test listdir for listing directory contents.
1187
+ """
1188
+ assert isinstance(os_ops, OsOperations)
1189
+ assert type(kill_signal_id) == tuple # noqa: E721
1190
+
1191
+ cmd = [
1192
+ sys.executable,
1193
+ "-c",
1194
+ "import time; print('ENTER');time.sleep(300);print('EXIT')"
1195
+ ]
1196
+
1197
+ logging.info("Local test process is creating ...")
1198
+ proc = subprocess.Popen(
1199
+ cmd,
1200
+ text=True,
1201
+ )
1202
+
1203
+ assert proc is not None
1204
+ assert type(proc) == subprocess.Popen # noqa: E721
1205
+ proc_pid = proc.pid
1206
+ assert type(proc_pid) == int # noqa: E721
1207
+ logging.info("Test process pid is {}".format(proc_pid))
1208
+
1209
+ logging.info("Get this test process ...")
1210
+ p1 = psutil.Process(proc_pid)
1211
+ assert p1 is not None
1212
+ del p1
1213
+
1214
+ logging.info("Kill this test process ...")
1215
+ os_ops.kill(proc_pid, kill_signal_id[1])
1216
+
1217
+ logging.info("Wait for finish ...")
1218
+ proc.wait()
1219
+
1220
+ logging.info("Try to get this test process ...")
1221
+
1222
+ attempt = 0
1223
+ while True:
1224
+ if attempt == 20:
1225
+ raise RuntimeError("Process did not die.")
1226
+
1227
+ attempt += 1
1228
+
1229
+ if attempt > 1:
1230
+ logging.info("Sleep 1 seconds...")
1231
+ time.sleep(1)
1232
+
1233
+ try:
1234
+ psutil.Process(proc_pid)
1235
+ except psutil.ZombieProcess as e:
1236
+ logging.info("Exception {}: {}".format(
1237
+ type(e).__name__,
1238
+ str(e),
1239
+ ))
1240
+ except psutil.NoSuchProcess:
1241
+ logging.info("OK. Process died.")
1242
+ break
1243
+
1244
+ logging.info("Process is alive!")
1245
+ continue
1246
+
1247
+ return
1248
+
1249
+ def test_kill__unk_pid(
1250
+ self,
1251
+ os_ops: OsOperations,
1252
+ kill_signal_id: T_KILL_SIGNAL_DESCR,
1253
+ ):
1254
+ """
1255
+ Test listdir for listing directory contents.
1256
+ """
1257
+ assert isinstance(os_ops, OsOperations)
1258
+ assert type(kill_signal_id) == tuple # noqa: E721
1259
+
1260
+ cmd = [
1261
+ sys.executable,
1262
+ "-c",
1263
+ "import sys; print(\"a\", file=sys.stdout); print(\"b\", file=sys.stderr)"
1264
+ ]
1265
+
1266
+ logging.info("Local test process is creating ...")
1267
+ proc = subprocess.Popen(
1268
+ cmd,
1269
+ text=True,
1270
+ stdout=subprocess.PIPE,
1271
+ stderr=subprocess.PIPE,
1272
+ )
1273
+
1274
+ assert proc is not None
1275
+ assert type(proc) == subprocess.Popen # noqa: E721
1276
+ proc_pid = proc.pid
1277
+ assert type(proc_pid) == int # noqa: E721
1278
+ logging.info("Test process pid is {}".format(proc_pid))
1279
+
1280
+ logging.info("Wait for finish ...")
1281
+ pout, perr = proc.communicate()
1282
+ logging.info("STDOUT: {}".format(pout))
1283
+ logging.info("STDERR: {}".format(pout))
1284
+ assert type(pout) == str # noqa: E721
1285
+ assert type(perr) == str # noqa: E721
1286
+ assert pout == "a\n"
1287
+ assert perr == "b\n"
1288
+ assert type(proc.returncode) == int # noqa: E721
1289
+ assert proc.returncode == 0
1290
+
1291
+ logging.info("Try to get this test process ...")
1292
+
1293
+ attempt = 0
1294
+ while True:
1295
+ if attempt == 20:
1296
+ raise RuntimeError("Process did not die.")
1297
+
1298
+ attempt += 1
1299
+
1300
+ if attempt > 1:
1301
+ logging.info("Sleep 1 seconds...")
1302
+ time.sleep(1)
1303
+
1304
+ try:
1305
+ psutil.Process(proc_pid)
1306
+ except psutil.ZombieProcess as e:
1307
+ logging.info("Exception {}: {}".format(
1308
+ type(e).__name__,
1309
+ str(e),
1310
+ ))
1311
+ except psutil.NoSuchProcess:
1312
+ logging.info("OK. Process died.")
1313
+ break
1314
+
1315
+ logging.info("Process is alive!")
1316
+ continue
1317
+
1318
+ # --------------------
1319
+ with pytest.raises(expected_exception=Exception) as x:
1320
+ os_ops.kill(proc_pid, kill_signal_id[1])
1321
+
1322
+ assert x is not None
1323
+ assert isinstance(x.value, Exception)
1324
+ assert not isinstance(x.value, AssertionError)
1325
+
1326
+ logging.info("Our error is [{}]".format(str(x.value)))
1327
+ logging.info("Our exception has type [{}]".format(type(x.value).__name__))
1328
+
1329
+ if type(os_ops).__name__ == "LocalOsOperations":
1330
+ assert type(x.value) == ProcessLookupError # noqa: E721
1331
+ assert "No such process" in str(x.value)
1332
+ elif type(os_ops).__name__ == "RemoteOsOperations":
1333
+ assert type(x.value) == ExecUtilException # noqa: E721
1334
+ assert "No such process" in str(x.value)
1335
+ else:
1336
+ RuntimeError("Unknown os_ops type: {}".format(type(os_ops).__name__))
1337
+
1338
+ return
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes