def test_backup_all(self): # Create the source directory. with TemporaryDirectory() as source_path: build_files_stage_1(source_path) # Create the target directory. with TemporaryDirectory() as target_path: configuration = Configuration('Foo', verbose=True) configuration.notifier = Mock(Notifier) configuration.source = PathSource(configuration.logger, configuration.notifier, source_path + '/') configuration.target = PathTarget(configuration.logger, configuration.notifier, target_path) # Back up the first time. result = backup(configuration) self.assertTrue(result) assert_paths_identical(self, source_path, os.path.join(target_path, 'latest')) real_snapshot_1_path = subprocess.check_output( ['readlink', '-f', 'latest'], cwd=target_path).decode('utf-8').strip() # Sleep for two seconds, so we are (hopefully) absolutely sure the time-based snapshot name generator # will not generate identical names for all snapshots. time.sleep(2) result = backup(configuration) self.assertTrue(result) assert_paths_identical(self, os.path.join(target_path, 'latest'), source_path) real_snapshot_2_path = subprocess.check_output( ['readlink', '-f', 'latest'], cwd=target_path).decode('utf-8').strip() # Ensure the previous snapshot has not changed. assert_paths_identical(self, real_snapshot_1_path, source_path) # Sleep for two seconds, so we are (hopefully) absolutely sure the time-based snapshot name generator # will not generate identical names for all snapshots. time.sleep(2) # Change the source data and create another snapshot. Confirm the first two snapshots remain untouched, # and only the new one contains the changes. build_files_stage_2(source_path) result = backup(configuration) self.assertTrue(result) assert_paths_identical(self, os.path.join(target_path, 'latest'), source_path) # Ensure the changes made to the source did not affect the previous snapshots. with self.assertRaises(AssertionError): assert_paths_identical(self, real_snapshot_1_path, source_path) with self.assertRaises(AssertionError): assert_paths_identical(self, real_snapshot_2_path, source_path)
def test_backup_with_file_path(self): path = 'sub/some.file.in.subdirectory' # Create the source directory. with TemporaryDirectory() as source_path: build_files_stage_1(source_path) # Create the target directory. with TemporaryDirectory() as target_path: configuration = Configuration('Foo', verbose=True) configuration.notifier = Mock(Notifier) configuration.source = PathSource(configuration.logger, configuration.notifier, source_path + '/') configuration.target = PathTarget(configuration.logger, configuration.notifier, target_path) # Back up the first time. result = backup(configuration, path) self.assertTrue(result) real_snapshot_1_path = subprocess.check_output( ['readlink', '-f', 'latest'], cwd=target_path).decode('utf-8').strip() with self.assertRaises(AssertionError): assert_paths_identical(self, source_path, real_snapshot_1_path) assert_paths_identical( self, os.path.join(source_path, path), os.path.join(real_snapshot_1_path, path)) # Sleep for two seconds, so we are (hopefully) absolutely sure the time-based snapshot name generator # will not generate identical names for all snapshots. time.sleep(2) result = backup(configuration, path) self.assertTrue(result) real_snapshot_2_path = subprocess.check_output( ['readlink', '-f', 'latest'], cwd=target_path).decode('utf-8').strip() with self.assertRaises(AssertionError): assert_paths_identical(self, source_path, real_snapshot_2_path) assert_paths_identical( self, os.path.join(source_path, path), os.path.join(real_snapshot_2_path, path)) # Ensure the previous snapshot has not changed. with self.assertRaises(AssertionError): assert_paths_identical(self, source_path, real_snapshot_1_path) assert_paths_identical( self, os.path.join(real_snapshot_1_path, path), os.path.join(source_path, path))
def add_backup_command_to_parser(parser): """Add the back-up command to a parser. :param parser: argparse.ArgumentParser :return: argparse.ArgumentParser """ backup_parser = parser.add_parser('backup', help='Starts a back-up.') backup_parser.set_defaults( func=lambda parsed_args: task.backup(parsed_args.configuration)) add_configuration_to_parser(backup_parser) add_path_to_args(backup_parser) return parser
def test_backup_with_unavailable_target(self): # Create the source directory. with TemporaryDirectory() as source_path: # Create the target directory. with TemporaryDirectory() as target_path: configuration = Configuration('Foo', verbose=True) configuration.notifier = Mock(Notifier) configuration.source = PathSource(configuration.logger, configuration.notifier, source_path) configuration.target = PathTarget( configuration.logger, configuration.notifier, target_path + '/NonExistentPath') result = backup(configuration) self.assertFalse(result)
def test_backup_with_subprocess_error(self, m): m.side_effect = subprocess.CalledProcessError(7, '') # Create the source directory. with TemporaryDirectory() as source_path: # Create the target directory. with TemporaryDirectory() as target_path: configuration = Configuration('Foo', verbose=True) configuration.notifier = Mock(Notifier) configuration.source = PathSource(configuration.logger, configuration.notifier, source_path + '/') configuration.target = PathTarget(configuration.logger, configuration.notifier, target_path) result = backup(configuration) self.assertFalse(result)
def test_backup(self): with TemporaryDirectory() as target_path: with TemporaryDirectory() as mirrored_local_source_path: self._container = SshLocationContainer( mount_point=mirrored_local_source_path) self._container.start() build_files_stage_1(mirrored_local_source_path) configuration = Configuration('Foo', verbose=True) configuration.notifier = Mock(Notifier) configuration.source = self._container.source(configuration) configuration.target = PathTarget(configuration.logger, configuration.notifier, target_path) result = backup(configuration) self.assertTrue(result) assert_paths_identical(self, mirrored_local_source_path, os.path.join( target_path, 'latest'))