@@ -3768,6 +3768,202 @@ def test_not_validate_diffenent_pg_version(self):
37683768# Clean after yourself
37693769self .del_test_dir (module_name ,fname )
37703770
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 ])
37713967
37723968# validate empty backup list
37733969# page from future during validate