testgres-pg-probackup2 0.9.1__tar.gz → 0.10.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_pg_probackup2-0.10.0/PKG-INFO +89 -0
- {testgres_pg_probackup2-0.9.1 → testgres_pg_probackup2-0.10.0}/README.md +4 -4
- testgres_pg_probackup2-0.10.0/pyproject.toml +65 -0
- testgres_pg_probackup2-0.10.0/src/__init__.py +1 -0
- {testgres_pg_probackup2-0.9.1/pg_probackup2 → testgres_pg_probackup2-0.10.0/src}/app.py +28 -26
- {testgres_pg_probackup2-0.9.1/pg_probackup2 → testgres_pg_probackup2-0.10.0/src}/gdb.py +33 -6
- {testgres_pg_probackup2-0.9.1/pg_probackup2 → testgres_pg_probackup2-0.10.0/src}/init_helpers.py +1 -1
- testgres_pg_probackup2-0.10.0/testgres_pg_probackup2.egg-info/PKG-INFO +89 -0
- testgres_pg_probackup2-0.10.0/testgres_pg_probackup2.egg-info/SOURCES.txt +16 -0
- testgres_pg_probackup2-0.10.0/testgres_pg_probackup2.egg-info/requires.txt +4 -0
- testgres_pg_probackup2-0.10.0/tests/test_basic.py +142 -0
- testgres_pg_probackup2-0.10.0/tests/test_common.py +17 -0
- testgres_pg_probackup2-0.10.0/tests/test_gdb.py +29 -0
- testgres_pg_probackup2-0.9.1/PKG-INFO +0 -22
- testgres_pg_probackup2-0.9.1/pg_probackup2/storage/__init__.py +0 -0
- testgres_pg_probackup2-0.9.1/setup.py +0 -23
- testgres_pg_probackup2-0.9.1/testgres_pg_probackup2.egg-info/PKG-INFO +0 -22
- testgres_pg_probackup2-0.9.1/testgres_pg_probackup2.egg-info/SOURCES.txt +0 -13
- testgres_pg_probackup2-0.9.1/testgres_pg_probackup2.egg-info/requires.txt +0 -4
- {testgres_pg_probackup2-0.9.1 → testgres_pg_probackup2-0.10.0}/setup.cfg +0 -0
- {testgres_pg_probackup2-0.9.1/pg_probackup2 → testgres_pg_probackup2-0.10.0/src/storage}/__init__.py +0 -0
- {testgres_pg_probackup2-0.9.1/pg_probackup2 → testgres_pg_probackup2-0.10.0/src}/storage/fs_backup.py +0 -0
- {testgres_pg_probackup2-0.9.1 → testgres_pg_probackup2-0.10.0}/testgres_pg_probackup2.egg-info/dependency_links.txt +0 -0
- {testgres_pg_probackup2-0.9.1 → testgres_pg_probackup2-0.10.0}/testgres_pg_probackup2.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: testgres_pg_probackup2
|
|
3
|
+
Version: 0.10.0
|
|
4
|
+
Summary: Plugin for testgres that manages pg_probackup2
|
|
5
|
+
Author-email: Postgres Professional <testgres@postgrespro.ru>
|
|
6
|
+
License: PostgreSQL
|
|
7
|
+
Project-URL: HomePage, https://github.com/postgrespro/testgres-pg_probackup2
|
|
8
|
+
Keywords: pg_probackup,testing,testgres
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Operating System :: Unix
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Classifier: Topic :: Software Development :: Testing
|
|
22
|
+
Requires-Python: >=3.7.3
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
Requires-Dist: lz4
|
|
25
|
+
Requires-Dist: pefile
|
|
26
|
+
Requires-Dist: testgres<1.18,>=1.14.4
|
|
27
|
+
Requires-Dist: zstd
|
|
28
|
+
|
|
29
|
+
[](https://badge.fury.io/py/testgres-pg_probackup2)
|
|
30
|
+
|
|
31
|
+
# testgres-pg_probackup2
|
|
32
|
+
|
|
33
|
+
Control and testing utility for [pg_probackup2](https://github.com/postgrespro/pg_probackup). Python 3.7+ is supported.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
To install `testgres-pg_probackup`, run:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
pip install testgres-pg_probackup
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
We encourage you to use `virtualenv` for your testing environment.
|
|
45
|
+
The package requires testgres.
|
|
46
|
+
|
|
47
|
+
## Usage
|
|
48
|
+
|
|
49
|
+
### Environment variables
|
|
50
|
+
|
|
51
|
+
| Variable | Required | Default value | Description |
|
|
52
|
+
| - | - | - | - |
|
|
53
|
+
| PGPROBACKUP_TMP_DIR | No | tests/tmp_dirs | The root of the temporary directory hierarchy where tests store data and logs. Relative paths start from the current working directory. |
|
|
54
|
+
| PG_PROBACKUP_TEST_BACKUP_DIR_PREFIX | No | Temporary test hierarchy | Prefix of the test backup directories. Must be an absolute path. Use this variable to store test backups in a location other than the temporary test hierarchy. |
|
|
55
|
+
| PG_PROBACKUP_VALGRIND | No | Not set | Run pg_probackup through valgrind if the variable is set to 'y'. Setting PG_PROBACKUP_VALGRIND_SUP (see below) to any value enables valgrind just like setting `PG_PROBACKUP_VALGRIND=y` would do. |
|
|
56
|
+
| PG_PROBACKUP_VALGRIND_SUP | No | Not set | Specify the path to a valgrind suppression file. If the variable is not set then a file named "valgrind.supp" is searched for in the current working directory (normally the root of pg_probackup repository). Setting PG_PROBACKUP_VALGRIND_SUP to any value enables valgrind just like setting `PG_PROBACKUP_VALGRIND=y` (see above) would do. |
|
|
57
|
+
|
|
58
|
+
See [Testgres](https://github.com/postgrespro/testgres/tree/master#environment) on how to configure a custom Postgres installation using `PG_CONFIG` and `PG_BIN` environment variables.
|
|
59
|
+
|
|
60
|
+
### Examples
|
|
61
|
+
|
|
62
|
+
Here is an example of what you can do with `testgres-pg_probackup2`:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
# You can see full script here plugins/pg_probackup2/pg_probackup2/tests/basic_test.py
|
|
66
|
+
def test_full_backup(self):
|
|
67
|
+
# Setting up a simple test node
|
|
68
|
+
node = self.pg_node.make_simple('node', pg_options={"fsync": "off", "synchronous_commit": "off"})
|
|
69
|
+
|
|
70
|
+
# Initialize and configure Probackup
|
|
71
|
+
self.pb.init()
|
|
72
|
+
self.pb.add_instance('node', node)
|
|
73
|
+
self.pb.set_archiving('node', node)
|
|
74
|
+
|
|
75
|
+
# Start the node and initialize pgbench
|
|
76
|
+
node.slow_start()
|
|
77
|
+
node.pgbench_init(scale=100, no_vacuum=True)
|
|
78
|
+
|
|
79
|
+
# Perform backup and validation
|
|
80
|
+
backup_id = self.pb.backup_node('node', node)
|
|
81
|
+
out = self.pb.validate('node', backup_id)
|
|
82
|
+
|
|
83
|
+
# Check if the backup is valid
|
|
84
|
+
self.assertIn(f"INFO: Backup {backup_id} is valid", out)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Authors
|
|
88
|
+
|
|
89
|
+
[Postgres Professional](https://postgrespro.ru/about)
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
[](https://badge.fury.io/py/testgres-pg_probackup2)
|
|
2
2
|
|
|
3
|
-
# testgres
|
|
3
|
+
# testgres-pg_probackup2
|
|
4
4
|
|
|
5
|
-
Control and testing utility for [pg_probackup2](https://github.com/postgrespro/pg_probackup). Python 3.
|
|
5
|
+
Control and testing utility for [pg_probackup2](https://github.com/postgrespro/pg_probackup). Python 3.7+ is supported.
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
## Installation
|
|
9
9
|
|
|
10
|
-
To install `testgres`, run:
|
|
10
|
+
To install `testgres-pg_probackup`, run:
|
|
11
11
|
|
|
12
12
|
```
|
|
13
13
|
pip install testgres-pg_probackup
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
We encourage you to use `virtualenv` for your testing environment.
|
|
17
|
-
The package requires testgres
|
|
17
|
+
The package requires testgres.
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[tool.setuptools.package-dir]
|
|
6
|
+
"pg_probackup2" = "src"
|
|
7
|
+
|
|
8
|
+
[tool.setuptools.dynamic]
|
|
9
|
+
version = {attr = "pg_probackup2.__version__"}
|
|
10
|
+
|
|
11
|
+
[tool.flake8]
|
|
12
|
+
extend-ignore = ["E501"]
|
|
13
|
+
exclude = [".git", "__pycache__", "env", "venv"]
|
|
14
|
+
|
|
15
|
+
[tool.pytest.ini_options]
|
|
16
|
+
testpaths = ["tests"]
|
|
17
|
+
log_file_level = "NOTSET"
|
|
18
|
+
log_file_format = "%(levelname)8s [%(asctime)s] %(message)s"
|
|
19
|
+
log_file_date_format = "%Y-%m-%d %H:%M:%S"
|
|
20
|
+
|
|
21
|
+
[project]
|
|
22
|
+
name = "testgres_pg_probackup2"
|
|
23
|
+
dynamic = ["version"]
|
|
24
|
+
description = "Plugin for testgres that manages pg_probackup2"
|
|
25
|
+
readme = "README.md"
|
|
26
|
+
requires-python = ">=3.7.3"
|
|
27
|
+
|
|
28
|
+
# Формат для совместимости с Python 3.7
|
|
29
|
+
license = {text = "PostgreSQL"}
|
|
30
|
+
|
|
31
|
+
authors = [
|
|
32
|
+
{name = "Postgres Professional", email = "testgres@postgrespro.ru"},
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
keywords = [
|
|
36
|
+
"pg_probackup",
|
|
37
|
+
"testing",
|
|
38
|
+
"testgres",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
classifiers = [
|
|
42
|
+
"Intended Audience :: Developers",
|
|
43
|
+
"Operating System :: Unix",
|
|
44
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
45
|
+
"Programming Language :: Python :: 3.7",
|
|
46
|
+
"Programming Language :: Python :: 3.8",
|
|
47
|
+
"Programming Language :: Python :: 3.9",
|
|
48
|
+
"Programming Language :: Python :: 3.10",
|
|
49
|
+
"Programming Language :: Python :: 3.11",
|
|
50
|
+
"Programming Language :: Python :: 3.12",
|
|
51
|
+
"Programming Language :: Python :: 3.13",
|
|
52
|
+
"Programming Language :: Python :: 3.14",
|
|
53
|
+
"Topic :: Software Development :: Libraries",
|
|
54
|
+
"Topic :: Software Development :: Testing",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
dependencies = [
|
|
58
|
+
"lz4",
|
|
59
|
+
"pefile",
|
|
60
|
+
"testgres>=1.14.4,<1.18",
|
|
61
|
+
"zstd",
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
[project.urls]
|
|
65
|
+
"HomePage" = "https://github.com/postgrespro/testgres-pg_probackup2"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.10.0"
|
|
@@ -126,7 +126,7 @@ class ProbackupApp:
|
|
|
126
126
|
if self.verbose:
|
|
127
127
|
print(self.test_class.cmd)
|
|
128
128
|
|
|
129
|
-
cmdline = self._form_cmdline(binary_path, command)
|
|
129
|
+
cmdline = self._form_cmdline(binary_path, command, use_valgrind=gdb is False)
|
|
130
130
|
|
|
131
131
|
if gdb is True:
|
|
132
132
|
# general test flow for using GDBObj
|
|
@@ -168,35 +168,37 @@ class ProbackupApp:
|
|
|
168
168
|
|
|
169
169
|
return command, strcommand
|
|
170
170
|
|
|
171
|
-
def _form_cmdline(self, binary_path, command):
|
|
171
|
+
def _form_cmdline(self, binary_path, command, use_valgrind=True):
|
|
172
172
|
cmdline = [binary_path, *command]
|
|
173
173
|
|
|
174
|
-
if
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
174
|
+
if not use_valgrind or command[0] == "--version":
|
|
175
|
+
return cmdline
|
|
176
|
+
if self.valgrind != 'y' and not self.valgrind_sup_path:
|
|
177
|
+
return cmdline
|
|
178
|
+
|
|
179
|
+
os.makedirs(self.pb_log_path, exist_ok=True)
|
|
180
|
+
valgrind_cmd = [
|
|
181
|
+
"valgrind",
|
|
182
|
+
"--gen-suppressions=all",
|
|
183
|
+
"--leak-check=full",
|
|
184
|
+
"--show-reachable=yes",
|
|
185
|
+
"--error-limit=no",
|
|
186
|
+
"--show-leak-kinds=all",
|
|
187
|
+
"--errors-for-leak-kinds=all",
|
|
188
|
+
"--error-exitcode=0",
|
|
189
|
+
f"--log-file={os.path.join(self.pb_log_path, f'valgrind-{command[0]}-%p.log')}"
|
|
190
|
+
]
|
|
191
|
+
if self.valgrind_sup_path:
|
|
192
|
+
if os.path.isfile(self.valgrind_sup_path):
|
|
193
|
+
valgrind_cmd += [f"--suppressions={self.valgrind_sup_path}"]
|
|
193
194
|
else:
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
195
|
+
raise FileNotFoundError(f"PG_PROBACKUP_VALGRIND_SUP must be the path to a valgrind suppression file, "
|
|
196
|
+
f"but found: {self.valgrind_sup_path}")
|
|
197
|
+
else:
|
|
198
|
+
# Assume the tests are started from the root of pg_probackup repository
|
|
199
|
+
valgrind_cmd += ["--suppressions=.valgrind.supp"]
|
|
198
200
|
|
|
199
|
-
return cmdline
|
|
201
|
+
return valgrind_cmd + cmdline
|
|
200
202
|
|
|
201
203
|
def _execute_command(self, cmdline, env, command, gdb, expect_error, return_id, daemonize):
|
|
202
204
|
try:
|
|
@@ -134,6 +134,8 @@ class GDBobj:
|
|
|
134
134
|
)
|
|
135
135
|
|
|
136
136
|
def remove_all_breakpoints(self):
|
|
137
|
+
if self._did_quit:
|
|
138
|
+
return
|
|
137
139
|
if not self.has_breakpoint:
|
|
138
140
|
return
|
|
139
141
|
|
|
@@ -149,6 +151,8 @@ class GDBobj:
|
|
|
149
151
|
)
|
|
150
152
|
|
|
151
153
|
def run_until_break(self):
|
|
154
|
+
if self._did_quit:
|
|
155
|
+
return
|
|
152
156
|
result = self._execute('run', False)
|
|
153
157
|
for line in result:
|
|
154
158
|
if line.startswith('*stopped,reason="breakpoint-hit"'):
|
|
@@ -158,6 +162,8 @@ class GDBobj:
|
|
|
158
162
|
)
|
|
159
163
|
|
|
160
164
|
def continue_execution_until_running(self):
|
|
165
|
+
if self._did_quit:
|
|
166
|
+
return
|
|
161
167
|
result = self._execute('continue')
|
|
162
168
|
|
|
163
169
|
for line in result:
|
|
@@ -175,9 +181,23 @@ class GDBobj:
|
|
|
175
181
|
def signal(self, sig):
|
|
176
182
|
if 'KILL' in sig:
|
|
177
183
|
self.remove_all_breakpoints()
|
|
184
|
+
# Avoid GDB 15.x SIGABRT: kill inferior directly, not via `signal`.
|
|
185
|
+
try:
|
|
186
|
+
pids = subprocess.check_output(
|
|
187
|
+
['pgrep', '-P', str(self.gdb_pid)],
|
|
188
|
+
text=True
|
|
189
|
+
).strip().split()
|
|
190
|
+
for pid in pids:
|
|
191
|
+
os.kill(int(pid), 9)
|
|
192
|
+
except (subprocess.CalledProcessError, ValueError, OSError):
|
|
193
|
+
pass
|
|
194
|
+
self.kill()
|
|
195
|
+
return
|
|
178
196
|
self._execute(f'signal {sig}')
|
|
179
197
|
|
|
180
198
|
def continue_execution_until_exit(self):
|
|
199
|
+
if self._did_quit:
|
|
200
|
+
return
|
|
181
201
|
self.remove_all_breakpoints()
|
|
182
202
|
result = self._execute('continue', False)
|
|
183
203
|
|
|
@@ -195,6 +215,8 @@ class GDBobj:
|
|
|
195
215
|
)
|
|
196
216
|
|
|
197
217
|
def continue_execution_until_error(self):
|
|
218
|
+
if self._did_quit:
|
|
219
|
+
return
|
|
198
220
|
self.remove_all_breakpoints()
|
|
199
221
|
result = self._execute('continue', False)
|
|
200
222
|
|
|
@@ -211,6 +233,8 @@ class GDBobj:
|
|
|
211
233
|
'Failed to continue execution until error.\n')
|
|
212
234
|
|
|
213
235
|
def continue_execution_until_break(self, ignore_count=0):
|
|
236
|
+
if self._did_quit:
|
|
237
|
+
return
|
|
214
238
|
if ignore_count > 0:
|
|
215
239
|
result = self._execute(
|
|
216
240
|
'continue ' + str(ignore_count),
|
|
@@ -253,6 +277,8 @@ class GDBobj:
|
|
|
253
277
|
|
|
254
278
|
# use for breakpoint, run, continue
|
|
255
279
|
def _execute(self, cmd, running=True):
|
|
280
|
+
if self._did_quit:
|
|
281
|
+
return []
|
|
256
282
|
output = []
|
|
257
283
|
self.proc.stdin.flush()
|
|
258
284
|
self.proc.stdin.write(cmd + '\n')
|
|
@@ -320,22 +346,23 @@ def needs_gdb(func):
|
|
|
320
346
|
check = _check_gdb_flag_or_skip_test()
|
|
321
347
|
if not check:
|
|
322
348
|
@functools.wraps(func)
|
|
323
|
-
def ok_wrapped(self):
|
|
349
|
+
def ok_wrapped(self, *args, **kwargs):
|
|
324
350
|
self._gdb_decorated = True
|
|
325
|
-
func(self)
|
|
351
|
+
return func(self, *args, **kwargs)
|
|
326
352
|
|
|
327
353
|
return ok_wrapped
|
|
328
354
|
reason = check[1]
|
|
329
355
|
if check[0] == "skip":
|
|
330
356
|
return unittest.skip(reason)(func)
|
|
331
|
-
|
|
357
|
+
|
|
358
|
+
if check[0] == "fail":
|
|
332
359
|
@functools.wraps(func)
|
|
333
|
-
def fail_wrapper(self):
|
|
360
|
+
def fail_wrapper(self, *args, **kwargs):
|
|
334
361
|
self.fail(reason)
|
|
335
362
|
|
|
336
363
|
return fail_wrapper
|
|
337
|
-
|
|
338
|
-
|
|
364
|
+
|
|
365
|
+
raise RuntimeError("Wrong action {0}".format(check))
|
|
339
366
|
|
|
340
367
|
|
|
341
368
|
_set_gdb(GDBobj)
|
{testgres_pg_probackup2-0.9.1/pg_probackup2 → testgres_pg_probackup2-0.10.0/src}/init_helpers.py
RENAMED
|
@@ -211,7 +211,7 @@ class Init(object):
|
|
|
211
211
|
self.probackup_path = probackup_path_tmp
|
|
212
212
|
|
|
213
213
|
if not self.probackup_path:
|
|
214
|
-
raise Exception('pg_probackup binary is not found')
|
|
214
|
+
raise Exception('pg_probackup binary is not found, add it to PATH or point PGPROBACKUPBIN')
|
|
215
215
|
|
|
216
216
|
if os_name == 'posix':
|
|
217
217
|
self.EXTERNAL_DIRECTORY_DELIMITER = ':'
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: testgres_pg_probackup2
|
|
3
|
+
Version: 0.10.0
|
|
4
|
+
Summary: Plugin for testgres that manages pg_probackup2
|
|
5
|
+
Author-email: Postgres Professional <testgres@postgrespro.ru>
|
|
6
|
+
License: PostgreSQL
|
|
7
|
+
Project-URL: HomePage, https://github.com/postgrespro/testgres-pg_probackup2
|
|
8
|
+
Keywords: pg_probackup,testing,testgres
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Operating System :: Unix
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Classifier: Topic :: Software Development :: Testing
|
|
22
|
+
Requires-Python: >=3.7.3
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
Requires-Dist: lz4
|
|
25
|
+
Requires-Dist: pefile
|
|
26
|
+
Requires-Dist: testgres<1.18,>=1.14.4
|
|
27
|
+
Requires-Dist: zstd
|
|
28
|
+
|
|
29
|
+
[](https://badge.fury.io/py/testgres-pg_probackup2)
|
|
30
|
+
|
|
31
|
+
# testgres-pg_probackup2
|
|
32
|
+
|
|
33
|
+
Control and testing utility for [pg_probackup2](https://github.com/postgrespro/pg_probackup). Python 3.7+ is supported.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
To install `testgres-pg_probackup`, run:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
pip install testgres-pg_probackup
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
We encourage you to use `virtualenv` for your testing environment.
|
|
45
|
+
The package requires testgres.
|
|
46
|
+
|
|
47
|
+
## Usage
|
|
48
|
+
|
|
49
|
+
### Environment variables
|
|
50
|
+
|
|
51
|
+
| Variable | Required | Default value | Description |
|
|
52
|
+
| - | - | - | - |
|
|
53
|
+
| PGPROBACKUP_TMP_DIR | No | tests/tmp_dirs | The root of the temporary directory hierarchy where tests store data and logs. Relative paths start from the current working directory. |
|
|
54
|
+
| PG_PROBACKUP_TEST_BACKUP_DIR_PREFIX | No | Temporary test hierarchy | Prefix of the test backup directories. Must be an absolute path. Use this variable to store test backups in a location other than the temporary test hierarchy. |
|
|
55
|
+
| PG_PROBACKUP_VALGRIND | No | Not set | Run pg_probackup through valgrind if the variable is set to 'y'. Setting PG_PROBACKUP_VALGRIND_SUP (see below) to any value enables valgrind just like setting `PG_PROBACKUP_VALGRIND=y` would do. |
|
|
56
|
+
| PG_PROBACKUP_VALGRIND_SUP | No | Not set | Specify the path to a valgrind suppression file. If the variable is not set then a file named "valgrind.supp" is searched for in the current working directory (normally the root of pg_probackup repository). Setting PG_PROBACKUP_VALGRIND_SUP to any value enables valgrind just like setting `PG_PROBACKUP_VALGRIND=y` (see above) would do. |
|
|
57
|
+
|
|
58
|
+
See [Testgres](https://github.com/postgrespro/testgres/tree/master#environment) on how to configure a custom Postgres installation using `PG_CONFIG` and `PG_BIN` environment variables.
|
|
59
|
+
|
|
60
|
+
### Examples
|
|
61
|
+
|
|
62
|
+
Here is an example of what you can do with `testgres-pg_probackup2`:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
# You can see full script here plugins/pg_probackup2/pg_probackup2/tests/basic_test.py
|
|
66
|
+
def test_full_backup(self):
|
|
67
|
+
# Setting up a simple test node
|
|
68
|
+
node = self.pg_node.make_simple('node', pg_options={"fsync": "off", "synchronous_commit": "off"})
|
|
69
|
+
|
|
70
|
+
# Initialize and configure Probackup
|
|
71
|
+
self.pb.init()
|
|
72
|
+
self.pb.add_instance('node', node)
|
|
73
|
+
self.pb.set_archiving('node', node)
|
|
74
|
+
|
|
75
|
+
# Start the node and initialize pgbench
|
|
76
|
+
node.slow_start()
|
|
77
|
+
node.pgbench_init(scale=100, no_vacuum=True)
|
|
78
|
+
|
|
79
|
+
# Perform backup and validation
|
|
80
|
+
backup_id = self.pb.backup_node('node', node)
|
|
81
|
+
out = self.pb.validate('node', backup_id)
|
|
82
|
+
|
|
83
|
+
# Check if the backup is valid
|
|
84
|
+
self.assertIn(f"INFO: Backup {backup_id} is valid", out)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Authors
|
|
88
|
+
|
|
89
|
+
[Postgres Professional](https://postgrespro.ru/about)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/__init__.py
|
|
4
|
+
src/app.py
|
|
5
|
+
src/gdb.py
|
|
6
|
+
src/init_helpers.py
|
|
7
|
+
src/storage/__init__.py
|
|
8
|
+
src/storage/fs_backup.py
|
|
9
|
+
testgres_pg_probackup2.egg-info/PKG-INFO
|
|
10
|
+
testgres_pg_probackup2.egg-info/SOURCES.txt
|
|
11
|
+
testgres_pg_probackup2.egg-info/dependency_links.txt
|
|
12
|
+
testgres_pg_probackup2.egg-info/requires.txt
|
|
13
|
+
testgres_pg_probackup2.egg-info/top_level.txt
|
|
14
|
+
tests/test_basic.py
|
|
15
|
+
tests/test_common.py
|
|
16
|
+
tests/test_gdb.py
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import shutil
|
|
5
|
+
import pytest
|
|
6
|
+
import unittest
|
|
7
|
+
|
|
8
|
+
import testgres
|
|
9
|
+
from src.app import ProbackupApp
|
|
10
|
+
from src.init_helpers import Init, init_params
|
|
11
|
+
from src.storage.fs_backup import FSTestBackupDir
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ProbackupTest(unittest.TestCase):
|
|
15
|
+
pg_node: testgres.NodeApp
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def probackup_is_available() -> bool:
|
|
19
|
+
p = os.environ.get("PGPROBACKUPBIN")
|
|
20
|
+
|
|
21
|
+
if p is None:
|
|
22
|
+
return False
|
|
23
|
+
|
|
24
|
+
if not os.path.exists(p):
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
return True
|
|
28
|
+
|
|
29
|
+
@pytest.fixture(autouse=True, scope="function")
|
|
30
|
+
def implicit_fixture(self, request: pytest.FixtureRequest):
|
|
31
|
+
assert isinstance(request, pytest.FixtureRequest)
|
|
32
|
+
self.helper__setUp(request)
|
|
33
|
+
yield
|
|
34
|
+
self.helper__tearDown()
|
|
35
|
+
|
|
36
|
+
def helper__setUp(self, request: pytest.FixtureRequest):
|
|
37
|
+
assert isinstance(request, pytest.FixtureRequest)
|
|
38
|
+
|
|
39
|
+
self.helper__setup_test_environment(request)
|
|
40
|
+
self.helper__setup_test_paths()
|
|
41
|
+
self.helper__setup_backup_dir()
|
|
42
|
+
self.helper__setup_probackup()
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
def helper__setup_test_environment(self, request: pytest.FixtureRequest):
|
|
46
|
+
assert isinstance(request, pytest.FixtureRequest)
|
|
47
|
+
|
|
48
|
+
self.output = None
|
|
49
|
+
self.cmd = None
|
|
50
|
+
self.nodes_to_cleanup = []
|
|
51
|
+
self.module_name, self.fname = request.node.cls.__name__, request.node.name
|
|
52
|
+
self.test_env = Init().test_env()
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
def helper__setup_test_paths(self):
|
|
56
|
+
self.rel_path = os.path.join(self.module_name, self.fname)
|
|
57
|
+
self.test_path = os.path.join(init_params.tmp_path, self.rel_path)
|
|
58
|
+
os.makedirs(self.test_path, exist_ok=True)
|
|
59
|
+
self.pb_log_path = os.path.join(self.test_path, "pb_log")
|
|
60
|
+
|
|
61
|
+
def helper__setup_backup_dir(self):
|
|
62
|
+
self.backup_dir = self.helper__build_backup_dir('backup')
|
|
63
|
+
self.backup_dir.cleanup()
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
def helper__setup_probackup(self):
|
|
67
|
+
self.pg_node = testgres.NodeApp(self.test_path, self.nodes_to_cleanup)
|
|
68
|
+
self.pb = ProbackupApp(
|
|
69
|
+
self,
|
|
70
|
+
self.pg_node,
|
|
71
|
+
self.pb_log_path,
|
|
72
|
+
self.test_env,
|
|
73
|
+
auto_compress_alg='zlib',
|
|
74
|
+
backup_dir=self.backup_dir,
|
|
75
|
+
)
|
|
76
|
+
return
|
|
77
|
+
|
|
78
|
+
def helper__tearDown(self):
|
|
79
|
+
if os.path.exists(self.test_path):
|
|
80
|
+
shutil.rmtree(self.test_path)
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
def helper__build_backup_dir(self, backup='backup'):
|
|
84
|
+
return FSTestBackupDir(rel_path=self.rel_path, backup=backup)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@pytest.mark.skipif(
|
|
88
|
+
not ProbackupTest.probackup_is_available(),
|
|
89
|
+
reason="Check that PGPROBACKUPBIN is defined and is valid.",
|
|
90
|
+
)
|
|
91
|
+
class TestBasic(ProbackupTest):
|
|
92
|
+
def test_full_backup(self):
|
|
93
|
+
assert self.pg_node is not None
|
|
94
|
+
assert type(self.pg_node) == testgres.NodeApp # noqa: E721
|
|
95
|
+
assert self.pb is not None
|
|
96
|
+
assert type(self.pb) == ProbackupApp # noqa: E721
|
|
97
|
+
|
|
98
|
+
# Setting up a simple test node
|
|
99
|
+
node = self.pg_node.make_simple(
|
|
100
|
+
'node',
|
|
101
|
+
pg_options={"fsync": "off", "synchronous_commit": "off"},
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
assert node is not None
|
|
105
|
+
assert type(node) == testgres.PostgresNode # noqa: E721
|
|
106
|
+
|
|
107
|
+
with node:
|
|
108
|
+
# Initialize and configure Probackup
|
|
109
|
+
self.pb.init()
|
|
110
|
+
self.pb.add_instance('node', node)
|
|
111
|
+
self.pb.set_archiving('node', node)
|
|
112
|
+
|
|
113
|
+
# Start the node and initialize pgbench
|
|
114
|
+
node.slow_start()
|
|
115
|
+
node.pgbench_init(scale=100, no_vacuum=True)
|
|
116
|
+
|
|
117
|
+
# Perform backup and validation
|
|
118
|
+
backup_id = self.pb.backup_node('node', node)
|
|
119
|
+
out = self.pb.validate('node', backup_id)
|
|
120
|
+
assert type(out) is str
|
|
121
|
+
|
|
122
|
+
# Check if the backup is valid
|
|
123
|
+
assert f"INFO: Backup {backup_id} is valid" in out
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def test_form_cmdline_respects_use_valgrind(tmp_path):
|
|
128
|
+
app = ProbackupApp.__new__(ProbackupApp)
|
|
129
|
+
app.valgrind = 'y'
|
|
130
|
+
app.valgrind_sup_path = None
|
|
131
|
+
app.pb_log_path = str(tmp_path)
|
|
132
|
+
|
|
133
|
+
binary = '/bin/true'
|
|
134
|
+
command = ['backup', '--instance=node']
|
|
135
|
+
|
|
136
|
+
wrapped = app._form_cmdline(binary, command)
|
|
137
|
+
plain = app._form_cmdline(binary, command, use_valgrind=False)
|
|
138
|
+
|
|
139
|
+
assert wrapped[0] == 'valgrind'
|
|
140
|
+
assert binary in wrapped
|
|
141
|
+
assert plain == [binary, *command]
|
|
142
|
+
return
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from src import __version__ as pg_probackup2_version
|
|
2
|
+
|
|
3
|
+
from packaging.version import Version
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TestCommon:
|
|
7
|
+
def test_pg_probackup2_version(self):
|
|
8
|
+
assert type(pg_probackup2_version) is str
|
|
9
|
+
|
|
10
|
+
v = Version(pg_probackup2_version)
|
|
11
|
+
|
|
12
|
+
assert v.major == 0
|
|
13
|
+
assert v.minor == 10
|
|
14
|
+
assert v.micro == 0
|
|
15
|
+
|
|
16
|
+
assert str(v) == pg_probackup2_version
|
|
17
|
+
return
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from unittest import mock
|
|
3
|
+
|
|
4
|
+
from src import gdb
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_needs_gdb_decorator_behavior():
|
|
8
|
+
# Isolate check flag, as in the original test
|
|
9
|
+
with mock.patch.object(gdb, '_check_gdb_flag_or_skip_test', return_value=None):
|
|
10
|
+
|
|
11
|
+
# Создаем тестовую функцию с декоратором @gdb.needs_gdb
|
|
12
|
+
@gdb.needs_gdb
|
|
13
|
+
def dummy_test_func(flag):
|
|
14
|
+
return flag
|
|
15
|
+
|
|
16
|
+
# Check that the decorator correctly sets the attribute (or executes the logic)
|
|
17
|
+
# Note: The original code checked self._gdb_decorated.
|
|
18
|
+
# Depending on the decorator implementation, the attribute
|
|
19
|
+
# may be on the function itself:
|
|
20
|
+
assert getattr(dummy_test_func, '_gdb_decorated', True)
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# We check the operation of the parameterizer itself in pytest style
|
|
25
|
+
@pytest.mark.parametrize("flag", [1, 0])
|
|
26
|
+
def test_parameterized_args_integration(flag):
|
|
27
|
+
with mock.patch.object(gdb, '_check_gdb_flag_or_skip_test', return_value=None):
|
|
28
|
+
assert flag in (0, 1)
|
|
29
|
+
return
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: testgres_pg_probackup2
|
|
3
|
-
Version: 0.9.1
|
|
4
|
-
Summary: Plugin for testgres that manages pg_probackup2
|
|
5
|
-
Home-page: https://github.com/postgrespro/testgres
|
|
6
|
-
Author: Postgres Professional
|
|
7
|
-
Author-email: testgres@postgrespro.ru
|
|
8
|
-
License: PostgreSQL
|
|
9
|
-
Keywords: pg_probackup,testing,testgres
|
|
10
|
-
Description-Content-Type: text/markdown
|
|
11
|
-
Requires-Dist: lz4
|
|
12
|
-
Requires-Dist: pefile
|
|
13
|
-
Requires-Dist: testgres>=1.14.4
|
|
14
|
-
Requires-Dist: zstd
|
|
15
|
-
Dynamic: author
|
|
16
|
-
Dynamic: author-email
|
|
17
|
-
Dynamic: description-content-type
|
|
18
|
-
Dynamic: home-page
|
|
19
|
-
Dynamic: keywords
|
|
20
|
-
Dynamic: license
|
|
21
|
-
Dynamic: requires-dist
|
|
22
|
-
Dynamic: summary
|
|
File without changes
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
try:
|
|
2
|
-
from setuptools import setup
|
|
3
|
-
except ImportError:
|
|
4
|
-
from distutils.core import setup
|
|
5
|
-
|
|
6
|
-
setup(
|
|
7
|
-
version='0.9.1',
|
|
8
|
-
name='testgres_pg_probackup2',
|
|
9
|
-
packages=['pg_probackup2', 'pg_probackup2.storage'],
|
|
10
|
-
description='Plugin for testgres that manages pg_probackup2',
|
|
11
|
-
url='https://github.com/postgrespro/testgres',
|
|
12
|
-
long_description_content_type='text/markdown',
|
|
13
|
-
license='PostgreSQL',
|
|
14
|
-
author='Postgres Professional',
|
|
15
|
-
author_email='testgres@postgrespro.ru',
|
|
16
|
-
keywords=['pg_probackup', 'testing', 'testgres'],
|
|
17
|
-
install_requires=[
|
|
18
|
-
'lz4',
|
|
19
|
-
'pefile',
|
|
20
|
-
'testgres>=1.14.4',
|
|
21
|
-
'zstd'
|
|
22
|
-
]
|
|
23
|
-
)
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: testgres_pg_probackup2
|
|
3
|
-
Version: 0.9.1
|
|
4
|
-
Summary: Plugin for testgres that manages pg_probackup2
|
|
5
|
-
Home-page: https://github.com/postgrespro/testgres
|
|
6
|
-
Author: Postgres Professional
|
|
7
|
-
Author-email: testgres@postgrespro.ru
|
|
8
|
-
License: PostgreSQL
|
|
9
|
-
Keywords: pg_probackup,testing,testgres
|
|
10
|
-
Description-Content-Type: text/markdown
|
|
11
|
-
Requires-Dist: lz4
|
|
12
|
-
Requires-Dist: pefile
|
|
13
|
-
Requires-Dist: testgres>=1.14.4
|
|
14
|
-
Requires-Dist: zstd
|
|
15
|
-
Dynamic: author
|
|
16
|
-
Dynamic: author-email
|
|
17
|
-
Dynamic: description-content-type
|
|
18
|
-
Dynamic: home-page
|
|
19
|
-
Dynamic: keywords
|
|
20
|
-
Dynamic: license
|
|
21
|
-
Dynamic: requires-dist
|
|
22
|
-
Dynamic: summary
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
README.md
|
|
2
|
-
setup.py
|
|
3
|
-
pg_probackup2/__init__.py
|
|
4
|
-
pg_probackup2/app.py
|
|
5
|
-
pg_probackup2/gdb.py
|
|
6
|
-
pg_probackup2/init_helpers.py
|
|
7
|
-
pg_probackup2/storage/__init__.py
|
|
8
|
-
pg_probackup2/storage/fs_backup.py
|
|
9
|
-
testgres_pg_probackup2.egg-info/PKG-INFO
|
|
10
|
-
testgres_pg_probackup2.egg-info/SOURCES.txt
|
|
11
|
-
testgres_pg_probackup2.egg-info/dependency_links.txt
|
|
12
|
-
testgres_pg_probackup2.egg-info/requires.txt
|
|
13
|
-
testgres_pg_probackup2.egg-info/top_level.txt
|
|
File without changes
|
{testgres_pg_probackup2-0.9.1/pg_probackup2 → testgres_pg_probackup2-0.10.0/src/storage}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|