Skip to content

Commit e291e53

Browse files
committed
Merge branch 'master' of git.postgrespro.ru:pgpro-dev/pg_probackup
2 parents bd681ed + b38410d commit e291e53

25 files changed

+385
-162
lines changed

tests/__init__.py

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,33 @@
66
ptrack_move_to_tablespace, ptrack_recovery, ptrack_vacuum, \
77
ptrack_vacuum_bits_frozen, ptrack_vacuum_bits_visibility, \
88
ptrack_vacuum_full, ptrack_vacuum_truncate, pgpro560, pgpro589, \
9-
false_positive, replica
9+
pgpro688, false_positive, replica
1010

1111

1212
def load_tests(loader, tests, pattern):
1313
suite = unittest.TestSuite()
14-
suite.addTests(loader.loadTestsFromModule(replica))
15-
suite.addTests(loader.loadTestsFromModule(pgpro560))
16-
suite.addTests(loader.loadTestsFromModule(pgpro589))
17-
suite.addTests(loader.loadTestsFromModule(false_positive))
18-
suite.addTests(loader.loadTestsFromModule(init_test))
19-
suite.addTests(loader.loadTestsFromModule(option_test))
20-
suite.addTests(loader.loadTestsFromModule(show_test))
21-
suite.addTests(loader.loadTestsFromModule(backup_test))
22-
suite.addTests(loader.loadTestsFromModule(delete_test))
23-
suite.addTests(loader.loadTestsFromModule(restore_test))
24-
suite.addTests(loader.loadTestsFromModule(validate_test))
25-
suite.addTests(loader.loadTestsFromModule(retention_test))
26-
suite.addTests(loader.loadTestsFromModule(ptrack_clean))
27-
suite.addTests(loader.loadTestsFromModule(ptrack_cluster))
28-
suite.addTests(loader.loadTestsFromModule(ptrack_move_to_tablespace))
29-
suite.addTests(loader.loadTestsFromModule(ptrack_recovery))
30-
suite.addTests(loader.loadTestsFromModule(ptrack_vacuum))
31-
suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_bits_frozen))
32-
suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_bits_visibility))
33-
suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_full))
34-
suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_truncate))
14+
# suite.addTests(loader.loadTestsFromModule(replica))
15+
# suite.addTests(loader.loadTestsFromModule(pgpro560))
16+
# suite.addTests(loader.loadTestsFromModule(pgpro589))
17+
suite.addTests(loader.loadTestsFromModule(pgpro688))
18+
# suite.addTests(loader.loadTestsFromModule(false_positive))
19+
# suite.addTests(loader.loadTestsFromModule(init_test))
20+
# suite.addTests(loader.loadTestsFromModule(option_test))
21+
# suite.addTests(loader.loadTestsFromModule(show_test))
22+
# suite.addTests(loader.loadTestsFromModule(backup_test))
23+
# suite.addTests(loader.loadTestsFromModule(delete_test))
24+
# suite.addTests(loader.loadTestsFromModule(restore_test))
25+
# suite.addTests(loader.loadTestsFromModule(validate_test))
26+
# suite.addTests(loader.loadTestsFromModule(retention_test))
27+
# suite.addTests(loader.loadTestsFromModule(ptrack_clean))
28+
# suite.addTests(loader.loadTestsFromModule(ptrack_cluster))
29+
# suite.addTests(loader.loadTestsFromModule(ptrack_move_to_tablespace))
30+
# suite.addTests(loader.loadTestsFromModule(ptrack_recovery))
31+
# suite.addTests(loader.loadTestsFromModule(ptrack_vacuum))
32+
# suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_bits_frozen))
33+
# suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_bits_visibility))
34+
# suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_full))
35+
# suite.addTests(loader.loadTestsFromModule(ptrack_vacuum_truncate))
3536

3637
return suite
3738

tests/backup_test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import unittest
22
from os import path, listdir
33
import six
4-
from .ptrack_helpers import ProbackupTest, ProbackupException
4+
from helpers.ptrack_helpers import ProbackupTest, ProbackupException
55
from testgres import stop_all
66

77

@@ -16,6 +16,7 @@ def tearDownClass(cls):
1616

1717
# @unittest.skip("skip")
1818
# @unittest.expectedFailure
19+
# PGPRO-707
1920
def test_backup_modes_archive(self):
2021
"""standart backup modes with ARCHIVE WAL method"""
2122
fname = self.id().split('.')[3]

tests/delete_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import unittest
22
from os import path
33
import six
4-
from .ptrack_helpers import ProbackupTest, ProbackupException
4+
from helpers.ptrack_helpers import ProbackupTest, ProbackupException
55
from testgres import stop_all
66
import subprocess
77

tests/expected/option_help.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,11 @@ pg_probackup - utility to manage backup/recovery of PostgreSQL database.
4242
pg_probackup delete -B backup-dir
4343
[--wal] [-i backup-id | --expired]
4444

45+
pg_probackup add-instance -B backup-dir
46+
--instance=instance_name
47+
48+
pg_probackup del-instance -B backup-dir
49+
--instance=instance_name
50+
4551
Read the website for details. <https://github.com/postgrespro/pg_probackup>
4652
Report bugs to <https://github.com/postgrespro/pg_probackup/issues>.

tests/false_positive.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import unittest
22
import os
33
import six
4-
from .ptrack_helpers import ProbackupTest, ProbackupException
4+
from helpers.ptrack_helpers import ProbackupTest, ProbackupException
55
from datetime import datetime, timedelta
66
from testgres import stop_all
77
import subprocess

tests/helpers/ptrack_helpers.py

Lines changed: 66 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@
5555
# You can lookup error message and cmdline in exception object attributes
5656
class ProbackupException(Exception):
5757
def __init__(self, message, cmd):
58-
# print message
59-
# self.message = repr(message).strip("'")
6058
self.message = message
6159
self.cmd = cmd
6260
#need that to make second raise
@@ -138,24 +136,31 @@ def __init__(self, *args, **kwargs):
138136

139137
self.helpers_path = os.path.dirname(os.path.realpath(__file__))
140138
self.dir_path = os.path.abspath(os.path.join(self.helpers_path, os.pardir))
139+
self.tmp_path = os.path.abspath(os.path.join(self.dir_path, 'tmp_dirs'))
141140
try:
142-
os.makedirs(os.path.join(self.dir_path, "tmp_dirs"))
141+
os.makedirs(os.path.join(self.dir_path, 'tmp_dirs'))
143142
except:
144143
pass
145144
self.probackup_path = os.path.abspath(os.path.join(
146-
self.dir_path,
147-
"../pg_probackup"
148-
))
145+
self.dir_path, "../pg_probackup"))
149146

150147
def arcwal_dir(self, node):
151148
return "%s/backup/wal" % node.base_dir
152149

153-
def backup_dir(self, node):
154-
return os.path.abspath("%s/backup" % node.base_dir)
150+
def backup_dir(self, node=None, path=None):
151+
if node:
152+
return os.path.abspath("{0}/backup".format(node.base_dir))
153+
if path:
154+
return
155155

156-
def make_simple_node(self, base_dir=None, set_replication=False,
157-
set_archiving=False, initdb_params=[], pg_options={}):
158-
real_base_dir = os.path.join(self.dir_path, base_dir)
156+
def make_simple_node(
157+
self,
158+
base_dir=None,
159+
set_replication=False,
160+
initdb_params=[],
161+
pg_options={}):
162+
163+
real_base_dir = os.path.join(self.tmp_path, base_dir)
159164
shutil.rmtree(real_base_dir, ignore_errors=True)
160165

161166
node = get_new_node('test', base_dir=real_base_dir)
@@ -173,9 +178,6 @@ def make_simple_node(self, base_dir=None, set_replication=False,
173178
# Allow replication in pg_hba.conf
174179
if set_replication:
175180
node.set_replication_conf()
176-
# Setup archiving for node
177-
if set_archiving:
178-
self.set_archiving_conf(node, self.arcwal_dir(node))
179181
return node
180182

181183
def create_tblspace_in_node(self, node, tblspc_name, cfs=False):
@@ -301,6 +303,7 @@ def check_ptrack_clean(self, idx_dict, size):
301303
def run_pb(self, command, async=False):
302304
try:
303305
self.cmd = [' '.join(map(str,[self.probackup_path] + command))]
306+
print self.cmd
304307
if async is True:
305308
return subprocess.Popen(
306309
[self.probackup_path] + command,
@@ -319,44 +322,55 @@ def run_pb(self, command, async=False):
319322
for line in self.output.splitlines():
320323
if 'INFO: Backup' and 'completed' in line:
321324
return line.split()[2]
322-
# backup_id = line.split()[2]
323-
# return {'cmd': cmd, 'output': output, 'backup_id': backup_id}
324325
else:
325326
return self.output
326-
# return {'cmd': cmd, 'output': output}
327327
except subprocess.CalledProcessError as e:
328-
raise ProbackupException(e.output, e.cmd)
328+
raise ProbackupException(e.output, self.cmd)
329329

330-
def init_pb(self, node):
330+
def init_pb(self, backup_dir):
331331

332332
return self.run_pb([
333333
"init",
334-
"-B", self.backup_dir(node),
334+
"-B", backup_dir
335+
])
336+
337+
def add_instance(self, backup_dir, instance, node):
338+
339+
return self.run_pb([
340+
"add-instance",
341+
"--instance={0}".format(instance),
342+
"-B", backup_dir,
343+
"-D", node.data_dir
344+
])
345+
346+
def del_instance(self, backup_dir, instance, node):
347+
348+
return self.run_pb([
349+
"del-instance",
350+
"--instance={0}".format(instance),
351+
"-B", backup_dir,
335352
"-D", node.data_dir
336353
])
337354

338355
def clean_pb(self, node):
339356
shutil.rmtree(self.backup_dir(node), ignore_errors=True)
340357

341-
def backup_pb(self, node=None, data_dir=None, backup_dir=None, backup_type="full", options=[], async=False):
342-
if data_dir is None:
343-
data_dir = node.data_dir
344-
if backup_dir is None:
345-
backup_dir = self.backup_dir(node)
358+
def backup_node(self, backup_dir, instance, node, backup_type="full", options=[], async=False):
346359

347360
cmd_list = [
348361
"backup",
349362
"-B", backup_dir,
350-
"-D", data_dir,
363+
"-D", node.data_dir,
351364
"-p", "%i" % node.port,
352-
"-d", "postgres"
365+
"-d", "postgres",
366+
"--instance={0}".format(instance)
353367
]
354368
if backup_type:
355369
cmd_list += ["-b", backup_type]
356370

357371
return self.run_pb(cmd_list + options, async)
358372

359-
def restore_pb(self, node=None, backup_dir=None, data_dir=None, id=None, options=[]):
373+
def restore_node(self, backup_dir, instance, data_dir=None, id=None, options=[]):
360374
if data_dir is None:
361375
data_dir = node.data_dir
362376
if backup_dir is None:
@@ -365,30 +379,35 @@ def restore_pb(self, node=None, backup_dir=None, data_dir=None, id=None, options
365379
cmd_list = [
366380
"restore",
367381
"-B", backup_dir,
368-
"-D", data_dir
382+
"-D", data_dir,
383+
"--instance={0}".format(instance)
369384
]
370385
if id:
371386
cmd_list += ["-i", id]
372387

373388
return self.run_pb(cmd_list + options)
374389

375-
def show_pb(self, node, id=None, options=[], as_text=False):
390+
def show_pb(self, backup_dir, instance=None, backup_id=None, options=[], as_text=False):
391+
376392
backup_list = []
377393
specific_record = {}
378394
cmd_list = [
379395
"show",
380-
"-B", self.backup_dir(node),
396+
"-B", backup_dir,
381397
]
382-
if id:
383-
cmd_list += ["-i", id]
398+
if instance:
399+
cmd_list += ["--instance={0}".format(instance)]
400+
401+
if backup_id:
402+
cmd_list += ["-i", backup_id]
384403

385404
if as_text:
386405
# You should print it when calling as_text=true
387406
return self.run_pb(cmd_list + options)
388407

389408
# get show result as list of lines
390409
show_splitted = self.run_pb(cmd_list + options).splitlines()
391-
if id is None:
410+
if instance is not None and backup_id is None:
392411
# cut header(ID, Mode, etc) from show as single string
393412
header = show_splitted[1:2][0]
394413
# cut backup records from show as single list with string for every backup record
@@ -430,36 +449,40 @@ def show_pb(self, node, id=None, options=[], as_text=False):
430449
specific_record[name.strip()] = var
431450
return specific_record
432451

433-
def validate_pb(self, node, id=None, options=[]):
452+
def validate_pb(self, backup_dir, instance=None, id=None, options=[]):
453+
434454
cmd_list = [
435455
"validate",
436-
"-B", self.backup_dir(node),
456+
"-B", backup_dir,
437457
]
458+
if instance:
459+
cmd_list += ["--instance={0}".format(instance)]
438460
if id:
439461
cmd_list += ["-i", id]
440462

441-
# print(cmd_list)
442463
return self.run_pb(cmd_list + options)
443464

444-
def delete_pb(self, node, id=None, options=[]):
465+
def delete_pb(self, backup_dir, instance=None, id=None, options=[]):
445466
cmd_list = [
446467
"delete",
447468
"-B", self.backup_dir(node),
448469
]
470+
if instance:
471+
cmd_list += ["--instance={0}".format(instance)]
449472
if id:
450473
cmd_list += ["-i", id]
451474

452475
# print(cmd_list)
453476
return self.run_pb(cmd_list + options)
454477

455-
def delete_expired(self, node, options=[]):
478+
def delete_expired(self, backup_dir, instance=None, options=[]):
456479
cmd_list = [
457480
"delete", "--expired",
458481
"-B", self.backup_dir(node),
459482
]
460483
return self.run_pb(cmd_list + options)
461484

462-
def show_config(self, node):
485+
def show_config(self, backup_dir, instance=None):
463486
out_dict = {}
464487
cmd_list = [
465488
"show-config",
@@ -484,9 +507,7 @@ def get_recovery_conf(self, node):
484507
out_dict[key.strip()] = value.strip(" '").replace("'\n", "")
485508
return out_dict
486509

487-
def set_archiving_conf(self, node, archive_dir=False, replica=False):
488-
if not archive_dir:
489-
archive_dir = self.arcwal_dir(node)
510+
def set_archiving(self, backup_dir, instance, node, replica=False):
490511

491512
if replica:
492513
archive_mode = 'always'
@@ -505,8 +526,8 @@ def set_archiving_conf(self, node, archive_dir=False, replica=False):
505526
if os.name == 'posix':
506527
node.append_conf(
507528
"postgresql.auto.conf",
508-
"archive_command = 'test ! -f {0}/%f && cp %p {0}/%f'".format(archive_dir)
509-
)
529+
"archive_command = '{0} archive-push -B {1} --instance={2} --wal-file-path %p --wal-file-name %f'".format(
530+
self.probackup_path, backup_dir, instance))
510531
#elif os.name == 'nt':
511532
# node.append_conf(
512533
# "postgresql.auto.conf",

0 commit comments

Comments
 (0)