@@ -3768,6 +3768,202 @@ def test_not_validate_diffenent_pg_version(self):
3768
3768
# Clean after yourself
3769
3769
self .del_test_dir (module_name , fname )
3770
3770
3771
+ # @unittest.expectedFailure
3772
+ # @unittest.skip("skip")
3773
+ def test_validate_corrupt_page_header_map (self ):
3774
+ """
3775
+ Check that corruption in page_header_map is detected
3776
+ """
3777
+ fname = self .id ().split ('.' )[3 ]
3778
+ backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
3779
+ node = self .make_simple_node (
3780
+ base_dir = os .path .join (module_name , fname , 'node' ),
3781
+ set_replication = True ,
3782
+ initdb_params = ['--data-checksums' ])
3783
+
3784
+ self .init_pb (backup_dir )
3785
+ self .add_instance (backup_dir , 'node' , node )
3786
+ node .slow_start ()
3787
+
3788
+ ok_1 = self .backup_node (backup_dir , 'node' , node , options = ['--stream' ])
3789
+
3790
+ # FULL backup
3791
+ backup_id = self .backup_node (
3792
+ backup_dir , 'node' , node , options = ['--stream' ])
3793
+
3794
+ ok_2 = self .backup_node (backup_dir , 'node' , node , options = ['--stream' ])
3795
+
3796
+ page_header_map = os .path .join (
3797
+ backup_dir , 'backups' , 'node' , backup_id , 'page_header_map' )
3798
+
3799
+ # Corrupt tablespace_map file in FULL backup
3800
+ with open (page_header_map , "rb+" , 0 ) as f :
3801
+ f .seek (42 )
3802
+ f .write (b"blah" )
3803
+ f .flush ()
3804
+ f .close
3805
+
3806
+ try :
3807
+ self .validate_pb (backup_dir , 'node' , backup_id = backup_id )
3808
+ self .assertEqual (
3809
+ 1 , 0 ,
3810
+ "Expecting Error because page_header is corrupted.\n "
3811
+ "Output: {0} \n CMD: {1}" .format (
3812
+ self .output , self .cmd ))
3813
+ except ProbackupException as e :
3814
+ self .assertTrue (
3815
+ 'WARNING: An error occured during metadata decompression' in e .message and
3816
+ 'data error' in e .message ,
3817
+ '\n Unexpected Error Message: {0}\n CMD: {1}' .format (
3818
+ repr (e .message ), self .cmd ))
3819
+
3820
+ self .assertIn ("Backup {0} is corrupt" .format (backup_id ), e .message )
3821
+
3822
+ try :
3823
+ self .validate_pb (backup_dir )
3824
+ self .assertEqual (
3825
+ 1 , 0 ,
3826
+ "Expecting Error because page_header is corrupted.\n "
3827
+ "Output: {0} \n CMD: {1}" .format (
3828
+ self .output , self .cmd ))
3829
+ except ProbackupException as e :
3830
+ self .assertTrue (
3831
+ 'WARNING: An error occured during metadata decompression' in e .message and
3832
+ 'data error' in e .message ,
3833
+ '\n Unexpected Error Message: {0}\n CMD: {1}' .format (
3834
+ repr (e .message ), self .cmd ))
3835
+
3836
+ self .assertIn ("INFO: Backup {0} data files are valid" .format (ok_1 ), e .message )
3837
+ self .assertIn ("WARNING: Backup {0} data files are corrupted" .format (backup_id ), e .message )
3838
+ self .assertIn ("INFO: Backup {0} data files are valid" .format (ok_2 ), e .message )
3839
+
3840
+ self .assertIn ("WARNING: Some backups are not valid" , e .message )
3841
+
3842
+ # Clean after yourself
3843
+ self .del_test_dir (module_name , fname , [node ])
3844
+
3845
+ # @unittest.expectedFailure
3846
+ # @unittest.skip("skip")
3847
+ def test_validate_truncated_page_header_map (self ):
3848
+ """
3849
+ Check that corruption in page_header_map is detected
3850
+ """
3851
+ fname = self .id ().split ('.' )[3 ]
3852
+ backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
3853
+ node = self .make_simple_node (
3854
+ base_dir = os .path .join (module_name , fname , 'node' ),
3855
+ set_replication = True ,
3856
+ initdb_params = ['--data-checksums' ])
3857
+
3858
+ self .init_pb (backup_dir )
3859
+ self .add_instance (backup_dir , 'node' , node )
3860
+ node .slow_start ()
3861
+
3862
+ ok_1 = self .backup_node (backup_dir , 'node' , node , options = ['--stream' ])
3863
+
3864
+ # FULL backup
3865
+ backup_id = self .backup_node (
3866
+ backup_dir , 'node' , node , options = ['--stream' ])
3867
+
3868
+ ok_2 = self .backup_node (backup_dir , 'node' , node , options = ['--stream' ])
3869
+
3870
+ page_header_map = os .path .join (
3871
+ backup_dir , 'backups' , 'node' , backup_id , 'page_header_map' )
3872
+
3873
+ # truncate page_header_map file
3874
+ with open (page_header_map , "rb+" , 0 ) as f :
3875
+ f .truncate (121 )
3876
+ f .flush ()
3877
+ f .close
3878
+
3879
+ try :
3880
+ self .validate_pb (backup_dir , 'node' , backup_id = backup_id )
3881
+ self .assertEqual (
3882
+ 1 , 0 ,
3883
+ "Expecting Error because page_header is corrupted.\n "
3884
+ "Output: {0} \n CMD: {1}" .format (
3885
+ self .output , self .cmd ))
3886
+ except ProbackupException as e :
3887
+ self .assertIn (
3888
+ 'ERROR: Backup {0} is corrupt' .format (backup_id ), e .message ,
3889
+ '\n Unexpected Error Message: {0}\n CMD: {1}' .format (
3890
+ repr (e .message ), self .cmd ))
3891
+
3892
+ try :
3893
+ self .validate_pb (backup_dir )
3894
+ self .assertEqual (
3895
+ 1 , 0 ,
3896
+ "Expecting Error because page_header is corrupted.\n "
3897
+ "Output: {0} \n CMD: {1}" .format (
3898
+ self .output , self .cmd ))
3899
+ except ProbackupException as e :
3900
+ self .assertIn ("INFO: Backup {0} data files are valid" .format (ok_1 ), e .message )
3901
+ self .assertIn ("WARNING: Backup {0} data files are corrupted" .format (backup_id ), e .message )
3902
+ self .assertIn ("INFO: Backup {0} data files are valid" .format (ok_2 ), e .message )
3903
+ self .assertIn ("WARNING: Some backups are not valid" , e .message )
3904
+
3905
+ # Clean after yourself
3906
+ self .del_test_dir (module_name , fname , [node ])
3907
+
3908
+ # @unittest.expectedFailure
3909
+ # @unittest.skip("skip")
3910
+ def test_validate_missing_page_header_map (self ):
3911
+ """
3912
+ Check that corruption in page_header_map is detected
3913
+ """
3914
+ fname = self .id ().split ('.' )[3 ]
3915
+ backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
3916
+ node = self .make_simple_node (
3917
+ base_dir = os .path .join (module_name , fname , 'node' ),
3918
+ set_replication = True ,
3919
+ initdb_params = ['--data-checksums' ])
3920
+
3921
+ self .init_pb (backup_dir )
3922
+ self .add_instance (backup_dir , 'node' , node )
3923
+ node .slow_start ()
3924
+
3925
+ ok_1 = self .backup_node (backup_dir , 'node' , node , options = ['--stream' ])
3926
+
3927
+ # FULL backup
3928
+ backup_id = self .backup_node (
3929
+ backup_dir , 'node' , node , options = ['--stream' ])
3930
+
3931
+ ok_2 = self .backup_node (backup_dir , 'node' , node , options = ['--stream' ])
3932
+
3933
+ page_header_map = os .path .join (
3934
+ backup_dir , 'backups' , 'node' , backup_id , 'page_header_map' )
3935
+
3936
+ # unlink page_header_map file
3937
+ os .remove (page_header_map )
3938
+
3939
+ try :
3940
+ self .validate_pb (backup_dir , 'node' , backup_id = backup_id )
3941
+ self .assertEqual (
3942
+ 1 , 0 ,
3943
+ "Expecting Error because page_header is corrupted.\n "
3944
+ "Output: {0} \n CMD: {1}" .format (
3945
+ self .output , self .cmd ))
3946
+ except ProbackupException as e :
3947
+ self .assertIn (
3948
+ 'ERROR: Backup {0} is corrupt' .format (backup_id ), e .message ,
3949
+ '\n Unexpected Error Message: {0}\n CMD: {1}' .format (
3950
+ repr (e .message ), self .cmd ))
3951
+
3952
+ try :
3953
+ self .validate_pb (backup_dir )
3954
+ self .assertEqual (
3955
+ 1 , 0 ,
3956
+ "Expecting Error because page_header is corrupted.\n "
3957
+ "Output: {0} \n CMD: {1}" .format (
3958
+ self .output , self .cmd ))
3959
+ except ProbackupException as e :
3960
+ self .assertIn ("INFO: Backup {0} data files are valid" .format (ok_1 ), e .message )
3961
+ self .assertIn ("WARNING: Backup {0} data files are corrupted" .format (backup_id ), e .message )
3962
+ self .assertIn ("INFO: Backup {0} data files are valid" .format (ok_2 ), e .message )
3963
+ self .assertIn ("WARNING: Some backups are not valid" , e .message )
3964
+
3965
+ # Clean after yourself
3966
+ self .del_test_dir (module_name , fname , [node ])
3771
3967
3772
3968
# validate empty backup list
3773
3969
# page from future during validate
0 commit comments