def test_delete_backup(self, mock_available_backups, tmpdir, caplog): """ Simple test for the deletion of a backup. We want to test the behaviour of the delete_backup method """ # Setup of the test backup_manager backup_manager = build_backup_manager() backup_manager.server.config.name = 'TestServer' backup_manager.server.config.barman_lock_directory = tmpdir.strpath backup_manager.server.config.backup_options = [] # Create a fake backup directory inside tmpdir (old format) base_dir = tmpdir.mkdir('base') backup_dir = base_dir.mkdir('fake_backup_id') pg_data = backup_dir.mkdir('pgdata') pg_data_v2 = backup_dir.mkdir('data') wal_dir = tmpdir.mkdir('wals') wal_history_file02 = wal_dir.join('00000002.history') wal_history_file03 = wal_dir.join('00000003.history') wal_history_file04 = wal_dir.join('00000004.history') wal_history_file02.write('1\t0/2000028\tat restore point "myrp"\n') wal_history_file03.write('1\t0/2000028\tat restore point "myrp"\n') wal_history_file04.write('1\t0/2000028\tat restore point "myrp"\n') wal_history_file04.write('2\t0/3000028\tunknown\n') wal_file = wal_dir.join('0000000100000000/000000010000000000000001') wal_file.ensure() xlog_db = wal_dir.join('xlog.db') xlog_db.write( '000000010000000000000001\t42\t43\tNone\n' '00000002.history\t42\t43\tNone\n' '00000003.history\t42\t43\tNone\n' '00000004.history\t42\t43\tNone\n') backup_manager.server.xlogdb.return_value.__enter__.return_value = ( xlog_db.open()) backup_manager.server.config.basebackups_directory = base_dir.strpath backup_manager.server.config.wals_directory = wal_dir.strpath # The following tablespaces are defined in the default backup info # generated by build_test_backup_info b_info = build_test_backup_info( backup_id='fake_backup_id', server=backup_manager.server, ) # Make sure we are not trying to delete any WAL file, # just by having a previous backup b_pre_info = build_test_backup_info( backup_id='fake_backup', server=backup_manager.server, ) mock_available_backups.return_value = { "fake_backup": b_pre_info, "fake_backup_id": b_info, } # Test 1: minimum redundancy not satisfied caplog_reset(caplog) backup_manager.server.config.minimum_redundancy = 2 b_info.set_attribute('backup_version', 1) build_backup_directories(b_info) backup_manager.delete_backup(b_info) assert 'WARNING Skipping delete of backup ' in caplog.text assert 'ERROR' not in caplog.text assert os.path.exists(pg_data.strpath) assert not os.path.exists(pg_data_v2.strpath) assert os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath) # Test 2: normal delete expecting no errors (old format) caplog_reset(caplog) backup_manager.server.config.minimum_redundancy = 1 b_info.set_attribute('backup_version', 1) build_backup_directories(b_info) backup_manager.delete_backup(b_info) # the backup must not exists on disk anymore assert 'WARNING' not in caplog.text assert 'ERROR' not in caplog.text assert not os.path.exists(pg_data.strpath) assert not os.path.exists(pg_data_v2.strpath) assert os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath) # Test 3: delete the backup again, expect a failure in log caplog_reset(caplog) backup_manager.delete_backup(b_info) assert 'ERROR Failure deleting backup fake_backup_id' in caplog.text assert not os.path.exists(pg_data.strpath) assert not os.path.exists(pg_data_v2.strpath) assert os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath) # Test 4: normal delete expecting no errors (new format) caplog_reset(caplog) b_info.set_attribute('backup_version', 2) build_backup_directories(b_info) backup_manager.delete_backup(b_info) assert 'WARNING' not in caplog.text assert 'ERROR' not in caplog.text assert not os.path.exists(pg_data.strpath) assert not os.path.exists(pg_data_v2.strpath) assert os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath) # Test 5: normal delete of first backup no errors and no skip # removing one of the two backups present (new format) # and all the previous wal caplog_reset(caplog) b_pre_info.set_attribute('backup_version', 2) build_backup_directories(b_pre_info) backup_manager.delete_backup(b_pre_info) assert 'WARNING' not in caplog.text assert 'ERROR' not in caplog.text assert not os.path.exists(pg_data.strpath) assert not os.path.exists(pg_data_v2.strpath) assert not os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath) # Test 6: normal delete of first backup no errors and no skip # removing one of the two backups present (new format) # the previous wal is retained as on a different timeline caplog_reset(caplog) wal_file.ensure() b_pre_info.set_attribute('timeline', 2) b_pre_info.set_attribute('backup_version', 2) build_backup_directories(b_pre_info) backup_manager.delete_backup(b_pre_info) assert 'WARNING' not in caplog.text assert 'ERROR' not in caplog.text assert not os.path.exists(pg_data.strpath) assert not os.path.exists(pg_data_v2.strpath) assert os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath) # Test 7: simulate an error deleting the the backup. with patch('barman.backup.BackupManager.delete_backup_data')\ as mock_delete_data: caplog_reset(caplog) # We force delete_pgdata method to raise an exception. mock_delete_data.side_effect = OSError('TestError') wal_file.ensure() b_pre_info.set_attribute('backup_version', 2) build_backup_directories(b_pre_info) backup_manager.delete_backup(b_info) assert 'TestError' in caplog.text assert os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath)
def test_delete_backup(self, mock_available_backups, tmpdir, caplog): """ Simple test for the deletion of a backup. We want to test the behaviour of the delete_backup method """ # Setup of the test backup_manager backup_manager = build_backup_manager() backup_manager.server.config.name = 'TestServer' backup_manager.server.config.barman_lock_directory = tmpdir.strpath backup_manager.server.config.backup_options = [] # Create a fake backup directory inside tmpdir (old format) base_dir = tmpdir.mkdir('base') backup_dir = base_dir.mkdir('fake_backup_id') pg_data = backup_dir.mkdir('pgdata') pg_data_v2 = backup_dir.mkdir('data') wal_dir = tmpdir.mkdir('wals') wal_history_file02 = wal_dir.join('00000002.history') wal_history_file03 = wal_dir.join('00000003.history') wal_history_file04 = wal_dir.join('00000004.history') wal_history_file02.write('1\t0/2000028\tat restore point "myrp"\n') wal_history_file03.write('1\t0/2000028\tat restore point "myrp"\n') wal_history_file04.write('1\t0/2000028\tat restore point "myrp"\n') wal_history_file04.write('2\t0/3000028\tunknown\n') wal_file = wal_dir.join('0000000100000000/000000010000000000000001') wal_file.ensure() xlog_db = wal_dir.join('xlog.db') xlog_db.write( '000000010000000000000001\t42\t43\tNone\n' '00000002.history\t42\t43\tNone\n' '00000003.history\t42\t43\tNone\n' '00000004.history\t42\t43\tNone\n') backup_manager.server.xlogdb.return_value.__enter__.return_value = ( xlog_db.open()) backup_manager.server.config.basebackups_directory = base_dir.strpath backup_manager.server.config.wals_directory = wal_dir.strpath # The following tablespaces are defined in the default backup info # generated by build_test_backup_info b_info = build_test_backup_info( backup_id='fake_backup_id', server=backup_manager.server, ) # Make sure we are not trying to delete any WAL file, # just by having a previous backup b_pre_info = build_test_backup_info( backup_id='fake_backup', server=backup_manager.server, ) mock_available_backups.return_value = { "fake_backup": b_pre_info, "fake_backup_id": b_info, } # Test 1: minimum redundancy not satisfied caplog_reset(caplog) backup_manager.server.config.minimum_redundancy = 2 b_info.set_attribute('backup_version', 1) build_backup_directories(b_info) backup_manager.delete_backup(b_info) assert 'WARNING Skipping delete of backup ' in caplog.text assert 'ERROR' not in caplog.text assert os.path.exists(pg_data.strpath) assert not os.path.exists(pg_data_v2.strpath) assert os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath) # Test 2: normal delete expecting no errors (old format) caplog_reset(caplog) backup_manager.server.config.minimum_redundancy = 1 b_info.set_attribute('backup_version', 1) build_backup_directories(b_info) backup_manager.delete_backup(b_info) # the backup must not exists on disk anymore assert 'WARNING' not in caplog.text assert 'ERROR' not in caplog.text assert not os.path.exists(pg_data.strpath) assert not os.path.exists(pg_data_v2.strpath) assert os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath) # Test 3: delete the backup again, expect a failure in log caplog_reset(caplog) backup_manager.delete_backup(b_info) assert 'ERROR Failure deleting backup fake_backup_id' in caplog.text assert not os.path.exists(pg_data.strpath) assert not os.path.exists(pg_data_v2.strpath) assert os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath) # Test 4: normal delete expecting no errors (new format) caplog_reset(caplog) b_info.set_attribute('backup_version', 2) build_backup_directories(b_info) backup_manager.delete_backup(b_info) assert 'WARNING' not in caplog.text assert 'ERROR' not in caplog.text assert not os.path.exists(pg_data.strpath) assert not os.path.exists(pg_data_v2.strpath) assert os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath) # Test 5: normal delete of first backup no errors and no skip # removing one of the two backups present (new format) # and all the previous wal caplog_reset(caplog) b_pre_info.set_attribute('backup_version', 2) build_backup_directories(b_pre_info) backup_manager.delete_backup(b_pre_info) assert 'WARNING' not in caplog.text assert 'ERROR' not in caplog.text assert not os.path.exists(pg_data.strpath) assert not os.path.exists(pg_data_v2.strpath) assert not os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath) # Test 6: normal delete of first backup no errors and no skip # removing one of the two backups present (new format) # the previous wal is retained as on a different timeline caplog_reset(caplog) wal_file.ensure() b_pre_info.set_attribute('timeline', 2) b_pre_info.set_attribute('backup_version', 2) build_backup_directories(b_pre_info) backup_manager.delete_backup(b_pre_info) assert 'WARNING' not in caplog.text assert 'ERROR' not in caplog.text assert not os.path.exists(pg_data.strpath) assert not os.path.exists(pg_data_v2.strpath) assert os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath) # Test 7: simulate an error deleting the the backup. with patch('barman.backup.BackupManager.delete_backup_data')\ as mock_delete_data: caplog_reset(caplog) # We force delete_pgdata method to raise an exception. mock_delete_data.side_effect = OSError('TestError') wal_file.ensure() b_pre_info.set_attribute('backup_version', 2) build_backup_directories(b_pre_info) backup_manager.delete_backup(b_info) assert 'TestError' in caplog.text assert os.path.exists(wal_file.strpath) assert os.path.exists(wal_history_file02.strpath) assert os.path.exists(wal_history_file03.strpath) assert os.path.exists(wal_history_file04.strpath)