|
3 | 3 | from .helpers.ptrack_helpers import ProbackupTest, ProbackupException, idx_ptrack |
4 | 4 | from datetime import datetime, timedelta |
5 | 5 | import subprocess |
6 | | -from testgres import QueryException |
| 6 | +from testgres import QueryException, StartNodeException |
7 | 7 | import shutil |
8 | 8 | import sys |
9 | | -import time |
| 9 | +from time import sleep |
10 | 10 | from threading import Thread |
11 | 11 |
|
12 | 12 |
|
@@ -3848,7 +3848,7 @@ def test_ptrack_zero_changes(self): |
3848 | 3848 | self.del_test_dir(module_name, fname) |
3849 | 3849 |
|
3850 | 3850 | # @unittest.skip("skip") |
3851 | | - # @unittest.expectedFailure |
| 3851 | + @unittest.expectedFailure |
3852 | 3852 | def test_ptrack_pg_resetxlog(self): |
3853 | 3853 | fname = self.id().split('.')[3] |
3854 | 3854 | node = self.make_simple_node( |
@@ -4016,28 +4016,115 @@ def test_corrupt_ptrack_map(self): |
4016 | 4016 |
|
4017 | 4017 | node.stop(['-m', 'immediate', '-D', node.data_dir]) |
4018 | 4018 |
|
| 4019 | + ptrack_map = os.path.join(node.data_dir, 'global', 'ptrack.map') |
| 4020 | + ptrack_map_mmap = os.path.join(node.data_dir, 'global', 'ptrack.map.mmap') |
| 4021 | + |
4019 | 4022 | # Let`s do index corruption. ptrack.map, ptrack.map.mmap |
4020 | | - with open(os.path.join(node.data_dir, 'global', 'ptrack.map'), "rb+", 0) as f: |
| 4023 | + with open(ptrack_map, "rb+", 0) as f: |
4021 | 4024 | f.seek(42) |
4022 | 4025 | f.write(b"blablahblahs") |
4023 | 4026 | f.flush() |
4024 | 4027 | f.close |
4025 | 4028 |
|
4026 | | - with open(os.path.join(node.data_dir, 'global', 'ptrack.map.mmap'), "rb+", 0) as f: |
| 4029 | + with open(ptrack_map_mmap, "rb+", 0) as f: |
4027 | 4030 | f.seek(42) |
4028 | 4031 | f.write(b"blablahblahs") |
4029 | 4032 | f.flush() |
4030 | 4033 | f.close |
4031 | 4034 |
|
4032 | 4035 | # os.remove(os.path.join(node.logs_dir, node.pg_log_name)) |
4033 | 4036 |
|
| 4037 | + try: |
| 4038 | + node.slow_start() |
| 4039 | + # we should die here because exception is what we expect to happen |
| 4040 | + self.assertEqual( |
| 4041 | + 1, 0, |
| 4042 | + "Expecting Error because ptrack.map is corrupted" |
| 4043 | + "\n Output: {0} \n CMD: {1}".format( |
| 4044 | + repr(self.output), self.cmd)) |
| 4045 | + except StartNodeException as e: |
| 4046 | + self.assertIn( |
| 4047 | + 'Cannot start node', |
| 4048 | + e.message, |
| 4049 | + '\n Unexpected Error Message: {0}\n' |
| 4050 | + ' CMD: {1}'.format(repr(e.message), self.cmd)) |
| 4051 | + |
| 4052 | + log_file = os.path.join(node.logs_dir, 'postgresql.log') |
| 4053 | + with open(log_file, 'r') as f: |
| 4054 | + log_content = f.read() |
| 4055 | + |
| 4056 | + self.assertIn( |
| 4057 | + 'FATAL: incorrect checksum of file "{0}"'.format(ptrack_map), |
| 4058 | + log_content) |
| 4059 | + |
| 4060 | + self.set_auto_conf(node, {'ptrack_map_size': '0'}) |
| 4061 | + |
| 4062 | + node.slow_start() |
| 4063 | + |
| 4064 | + try: |
| 4065 | + self.backup_node( |
| 4066 | + backup_dir, 'node', node, |
| 4067 | + backup_type='ptrack', options=['--stream']) |
| 4068 | + # we should die here because exception is what we expect to happen |
| 4069 | + self.assertEqual( |
| 4070 | + 1, 0, |
| 4071 | + "Expecting Error because instance ptrack is disabled" |
| 4072 | + "\n Output: {0} \n CMD: {1}".format( |
| 4073 | + repr(self.output), self.cmd)) |
| 4074 | + except ProbackupException as e: |
| 4075 | + self.assertIn( |
| 4076 | + 'ERROR: Ptrack is disabled', |
| 4077 | + e.message, |
| 4078 | + '\n Unexpected Error Message: {0}\n' |
| 4079 | + ' CMD: {1}'.format(repr(e.message), self.cmd)) |
| 4080 | + |
| 4081 | + node.safe_psql( |
| 4082 | + 'postgres', |
| 4083 | + "update t_heap set id = nextval('t_seq'), text = md5(text), " |
| 4084 | + "tsvector = md5(repeat(tsvector::text, 10))::tsvector") |
| 4085 | + |
| 4086 | + node.stop(['-m', 'immediate', '-D', node.data_dir]) |
| 4087 | + |
| 4088 | + self.set_auto_conf(node, {'ptrack_map_size': '32'}) |
| 4089 | + |
4034 | 4090 | node.slow_start() |
4035 | 4091 |
|
| 4092 | + sleep(1) |
| 4093 | + |
| 4094 | + try: |
| 4095 | + self.backup_node( |
| 4096 | + backup_dir, 'node', node, |
| 4097 | + backup_type='ptrack', options=['--stream']) |
| 4098 | + # we should die here because exception is what we expect to happen |
| 4099 | + self.assertEqual( |
| 4100 | + 1, 0, |
| 4101 | + "Expecting Error because ptrack map is from future" |
| 4102 | + "\n Output: {0} \n CMD: {1}".format( |
| 4103 | + repr(self.output), self.cmd)) |
| 4104 | + except ProbackupException as e: |
| 4105 | + self.assertIn( |
| 4106 | + 'ERROR: LSN from ptrack_control', |
| 4107 | + e.message, |
| 4108 | + '\n Unexpected Error Message: {0}\n' |
| 4109 | + ' CMD: {1}'.format(repr(e.message), self.cmd)) |
| 4110 | + |
| 4111 | + sleep(1) |
| 4112 | + |
| 4113 | + self.backup_node( |
| 4114 | + backup_dir, 'node', node, |
| 4115 | + backup_type='delta', options=['--stream']) |
| 4116 | + |
| 4117 | + node.safe_psql( |
| 4118 | + 'postgres', |
| 4119 | + "update t_heap set id = nextval('t_seq'), text = md5(text), " |
| 4120 | + "tsvector = md5(repeat(tsvector::text, 10))::tsvector") |
| 4121 | + |
4036 | 4122 | self.backup_node( |
4037 | 4123 | backup_dir, 'node', node, |
4038 | 4124 | backup_type='ptrack', options=['--stream']) |
4039 | 4125 |
|
4040 | 4126 | pgdata = self.pgdata_content(node.data_dir) |
| 4127 | + |
4041 | 4128 | node.cleanup() |
4042 | 4129 |
|
4043 | 4130 | self.restore_node(backup_dir, 'node', node) |
|
0 commit comments