Skip to content

Commit 2bbecfd

Browse files
committed
tests: added test_validate_instance_with_several_corrupt_backups and test_validate_instance_with_several_corrupt_backups_interrupt
1 parent 931e0a4 commit 2bbecfd

File tree

1 file changed

+198
-0
lines changed

1 file changed

+198
-0
lines changed

tests/validate.py

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,204 @@ def test_validate_specific_target_corrupted_intermediate_backups(self):
982982
# Clean after yourself
983983
self.del_test_dir(module_name, fname)
984984

985+
# @unittest.skip("skip")
986+
def test_validate_instance_with_several_corrupt_backups(self):
987+
"""
988+
make archive node, take FULL1, PAGE1_1, FULL2, PAGE2_1 backups, FULL3
989+
corrupt file in FULL and FULL2 and run validate on instance,
990+
expect FULL1 to gain status CORRUPT, PAGE1_1 to gain status ORPHAN
991+
FULL2 to gain status CORRUPT, PAGE2_1 to gain status ORPHAN
992+
"""
993+
fname = self.id().split('.')[3]
994+
node = self.make_simple_node(
995+
base_dir=os.path.join(module_name, fname, 'node'),
996+
initdb_params=['--data-checksums'])
997+
998+
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
999+
self.init_pb(backup_dir)
1000+
self.add_instance(backup_dir, 'node', node)
1001+
self.set_archiving(backup_dir, 'node', node)
1002+
node.slow_start()
1003+
1004+
node.safe_psql(
1005+
"postgres",
1006+
"create table t_heap as select generate_series(0,1) i")
1007+
# FULL1
1008+
backup_id_1 = self.backup_node(
1009+
backup_dir, 'node', node, options=['--no-validate'])
1010+
1011+
# FULL2
1012+
backup_id_2 = self.backup_node(backup_dir, 'node', node)
1013+
rel_path = node.safe_psql(
1014+
"postgres",
1015+
"select pg_relation_filepath('t_heap')").decode('utf-8').rstrip()
1016+
1017+
node.safe_psql(
1018+
"postgres",
1019+
"insert into t_heap values(2)")
1020+
1021+
backup_id_3 = self.backup_node(
1022+
backup_dir, 'node', node, backup_type='page')
1023+
1024+
# FULL3
1025+
backup_id_4 = self.backup_node(backup_dir, 'node', node)
1026+
1027+
node.safe_psql(
1028+
"postgres",
1029+
"insert into t_heap values(3)")
1030+
1031+
backup_id_5 = self.backup_node(
1032+
backup_dir, 'node', node, backup_type='page')
1033+
1034+
# FULL4
1035+
backup_id_6 = self.backup_node(
1036+
backup_dir, 'node', node, options=['--no-validate'])
1037+
1038+
# Corrupt some files in FULL2 and FULL3 backup
1039+
os.remove(os.path.join(
1040+
backup_dir, 'backups', 'node', backup_id_2,
1041+
'database', rel_path))
1042+
os.remove(os.path.join(
1043+
backup_dir, 'backups', 'node', backup_id_4,
1044+
'database', rel_path))
1045+
1046+
# Validate Instance
1047+
try:
1048+
self.validate_pb(backup_dir, 'node', options=["-j", "4", "--log-level-file=LOG"])
1049+
self.assertEqual(
1050+
1, 0,
1051+
"Expecting Error because of data files corruption.\n "
1052+
"Output: {0} \n CMD: {1}".format(
1053+
repr(self.output), self.cmd))
1054+
except ProbackupException as e:
1055+
self.assertTrue(
1056+
"INFO: Validate backups of the instance 'node'" in e.message,
1057+
"\n Unexpected Error Message: {0}\n "
1058+
"CMD: {1}".format(repr(e.message), self.cmd))
1059+
self.assertTrue(
1060+
'WARNING: Some backups are not valid' in e.message,
1061+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
1062+
repr(e.message), self.cmd))
1063+
1064+
self.assertEqual(
1065+
'OK', self.show_pb(backup_dir, 'node', backup_id_1)['status'],
1066+
'Backup STATUS should be "OK"')
1067+
self.assertEqual(
1068+
'CORRUPT', self.show_pb(backup_dir, 'node', backup_id_2)['status'],
1069+
'Backup STATUS should be "CORRUPT"')
1070+
self.assertEqual(
1071+
'ORPHAN', self.show_pb(backup_dir, 'node', backup_id_3)['status'],
1072+
'Backup STATUS should be "ORPHAN"')
1073+
self.assertEqual(
1074+
'CORRUPT', self.show_pb(backup_dir, 'node', backup_id_4)['status'],
1075+
'Backup STATUS should be "CORRUPT"')
1076+
self.assertEqual(
1077+
'ORPHAN', self.show_pb(backup_dir, 'node', backup_id_5)['status'],
1078+
'Backup STATUS should be "ORPHAN"')
1079+
self.assertEqual(
1080+
'OK', self.show_pb(backup_dir, 'node', backup_id_6)['status'],
1081+
'Backup STATUS should be "OK"')
1082+
1083+
# Clean after yourself
1084+
self.del_test_dir(module_name, fname)
1085+
1086+
# @unittest.skip("skip")
1087+
def test_validate_instance_with_several_corrupt_backups_interrupt(self):
1088+
"""
1089+
check that interrupt during validation is handled correctly
1090+
"""
1091+
fname = self.id().split('.')[3]q
1092+
node = self.make_simple_node(
1093+
base_dir=os.path.join(module_name, fname, 'node'),
1094+
initdb_params=['--data-checksums'])
1095+
1096+
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
1097+
self.init_pb(backup_dir)
1098+
self.add_instance(backup_dir, 'node', node)
1099+
self.set_archiving(backup_dir, 'node', node)
1100+
node.slow_start()
1101+
1102+
node.safe_psql(
1103+
"postgres",
1104+
"create table t_heap as select generate_series(0,1) i")
1105+
# FULL1
1106+
backup_id_1 = self.backup_node(
1107+
backup_dir, 'node', node, options=['--no-validate'])
1108+
1109+
# FULL2
1110+
backup_id_2 = self.backup_node(backup_dir, 'node', node)
1111+
rel_path = node.safe_psql(
1112+
"postgres",
1113+
"select pg_relation_filepath('t_heap')").decode('utf-8').rstrip()
1114+
1115+
node.safe_psql(
1116+
"postgres",
1117+
"insert into t_heap values(2)")
1118+
1119+
backup_id_3 = self.backup_node(
1120+
backup_dir, 'node', node, backup_type='page')
1121+
1122+
# FULL3
1123+
backup_id_4 = self.backup_node(backup_dir, 'node', node)
1124+
1125+
node.safe_psql(
1126+
"postgres",
1127+
"insert into t_heap values(3)")
1128+
1129+
backup_id_5 = self.backup_node(
1130+
backup_dir, 'node', node, backup_type='page')
1131+
1132+
# FULL4
1133+
backup_id_6 = self.backup_node(
1134+
backup_dir, 'node', node, options=['--no-validate'])
1135+
1136+
# Corrupt some files in FULL2 and FULL3 backup
1137+
os.remove(os.path.join(
1138+
backup_dir, 'backups', 'node', backup_id_1,
1139+
'database', rel_path))
1140+
os.remove(os.path.join(
1141+
backup_dir, 'backups', 'node', backup_id_3,
1142+
'database', rel_path))
1143+
1144+
# Validate Instance
1145+
gdb = self.validate_pb(
1146+
backup_dir, 'node', options=["-j", "4", "--log-level-file=LOG"], gdb=True)
1147+
1148+
gdb.set_breakpoint('validate_file_pages')
1149+
gdb.run_until_break()
1150+
gdb.continue_execution_until_break()
1151+
gdb.remove_all_breakpoints()
1152+
gdb._execute('signal SIGINT')
1153+
gdb.continue_execution_until_error()
1154+
1155+
self.assertEqual(
1156+
'DONE', self.show_pb(backup_dir, 'node', backup_id_1)['status'],
1157+
'Backup STATUS should be "OK"')
1158+
self.assertEqual(
1159+
'OK', self.show_pb(backup_dir, 'node', backup_id_2)['status'],
1160+
'Backup STATUS should be "OK"')
1161+
self.assertEqual(
1162+
'OK', self.show_pb(backup_dir, 'node', backup_id_3)['status'],
1163+
'Backup STATUS should be "CORRUPT"')
1164+
self.assertEqual(
1165+
'OK', self.show_pb(backup_dir, 'node', backup_id_4)['status'],
1166+
'Backup STATUS should be "ORPHAN"')
1167+
self.assertEqual(
1168+
'OK', self.show_pb(backup_dir, 'node', backup_id_5)['status'],
1169+
'Backup STATUS should be "OK"')
1170+
self.assertEqual(
1171+
'DONE', self.show_pb(backup_dir, 'node', backup_id_6)['status'],
1172+
'Backup STATUS should be "OK"')
1173+
1174+
log_file = os.path.join(backup_dir, 'log', 'pg_probackup.log')
1175+
with open(log_file, 'r') as f:
1176+
log_content = f.read()
1177+
self.assertNotIn(
1178+
'Interrupted while locking backup', log_content)
1179+
1180+
# Clean after yourself
1181+
self.del_test_dir(module_name, fname)
1182+
9851183
# @unittest.skip("skip")
9861184
def test_validate_instance_with_corrupted_page(self):
9871185
"""

0 commit comments

Comments
 (0)