testgres 1.15.2__tar.gz → 1.16.0__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.
- {testgres-1.15.2/testgres.egg-info → testgres-1.16.0}/PKG-INFO +2 -2
- {testgres-1.15.2 → testgres-1.16.0}/pyproject.toml +1 -1
- {testgres-1.15.2 → testgres-1.16.0}/src/__init__.py +8 -3
- {testgres-1.15.2 → testgres-1.16.0}/src/backup.py +9 -2
- {testgres-1.15.2 → testgres-1.16.0}/src/cache.py +14 -7
- {testgres-1.15.2 → testgres-1.16.0}/src/exceptions.py +2 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/impl/platforms/linux/internal_platform_utils.py +15 -18
- {testgres-1.15.2 → testgres-1.16.0}/src/node.py +118 -36
- {testgres-1.15.2 → testgres-1.16.0}/src/utils.py +92 -40
- {testgres-1.15.2 → testgres-1.16.0/testgres.egg-info}/PKG-INFO +2 -2
- {testgres-1.15.2 → testgres-1.16.0}/testgres.egg-info/requires.txt +1 -1
- {testgres-1.15.2 → testgres-1.16.0}/tests/test_os_ops_common.py +2697 -30
- {testgres-1.15.2 → testgres-1.16.0}/tests/test_os_ops_local.py +3 -3
- {testgres-1.15.2 → testgres-1.16.0}/tests/test_os_ops_remote.py +28 -5
- {testgres-1.15.2 → testgres-1.16.0}/tests/test_testgres_common.py +2 -2
- {testgres-1.15.2 → testgres-1.16.0}/tests/test_utils.py +3 -3
- {testgres-1.15.2 → testgres-1.16.0}/LICENSE +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/README.md +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/setup.cfg +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/api.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/config.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/connection.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/consts.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/decorators.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/defaults.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/enums.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/impl/file_line_reader.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/impl/internal_utils.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/impl/platforms/internal_platform_utils.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/impl/platforms/internal_platform_utils_factory.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/impl/platforms/win32/internal_platform_utils.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/impl/port_manager__generic.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/impl/port_manager__generic2.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/impl/port_manager__this_host.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/logger.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/node_app.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/port_manager.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/pubsub.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/raise_error.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/src/standby.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/testgres.egg-info/SOURCES.txt +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/testgres.egg-info/dependency_links.txt +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/testgres.egg-info/top_level.txt +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/tests/test_api.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/tests/test_config.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/tests/test_raise_error.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/tests/test_testgres_local.py +0 -0
- {testgres-1.15.2 → testgres-1.16.0}/tests/test_testgres_remote.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: testgres
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.16.0
|
|
4
4
|
Summary: Testing utility for PostgreSQL and its extensions
|
|
5
5
|
Author-email: Postgres Professional <testgres@postgrespro.ru>
|
|
6
6
|
License: PostgreSQL
|
|
@@ -27,7 +27,7 @@ Requires-Dist: port-for>=0.4
|
|
|
27
27
|
Requires-Dist: six>=1.9.0
|
|
28
28
|
Requires-Dist: psutil
|
|
29
29
|
Requires-Dist: packaging
|
|
30
|
-
Requires-Dist: testgres.os_ops<4.0.0,>=3.
|
|
30
|
+
Requires-Dist: testgres.os_ops<4.0.0,>=3.3.0
|
|
31
31
|
Dynamic: license-file
|
|
32
32
|
|
|
33
33
|
[](https://github.com/postgrespro/testgres/actions/workflows/ci.yml)
|
|
@@ -18,6 +18,7 @@ from .connection import \
|
|
|
18
18
|
from .exceptions import \
|
|
19
19
|
TestgresException, \
|
|
20
20
|
ExecUtilException, \
|
|
21
|
+
ExecTimeoutException, \
|
|
21
22
|
QueryException, \
|
|
22
23
|
QueryTimeoutException, \
|
|
23
24
|
TimeoutException, \
|
|
@@ -53,11 +54,13 @@ from .standby import \
|
|
|
53
54
|
|
|
54
55
|
from .config import testgres_config
|
|
55
56
|
|
|
56
|
-
from testgres.operations.os_ops import OsOperations
|
|
57
|
+
from testgres.operations.os_ops import OsOperations
|
|
58
|
+
from testgres.operations.os_ops import ConnectionParams
|
|
59
|
+
from testgres.operations.os_ops import OsProcessController
|
|
57
60
|
from testgres.operations.local_ops import LocalOperations
|
|
58
61
|
from testgres.operations.remote_ops import RemoteOperations
|
|
59
62
|
|
|
60
|
-
__version__ = "1.
|
|
63
|
+
__version__ = "1.16.0"
|
|
61
64
|
|
|
62
65
|
__all__ = [
|
|
63
66
|
"get_new_node",
|
|
@@ -66,6 +69,7 @@ __all__ = [
|
|
|
66
69
|
"TestgresConfig", "configure_testgres", "scoped_config", "push_config", "pop_config",
|
|
67
70
|
"NodeConnection", "DatabaseError", "InternalError", "ProgrammingError", "OperationalError",
|
|
68
71
|
"TestgresException", "ExecUtilException", "QueryException",
|
|
72
|
+
"ExecTimeoutException",
|
|
69
73
|
"QueryTimeoutException",
|
|
70
74
|
"TimeoutException", "CatchUpException", "StartNodeException", "InitNodeException", "BackupException", "InvalidOperationException",
|
|
71
75
|
"XLogMethod", "IsolationLevel", "NodeStatus", "ProcessType", "DumpFormat",
|
|
@@ -74,5 +78,6 @@ __all__ = [
|
|
|
74
78
|
"PortManager",
|
|
75
79
|
"reserve_port", "release_port", "get_bin_path", "get_bin_dir", "get_pg_config", "get_pg_version", "parse_pg_version",
|
|
76
80
|
"First", "Any",
|
|
77
|
-
"OsOperations", "LocalOperations", "RemoteOperations", "ConnectionParams"
|
|
81
|
+
"OsOperations", "LocalOperations", "RemoteOperations", "ConnectionParams",
|
|
82
|
+
"OsProcessController",
|
|
78
83
|
]
|
|
@@ -15,9 +15,10 @@ from .exceptions import BackupException
|
|
|
15
15
|
|
|
16
16
|
from testgres.operations.os_ops import OsOperations
|
|
17
17
|
|
|
18
|
+
from . import utils
|
|
19
|
+
|
|
18
20
|
from .utils import \
|
|
19
21
|
get_bin_path2, \
|
|
20
|
-
execute_utility2, \
|
|
21
22
|
clean_on_error
|
|
22
23
|
|
|
23
24
|
|
|
@@ -86,7 +87,13 @@ class NodeBackup(object):
|
|
|
86
87
|
"-X", xlog_method.value
|
|
87
88
|
] # yapf: disable
|
|
88
89
|
_params += options
|
|
89
|
-
|
|
90
|
+
|
|
91
|
+
utils.execute_utility3(
|
|
92
|
+
self.os_ops,
|
|
93
|
+
_params,
|
|
94
|
+
self.log_file,
|
|
95
|
+
)
|
|
96
|
+
return
|
|
90
97
|
|
|
91
98
|
def __enter__(self):
|
|
92
99
|
return self
|
|
@@ -8,14 +8,12 @@ from .consts import XLOG_CONTROL_FILE
|
|
|
8
8
|
|
|
9
9
|
from .defaults import generate_system_id
|
|
10
10
|
|
|
11
|
+
from . import utils
|
|
12
|
+
|
|
11
13
|
from .exceptions import \
|
|
12
14
|
InitNodeException, \
|
|
13
15
|
ExecUtilException
|
|
14
16
|
|
|
15
|
-
from .utils import \
|
|
16
|
-
get_bin_path2, \
|
|
17
|
-
execute_utility2
|
|
18
|
-
|
|
19
17
|
from testgres.operations.local_ops import LocalOperations
|
|
20
18
|
from testgres.operations.os_ops import OsOperations
|
|
21
19
|
|
|
@@ -39,13 +37,17 @@ def cached_initdb(data_dir, logfile=None, params=None, os_ops: OsOperations = No
|
|
|
39
37
|
if bin_path:
|
|
40
38
|
return os_ops.build_path(bin_path, name)
|
|
41
39
|
|
|
42
|
-
return get_bin_path2(os_ops, name)
|
|
40
|
+
return utils.get_bin_path2(os_ops, name)
|
|
43
41
|
|
|
44
42
|
def call_initdb(initdb_dir, log=logfile):
|
|
45
43
|
try:
|
|
46
44
|
initdb_path = make_utility_path("initdb")
|
|
47
45
|
_params = [initdb_path, "-D", initdb_dir, "-N"]
|
|
48
|
-
|
|
46
|
+
utils.execute_utility3(
|
|
47
|
+
os_ops,
|
|
48
|
+
_params + (params or []),
|
|
49
|
+
log,
|
|
50
|
+
)
|
|
49
51
|
except ExecUtilException as e:
|
|
50
52
|
raise_from(InitNodeException("Failed to run initdb"), e)
|
|
51
53
|
|
|
@@ -78,7 +80,12 @@ def cached_initdb(data_dir, logfile=None, params=None, os_ops: OsOperations = No
|
|
|
78
80
|
|
|
79
81
|
# XXX: build new WAL segment with our system id
|
|
80
82
|
_params = [make_utility_path("pg_resetwal"), "-D", data_dir, "-f"]
|
|
81
|
-
|
|
83
|
+
|
|
84
|
+
utils.execute_utility3(
|
|
85
|
+
os_ops,
|
|
86
|
+
_params,
|
|
87
|
+
logfile,
|
|
88
|
+
)
|
|
82
89
|
|
|
83
90
|
except ExecUtilException as e:
|
|
84
91
|
msg = "Failed to reset WAL for system id"
|
|
@@ -6,6 +6,7 @@ import typing
|
|
|
6
6
|
from testgres.operations.exceptions import TestgresException
|
|
7
7
|
from testgres.operations.exceptions import ExecUtilException
|
|
8
8
|
from testgres.operations.exceptions import InvalidOperationException
|
|
9
|
+
from testgres.operations.exceptions import ExecTimeoutException
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class PortForException(TestgresException):
|
|
@@ -298,3 +299,4 @@ class BackupException(TestgresException):
|
|
|
298
299
|
|
|
299
300
|
assert ExecUtilException.__name__ == "ExecUtilException"
|
|
300
301
|
assert InvalidOperationException.__name__ == "InvalidOperationException"
|
|
302
|
+
assert ExecTimeoutException.__name__ == "ExecTimeoutException"
|
|
@@ -5,7 +5,9 @@ from ... import internal_utils
|
|
|
5
5
|
from ....raise_error import RaiseError
|
|
6
6
|
|
|
7
7
|
from testgres.operations.os_ops import OsOperations
|
|
8
|
+
from testgres.operations.os_ops import OsCommandResult
|
|
8
9
|
from testgres.operations.exceptions import ExecUtilException
|
|
10
|
+
from testgres.operations.types import T_OS_EXEC_ENV
|
|
9
11
|
|
|
10
12
|
import re
|
|
11
13
|
import shlex
|
|
@@ -17,7 +19,7 @@ class InternalPlatformUtils(base.InternalPlatformUtils):
|
|
|
17
19
|
C_MAX_FIND_POSTMASTER_ATTEMPTS = 5
|
|
18
20
|
C_BASH_EXE = "/bin/bash"
|
|
19
21
|
|
|
20
|
-
sm_exec_env = {
|
|
22
|
+
sm_exec_env: T_OS_EXEC_ENV = {
|
|
21
23
|
"LANG": "en_US.UTF-8",
|
|
22
24
|
"LC_ALL": "en_US.UTF-8",
|
|
23
25
|
}
|
|
@@ -113,37 +115,32 @@ class InternalPlatformUtils(base.InternalPlatformUtils):
|
|
|
113
115
|
"ps -ewwo \"pid=,ppid=,args=\" | grep -E " + shlex.quote(regexp),
|
|
114
116
|
]
|
|
115
117
|
|
|
116
|
-
exec_r = os_ops.
|
|
118
|
+
exec_r = os_ops.run(
|
|
117
119
|
cmd=cmd,
|
|
118
|
-
|
|
119
|
-
verbose=True,
|
|
120
|
+
check=False,
|
|
120
121
|
exec_env=__class__.sm_exec_env,
|
|
121
122
|
)
|
|
122
123
|
|
|
123
|
-
assert type(exec_r) is
|
|
124
|
-
assert
|
|
124
|
+
assert type(exec_r) is OsCommandResult
|
|
125
|
+
assert type(exec_r.returncode) is int
|
|
126
|
+
assert type(exec_r.stdout) is bytes
|
|
127
|
+
assert type(exec_r.stderr) is bytes
|
|
125
128
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
assert type(exit_status) is int
|
|
129
|
-
assert type(output_b) is bytes
|
|
130
|
-
assert type(error_b) is bytes
|
|
131
|
-
|
|
132
|
-
if exit_status == 1:
|
|
129
|
+
if exec_r.returncode == 1:
|
|
133
130
|
return None
|
|
134
131
|
|
|
135
|
-
output =
|
|
136
|
-
error =
|
|
132
|
+
output = exec_r.stdout.decode("utf-8")
|
|
133
|
+
error = exec_r.stderr.decode("utf-8")
|
|
137
134
|
|
|
138
135
|
assert type(output) is str
|
|
139
136
|
assert type(error) is str
|
|
140
137
|
|
|
141
|
-
if
|
|
142
|
-
errMsg = f"test command returned an unexpected exit code: {
|
|
138
|
+
if exec_r.returncode != 0:
|
|
139
|
+
errMsg = f"test command returned an unexpected exit code: {exec_r.returncode}"
|
|
143
140
|
raise ExecUtilException(
|
|
144
141
|
message=errMsg,
|
|
145
142
|
command=cmd,
|
|
146
|
-
exit_code=
|
|
143
|
+
exit_code=exec_r.returncode,
|
|
147
144
|
out=output,
|
|
148
145
|
error=error,
|
|
149
146
|
)
|
|
@@ -92,7 +92,6 @@ from .utils import \
|
|
|
92
92
|
PgVer, \
|
|
93
93
|
eprint, \
|
|
94
94
|
get_pg_version2, \
|
|
95
|
-
execute_utility2, \
|
|
96
95
|
options_string, \
|
|
97
96
|
clean_on_error
|
|
98
97
|
|
|
@@ -101,6 +100,8 @@ from .raise_error import RaiseError
|
|
|
101
100
|
from .backup import NodeBackup
|
|
102
101
|
|
|
103
102
|
from testgres.operations.os_ops import OsOperations
|
|
103
|
+
from testgres.operations.os_ops import OsCommandResult
|
|
104
|
+
from testgres.operations.os_ops import OsProcessController
|
|
104
105
|
from testgres.operations.local_ops import LocalOperations
|
|
105
106
|
|
|
106
107
|
InternalError = pglib.InternalError
|
|
@@ -674,7 +675,11 @@ class PostgresNode(object):
|
|
|
674
675
|
|
|
675
676
|
ps_command = ['ps', '-o', 'pid=', '-p', str(node_pid)]
|
|
676
677
|
|
|
677
|
-
ps_output = self._os_ops.
|
|
678
|
+
ps_output = self._os_ops.run(
|
|
679
|
+
cmd=ps_command,
|
|
680
|
+
shell=True,
|
|
681
|
+
check=False,
|
|
682
|
+
).stdout.decode('utf-8')
|
|
678
683
|
assert type(ps_output) is str
|
|
679
684
|
|
|
680
685
|
if ps_output == "":
|
|
@@ -693,7 +698,11 @@ class PostgresNode(object):
|
|
|
693
698
|
pass
|
|
694
699
|
|
|
695
700
|
# Check that node stopped - print only column pid without headers
|
|
696
|
-
ps_output = self._os_ops.
|
|
701
|
+
ps_output = self._os_ops.run(
|
|
702
|
+
cmd=ps_command,
|
|
703
|
+
shell=True,
|
|
704
|
+
check=False,
|
|
705
|
+
).stdout.decode('utf-8')
|
|
697
706
|
assert type(ps_output) is str
|
|
698
707
|
|
|
699
708
|
if ps_output == "":
|
|
@@ -1093,11 +1102,16 @@ class PostgresNode(object):
|
|
|
1093
1102
|
_params += ["-D"] if self._pg_version >= PgVer('9.5') else []
|
|
1094
1103
|
_params += [self.data_dir]
|
|
1095
1104
|
|
|
1096
|
-
|
|
1105
|
+
exec_r = utils.execute_utility3(
|
|
1106
|
+
self._os_ops,
|
|
1107
|
+
_params,
|
|
1108
|
+
self.utils_log_file,
|
|
1109
|
+
)
|
|
1110
|
+
assert type(exec_r.stdout) is str
|
|
1097
1111
|
|
|
1098
1112
|
out_dict = {}
|
|
1099
1113
|
|
|
1100
|
-
for line in
|
|
1114
|
+
for line in exec_r.stdout.splitlines():
|
|
1101
1115
|
key, _, value = line.partition(':')
|
|
1102
1116
|
out_dict[key.strip()] = value.strip()
|
|
1103
1117
|
|
|
@@ -1248,10 +1262,17 @@ class PostgresNode(object):
|
|
|
1248
1262
|
|
|
1249
1263
|
def LOCAL__start_node():
|
|
1250
1264
|
# 'error' will be None on Windows
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1265
|
+
exec_r = utils.execute_utility3(
|
|
1266
|
+
self._os_ops,
|
|
1267
|
+
_params,
|
|
1268
|
+
self.utils_log_file,
|
|
1269
|
+
exec_env=exec_env,
|
|
1270
|
+
)
|
|
1271
|
+
# TODO: WTF? Remove it!
|
|
1272
|
+
assert exec_r.returncode == 0
|
|
1273
|
+
assert exec_r.stderr is None or type(exec_r.stderr) is str
|
|
1274
|
+
if exec_r.stderr is not None and 'does not exist' in exec_r.stderr:
|
|
1275
|
+
raise ExecUtilException(exec_r.stderr)
|
|
1255
1276
|
|
|
1256
1277
|
def LOCAL__raise_cannot_start_node__std(from_exception):
|
|
1257
1278
|
assert isinstance(from_exception, Exception)
|
|
@@ -1338,7 +1359,11 @@ class PostgresNode(object):
|
|
|
1338
1359
|
] + params # yapf: disable
|
|
1339
1360
|
|
|
1340
1361
|
try:
|
|
1341
|
-
|
|
1362
|
+
utils.execute_utility3(
|
|
1363
|
+
self._os_ops,
|
|
1364
|
+
_params,
|
|
1365
|
+
logfile=self.utils_log_file,
|
|
1366
|
+
)
|
|
1342
1367
|
self._manually_started_pm_pid = None
|
|
1343
1368
|
finally:
|
|
1344
1369
|
# always stop the reader thread, even if pg_ctl stop failed,
|
|
@@ -1399,9 +1424,16 @@ class PostgresNode(object):
|
|
|
1399
1424
|
] + params # yapf: disable
|
|
1400
1425
|
|
|
1401
1426
|
try:
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1427
|
+
exec_r = utils.execute_utility3(
|
|
1428
|
+
self._os_ops,
|
|
1429
|
+
_params,
|
|
1430
|
+
logfile=self.utils_log_file,
|
|
1431
|
+
)
|
|
1432
|
+
# TODO: WTF? Remove it!
|
|
1433
|
+
assert exec_r.returncode == 0
|
|
1434
|
+
assert exec_r.stderr is None or type(exec_r.stderr) is str
|
|
1435
|
+
if exec_r.stderr is not None and 'could not start server' in exec_r.stderr:
|
|
1436
|
+
raise ExecUtilException(exec_r.stderr)
|
|
1405
1437
|
except ExecUtilException as e:
|
|
1406
1438
|
msg = 'Cannot restart node'
|
|
1407
1439
|
files = self._collect_special_files()
|
|
@@ -1428,7 +1460,11 @@ class PostgresNode(object):
|
|
|
1428
1460
|
"reload"
|
|
1429
1461
|
] + params # yapf: disable
|
|
1430
1462
|
|
|
1431
|
-
|
|
1463
|
+
utils.execute_utility3(
|
|
1464
|
+
self._os_ops,
|
|
1465
|
+
_params,
|
|
1466
|
+
logfile=self.utils_log_file,
|
|
1467
|
+
)
|
|
1432
1468
|
|
|
1433
1469
|
return self
|
|
1434
1470
|
|
|
@@ -1450,7 +1486,11 @@ class PostgresNode(object):
|
|
|
1450
1486
|
"promote"
|
|
1451
1487
|
] # yapf: disable
|
|
1452
1488
|
|
|
1453
|
-
|
|
1489
|
+
utils.execute_utility3(
|
|
1490
|
+
self._os_ops,
|
|
1491
|
+
_params,
|
|
1492
|
+
self.utils_log_file,
|
|
1493
|
+
)
|
|
1454
1494
|
|
|
1455
1495
|
# for versions below 10 `promote` is asynchronous so we need to wait
|
|
1456
1496
|
# until it actually becomes writable
|
|
@@ -1485,7 +1525,11 @@ class PostgresNode(object):
|
|
|
1485
1525
|
"-w" # wait
|
|
1486
1526
|
] + params # yapf: disable
|
|
1487
1527
|
|
|
1488
|
-
return
|
|
1528
|
+
return utils.execute_utility3(
|
|
1529
|
+
self._os_ops,
|
|
1530
|
+
_params,
|
|
1531
|
+
self.utils_log_file,
|
|
1532
|
+
).stdout
|
|
1489
1533
|
|
|
1490
1534
|
def release_resources(self):
|
|
1491
1535
|
"""
|
|
@@ -1564,7 +1608,7 @@ class PostgresNode(object):
|
|
|
1564
1608
|
assert port is None or type(port) is int
|
|
1565
1609
|
assert type(variables) is dict
|
|
1566
1610
|
|
|
1567
|
-
|
|
1611
|
+
r = self._psql(
|
|
1568
1612
|
ignore_errors=True,
|
|
1569
1613
|
query=query,
|
|
1570
1614
|
filename=filename,
|
|
@@ -1575,6 +1619,8 @@ class PostgresNode(object):
|
|
|
1575
1619
|
port=port,
|
|
1576
1620
|
**variables
|
|
1577
1621
|
)
|
|
1622
|
+
assert type(r) is OsCommandResult
|
|
1623
|
+
return r.returncode, r.stdout, r.stderr
|
|
1578
1624
|
|
|
1579
1625
|
def _psql(
|
|
1580
1626
|
self,
|
|
@@ -1586,7 +1632,8 @@ class PostgresNode(object):
|
|
|
1586
1632
|
input=None,
|
|
1587
1633
|
host: typing.Optional[str] = None,
|
|
1588
1634
|
port: typing.Optional[int] = None,
|
|
1589
|
-
**variables
|
|
1635
|
+
**variables
|
|
1636
|
+
) -> OsCommandResult:
|
|
1590
1637
|
assert host is None or type(host) is str
|
|
1591
1638
|
assert port is None or type(port) is int
|
|
1592
1639
|
assert type(variables) is dict
|
|
@@ -1636,13 +1683,15 @@ class PostgresNode(object):
|
|
|
1636
1683
|
else:
|
|
1637
1684
|
raise QueryException('Query or filename must be provided')
|
|
1638
1685
|
|
|
1639
|
-
|
|
1686
|
+
r = self._os_ops.run(
|
|
1640
1687
|
psql_params,
|
|
1641
|
-
verbose=True,
|
|
1642
1688
|
input=input,
|
|
1643
1689
|
stderr=subprocess.PIPE,
|
|
1644
1690
|
stdout=subprocess.PIPE,
|
|
1645
|
-
|
|
1691
|
+
check=not ignore_errors,
|
|
1692
|
+
)
|
|
1693
|
+
assert type(r) is OsCommandResult
|
|
1694
|
+
return r
|
|
1646
1695
|
|
|
1647
1696
|
@method_decorator(positional_args_hack(['dbname', 'query']))
|
|
1648
1697
|
def safe_psql(self, query=None, expect_error=False, **kwargs):
|
|
@@ -1670,7 +1719,7 @@ class PostgresNode(object):
|
|
|
1670
1719
|
# force this setting
|
|
1671
1720
|
kwargs['ON_ERROR_STOP'] = 1
|
|
1672
1721
|
try:
|
|
1673
|
-
|
|
1722
|
+
exec_r = self._psql(ignore_errors=False, query=query, **kwargs)
|
|
1674
1723
|
except ExecUtilException as e:
|
|
1675
1724
|
if not expect_error:
|
|
1676
1725
|
raise QueryException(e.message, query)
|
|
@@ -1685,7 +1734,7 @@ class PostgresNode(object):
|
|
|
1685
1734
|
if expect_error:
|
|
1686
1735
|
raise InvalidOperationException("Exception was expected, but query finished successfully: `{}`.".format(query))
|
|
1687
1736
|
|
|
1688
|
-
return
|
|
1737
|
+
return exec_r.stdout
|
|
1689
1738
|
|
|
1690
1739
|
def dump(self,
|
|
1691
1740
|
filename=None,
|
|
@@ -1740,7 +1789,11 @@ class PostgresNode(object):
|
|
|
1740
1789
|
if options:
|
|
1741
1790
|
_params.extend(options)
|
|
1742
1791
|
|
|
1743
|
-
|
|
1792
|
+
utils.execute_utility3(
|
|
1793
|
+
self._os_ops,
|
|
1794
|
+
_params,
|
|
1795
|
+
self.utils_log_file,
|
|
1796
|
+
)
|
|
1744
1797
|
|
|
1745
1798
|
return filename
|
|
1746
1799
|
|
|
@@ -1769,7 +1822,11 @@ class PostgresNode(object):
|
|
|
1769
1822
|
|
|
1770
1823
|
# try pg_restore if dump is binary format, and psql if not
|
|
1771
1824
|
try:
|
|
1772
|
-
|
|
1825
|
+
utils.execute_utility3(
|
|
1826
|
+
self._os_ops,
|
|
1827
|
+
_params,
|
|
1828
|
+
self.utils_log_file,
|
|
1829
|
+
)
|
|
1773
1830
|
except ExecUtilException:
|
|
1774
1831
|
self.psql(filename=filename, dbname=dbname, username=username)
|
|
1775
1832
|
|
|
@@ -2010,12 +2067,14 @@ class PostgresNode(object):
|
|
|
2010
2067
|
dbname=dbname, username=username, **params)
|
|
2011
2068
|
# yapf: enable
|
|
2012
2069
|
|
|
2013
|
-
def pgbench(
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2070
|
+
def pgbench(
|
|
2071
|
+
self,
|
|
2072
|
+
dbname=None,
|
|
2073
|
+
username=None,
|
|
2074
|
+
stdout=None,
|
|
2075
|
+
stderr=None,
|
|
2076
|
+
options=None,
|
|
2077
|
+
) -> OsProcessController:
|
|
2019
2078
|
"""
|
|
2020
2079
|
Spawn a pgbench process.
|
|
2021
2080
|
|
|
@@ -2027,7 +2086,7 @@ class PostgresNode(object):
|
|
|
2027
2086
|
options: additional options for pgbench (list).
|
|
2028
2087
|
|
|
2029
2088
|
Returns:
|
|
2030
|
-
|
|
2089
|
+
OsProcessController.
|
|
2031
2090
|
"""
|
|
2032
2091
|
if options is None:
|
|
2033
2092
|
options = []
|
|
@@ -2044,10 +2103,14 @@ class PostgresNode(object):
|
|
|
2044
2103
|
# should be the last one
|
|
2045
2104
|
_params.append(dbname)
|
|
2046
2105
|
|
|
2047
|
-
proc = self._os_ops.
|
|
2106
|
+
proc = self._os_ops.popen(
|
|
2107
|
+
_params,
|
|
2108
|
+
stdout=stdout,
|
|
2109
|
+
stderr=stderr,
|
|
2110
|
+
)
|
|
2048
2111
|
|
|
2049
2112
|
# [2026-06-21] It is so
|
|
2050
|
-
assert isinstance(proc,
|
|
2113
|
+
assert isinstance(proc, OsProcessController)
|
|
2051
2114
|
return proc
|
|
2052
2115
|
|
|
2053
2116
|
def pgbench_with_wait(self,
|
|
@@ -2130,7 +2193,11 @@ class PostgresNode(object):
|
|
|
2130
2193
|
# should be the last one
|
|
2131
2194
|
_params.append(dbname)
|
|
2132
2195
|
|
|
2133
|
-
return
|
|
2196
|
+
return utils.execute_utility3(
|
|
2197
|
+
self._os_ops,
|
|
2198
|
+
_params,
|
|
2199
|
+
self.utils_log_file,
|
|
2200
|
+
).stdout
|
|
2134
2201
|
|
|
2135
2202
|
def connect(self,
|
|
2136
2203
|
dbname=None,
|
|
@@ -2303,7 +2370,22 @@ class PostgresNode(object):
|
|
|
2303
2370
|
]
|
|
2304
2371
|
upgrade_command += options
|
|
2305
2372
|
|
|
2306
|
-
|
|
2373
|
+
r: typing.Optional[typing.Any] = None
|
|
2374
|
+
try:
|
|
2375
|
+
r = self._os_ops.run(upgrade_command).stdout
|
|
2376
|
+
except BaseException as e:
|
|
2377
|
+
if not expect_error:
|
|
2378
|
+
raise
|
|
2379
|
+
|
|
2380
|
+
logging.info("Exception ({}): {}".format(
|
|
2381
|
+
type(e).__name__,
|
|
2382
|
+
e,
|
|
2383
|
+
))
|
|
2384
|
+
|
|
2385
|
+
if expect_error:
|
|
2386
|
+
raise RuntimeError("Operation executed without any errors.")
|
|
2387
|
+
|
|
2388
|
+
return r
|
|
2307
2389
|
|
|
2308
2390
|
def _release_resources(self):
|
|
2309
2391
|
self._free_port()
|