Skip to content

Commit ac3b017

Browse files
committed
PGPRO-1918 tests: added test_locking_running_validate_2_specific_id()
1 parent 8960f2a commit ac3b017

File tree

2 files changed

+133
-12
lines changed

2 files changed

+133
-12
lines changed

tests/helpers/ptrack_helpers.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1383,14 +1383,26 @@ def continue_execution_until_exit(self):
13831383
if line.startswith('*stopped,reason="breakpoint-hit"'):
13841384
continue
13851385
if (
1386-
line.startswith('*stopped,reason="exited-normally"') or
1386+
line.startswith('*stopped,reason="exited"') or
13871387
line == '*stopped\n'
13881388
):
13891389
return
13901390
raise GdbException(
13911391
'Failed to continue execution until exit.\n'
13921392
)
13931393

1394+
def continue_execution_until_error(self):
1395+
result = self._execute('continue', False)
1396+
1397+
for line in result:
1398+
if line.startswith('^error'):
1399+
return
1400+
if line.startswith('*stopped,reason="exited'):
1401+
return
1402+
1403+
raise GdbException(
1404+
'Failed to continue execution until error.\n')
1405+
13941406
def continue_execution_until_break(self, ignore_count=0):
13951407
if ignore_count > 0:
13961408
result = self._execute(
@@ -1436,6 +1448,8 @@ def _execute(self, cmd, running=True):
14361448
print(repr(line))
14371449
if line.startswith('^done') or line.startswith('*stopped'):
14381450
break
1451+
if line.startswith('^error'):
1452+
break
14391453
if running and (line.startswith('*running') or line.startswith('^running')):
14401454
# if running and line.startswith('*running'):
14411455
break

tests/locking.py

Lines changed: 118 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class LockingTest(ProbackupTest, unittest.TestCase):
1111

1212
# @unittest.skip("skip")
1313
# @unittest.expectedFailure
14-
def test_locking_running_1(self):
14+
def test_locking_running_validate_1(self):
1515
"""
1616
make node, take full backup, stop it in the middle
1717
run validate, expect it to successfully executed,
@@ -46,18 +46,26 @@ def test_locking_running_1(self):
4646
self.assertEqual(
4747
'RUNNING', self.show_pb(backup_dir, 'node')[1]['status'])
4848

49-
self.validate_pb(backup_dir, options=['--log-level-file=VERBOSE'])
49+
validate_output = self.validate_pb(
50+
backup_dir, options=['--log-level-console=LOG'])
51+
52+
backup_id = self.show_pb(backup_dir, 'node')[1]['id']
53+
54+
self.assertIn(
55+
"is using backup {0} and still is running".format(backup_id),
56+
validate_output,
57+
'\n Unexpected Validate Output: {0}\n'.format(repr(validate_output)))
5058

5159
self.assertEqual(
5260
'OK', self.show_pb(backup_dir, 'node')[0]['status'])
5361

5462
self.assertEqual(
55-
'ERROR', self.show_pb(backup_dir, 'node')[1]['status'])
63+
'RUNNING', self.show_pb(backup_dir, 'node')[1]['status'])
5664

5765
# Clean after yourself
58-
self.del_test_dir(module_name, fname)
66+
# self.del_test_dir(module_name, fname)
5967

60-
def test_locking_running_2(self):
68+
def test_locking_running_validate_2(self):
6169
"""
6270
make node, take full backup, stop it in the middle,
6371
kill process so no cleanup is done - pid file is in place,
@@ -89,18 +97,105 @@ def test_locking_running_2(self):
8997
self.AssertTrue(False, 'Failed to hit breakpoint')
9098

9199
gdb._execute('signal SIGKILL')
92-
gdb.continue_execution_until_running()
100+
gdb.continue_execution_until_error()
93101

94102
self.assertEqual(
95103
'OK', self.show_pb(backup_dir, 'node')[0]['status'])
96104

97105
self.assertEqual(
98106
'RUNNING', self.show_pb(backup_dir, 'node')[1]['status'])
99107

108+
backup_id = self.show_pb(backup_dir, 'node')[1]['id']
109+
100110
try:
101111
self.validate_pb(backup_dir)
102-
except:
103-
pass
112+
self.assertEqual(
113+
1, 0,
114+
"Expecting Error because RUNNING backup is no longer active.\n "
115+
"Output: {0} \n CMD: {1}".format(
116+
repr(self.output), self.cmd))
117+
except ProbackupException as e:
118+
self.assertTrue(
119+
"which used backup {0} no longer exists".format(
120+
backup_id) in e.message and
121+
"Backup {0} has status RUNNING, change it "
122+
"to ERROR and skip validation".format(
123+
backup_id) in e.message and
124+
"WARNING: Some backups are not valid" in
125+
e.message,
126+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
127+
repr(e.message), self.cmd))
128+
129+
self.assertEqual(
130+
'OK', self.show_pb(backup_dir, 'node')[0]['status'])
131+
132+
self.assertEqual(
133+
'ERROR', self.show_pb(backup_dir, 'node')[1]['status'])
134+
135+
# Clean after yourself
136+
self.del_test_dir(module_name, fname)
137+
138+
def test_locking_running_validate_2_specific_id(self):
139+
"""
140+
make node, take full backup, stop it in the middle,
141+
kill process so no cleanup is done - pid file is in place,
142+
run validate on this specific backup,
143+
expect it to not successfully executed,
144+
RUNNING backup with pid file AND without active pid is legal,
145+
but his status must be changed to ERROR and pid file is deleted
146+
"""
147+
fname = self.id().split('.')[3]
148+
node = self.make_simple_node(
149+
base_dir=os.path.join(module_name, fname, 'node'),
150+
initdb_params=['--data-checksums'],
151+
pg_options={'wal_level': 'replica'})
152+
153+
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
154+
self.init_pb(backup_dir)
155+
self.add_instance(backup_dir, 'node', node)
156+
self.set_archiving(backup_dir, 'node', node)
157+
node.slow_start()
158+
159+
self.backup_node(backup_dir, 'node', node)
160+
161+
gdb = self.backup_node(
162+
backup_dir, 'node', node, gdb=True)
163+
164+
gdb.set_breakpoint('copy_file')
165+
gdb.run_until_break()
166+
167+
if gdb.continue_execution_until_break(20) != 'breakpoint-hit':
168+
self.AssertTrue(False, 'Failed to hit breakpoint')
169+
170+
gdb._execute('signal SIGKILL')
171+
gdb.continue_execution_until_error()
172+
173+
self.assertEqual(
174+
'OK', self.show_pb(backup_dir, 'node')[0]['status'])
175+
176+
self.assertEqual(
177+
'RUNNING', self.show_pb(backup_dir, 'node')[1]['status'])
178+
179+
backup_id = self.show_pb(backup_dir, 'node')[1]['id']
180+
181+
try:
182+
self.validate_pb(backup_dir, 'node', backup_id)
183+
self.assertEqual(
184+
1, 0,
185+
"Expecting Error because RUNNING backup is no longer active.\n "
186+
"Output: {0} \n CMD: {1}".format(
187+
repr(self.output), self.cmd))
188+
except ProbackupException as e:
189+
self.assertTrue(
190+
"which used backup {0} no longer exists".format(
191+
backup_id) in e.message and
192+
"Backup {0} has status RUNNING, change it "
193+
"to ERROR and skip validation".format(
194+
backup_id) in e.message and
195+
"WARNING: Some backups are not valid" in
196+
e.message,
197+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
198+
repr(e.message), self.cmd))
104199

105200
self.assertEqual(
106201
'OK', self.show_pb(backup_dir, 'node')[0]['status'])
@@ -143,7 +238,7 @@ def test_locking_running_3(self):
143238
self.AssertTrue(False, 'Failed to hit breakpoint')
144239

145240
gdb._execute('signal SIGKILL')
146-
gdb.continue_execution_until_running()
241+
gdb.continue_execution_until_error()
147242

148243
self.assertEqual(
149244
'OK', self.show_pb(backup_dir, 'node')[0]['status'])
@@ -158,8 +253,20 @@ def test_locking_running_3(self):
158253

159254
try:
160255
self.validate_pb(backup_dir)
161-
except:
162-
pass
256+
self.assertEqual(
257+
1, 0,
258+
"Expecting Error because RUNNING backup is no longer active.\n "
259+
"Output: {0} \n CMD: {1}".format(
260+
repr(self.output), self.cmd))
261+
except ProbackupException as e:
262+
self.assertTrue(
263+
"Backup {0} has status RUNNING, change it "
264+
"to ERROR and skip validation".format(
265+
backup_id) in e.message and
266+
"WARNING: Some backups are not valid" in
267+
e.message,
268+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
269+
repr(e.message), self.cmd))
163270

164271
self.assertEqual(
165272
'OK', self.show_pb(backup_dir, 'node')[0]['status'])

0 commit comments

Comments
 (0)