1
1
import unittest
2
- from os import path , listdir
2
+ import os
3
3
import six
4
+ from time import sleep
4
5
from helpers .ptrack_helpers import ProbackupTest , ProbackupException
5
6
from testgres import stop_all
6
7
@@ -9,6 +10,7 @@ class BackupTest(ProbackupTest, unittest.TestCase):
9
10
10
11
def __init__ (self , * args , ** kwargs ):
11
12
super (BackupTest , self ).__init__ (* args , ** kwargs )
13
+ self .module_name = 'backup'
12
14
13
15
@classmethod
14
16
def tearDownClass (cls ):
@@ -20,132 +22,198 @@ def tearDownClass(cls):
20
22
def test_backup_modes_archive (self ):
21
23
"""standart backup modes with ARCHIVE WAL method"""
22
24
fname = self .id ().split ('.' )[3 ]
23
- node = self .make_simple_node (base_dir = "tmp_dirs/backup/{0}" .format (fname ),
24
- set_archiving = True ,
25
+ node = self .make_simple_node (base_dir = "{0}/{1}/node" .format (self .module_name , fname ),
25
26
initdb_params = ['--data-checksums' ],
26
27
pg_options = {'wal_level' : 'replica' , 'ptrack_enable' : 'on' }
27
28
)
29
+ backup_dir = os .path .join (self .tmp_path , self .module_name , fname , 'backup' )
30
+ self .init_pb (backup_dir )
31
+ self .add_instance (backup_dir , 'node' , node )
32
+ self .set_archiving (backup_dir , 'node' , node )
28
33
node .start ()
29
- self .assertEqual (self .init_pb (node ), six .b ("" ))
30
34
31
35
# full backup mode
32
36
#with open(path.join(node.logs_dir, "backup_full.log"), "wb") as backup_log:
33
- # backup_log.write(self.backup_pb (node, options=["--verbose"]))
37
+ # backup_log.write(self.backup_node (node, options=["--verbose"]))
34
38
35
- self .backup_pb (node )
39
+ backup_id = self .backup_node (backup_dir , 'node' , node )
40
+ show_backup = self .show_pb (backup_dir , 'node' )[0 ]
36
41
37
- show_backup = self .show_pb (node )[0 ]
38
- full_backup_id = show_backup ['ID' ]
39
42
self .assertEqual (show_backup ['Status' ], six .b ("OK" ))
40
43
self .assertEqual (show_backup ['Mode' ], six .b ("FULL" ))
41
44
42
45
# postmaster.pid and postmaster.opts shouldn't be copied
43
46
excluded = True
44
- backups_dir = path .join (self .backup_dir (node ), "backups" )
45
- for backup in listdir (backups_dir ):
46
- db_dir = path .join (backups_dir , backup , "database" )
47
- for f in listdir (db_dir ):
48
- if path .isfile (path .join (db_dir , f )) and \
49
- (f == "postmaster.pid" or f == "postmaster.opts" ):
47
+ db_dir = os .path .join (backup_dir , "backups" , 'node' , backup_id , "database" )
48
+ for f in os .listdir (db_dir ):
49
+ if os .path .isfile (os .path .join (db_dir , f )) \
50
+ and (f == "postmaster.pid" or f == "postmaster.opts" ):
50
51
excluded = False
51
52
self .assertEqual (excluded , True )
52
53
53
54
# page backup mode
54
- self .backup_pb ( node , backup_type = "page" )
55
+ page_backup_id = self .backup_node ( backup_dir , 'node' , node , backup_type = "page" )
55
56
56
57
# print self.show_pb(node)
57
- show_backup = self .show_pb (node )[1 ]
58
+ show_backup = self .show_pb (backup_dir , ' node' )[1 ]
58
59
self .assertEqual (show_backup ['Status' ], six .b ("OK" ))
59
60
self .assertEqual (show_backup ['Mode' ], six .b ("PAGE" ))
60
61
61
62
# Check parent backup
62
63
self .assertEqual (
63
- full_backup_id ,
64
- self .show_pb (node , id = show_backup ['ID' ])["parent-backup-id" ])
64
+ backup_id ,
65
+ self .show_pb (backup_dir , ' node' , backup_id = show_backup ['ID' ])["parent-backup-id" ])
65
66
66
67
# ptrack backup mode
67
- self .backup_pb ( node , backup_type = "ptrack" )
68
+ self .backup_node ( backup_dir , 'node' , node , backup_type = "ptrack" )
68
69
69
- show_backup = self .show_pb (node )[2 ]
70
+ show_backup = self .show_pb (backup_dir , ' node' )[2 ]
70
71
self .assertEqual (show_backup ['Status' ], six .b ("OK" ))
71
72
self .assertEqual (show_backup ['Mode' ], six .b ("PTRACK" ))
72
73
74
+ # Check parent backup
75
+ self .assertEqual (
76
+ page_backup_id ,
77
+ self .show_pb (backup_dir , 'node' , backup_id = show_backup ['ID' ])["parent-backup-id" ])
78
+
73
79
node .stop ()
74
80
81
+ # @unittest.skip("skip")
75
82
def test_smooth_checkpoint (self ):
76
83
"""full backup with smooth checkpoint"""
77
84
fname = self .id ().split ('.' )[3 ]
78
- node = self .make_simple_node (base_dir = "tmp_dirs/backup/{0}" .format (fname ),
79
- set_archiving = True ,
85
+ node = self .make_simple_node (base_dir = "{0}/{1}/node" .format (self .module_name , fname ),
80
86
initdb_params = ['--data-checksums' ],
81
87
pg_options = {'wal_level' : 'replica' }
82
88
)
89
+ backup_dir = os .path .join (self .tmp_path , self .module_name , fname , 'backup' )
90
+ self .init_pb (backup_dir )
91
+ self .add_instance (backup_dir , 'node' , node )
92
+ self .set_archiving (backup_dir , 'node' , node )
93
+ node .start ()
94
+
95
+ self .backup_node (backup_dir , 'node' ,node , options = ["-C" ])
96
+ self .assertEqual (self .show_pb (backup_dir , 'node' )[0 ]['Status' ], six .b ("OK" ))
97
+ node .stop ()
98
+
99
+ #@unittest.skip("skip")
100
+ def test_incremental_backup_without_full (self ):
101
+ """page-level backup without validated full backup"""
102
+ fname = self .id ().split ('.' )[3 ]
103
+ node = self .make_simple_node (base_dir = "{0}/{1}/node" .format (self .module_name , fname ),
104
+ initdb_params = ['--data-checksums' ],
105
+ pg_options = {'wal_level' : 'replica' , 'ptrack_enable' : 'on' }
106
+ )
107
+ backup_dir = os .path .join (self .tmp_path , self .module_name , fname , 'backup' )
108
+ self .init_pb (backup_dir )
109
+ self .add_instance (backup_dir , 'node' , node )
110
+ self .set_archiving (backup_dir , 'node' , node )
83
111
node .start ()
84
- self .assertEqual (self .init_pb (node ), six .b ("" ))
85
112
86
- self .backup_pb (node , options = ["-C" ])
113
+ try :
114
+ self .backup_node (backup_dir , 'node' , node , backup_type = "page" )
115
+ # we should die here because exception is what we expect to happen
116
+ self .assertEqual (1 , 0 , "Expecting Error because page backup should not be possible without valid full backup.\n Output: {0} \n CMD: {1}" .format (
117
+ repr (self .output ), self .cmd ))
118
+ except ProbackupException , e :
119
+ self .assertEqual (e .message ,
120
+ 'ERROR: Valid backup on current timeline is not found. Create new FULL backup before an incremental one.\n ' ,
121
+ '\n Unexpected Error Message: {0}\n CMD: {1}' .format (repr (e .message ), self .cmd ))
87
122
88
- self . assertEqual ( self . show_pb ( node )[ 0 ][ 'Status' ], six . b ( "OK" ) )
123
+ sleep ( 1 )
89
124
125
+ try :
126
+ self .backup_node (backup_dir , 'node' , node , backup_type = "ptrack" )
127
+ # we should die here because exception is what we expect to happen
128
+ self .assertEqual (1 , 0 , "Expecting Error because page backup should not be possible without valid full backup.\n Output: {0} \n CMD: {1}" .format (
129
+ repr (self .output ), self .cmd ))
130
+ except ProbackupException , e :
131
+ self .assertEqual (e .message ,
132
+ 'ERROR: Valid backup on current timeline is not found. Create new FULL backup before an incremental one.\n ' ,
133
+ '\n Unexpected Error Message: {0}\n CMD: {1}' .format (repr (e .message ), self .cmd ))
134
+
135
+ self .assertEqual (self .show_pb (backup_dir , 'node' )[0 ]['Status' ], six .b ("ERROR" ))
90
136
node .stop ()
91
137
92
- def test_page_backup_without_full (self ):
93
- """page-level backup without validated full backup"""
138
+ @unittest .expectedFailure
139
+ # Need to forcibly validate parent
140
+ def test_incremental_backup_corrupt_full (self ):
141
+ """page-level backup with corrupted full backup"""
94
142
fname = self .id ().split ('.' )[3 ]
95
- node = self .make_simple_node (base_dir = "tmp_dirs/backup/{0}" .format (fname ),
96
- set_archiving = True ,
143
+ node = self .make_simple_node (base_dir = "{0}/{1}/node" .format (self .module_name , fname ),
97
144
initdb_params = ['--data-checksums' ],
98
- pg_options = {'wal_level' : 'replica' }
145
+ pg_options = {'wal_level' : 'replica' , 'ptrack_enable' : 'on' }
99
146
)
147
+ backup_dir = os .path .join (self .tmp_path , self .module_name , fname , 'backup' )
148
+ self .init_pb (backup_dir )
149
+ self .add_instance (backup_dir , 'node' , node )
150
+ self .set_archiving (backup_dir , 'node' , node )
100
151
node .start ()
101
- self .assertEqual (self .init_pb (node ), six .b ("" ))
152
+
153
+ backup_id = self .backup_node (backup_dir , 'node' , node )
154
+ file = os .path .join (backup_dir , "backups" , "node" , backup_id .decode ("utf-8" ), "database" , "postgresql.conf" )
155
+ os .remove (file )
102
156
103
157
try :
104
- self .backup_pb (node , backup_type = "page" )
158
+ self .backup_node (backup_dir , 'node' , node , backup_type = "page" )
159
+ # we should die here because exception is what we expect to happen
160
+ self .assertEqual (1 , 0 , "Expecting Error because page backup should not be possible without valid full backup.\n Output: {0} \n CMD: {1}" .format (
161
+ repr (self .output ), self .cmd ))
162
+ except ProbackupException , e :
163
+ self .assertEqual (e .message ,
164
+ 'ERROR: Valid backup on current timeline is not found. Create new FULL backup before an incremental one.\n ' ,
165
+ '\n Unexpected Error Message: {0}\n CMD: {1}' .format (repr (e .message ), self .cmd ))
166
+
167
+ sleep (1 )
168
+ self .assertEqual (1 , 0 , "Expecting Error because page backup should not be possible without valid full backup.\n Output: {0} \n CMD: {1}" .format (
169
+ repr (self .output ), self .cmd ))
105
170
except ProbackupException , e :
106
- pass
107
- self .assertEqual (self .show_pb (node )[0 ]['Status' ], six .b ("ERROR" ))
171
+ self .assertEqual (e .message ,
172
+ 'ERROR: Valid backup on current timeline is not found. Create new FULL backup before an incremental one.\n ' ,
173
+ '\n Unexpected Error Message: {0}\n CMD: {1}' .format (repr (e .message ), self .cmd ))
108
174
175
+ self .assertEqual (self .show_pb (backup_dir , 'node' )[0 ]['Status' ], six .b ("ERROR" ))
109
176
node .stop ()
110
177
178
+ # @unittest.skip("skip")
111
179
def test_ptrack_threads (self ):
112
180
"""ptrack multi thread backup mode"""
113
181
fname = self .id ().split ('.' )[3 ]
114
- node = self .make_simple_node (base_dir = "tmp_dirs/backup/{0}" .format (fname ),
115
- set_archiving = True ,
182
+ node = self .make_simple_node (base_dir = "{0}/{1}/node" .format (self .module_name , fname ),
116
183
initdb_params = ['--data-checksums' ],
117
- pg_options = {'wal_level' : 'replica' , " ptrack_enable" : "on" , 'max_wal_senders' : '2 ' }
184
+ pg_options = {'wal_level' : 'replica' , ' ptrack_enable' : 'on ' }
118
185
)
186
+ backup_dir = os .path .join (self .tmp_path , self .module_name , fname , 'backup' )
187
+ self .init_pb (backup_dir )
188
+ self .add_instance (backup_dir , 'node' , node )
189
+ self .set_archiving (backup_dir , 'node' , node )
119
190
node .start ()
120
- self .assertEqual (self .init_pb (node ), six .b ("" ))
121
-
122
- self .backup_pb (node , backup_type = "full" , options = ["-j" , "4" ])
123
-
124
- self .assertEqual (self .show_pb (node )[0 ]['Status' ], six .b ("OK" ))
125
191
126
- with open ( path . join ( node . logs_dir , "backup_ptrack.log" ), "wb" ) as backup_log :
127
- backup_log . write (self .backup_pb ( node , backup_type = "ptrack" , options = [ "-j" , "4" ] ))
192
+ self . backup_node ( backup_dir , ' node' , node , backup_type = "full" , options = [ "-j" , "4" ])
193
+ self . assertEqual (self .show_pb ( backup_dir , 'node' )[ 0 ][ 'Status' ], six . b ( "OK" ))
128
194
129
- self .assertEqual (self .show_pb (node )[0 ]['Status' ], six .b ("OK" ))
195
+ self .backup_node (backup_dir , 'node' , node , backup_type = "ptrack" , options = ["-j" , "4" ])
196
+ self .assertEqual (self .show_pb (backup_dir , 'node' )[0 ]['Status' ], six .b ("OK" ))
130
197
131
198
node .stop ()
132
199
200
+ # @unittest.skip("skip")
133
201
def test_ptrack_threads_stream (self ):
134
202
"""ptrack multi thread backup mode and stream"""
135
203
fname = self .id ().split ('.' )[3 ]
136
- node = self .make_simple_node (base_dir = "tmp_dirs/backup/ {0}" .format (fname ),
204
+ node = self .make_simple_node (base_dir = "{0}/{1}/node " .format (self . module_name , fname ),
137
205
set_replication = True ,
138
206
initdb_params = ['--data-checksums' ],
139
207
pg_options = {'wal_level' : 'replica' , 'ptrack_enable' : 'on' , 'max_wal_senders' : '2' }
140
208
)
209
+ backup_dir = os .path .join (self .tmp_path , self .module_name , fname , 'backup' )
210
+ self .init_pb (backup_dir )
211
+ self .add_instance (backup_dir , 'node' , node )
141
212
node .start ()
142
- self .assertEqual (self .init_pb (node ), six .b ("" ))
143
-
144
- self .backup_pb (node , backup_type = "full" , options = ["-j" , "4" , "--stream" ])
145
-
146
- self .assertEqual (self .show_pb (node )[0 ]['Status' ], six .b ("OK" ))
147
213
148
- self .backup_pb ( node , backup_type = "ptrack " , options = ["-j" , "4" , "--stream" ])
214
+ self .backup_node ( backup_dir , ' node' , node , backup_type = "full " , options = ["-j" , "4" , "--stream" ])
149
215
150
- self .assertEqual (self .show_pb (node )[1 ]['Status' ], six .b ("OK" ))
216
+ self .assertEqual (self .show_pb (backup_dir , 'node' )[0 ]['Status' ], six .b ("OK" ))
217
+ self .backup_node (backup_dir , 'node' , node , backup_type = "ptrack" , options = ["-j" , "4" , "--stream" ])
218
+ self .assertEqual (self .show_pb (backup_dir , 'node' )[1 ]['Status' ], six .b ("OK" ))
151
219
node .stop ()
0 commit comments