|
5 | 5 | import subprocess
|
6 | 6 | from sys import exit
|
7 | 7 | import time
|
| 8 | +import hashlib |
8 | 9 |
|
9 | 10 |
|
10 | 11 | module_name = 'validate'
|
@@ -3064,4 +3065,74 @@ def test_validate_with_missing_backup_2(self):
|
3064 | 3065 | # Clean after yourself
|
3065 | 3066 | self.del_test_dir(module_name, fname)
|
3066 | 3067 |
|
| 3068 | + # @unittest.skip("skip") |
| 3069 | + def test_corrupt_pg_control_via_resetxlog(self): |
| 3070 | + """ PGPRO-2096 """ |
| 3071 | + fname = self.id().split('.')[3] |
| 3072 | + node = self.make_simple_node( |
| 3073 | + base_dir="{0}/{1}/node".format(module_name, fname), |
| 3074 | + set_replication=True, |
| 3075 | + initdb_params=['--data-checksums'], |
| 3076 | + pg_options={'wal_level': 'replica', 'max_wal_senders': '2'} |
| 3077 | + ) |
| 3078 | + backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup') |
| 3079 | + self.init_pb(backup_dir) |
| 3080 | + self.add_instance(backup_dir, 'node', node) |
| 3081 | + self.set_archiving(backup_dir, 'node', node) |
| 3082 | + node.start() |
| 3083 | + |
| 3084 | + backup_id = self.backup_node(backup_dir, 'node', node) |
| 3085 | + |
| 3086 | + if self.get_version(node) < 100000: |
| 3087 | + pg_resetxlog_path = self.get_bin_path('pg_resetxlog') |
| 3088 | + wal_dir = 'pg_xlog' |
| 3089 | + else: |
| 3090 | + pg_resetxlog_path = self.get_bin_path('pg_resetwal') |
| 3091 | + wal_dir = 'pg_wal' |
| 3092 | + |
| 3093 | + os.mkdir( |
| 3094 | + os.path.join( |
| 3095 | + backup_dir, 'backups', 'node', backup_id, 'database', wal_dir, 'archive_status')) |
| 3096 | + |
| 3097 | + pg_control_path = os.path.join( |
| 3098 | + backup_dir, 'backups', 'node', |
| 3099 | + backup_id, 'database', 'global', 'pg_control') |
| 3100 | + |
| 3101 | + md5_before = hashlib.md5( |
| 3102 | + open(pg_control_path, 'rb').read()).hexdigest() |
| 3103 | + |
| 3104 | + self.run_binary( |
| 3105 | + [ |
| 3106 | + pg_resetxlog_path, |
| 3107 | + os.path.join(backup_dir, 'backups', 'node', backup_id, 'database'), |
| 3108 | + '-o 42', |
| 3109 | + '-f' |
| 3110 | + ], |
| 3111 | + async=False) |
| 3112 | + |
| 3113 | + md5_after = hashlib.md5( |
| 3114 | + open(pg_control_path, 'rb').read()).hexdigest() |
| 3115 | + |
| 3116 | + if self.verbose: |
| 3117 | + print('\n MD5 BEFORE resetxlog: {0}\n MD5 AFTER resetxlog: {1}'.format( |
| 3118 | + md5_before, md5_after)) |
| 3119 | + |
| 3120 | + # Validate backup |
| 3121 | + try: |
| 3122 | + self.validate_pb(backup_dir, 'node') |
| 3123 | + self.assertEqual( |
| 3124 | + 1, 0, |
| 3125 | + "Expecting Error because of pg_control change.\n " |
| 3126 | + "Output: {0} \n CMD: {1}".format( |
| 3127 | + self.output, self.cmd)) |
| 3128 | + except ProbackupException as e: |
| 3129 | + self.assertIn( |
| 3130 | + 'data files are corrupted', |
| 3131 | + e.message, |
| 3132 | + '\n Unexpected Error Message: {0}\n CMD: {1}'.format( |
| 3133 | + repr(e.message), self.cmd)) |
| 3134 | + |
| 3135 | + # Clean after yourself |
| 3136 | + self.del_test_dir(module_name, fname) |
| 3137 | + |
3067 | 3138 | # validate empty backup list
|
0 commit comments