Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3c82429

Browse files
committed
Add delete and backup tests. Add simple parser for show line.
1 parent e7d6a08 commit 3c82429

File tree

5 files changed

+262
-14
lines changed

5 files changed

+262
-14
lines changed

tests/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import unittest
22

3-
from . import init_test, option_test, show_test
3+
from . import init_test, option_test, show_test, backup_test, delete_test
44

55

66
def load_tests(loader, tests, pattern):
77
suite = unittest.TestSuite()
88
suite.addTests(loader.loadTestsFromModule(init_test))
99
suite.addTests(loader.loadTestsFromModule(option_test))
1010
suite.addTests(loader.loadTestsFromModule(show_test))
11+
suite.addTests(loader.loadTestsFromModule(backup_test))
12+
suite.addTests(loader.loadTestsFromModule(delete_test))
1113

1214
return suite

tests/backup_test.py

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import unittest
2+
from os import path
3+
import six
4+
from .pb_lib import ProbackupTest
5+
from testgres import stop_all
6+
7+
8+
class BackupTest(ProbackupTest, unittest.TestCase):
9+
10+
def __init__(self, *args, **kwargs):
11+
super(BackupTest, self).__init__(*args, **kwargs)
12+
13+
@classmethod
14+
def tearDownClass(cls):
15+
stop_all()
16+
17+
def test_backup_modes_1(self):
18+
"""standart backup modes"""
19+
node = self.make_bnode('backup_modes_', base_dir="tmp_dirs/backup/backup_modes_1")
20+
node.start()
21+
self.assertEqual(self.init_pb(node), six.b(""))
22+
23+
# detect ptrack
24+
is_ptrack = node.execute("postgres", "SELECT proname FROM pg_proc WHERE proname='pg_ptrack_clear'")
25+
if len(is_ptrack):
26+
node.append_conf("postgresql.conf", "ptrack_enable = on")
27+
node.restart()
28+
29+
# full backup mode
30+
with open(path.join(node.logs_dir, "backup_full.log"), "wb") as backup_log:
31+
backup_log.write(self.backup_pb(node, options=["--verbose"]))
32+
33+
show_backup = self.show_pb(node)[0]
34+
self.assertEqual(show_backup.status, six.b("OK"))
35+
self.assertEqual(show_backup.mode, six.b("FULL"))
36+
37+
# page backup mode
38+
with open(path.join(node.logs_dir, "backup_page.log"), "wb") as backup_log:
39+
backup_log.write(self.backup_pb(node, backup_type="page", options=["--verbose"]))
40+
41+
show_backup = self.show_pb(node)[0]
42+
self.assertEqual(show_backup.status, six.b("OK"))
43+
self.assertEqual(show_backup.mode, six.b("PAGE"))
44+
45+
# ptrack backup mode
46+
if len(is_ptrack):
47+
with open(path.join(node.logs_dir, "backup_ptrack.log"), "wb") as backup_log:
48+
backup_log.write(self.backup_pb(node, backup_type="ptrack", options=["--verbose"]))
49+
50+
show_backup = self.show_pb(node)[0]
51+
self.assertEqual(show_backup.status, six.b("OK"))
52+
self.assertEqual(show_backup.mode, six.b("PTRACK"))
53+
54+
node.stop()
55+
56+
def test_smooth_checkpoint_2(self):
57+
"""full backup with smooth checkpoint"""
58+
node = self.make_bnode('smooth_checkpoint_2', base_dir="tmp_dirs/backup/smooth_checkpoint_2")
59+
node.start()
60+
self.assertEqual(self.init_pb(node), six.b(""))
61+
62+
with open(path.join(node.logs_dir, "backup.log"), "wb") as backup_log:
63+
backup_log.write(self.backup_pb(node, options=["--verbose", "-C"]))
64+
65+
self.assertEqual(self.show_pb(node)[0].status, six.b("OK"))
66+
67+
node.stop()
68+
69+
def test_page_backup_without_full_3(self):
70+
"""page-level backup without validated full backup"""
71+
node = self.make_bnode('without_full_3', base_dir="tmp_dirs/backup/without_full_3")
72+
node.start()
73+
self.assertEqual(self.init_pb(node), six.b(""))
74+
75+
with open(path.join(node.logs_dir, "backup.log"), "wb") as backup_log:
76+
backup_log.write(self.backup_pb(node, backup_type="page", options=["--verbose"]))
77+
78+
self.assertEqual(self.show_pb(node)[0].status, six.b("ERROR"))
79+
80+
node.stop()
81+
82+
def test_ptrack_threads_4(self):
83+
"""ptrack multi thread backup mode"""
84+
node = self.make_bnode(
85+
'ptrack_threads_4',
86+
base_dir="tmp_dirs/backup/ptrack_threads_4",
87+
options={"ptrack_enable": "on"}
88+
)
89+
node.start()
90+
self.assertEqual(self.init_pb(node), six.b(""))
91+
92+
with open(path.join(node.logs_dir, "backup_full.log"), "wb") as backup_log:
93+
backup_log.write(self.backup_pb(node, backup_type="full", options=["--verbose", "-j", "4"]))
94+
95+
self.assertEqual(self.show_pb(node)[0].status, six.b("OK"))
96+
97+
with open(path.join(node.logs_dir, "backup_ptrack.log"), "wb") as backup_log:
98+
backup_log.write(self.backup_pb(node, backup_type="ptrack", options=["--verbose", "-j", "4"]))
99+
100+
self.assertEqual(self.show_pb(node)[0].status, six.b("OK"))
101+
102+
node.stop()
103+
104+
def test_ptrack_threads_stream_5(self):
105+
"""ptrack multi thread backup mode and stream"""
106+
node = self.make_bnode(
107+
'ptrack_threads_stream_5',
108+
base_dir="tmp_dirs/backup/ptrack_threads_stream_5",
109+
options={
110+
"ptrack_enable": "on",
111+
"max_wal_senders": "5"
112+
}
113+
)
114+
node.append_conf("pg_hba.conf", "local replication all trust")
115+
node.append_conf("pg_hba.conf", "host replication all 127.0.0.1/32 trust")
116+
node.start()
117+
self.assertEqual(self.init_pb(node), six.b(""))
118+
119+
with open(path.join(node.logs_dir, "backup_full.log"), "wb") as backup_log:
120+
backup_log.write(self.backup_pb(
121+
node,
122+
backup_type="full",
123+
options=["--verbose", "-j", "4", "--stream"]
124+
))
125+
126+
self.assertEqual(self.show_pb(node)[0].status, six.b("OK"))
127+
128+
with open(path.join(node.logs_dir, "backup_ptrack.log"), "wb") as backup_log:
129+
backup_log.write(self.backup_pb(
130+
node,
131+
backup_type="ptrack",
132+
options=["--verbose", "-j", "4", "--stream"]
133+
))
134+
135+
self.assertEqual(self.show_pb(node)[0].status, six.b("OK"))
136+
137+
node.stop()

tests/delete_test.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import unittest
2+
from os import path
3+
import six
4+
from .pb_lib import ProbackupTest
5+
from testgres import stop_all
6+
import subprocess
7+
8+
9+
class DeleteTest(ProbackupTest, unittest.TestCase):
10+
11+
def __init__(self, *args, **kwargs):
12+
super(DeleteTest, self).__init__(*args, **kwargs)
13+
14+
@classmethod
15+
def tearDownClass(cls):
16+
stop_all()
17+
18+
def test_delete_full_backups_1(self):
19+
"""delete full backups"""
20+
node = self.make_bnode('delete_full_backups_1', base_dir="tmp_dirs/delete/delete_full_backups_1")
21+
node.start()
22+
self.assertEqual(self.init_pb(node), six.b(""))
23+
node.pgbench_init()
24+
25+
# full backup mode
26+
with open(path.join(node.logs_dir, "backup_1.log"), "wb") as backup_log:
27+
backup_log.write(self.backup_pb(node, options=["--verbose"]))
28+
29+
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
30+
pgbench.wait()
31+
pgbench.stdout.close()
32+
33+
with open(path.join(node.logs_dir, "backup_2.log"), "wb") as backup_log:
34+
backup_log.write(self.backup_pb(node, options=["--verbose"]))
35+
36+
pgbench = node.pgbench(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
37+
pgbench.wait()
38+
pgbench.stdout.close()
39+
40+
with open(path.join(node.logs_dir, "backup_3.log"), "wb") as backup_log:
41+
backup_log.write(self.backup_pb(node, options=["--verbose"]))
42+
43+
show_backups = self.show_pb(node)
44+
id_1 = show_backups[0].id
45+
id_2 = show_backups[2].id
46+
self.delete_pb(node, show_backups[1].id)
47+
show_backups = self.show_pb(node)
48+
self.assertEqual(show_backups[0].id, id_1)
49+
self.assertEqual(show_backups[1].id, id_2)
50+
51+
node.stop()
52+
53+
def test_delete_increment_2(self):
54+
"""delete increment and all after him"""
55+
node = self.make_bnode('delete_increment_2', base_dir="tmp_dirs/delete/delete_increment_2")
56+
node.start()
57+
self.assertEqual(self.init_pb(node), six.b(""))
58+
59+
# full backup mode
60+
with open(path.join(node.logs_dir, "backup_1.log"), "wb") as backup_log:
61+
backup_log.write(self.backup_pb(node, options=["--verbose"]))
62+
63+
# page backup mode
64+
with open(path.join(node.logs_dir, "backup_2.log"), "wb") as backup_log:
65+
backup_log.write(self.backup_pb(node, backup_type="page", options=["--verbose"]))
66+
67+
# page backup mode
68+
with open(path.join(node.logs_dir, "backup_3.log"), "wb") as backup_log:
69+
backup_log.write(self.backup_pb(node, backup_type="page", options=["--verbose"]))
70+
71+
show_backups = self.show_pb(node)
72+
self.assertEqual(len(show_backups), 3)
73+
self.delete_pb(node, show_backups[1].id)
74+
show_backups = self.show_pb(node)
75+
self.assertEqual(len(show_backups), 1)
76+
self.assertEqual(show_backups[0].mode, six.b("FULL"))
77+
self.assertEqual(show_backups[0].status, six.b("OK"))
78+
79+
node.stop()

tests/pb_lib.py

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,21 @@ def dir_files(base_dir):
1717
return out_list
1818

1919

20+
class ShowBackup(object):
21+
def __init__(self, split_line):
22+
self.id = split_line[0]
23+
# TODO: parse to datetime
24+
self.recovery_time = "%s %s" % (split_line[1], split_line[2])
25+
self.mode = split_line[3]
26+
self.cur_tli = split_line[4]
27+
self.parent_tli = split_line[6]
28+
# TODO: parse to interval
29+
self.time = split_line[7]
30+
# TODO: maybe rename to size?
31+
self.data = split_line[8]
32+
self.status = split_line[9]
33+
34+
2035
class ProbackupTest(object):
2136
def __init__(self, *args, **kwargs):
2237
super(ProbackupTest, self).__init__(*args, **kwargs)
@@ -36,13 +51,10 @@ def arcwal_dir(self, node):
3651
def backup_dir(self, node):
3752
return os.path.abspath("%s/backup" % node.base_dir)
3853

39-
def make_bnode(self, name, base_dir=None):
40-
node = get_new_node('test', base_dir=path.join(self.dir_path, base_dir))
41-
try:
42-
node.cleanup()
43-
except:
44-
pass
45-
shutil.rmtree(self.backup_dir(node), ignore_errors=True)
54+
def make_bnode(self, name, base_dir=None, options={}):
55+
real_base_dir = path.join(self.dir_path, base_dir)
56+
shutil.rmtree(real_base_dir, ignore_errors=True)
57+
node = get_new_node('test', base_dir=real_base_dir)
4658
node.init()
4759

4860
node.append_conf("postgresql.conf", "wal_level = hot_standby")
@@ -51,6 +63,10 @@ def make_bnode(self, name, base_dir=None):
5163
"postgresql.conf",
5264
"""archive_command = 'cp "%%p" "%s/%%f"'""" % os.path.abspath(self.arcwal_dir(node))
5365
)
66+
67+
for key, value in six.iteritems(options):
68+
node.append_conf("postgresql.conf", "%s = %s" % (key, value))
69+
5470
return node
5571

5672
def run_pb(self, command):
@@ -86,7 +102,7 @@ def backup_pb(self, node, backup_type="full", options=[]):
86102
# print(cmd_list)
87103
return self.run_pb(cmd_list + options)
88104

89-
def show_pb(self, node, id=None, options=[]):
105+
def show_pb(self, node, id=None, options=[], as_text=False):
90106
cmd_list = [
91107
"-B", self.backup_dir(node),
92108
"show",
@@ -95,9 +111,12 @@ def show_pb(self, node, id=None, options=[]):
95111
cmd_list += [id]
96112

97113
# print(cmd_list)
98-
return self.run_pb(options + cmd_list)
114+
if as_text:
115+
return self.run_pb(options + cmd_list)
116+
else:
117+
return [ShowBackup(line.split()) for line in self.run_pb(options + cmd_list).splitlines()[3:]]
99118

100-
def validate_pb(self, node, id=None, options=[]):
119+
def validate_pb(self, node, id, options=[]):
101120
cmd_list = [
102121
"-B", self.backup_dir(node),
103122
"validate",
@@ -107,3 +126,14 @@ def validate_pb(self, node, id=None, options=[]):
107126

108127
# print(cmd_list)
109128
return self.run_pb(options + cmd_list)
129+
130+
def delete_pb(self, node, id=None, options=[]):
131+
cmd_list = [
132+
"-B", self.backup_dir(node),
133+
"delete",
134+
]
135+
if id:
136+
cmd_list += [id]
137+
138+
# print(cmd_list)
139+
return self.run_pb(options + cmd_list)

tests/show_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def test_ok_1(self):
2525
self.backup_pb(node, options=["--quiet"]),
2626
six.b("")
2727
)
28-
self.assertIn(six.b("OK"), self.show_pb(node))
28+
self.assertIn(six.b("OK"), self.show_pb(node, as_text=True))
2929

3030
node.stop()
3131

@@ -40,10 +40,10 @@ def test_corrupt_2(self):
4040
six.b("")
4141
)
4242

43-
id_backup = self.show_pb(node).splitlines()[3].split()[0]
43+
id_backup = self.show_pb(node)[0].id
4444
os.remove(path.join(self.backup_dir(node), "backups", id_backup.decode("utf-8"), "database", "postgresql.conf"))
4545

4646
self.validate_pb(node, id_backup)
47-
self.assertIn(six.b("CORRUPT"), self.show_pb(node))
47+
self.assertIn(six.b("CORRUPT"), self.show_pb(node, as_text=True))
4848

4949
node.stop()

0 commit comments

Comments
 (0)