From 9a80fec91b0de3d2f9508aaaf48d823ca9ff3a7a Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Thu, 17 Jul 2025 23:24:58 -0700 Subject: [PATCH] When running tests, use Ruff for faster and more comprehensive code linting and formatting. --- NEWS | 2 + borgmatic/actions/borg.py | 3 +- borgmatic/actions/break_lock.py | 3 +- borgmatic/actions/change_passphrase.py | 3 +- borgmatic/actions/check.py | 113 ++--- borgmatic/actions/compact.py | 3 +- borgmatic/actions/config/bootstrap.py | 17 +- borgmatic/actions/config/generate.py | 6 +- borgmatic/actions/config/validate.py | 2 +- borgmatic/actions/create.py | 16 +- borgmatic/actions/delete.py | 3 +- borgmatic/actions/export_key.py | 3 +- borgmatic/actions/export_tar.py | 3 +- borgmatic/actions/extract.py | 3 +- borgmatic/actions/import_key.py | 3 +- borgmatic/actions/info.py | 3 +- borgmatic/actions/list.py | 3 +- borgmatic/actions/mount.py | 3 +- borgmatic/actions/pattern.py | 26 +- borgmatic/actions/prune.py | 3 +- borgmatic/actions/recreate.py | 24 +- borgmatic/actions/repo_create.py | 5 +- borgmatic/actions/repo_delete.py | 5 +- borgmatic/actions/repo_info.py | 3 +- borgmatic/actions/repo_list.py | 3 +- borgmatic/actions/restore.py | 47 +- borgmatic/actions/transfer.py | 2 +- borgmatic/borg/borg.py | 14 +- borgmatic/borg/change_passphrase.py | 4 +- borgmatic/borg/check.py | 15 +- borgmatic/borg/compact.py | 2 +- borgmatic/borg/create.py | 51 +- borgmatic/borg/delete.py | 13 +- borgmatic/borg/environment.py | 3 +- borgmatic/borg/export_key.py | 2 +- borgmatic/borg/export_tar.py | 7 +- borgmatic/borg/extract.py | 6 +- borgmatic/borg/flags.py | 34 +- borgmatic/borg/info.py | 5 +- borgmatic/borg/list.py | 23 +- borgmatic/borg/pattern.py | 20 +- borgmatic/borg/recreate.py | 6 +- borgmatic/borg/rename.py | 4 +- borgmatic/borg/repo_create.py | 6 +- borgmatic/borg/repo_delete.py | 14 +- borgmatic/borg/repo_info.py | 20 +- borgmatic/borg/repo_list.py | 30 +- borgmatic/commands/arguments.py | 316 +++++++++---- borgmatic/commands/borgmatic.py | 229 ++++----- borgmatic/commands/completion/actions.py | 8 +- borgmatic/commands/completion/bash.py | 17 +- borgmatic/commands/completion/fish.py | 45 +- borgmatic/commands/completion/flag.py | 2 +- borgmatic/commands/generate_config.py | 4 +- borgmatic/commands/validate_config.py | 4 +- borgmatic/config/arguments.py | 2 +- borgmatic/config/collect.py | 2 +- borgmatic/config/constants.py | 24 +- borgmatic/config/environment.py | 2 +- borgmatic/config/generate.py | 74 +-- borgmatic/config/load.py | 37 +- borgmatic/config/normalize.py | 94 ++-- borgmatic/config/override.py | 30 +- borgmatic/config/paths.py | 16 +- borgmatic/config/schema.py | 14 +- borgmatic/config/validate.py | 23 +- borgmatic/execute.py | 48 +- borgmatic/hooks/command.py | 8 +- borgmatic/hooks/credential/container.py | 3 +- borgmatic/hooks/credential/file.py | 3 +- borgmatic/hooks/credential/parse.py | 5 +- borgmatic/hooks/credential/systemd.py | 6 +- borgmatic/hooks/data_source/bootstrap.py | 27 +- borgmatic/hooks/data_source/btrfs.py | 56 ++- borgmatic/hooks/data_source/dump.py | 4 +- borgmatic/hooks/data_source/lvm.py | 61 ++- borgmatic/hooks/data_source/mariadb.py | 50 +- borgmatic/hooks/data_source/mongodb.py | 42 +- borgmatic/hooks/data_source/mysql.py | 56 ++- borgmatic/hooks/data_source/postgresql.py | 53 ++- borgmatic/hooks/data_source/sqlite.py | 36 +- borgmatic/hooks/data_source/zfs.py | 56 ++- borgmatic/hooks/dispatch.py | 4 +- borgmatic/hooks/monitoring/apprise.py | 16 +- borgmatic/hooks/monitoring/cronhub.py | 8 +- borgmatic/hooks/monitoring/cronitor.py | 8 +- borgmatic/hooks/monitoring/healthchecks.py | 10 +- borgmatic/hooks/monitoring/logs.py | 5 +- borgmatic/hooks/monitoring/loki.py | 10 +- borgmatic/hooks/monitoring/ntfy.py | 24 +- borgmatic/hooks/monitoring/pagerduty.py | 17 +- borgmatic/hooks/monitoring/pushover.py | 20 +- borgmatic/hooks/monitoring/sentry.py | 12 +- borgmatic/hooks/monitoring/uptime_kuma.py | 8 +- borgmatic/hooks/monitoring/zabbix.py | 19 +- borgmatic/logger.py | 74 ++- docs/how-to/develop-on-borgmatic.md | 43 +- pyproject.toml | 92 +++- scripts/run-full-tests | 2 +- test_requirements.txt | 37 +- tests/end-to-end/commands/fake_btrfs.py | 2 +- tests/end-to-end/commands/fake_lsblk.py | 2 +- tests/end-to-end/commands/fake_lvs.py | 6 +- tests/end-to-end/docker-compose.yaml | 2 +- .../hooks/credential/test_systemd.py | 6 +- .../hooks/data_source/test_btrfs.py | 8 +- .../hooks/data_source/test_database.py | 60 ++- .../end-to-end/hooks/data_source/test_lvm.py | 16 +- .../end-to-end/hooks/data_source/test_zfs.py | 6 +- .../hooks/monitoring/test_monitoring.py | 10 +- tests/end-to-end/test_borgmatic.py | 4 +- tests/end-to-end/test_config_flag.py | 10 +- tests/end-to-end/test_environment_variable.py | 2 +- tests/end-to-end/test_generate_config.py | 4 +- tests/end-to-end/test_invalid_flag.py | 6 +- tests/end-to-end/test_override.py | 8 +- tests/end-to-end/test_passcommand.py | 4 +- tests/end-to-end/test_validate_config.py | 2 +- tests/integration/borg/test_commands.py | 23 +- .../commands/completion/test_actions.py | 8 +- tests/integration/commands/test_arguments.py | 73 ++- tests/integration/config/test_generate.py | 8 +- tests/integration/config/test_load.py | 354 +++++++++----- tests/integration/config/test_override.py | 4 +- tests/integration/config/test_validate.py | 82 ++-- .../hooks/monitoring/test_apprise.py | 16 +- .../hooks/monitoring/test_healthchecks.py | 16 +- .../integration/hooks/monitoring/test_loki.py | 22 +- tests/integration/test_execute.py | 62 ++- tests/unit/actions/config/test_bootstrap.py | 98 ++-- tests/unit/actions/test_borg.py | 2 +- tests/unit/actions/test_check.py | 367 ++++++++------- tests/unit/actions/test_compact.py | 4 +- tests/unit/actions/test_create.py | 62 +-- tests/unit/actions/test_delete.py | 4 +- tests/unit/actions/test_info.py | 14 +- tests/unit/actions/test_json.py | 4 +- tests/unit/actions/test_list.py | 17 +- tests/unit/actions/test_pattern.py | 91 ++-- tests/unit/actions/test_prune.py | 12 +- tests/unit/actions/test_recreate.py | 42 +- tests/unit/actions/test_repo_create.py | 2 +- tests/unit/actions/test_repo_delete.py | 4 +- tests/unit/actions/test_repo_info.py | 8 +- tests/unit/actions/test_repo_list.py | 6 +- tests/unit/actions/test_restore.py | 137 +++--- tests/unit/borg/test_borg.py | 6 +- tests/unit/borg/test_change_passphrase.py | 20 +- tests/unit/borg/test_check.py | 80 ++-- tests/unit/borg/test_compact.py | 48 +- tests/unit/borg/test_create.py | 231 ++++----- tests/unit/borg/test_delete.py | 70 +-- tests/unit/borg/test_environment.py | 42 +- tests/unit/borg/test_export_key.py | 7 +- tests/unit/borg/test_export_tar.py | 49 +- tests/unit/borg/test_extract.py | 119 ++--- tests/unit/borg/test_flags.py | 80 ++-- tests/unit/borg/test_import_key.py | 8 +- tests/unit/borg/test_info.py | 111 +++-- tests/unit/borg/test_list.py | 54 ++- tests/unit/borg/test_mount.py | 42 +- tests/unit/borg/test_passcommand.py | 8 +- tests/unit/borg/test_prune.py | 155 ++++--- tests/unit/borg/test_recreate.py | 108 ++--- tests/unit/borg/test_rename.py | 4 +- tests/unit/borg/test_repo_create.py | 94 ++-- tests/unit/borg/test_repo_delete.py | 49 +- tests/unit/borg/test_repo_info.py | 56 +-- tests/unit/borg/test_repo_list.py | 179 +++++-- tests/unit/borg/test_transfer.py | 117 +++-- tests/unit/borg/test_umount.py | 5 +- tests/unit/borg/test_version.py | 6 +- .../unit/commands/completion/test_actions.py | 4 +- tests/unit/commands/completion/test_bash.py | 4 +- tests/unit/commands/completion/test_fish.py | 15 +- tests/unit/commands/test_arguments.py | 169 ++++--- tests/unit/commands/test_borgmatic.py | 438 +++++++++++------- tests/unit/config/test_arguments.py | 20 +- tests/unit/config/test_checks.py | 6 +- tests/unit/config/test_collect.py | 4 +- tests/unit/config/test_environment.py | 28 +- tests/unit/config/test_generate.py | 50 +- tests/unit/config/test_load.py | 13 +- tests/unit/config/test_normalize.py | 28 +- tests/unit/config/test_override.py | 23 +- tests/unit/config/test_paths.py | 66 +-- tests/unit/config/test_schema.py | 24 +- tests/unit/config/test_validate.py | 97 ++-- tests/unit/hooks/credential/test_container.py | 34 +- tests/unit/hooks/credential/test_file.py | 52 ++- tests/unit/hooks/credential/test_keepassxc.py | 78 ++-- tests/unit/hooks/credential/test_systemd.py | 24 +- .../unit/hooks/data_source/test_bootstrap.py | 20 +- tests/unit/hooks/data_source/test_btrfs.py | 396 ++++++++-------- tests/unit/hooks/data_source/test_lvm.py | 318 ++++++++----- tests/unit/hooks/data_source/test_mariadb.py | 248 ++++++---- tests/unit/hooks/data_source/test_mongodb.py | 75 +-- tests/unit/hooks/data_source/test_mysql.py | 233 +++++----- .../unit/hooks/data_source/test_postgresql.py | 147 +++--- tests/unit/hooks/data_source/test_sqlite.py | 38 +- tests/unit/hooks/data_source/test_zfs.py | 186 ++++---- tests/unit/hooks/monitoring/test_apprise.py | 37 +- tests/unit/hooks/monitoring/test_cronhub.py | 19 +- tests/unit/hooks/monitoring/test_cronitor.py | 16 +- .../hooks/monitoring/test_healthchecks.py | 121 +++-- tests/unit/hooks/monitoring/test_logs.py | 4 +- tests/unit/hooks/monitoring/test_loki.py | 6 +- tests/unit/hooks/monitoring/test_ntfy.py | 40 +- tests/unit/hooks/monitoring/test_pagerduty.py | 44 +- tests/unit/hooks/monitoring/test_pushover.py | 36 +- tests/unit/hooks/monitoring/test_sentry.py | 2 +- .../unit/hooks/monitoring/test_uptimekuma.py | 34 +- tests/unit/hooks/monitoring/test_zabbix.py | 65 ++- tests/unit/hooks/test_command.py | 90 ++-- tests/unit/hooks/test_dispatch.py | 113 +++-- tests/unit/test_execute.py | 51 +- tests/unit/test_logger.py | 77 +-- tests/unit/test_signals.py | 2 +- tox.ini | 38 +- 219 files changed, 5691 insertions(+), 3845 deletions(-) diff --git a/NEWS b/NEWS index bdf49ca2..6249cc1e 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ 2.0.8.dev0 * #1118: Fix a bug in which Borg hangs during database backup when different filesystems are in use. + * When running tests, use Ruff for faster and more comprehensive code linting and formatting, + replacing Flake8, Black, isort, etc. 2.0.7 * #1032: Fix a bug in which a Borg archive gets created even when a database hook fails. diff --git a/borgmatic/actions/borg.py b/borgmatic/actions/borg.py index cb9f6e3f..3daaff3f 100644 --- a/borgmatic/actions/borg.py +++ b/borgmatic/actions/borg.py @@ -20,7 +20,8 @@ def run_borg( Run the "borg" action for the given repository. ''' if borg_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, borg_arguments.repository + repository, + borg_arguments.repository, ): logger.info('Running arbitrary Borg command') archive_name = borgmatic.borg.repo_list.resolve_archive_name( diff --git a/borgmatic/actions/break_lock.py b/borgmatic/actions/break_lock.py index 80319a30..5489ff2a 100644 --- a/borgmatic/actions/break_lock.py +++ b/borgmatic/actions/break_lock.py @@ -19,7 +19,8 @@ def run_break_lock( Run the "break-lock" action for the given repository. ''' if break_lock_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, break_lock_arguments.repository + repository, + break_lock_arguments.repository, ): logger.info('Breaking repository and cache locks') borgmatic.borg.break_lock.break_lock( diff --git a/borgmatic/actions/change_passphrase.py b/borgmatic/actions/change_passphrase.py index 6d0ff31c..14d349e1 100644 --- a/borgmatic/actions/change_passphrase.py +++ b/borgmatic/actions/change_passphrase.py @@ -21,7 +21,8 @@ def run_change_passphrase( if ( change_passphrase_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, change_passphrase_arguments.repository + repository, + change_passphrase_arguments.repository, ) ): logger.info('Changing repository passphrase') diff --git a/borgmatic/actions/check.py b/borgmatic/actions/check.py index 795615e1..e0b6d2e9 100644 --- a/borgmatic/actions/check.py +++ b/borgmatic/actions/check.py @@ -1,4 +1,5 @@ import calendar +import contextlib import datetime import hashlib import itertools @@ -55,12 +56,12 @@ def parse_checks(config, only_checks=None): if 'disabled' in checks: logger.warning( - 'The "disabled" value for the "checks" option is deprecated and will be removed from a future release; use "skip_actions" instead' + 'The "disabled" value for the "checks" option is deprecated and will be removed from a future release; use "skip_actions" instead', ) if len(checks) > 1: logger.warning( - 'Multiple checks are configured, but one of them is "disabled"; not running any checks' + 'Multiple checks are configured, but one of them is "disabled"; not running any checks', ) return () @@ -175,7 +176,7 @@ def filter_checks_on_frequency( if calendar.day_name[datetime_now().weekday()] not in days: logger.info( - f"Skipping {check} check due to day of the week; check only runs on {'/'.join(day.title() for day in days)} (use --force to check anyway)" + f"Skipping {check} check due to day of the week; check only runs on {'/'.join(day.title() for day in days)} (use --force to check anyway)", ) filtered_checks.remove(check) continue @@ -193,7 +194,7 @@ def filter_checks_on_frequency( if datetime_now() < check_time + frequency_delta: remaining = check_time + frequency_delta - datetime_now() logger.info( - f'Skipping {check} check due to configured frequency; {remaining} until next check (use --force to check anyway)' + f'Skipping {check} check due to configured frequency; {remaining} until next check (use --force to check anyway)', ) filtered_checks.remove(check) @@ -219,7 +220,7 @@ def make_check_time_path(config, borg_repository_id, check_type, archives_check_ ''' borgmatic_state_directory = borgmatic.config.paths.get_borgmatic_state_directory(config) - if check_type in ('archives', 'data'): + if check_type in {'archives', 'data'}: return os.path.join( borgmatic_state_directory, 'checks', @@ -254,7 +255,7 @@ def read_check_time(path): logger.debug(f'Reading check time from {path}') try: - return datetime.datetime.fromtimestamp(os.stat(path).st_mtime) + return datetime.datetime.fromtimestamp(os.stat(path).st_mtime) # noqa: DTZ006 except FileNotFoundError: return None @@ -285,7 +286,7 @@ def probe_for_check_time(config, borg_repository_id, check, archives_check_id): ( make_check_time_path(config, borg_repository_id, check, archives_check_id), make_check_time_path(config, borg_repository_id, check), - ) + ), ) ) @@ -317,16 +318,17 @@ def upgrade_check_times(config, borg_repository_id): {borgmatic_state_directory}/checks/1234567890/archives/all ''' borgmatic_source_checks_path = os.path.join( - borgmatic.config.paths.get_borgmatic_source_directory(config), 'checks' + borgmatic.config.paths.get_borgmatic_source_directory(config), + 'checks', ) borgmatic_state_path = borgmatic.config.paths.get_borgmatic_state_directory(config) borgmatic_state_checks_path = os.path.join(borgmatic_state_path, 'checks') if os.path.exists(borgmatic_source_checks_path) and not os.path.exists( - borgmatic_state_checks_path + borgmatic_state_checks_path, ): logger.debug( - f'Upgrading archives check times directory from {borgmatic_source_checks_path} to {borgmatic_state_checks_path}' + f'Upgrading archives check times directory from {borgmatic_source_checks_path} to {borgmatic_state_checks_path}', ) os.makedirs(borgmatic_state_path, mode=0o700, exist_ok=True) shutil.move(borgmatic_source_checks_path, borgmatic_state_checks_path) @@ -341,10 +343,8 @@ def upgrade_check_times(config, borg_repository_id): logger.debug(f'Upgrading archives check time file from {old_path} to {new_path}') - try: + with contextlib.suppress(FileNotFoundError): shutil.move(old_path, temporary_path) - except FileNotFoundError: - pass os.mkdir(old_path) shutil.move(temporary_path, new_path) @@ -369,31 +369,29 @@ def collect_spot_check_source_paths( 'use_streaming', config, borgmatic.hooks.dispatch.Hook_type.DATA_SOURCE, - ).values() + ).values(), ) working_directory = borgmatic.config.paths.get_working_directory(config) - (create_flags, create_positional_arguments, pattern_file) = ( - borgmatic.borg.create.make_base_create_command( - dry_run=True, - repository_path=repository['path'], - # Omit "progress" because it interferes with "list_details". - config=dict( - {option: value for option, value in config.items() if option != 'progress'}, - list_details=True, - ), - patterns=borgmatic.actions.pattern.process_patterns( - borgmatic.actions.pattern.collect_patterns(config), - config, - working_directory, - ), - local_borg_version=local_borg_version, - global_arguments=global_arguments, - borgmatic_runtime_directory=borgmatic_runtime_directory, - local_path=local_path, - remote_path=remote_path, - stream_processes=stream_processes, - ) + (create_flags, create_positional_arguments, _) = borgmatic.borg.create.make_base_create_command( + dry_run=True, + repository_path=repository['path'], + # Omit "progress" because it interferes with "list_details". + config=dict( + {option: value for option, value in config.items() if option != 'progress'}, + list_details=True, + ), + patterns=borgmatic.actions.pattern.process_patterns( + borgmatic.actions.pattern.collect_patterns(config), + config, + working_directory, + ), + local_borg_version=local_borg_version, + global_arguments=global_arguments, + borgmatic_runtime_directory=borgmatic_runtime_directory, + local_path=local_path, + remote_path=remote_path, + stream_processes=stream_processes, ) working_directory = borgmatic.config.paths.get_working_directory(config) @@ -409,7 +407,7 @@ def collect_spot_check_source_paths( paths = tuple( path_line.split(' ', 1)[1] for path_line in paths_output.splitlines() - if path_line and path_line.startswith('- ') or path_line.startswith('+ ') + if path_line and path_line.startswith(('- ', '+ ')) ) return tuple( @@ -450,12 +448,12 @@ def collect_spot_check_archive_paths( config, local_borg_version, global_arguments, - path_format='{type} {path}{NUL}', # noqa: FS003 + path_format='{type} {path}{NUL}', local_path=local_path, remote_path=remote_path, ) for (file_type, path) in (line.split(' ', 1),) - if file_type not in (BORG_DIRECTORY_FILE_TYPE, BORG_PIPE_FILE_TYPE) + if file_type not in {BORG_DIRECTORY_FILE_TYPE, BORG_PIPE_FILE_TYPE} if pathlib.Path('borgmatic') not in pathlib.Path(path).parents if pathlib.Path(borgmatic_source_directory.lstrip(os.path.sep)) not in pathlib.Path(path).parents @@ -488,7 +486,8 @@ def compare_spot_check_hashes( # source directories. spot_check_config = next(check for check in config['checks'] if check['name'] == 'spot') sample_count = max( - int(len(source_paths) * (min(spot_check_config['data_sample_percentage'], 100) / 100)), 1 + int(len(source_paths) * (min(spot_check_config['data_sample_percentage'], 100) / 100)), + 1, ) source_sample_paths = tuple(random.SystemRandom().sample(source_paths, sample_count)) working_directory = borgmatic.config.paths.get_working_directory(config) @@ -500,7 +499,7 @@ def compare_spot_check_hashes( if not os.path.islink(full_source_path) } logger.debug( - f'Sampling {sample_count} source paths (~{spot_check_config["data_sample_percentage"]}%) for spot check' + f'Sampling {sample_count} source paths (~{spot_check_config["data_sample_percentage"]}%) for spot check', ) source_sample_paths_iterator = iter(source_sample_paths) @@ -512,7 +511,7 @@ def compare_spot_check_hashes( while True: # Hash each file in the sample paths (if it exists). source_sample_paths_subset = tuple( - itertools.islice(source_sample_paths_iterator, SAMPLE_PATHS_SUBSET_COUNT) + itertools.islice(source_sample_paths_iterator, SAMPLE_PATHS_SUBSET_COUNT), ) if not source_sample_paths_subset: break @@ -539,7 +538,7 @@ def compare_spot_check_hashes( for path in source_sample_paths_subset if path not in hashable_source_sample_path }, - ) + ), ) # Get the hash for each file in the archive. @@ -553,12 +552,12 @@ def compare_spot_check_hashes( local_borg_version, global_arguments, list_paths=source_sample_paths_subset, - path_format='{xxh64} {path}{NUL}', # noqa: FS003 + path_format='{xxh64} {path}{NUL}', local_path=local_path, remote_path=remote_path, ) if line - ) + ), ) # Compare the source hashes with the archive hashes to see how many match. @@ -607,7 +606,7 @@ def spot_check( if spot_check_config['data_tolerance_percentage'] > spot_check_config['data_sample_percentage']: raise ValueError( - 'The data_tolerance_percentage must be less than or equal to the data_sample_percentage' + 'The data_tolerance_percentage must be less than or equal to the data_sample_percentage', ) source_paths = collect_spot_check_source_paths( @@ -652,7 +651,7 @@ def spot_check( ) logger.debug(f'Paths in latest archive but not source paths: {truncated_archive_paths}') raise ValueError( - 'Spot check failed: There are no source paths to compare against the archive' + 'Spot check failed: There are no source paths to compare against the archive', ) # Calculate the percentage delta between the source paths count and the archive paths count, and @@ -660,14 +659,14 @@ def spot_check( count_delta_percentage = abs(len(source_paths) - len(archive_paths)) / len(source_paths) * 100 if count_delta_percentage > spot_check_config['count_tolerance_percentage']: - rootless_source_paths = set(path.lstrip(os.path.sep) for path in source_paths) + rootless_source_paths = {path.lstrip(os.path.sep) for path in source_paths} truncated_exclusive_source_paths = textwrap.shorten( ', '.join(rootless_source_paths - set(archive_paths)) or 'none', width=MAX_SPOT_CHECK_PATHS_LENGTH, placeholder=' ...', ) logger.debug( - f'Paths in source paths but not latest archive: {truncated_exclusive_source_paths}' + f'Paths in source paths but not latest archive: {truncated_exclusive_source_paths}', ) truncated_exclusive_archive_paths = textwrap.shorten( ', '.join(set(archive_paths) - rootless_source_paths) or 'none', @@ -675,10 +674,10 @@ def spot_check( placeholder=' ...', ) logger.debug( - f'Paths in latest archive but not source paths: {truncated_exclusive_archive_paths}' + f'Paths in latest archive but not source paths: {truncated_exclusive_archive_paths}', ) raise ValueError( - f'Spot check failed: {count_delta_percentage:.2f}% file count delta between source paths and latest archive (tolerance is {spot_check_config["count_tolerance_percentage"]}%)' + f'Spot check failed: {count_delta_percentage:.2f}% file count delta between source paths and latest archive (tolerance is {spot_check_config["count_tolerance_percentage"]}%)', ) failing_paths = compare_spot_check_hashes( @@ -704,14 +703,14 @@ def spot_check( placeholder=' ...', ) logger.debug( - f'Source paths with data not matching the latest archive: {truncated_failing_paths}' + f'Source paths with data not matching the latest archive: {truncated_failing_paths}', ) raise ValueError( - f'Spot check failed: {failing_percentage:.2f}% of source paths with data not matching the latest archive (tolerance is {data_tolerance_percentage}%)' + f'Spot check failed: {failing_percentage:.2f}% of source paths with data not matching the latest archive (tolerance is {data_tolerance_percentage}%)', ) logger.info( - f'Spot check passed with a {count_delta_percentage:.2f}% file count delta and a {failing_percentage:.2f}% file data delta' + f'Spot check passed with a {count_delta_percentage:.2f}% file count delta and a {failing_percentage:.2f}% file data delta', ) @@ -731,7 +730,8 @@ def run_check( Raise ValueError if the Borg repository ID cannot be determined. ''' if check_arguments.repository and not borgmatic.config.validate.repositories_match( - repository, check_arguments.repository + repository, + check_arguments.repository, ): return @@ -748,7 +748,10 @@ def run_check( upgrade_check_times(config, repository_id) configured_checks = parse_checks(config, check_arguments.only_checks) archive_filter_flags = borgmatic.borg.check.make_archive_filter_flags( - local_borg_version, config, configured_checks, check_arguments + local_borg_version, + config, + configured_checks, + check_arguments, ) archives_check_id = make_archives_check_id(archive_filter_flags) checks = filter_checks_on_frequency( diff --git a/borgmatic/actions/compact.py b/borgmatic/actions/compact.py index 551c680d..c6be7a5e 100644 --- a/borgmatic/actions/compact.py +++ b/borgmatic/actions/compact.py @@ -23,7 +23,8 @@ def run_compact( Run the "compact" action for the given repository. ''' if compact_arguments.repository and not borgmatic.config.validate.repositories_match( - repository, compact_arguments.repository + repository, + compact_arguments.repository, ): return diff --git a/borgmatic/actions/config/bootstrap.py b/borgmatic/actions/config/bootstrap.py index 520bcb1c..10ee8c56 100644 --- a/borgmatic/actions/config/bootstrap.py +++ b/borgmatic/actions/config/bootstrap.py @@ -36,7 +36,7 @@ def get_config_paths(archive_name, bootstrap_arguments, global_arguments, local_ expected configuration path data. ''' borgmatic_source_directory = borgmatic.config.paths.get_borgmatic_source_directory( - {'borgmatic_source_directory': bootstrap_arguments.borgmatic_source_directory} + {'borgmatic_source_directory': bootstrap_arguments.borgmatic_source_directory}, ) config = make_bootstrap_config(bootstrap_arguments) @@ -52,7 +52,9 @@ def get_config_paths(archive_name, bootstrap_arguments, global_arguments, local_ borgmatic_source_directory, ): borgmatic_manifest_path = 'sh:' + os.path.join( - base_directory, 'bootstrap', 'manifest.json' + base_directory, + 'bootstrap', + 'manifest.json', ) extract_process = borgmatic.borg.extract.extract_archive( @@ -73,21 +75,21 @@ def get_config_paths(archive_name, bootstrap_arguments, global_arguments, local_ break else: raise ValueError( - 'Cannot read configuration paths from archive due to missing bootstrap manifest' + 'Cannot read configuration paths from archive due to missing bootstrap manifest', ) try: manifest_data = json.loads(manifest_json) except json.JSONDecodeError as error: raise ValueError( - f'Cannot read configuration paths from archive due to invalid bootstrap manifest JSON: {error}' + f'Cannot read configuration paths from archive due to invalid bootstrap manifest JSON: {error}', ) try: return manifest_data['config_paths'] except KeyError: raise ValueError( - 'Cannot read configuration paths from archive due to invalid bootstrap manifest' + 'Cannot read configuration paths from archive due to invalid bootstrap manifest', ) @@ -109,7 +111,10 @@ def run_bootstrap(bootstrap_arguments, global_arguments, local_borg_version): remote_path=bootstrap_arguments.remote_path, ) manifest_config_paths = get_config_paths( - archive_name, bootstrap_arguments, global_arguments, local_borg_version + archive_name, + bootstrap_arguments, + global_arguments, + local_borg_version, ) logger.info(f"Bootstrapping config paths: {', '.join(manifest_config_paths)}") diff --git a/borgmatic/actions/config/generate.py b/borgmatic/actions/config/generate.py index 48b9a7dd..199046eb 100644 --- a/borgmatic/actions/config/generate.py +++ b/borgmatic/actions/config/generate.py @@ -19,7 +19,7 @@ def run_generate(generate_arguments, global_arguments): dry_run_label = ' (dry run; not actually writing anything)' if global_arguments.dry_run else '' logger.answer( - f'Generating a configuration file at: {generate_arguments.destination_filename}{dry_run_label}' + f'Generating a configuration file at: {generate_arguments.destination_filename}{dry_run_label}', ) borgmatic.config.generate.generate_sample_configuration( @@ -36,7 +36,7 @@ def run_generate(generate_arguments, global_arguments): Merged in the contents of configuration file at: {generate_arguments.source_filename} To review the changes made, run: - diff --unified {generate_arguments.source_filename} {generate_arguments.destination_filename}''' + diff --unified {generate_arguments.source_filename} {generate_arguments.destination_filename}''', ) logger.answer( @@ -44,5 +44,5 @@ To review the changes made, run: This includes all available configuration options with example values, the few required options as indicated. Please edit the file to suit your needs. -If you ever need help: https://torsion.org/borgmatic/#issues''' +If you ever need help: https://torsion.org/borgmatic/#issues''', ) diff --git a/borgmatic/actions/config/validate.py b/borgmatic/actions/config/validate.py index 2929ccaa..9cc97593 100644 --- a/borgmatic/actions/config/validate.py +++ b/borgmatic/actions/config/validate.py @@ -18,7 +18,7 @@ def run_validate(validate_arguments, configs): borgmatic.logger.add_custom_log_levels() if validate_arguments.show: - for config_path, config in configs.items(): + for config in configs.values(): if len(configs) > 1: logger.answer('---') diff --git a/borgmatic/actions/create.py b/borgmatic/actions/create.py index fb5deae7..97b2ebf8 100644 --- a/borgmatic/actions/create.py +++ b/borgmatic/actions/create.py @@ -30,18 +30,19 @@ def run_create( If create_arguments.json is True, yield the JSON output from creating the archive. ''' if create_arguments.repository and not borgmatic.config.validate.repositories_match( - repository, create_arguments.repository + repository, + create_arguments.repository, ): return if config.get('list_details') and config.get('progress'): raise ValueError( - 'With the create action, only one of --list/--files/list_details and --progress/progress can be used.' + 'With the create action, only one of --list/--files/list_details and --progress/progress can be used.', ) if config.get('list_details') and create_arguments.json: raise ValueError( - 'With the create action, only one of --list/--files/list_details and --json can be used.' + 'With the create action, only one of --list/--files/list_details and --json can be used.', ) logger.info(f'Creating archive{dry_run_label}') @@ -56,7 +57,9 @@ def run_create( global_arguments.dry_run, ) patterns = pattern.process_patterns( - pattern.collect_patterns(config), config, working_directory + pattern.collect_patterns(config), + config, + working_directory, ) active_dumps = borgmatic.hooks.dispatch.call_hooks( 'dump_data_sources', @@ -72,7 +75,10 @@ def run_create( # we could end up with duplicate paths that cause Borg to hang when it tries to read from # the same named pipe twice. patterns = pattern.process_patterns( - patterns, config, working_directory, skip_expand_paths=config_paths + patterns, + config, + working_directory, + skip_expand_paths=config_paths, ) stream_processes = [process for processes in active_dumps.values() for process in processes] diff --git a/borgmatic/actions/delete.py b/borgmatic/actions/delete.py index d4ce5602..c1f0659b 100644 --- a/borgmatic/actions/delete.py +++ b/borgmatic/actions/delete.py @@ -21,7 +21,8 @@ def run_delete( Run the "delete" action for the given repository and archive(s). ''' if delete_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, delete_arguments.repository + repository, + delete_arguments.repository, ): logger.answer('Deleting archives') diff --git a/borgmatic/actions/export_key.py b/borgmatic/actions/export_key.py index 067ff176..1a7b0e53 100644 --- a/borgmatic/actions/export_key.py +++ b/borgmatic/actions/export_key.py @@ -19,7 +19,8 @@ def run_export_key( Run the "key export" action for the given repository. ''' if export_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, export_arguments.repository + repository, + export_arguments.repository, ): logger.info('Exporting repository key') borgmatic.borg.export_key.export_key( diff --git a/borgmatic/actions/export_tar.py b/borgmatic/actions/export_tar.py index f04b06ff..60dbed85 100644 --- a/borgmatic/actions/export_tar.py +++ b/borgmatic/actions/export_tar.py @@ -20,7 +20,8 @@ def run_export_tar( Run the "export-tar" action for the given repository. ''' if export_tar_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, export_tar_arguments.repository + repository, + export_tar_arguments.repository, ): logger.info(f'Exporting archive {export_tar_arguments.archive} as tar file') borgmatic.borg.export_tar.export_tar_archive( diff --git a/borgmatic/actions/extract.py b/borgmatic/actions/extract.py index feaaac81..f967b18b 100644 --- a/borgmatic/actions/extract.py +++ b/borgmatic/actions/extract.py @@ -22,7 +22,8 @@ def run_extract( Run the "extract" action for the given repository. ''' if extract_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, extract_arguments.repository + repository, + extract_arguments.repository, ): logger.info(f'Extracting archive {extract_arguments.archive}') borgmatic.borg.extract.extract_archive( diff --git a/borgmatic/actions/import_key.py b/borgmatic/actions/import_key.py index 42813efa..9ac2be65 100644 --- a/borgmatic/actions/import_key.py +++ b/borgmatic/actions/import_key.py @@ -19,7 +19,8 @@ def run_import_key( Run the "key import" action for the given repository. ''' if import_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, import_arguments.repository + repository, + import_arguments.repository, ): logger.info('Importing repository key') borgmatic.borg.import_key.import_key( diff --git a/borgmatic/actions/info.py b/borgmatic/actions/info.py index 976d487c..7531aa60 100644 --- a/borgmatic/actions/info.py +++ b/borgmatic/actions/info.py @@ -24,7 +24,8 @@ def run_info( If info_arguments.json is True, yield the JSON output from the info for the archive. ''' if info_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, info_arguments.repository + repository, + info_arguments.repository, ): if not info_arguments.json: logger.answer('Displaying archive summary information') diff --git a/borgmatic/actions/list.py b/borgmatic/actions/list.py index 0def72fb..4024b498 100644 --- a/borgmatic/actions/list.py +++ b/borgmatic/actions/list.py @@ -23,7 +23,8 @@ def run_list( If list_arguments.json is True, yield the JSON output from listing the archive. ''' if list_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, list_arguments.repository + repository, + list_arguments.repository, ): if not list_arguments.json: if list_arguments.find_paths: # pragma: no cover diff --git a/borgmatic/actions/mount.py b/borgmatic/actions/mount.py index f7917463..41e548cc 100644 --- a/borgmatic/actions/mount.py +++ b/borgmatic/actions/mount.py @@ -20,7 +20,8 @@ def run_mount( Run the "mount" action for the given repository. ''' if mount_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, mount_arguments.repository + repository, + mount_arguments.repository, ): if mount_arguments.archive: logger.info(f'Mounting archive {mount_arguments.archive}') diff --git a/borgmatic/actions/pattern.py b/borgmatic/actions/pattern.py index 865cb52e..a8a704e0 100644 --- a/borgmatic/actions/pattern.py +++ b/borgmatic/actions/pattern.py @@ -47,7 +47,8 @@ def collect_patterns(config): return ( tuple( borgmatic.borg.pattern.Pattern( - source_directory, source=borgmatic.borg.pattern.Pattern_source.CONFIG + source_directory, + source=borgmatic.borg.pattern.Pattern_source.CONFIG, ) for source_directory in config.get('source_directories', ()) ) @@ -67,7 +68,7 @@ def collect_patterns(config): + tuple( parse_pattern(pattern_line.strip()) for filename in config.get('patterns_from', ()) - for pattern_line in open(filename).readlines() + for pattern_line in open(filename, encoding='utf-8').readlines() if not pattern_line.lstrip().startswith('#') if pattern_line.strip() ) @@ -77,7 +78,7 @@ def collect_patterns(config): borgmatic.borg.pattern.Pattern_style.FNMATCH, ) for filename in config.get('exclude_from', ()) - for exclude_line in open(filename).readlines() + for exclude_line in open(filename, encoding='utf-8').readlines() if not exclude_line.lstrip().startswith('#') if exclude_line.strip() ) @@ -112,9 +113,8 @@ def expand_directory(directory, working_directory): glob_path # If these are equal, that means we didn't add any working directory prefix above. if normalized_directory == expanded_directory - # Remove the working directory prefix that we added above in order to make glob() work. - # We can't use os.path.relpath() here because it collapses any use of Borg's slashdot - # hack. + # Remove the working directory prefix added above in order to make glob() work. We + # can't use os.path.relpath() here because it collapses any use of Borg's slashdot hack. else glob_path.removeprefix(working_directory_prefix) ) for glob_path in glob_paths @@ -161,7 +161,7 @@ def expand_patterns(patterns, working_directory=None, skip_paths=None): ) ) for pattern in patterns - ) + ), ) @@ -180,8 +180,10 @@ def get_existent_path_or_parent(path): try: return next( candidate_path - for candidate_path in (path,) - + tuple(str(parent) for parent in pathlib.PurePath(path).parents) + for candidate_path in ( + path, + *tuple(str(parent) for parent in pathlib.PurePath(path).parents), + ) if os.path.exists(candidate_path) ) except StopIteration: @@ -219,7 +221,7 @@ def device_map_patterns(patterns, working_directory=None): for pattern in patterns for existent_path in ( get_existent_path_or_parent( - os.path.join(working_directory or '', pattern.path.lstrip('^')) + os.path.join(working_directory or '', pattern.path.lstrip('^')), ), ) ) @@ -289,8 +291,8 @@ def process_patterns(patterns, config, working_directory, skip_expand_paths=None patterns, working_directory=working_directory, skip_paths=skip_paths, - ) + ), ), config, - ) + ), ) diff --git a/borgmatic/actions/prune.py b/borgmatic/actions/prune.py index e7caa158..10ea1ff5 100644 --- a/borgmatic/actions/prune.py +++ b/borgmatic/actions/prune.py @@ -22,7 +22,8 @@ def run_prune( Run the "prune" action for the given repository. ''' if prune_arguments.repository and not borgmatic.config.validate.repositories_match( - repository, prune_arguments.repository + repository, + prune_arguments.repository, ): return diff --git a/borgmatic/actions/recreate.py b/borgmatic/actions/recreate.py index f598e87a..94a1b516 100644 --- a/borgmatic/actions/recreate.py +++ b/borgmatic/actions/recreate.py @@ -26,7 +26,8 @@ def run_recreate( Run the "recreate" action for the given repository. ''' if recreate_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, recreate_arguments.repository + repository, + recreate_arguments.repository, ): if recreate_arguments.archive: logger.answer(f'Recreating archive {recreate_arguments.archive}') @@ -35,7 +36,9 @@ def run_recreate( # Collect and process patterns. processed_patterns = process_patterns( - collect_patterns(config), config, borgmatic.config.paths.get_working_directory(config) + collect_patterns(config), + config, + borgmatic.config.paths.get_working_directory(config), ) archive = borgmatic.borg.repo_list.resolve_archive_name( @@ -51,13 +54,13 @@ def run_recreate( if archive and archive.endswith('.recreate'): if recreate_arguments.archive == 'latest': raise ValueError( - f'The latest archive "{archive}" is leftover from a prior recreate. Delete it first or select a different archive.' - ) - else: - raise ValueError( - f'The archive "{recreate_arguments.archive}" is leftover from a prior recreate. Select a different archive.' + f'The latest archive "{archive}" is leftover from a prior recreate. Delete it first or select a different archive.', ) + raise ValueError( + f'The archive "{recreate_arguments.archive}" is leftover from a prior recreate. Select a different archive.', + ) + try: borgmatic.borg.recreate.recreate_archive( repository['path'], @@ -74,11 +77,12 @@ def run_recreate( if error.returncode == BORG_EXIT_CODE_ARCHIVE_ALREADY_EXISTS: if recreate_arguments.target: raise ValueError( - f'The archive "{recreate_arguments.target}" already exists. Delete it first or set a different target archive name.' + f'The archive "{recreate_arguments.target}" already exists. Delete it first or set a different target archive name.', ) - elif archive: + + if archive: raise ValueError( - f'The archive "{archive}.recreate" is leftover from a prior recreate. Delete it first or select a different archive.' + f'The archive "{archive}.recreate" is leftover from a prior recreate. Delete it first or select a different archive.', ) raise diff --git a/borgmatic/actions/repo_create.py b/borgmatic/actions/repo_create.py index 38d35922..125a8e7e 100644 --- a/borgmatic/actions/repo_create.py +++ b/borgmatic/actions/repo_create.py @@ -19,7 +19,8 @@ def run_repo_create( Run the "repo-create" action for the given repository. ''' if repo_create_arguments.repository and not borgmatic.config.validate.repositories_match( - repository, repo_create_arguments.repository + repository, + repo_create_arguments.repository, ): return @@ -29,7 +30,7 @@ def run_repo_create( if not encryption_mode: raise ValueError( - 'With the repo-create action, either the --encryption flag or the repository encryption option is required.' + 'With the repo-create action, either the --encryption flag or the repository encryption option is required.', ) borgmatic.borg.repo_create.create_repository( diff --git a/borgmatic/actions/repo_delete.py b/borgmatic/actions/repo_delete.py index 29227b15..caade146 100644 --- a/borgmatic/actions/repo_delete.py +++ b/borgmatic/actions/repo_delete.py @@ -18,10 +18,11 @@ def run_repo_delete( Run the "repo-delete" action for the given repository. ''' if repo_delete_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, repo_delete_arguments.repository + repository, + repo_delete_arguments.repository, ): logger.answer( - 'Deleting repository' + (' cache' if repo_delete_arguments.cache_only else '') + 'Deleting repository' + (' cache' if repo_delete_arguments.cache_only else ''), ) borgmatic.borg.repo_delete.delete_repository( diff --git a/borgmatic/actions/repo_info.py b/borgmatic/actions/repo_info.py index c8f035c0..84d33191 100644 --- a/borgmatic/actions/repo_info.py +++ b/borgmatic/actions/repo_info.py @@ -22,7 +22,8 @@ def run_repo_info( If repo_info_arguments.json is True, yield the JSON output from the info for the repository. ''' if repo_info_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, repo_info_arguments.repository + repository, + repo_info_arguments.repository, ): if not repo_info_arguments.json: logger.answer('Displaying repository summary information') diff --git a/borgmatic/actions/repo_list.py b/borgmatic/actions/repo_list.py index 39128333..a8d9d1b7 100644 --- a/borgmatic/actions/repo_list.py +++ b/borgmatic/actions/repo_list.py @@ -22,7 +22,8 @@ def run_repo_list( If repo_list_arguments.json is True, yield the JSON output from listing the repository. ''' if repo_list_arguments.repository is None or borgmatic.config.validate.repositories_match( - repository, repo_list_arguments.repository + repository, + repo_list_arguments.repository, ): if not repo_list_arguments.json: logger.answer('Listing repository') diff --git a/borgmatic/actions/restore.py b/borgmatic/actions/restore.py index 1bb1e919..7c9cb99f 100644 --- a/borgmatic/actions/restore.py +++ b/borgmatic/actions/restore.py @@ -44,7 +44,7 @@ def dumps_match(first, second, default_port=None): if second_value == default_port and first_value is None: continue - if first_value == UNSPECIFIED or second_value == UNSPECIFIED: + if first_value == UNSPECIFIED or second_value == UNSPECIFIED: # noqa: PLR1714 continue if first_value != second_value: @@ -66,7 +66,7 @@ def render_dump_metadata(dump): else: metadata = f'{name}' if hostname is UNSPECIFIED else f'{name}@{hostname}' - if dump.hook_name not in (None, UNSPECIFIED): + if dump.hook_name not in {None, UNSPECIFIED}: return f'{metadata} ({dump.hook_name})' return metadata @@ -112,14 +112,15 @@ def get_configured_data_source(config, restore_dump): if len(matching_dumps) > 1: raise ValueError( - f'Cannot restore data source {render_dump_metadata(restore_dump)} because there are multiple matching data sources configured' + f'Cannot restore data source {render_dump_metadata(restore_dump)} because there are multiple matching data sources configured', ) return matching_dumps[0] def strip_path_prefix_from_extracted_dump_destination( - destination_path, borgmatic_runtime_directory + destination_path, + borgmatic_runtime_directory, ): ''' Directory-format dump files get extracted into a temporary directory containing a path prefix @@ -146,7 +147,8 @@ def strip_path_prefix_from_extracted_dump_destination( continue shutil.move( - subdirectory_path, os.path.join(borgmatic_runtime_directory, databases_directory) + subdirectory_path, + os.path.join(borgmatic_runtime_directory, databases_directory), ) break @@ -170,7 +172,7 @@ def restore_single_dump( that data source from the archive. ''' dump_metadata = render_dump_metadata( - Dump(hook_name, data_source['name'], data_source.get('hostname'), data_source.get('port')) + Dump(hook_name, data_source['name'], data_source.get('hostname'), data_source.get('port')), ) logger.info(f'Restoring data source {dump_metadata}') @@ -198,8 +200,8 @@ def restore_single_dump( archive=archive_name, paths=[ borgmatic.hooks.data_source.dump.convert_glob_patterns_to_borg_pattern( - dump_patterns - ) + dump_patterns, + ), ], config=config, local_borg_version=local_borg_version, @@ -214,7 +216,8 @@ def restore_single_dump( if destination_path and not global_arguments.dry_run: strip_path_prefix_from_extracted_dump_destination( - destination_path, borgmatic_runtime_directory + destination_path, + borgmatic_runtime_directory, ) finally: if destination_path and not global_arguments.dry_run: @@ -250,7 +253,7 @@ def collect_dumps_from_archive( and return them as a set of Dump instances. ''' borgmatic_source_directory = str( - pathlib.Path(borgmatic.config.paths.get_borgmatic_source_directory(config)) + pathlib.Path(borgmatic.config.paths.get_borgmatic_source_directory(config)), ) # Probe for the data source dumps in multiple locations, as the default location has moved to @@ -265,7 +268,8 @@ def collect_dumps_from_archive( list_paths=[ 'sh:' + borgmatic.hooks.data_source.dump.make_data_source_dump_path( - base_directory, '*_databases/*/*' + base_directory, + '*_databases/*/*', ) for base_directory in ( 'borgmatic', @@ -292,7 +296,8 @@ def collect_dumps_from_archive( ): try: (hook_name, host_and_port, data_source_name) = dump_path.split( - base_directory + os.path.sep, 1 + base_directory + os.path.sep, + 1, )[1].split(os.path.sep)[0:3] except (ValueError, IndexError): continue @@ -315,7 +320,7 @@ def collect_dumps_from_archive( break else: logger.warning( - f'Ignoring invalid data source dump path "{dump_path}" in archive {archive}' + f'Ignoring invalid data source dump path "{dump_path}" in archive {archive}', ) return dumps_from_archive @@ -359,7 +364,7 @@ def get_dumps_to_restore(restore_arguments, dumps_from_archive): data_source_name='all', hostname=UNSPECIFIED, port=UNSPECIFIED, - ) + ), } ) missing_dumps = set() @@ -386,7 +391,7 @@ def get_dumps_to_restore(restore_arguments, dumps_from_archive): dumps_to_restore.add(matching_dumps[0]) else: raise ValueError( - f'Cannot restore data source {render_dump_metadata(requested_dump)} because there are multiple matching dumps in the archive. Try adding flags to disambiguate.' + f'Cannot restore data source {render_dump_metadata(requested_dump)} because there are multiple matching dumps in the archive. Try adding flags to disambiguate.', ) if missing_dumps: @@ -395,7 +400,7 @@ def get_dumps_to_restore(restore_arguments, dumps_from_archive): ) raise ValueError( - f"Cannot restore data source dump{'s' if len(missing_dumps) > 1 else ''} {rendered_dumps} missing from archive" + f"Cannot restore data source dump{'s' if len(missing_dumps) > 1 else ''} {rendered_dumps} missing from archive", ) return dumps_to_restore @@ -411,14 +416,15 @@ def ensure_requested_dumps_restored(dumps_to_restore, dumps_actually_restored): raise ValueError('No data source dumps were found to restore') missing_dumps = sorted( - dumps_to_restore - dumps_actually_restored, key=lambda dump: dump.data_source_name + dumps_to_restore - dumps_actually_restored, + key=lambda dump: dump.data_source_name, ) if missing_dumps: rendered_dumps = ', '.join(f'{render_dump_metadata(dump)}' for dump in missing_dumps) raise ValueError( - f"Cannot restore data source{'s' if len(missing_dumps) > 1 else ''} {rendered_dumps} missing from borgmatic's configuration" + f"Cannot restore data source{'s' if len(missing_dumps) > 1 else ''} {rendered_dumps} missing from borgmatic's configuration", ) @@ -439,7 +445,8 @@ def run_restore( matching dump in the archive. ''' if restore_arguments.repository and not borgmatic.config.validate.repositories_match( - repository, restore_arguments.repository + repository, + restore_arguments.repository, ): return @@ -516,7 +523,7 @@ def run_restore( remote_path, archive_name, restore_dump.hook_name, - dict(found_data_source, **{'schemas': restore_arguments.schemas}), + dict(found_data_source, schemas=restore_arguments.schemas), connection_params, borgmatic_runtime_directory, ) diff --git a/borgmatic/actions/transfer.py b/borgmatic/actions/transfer.py index c9601515..182f516e 100644 --- a/borgmatic/actions/transfer.py +++ b/borgmatic/actions/transfer.py @@ -19,7 +19,7 @@ def run_transfer( ''' if transfer_arguments.archive and config.get('match_archives'): raise ValueError( - 'With the transfer action, only one of --archive and --match-archives/match_archives can be used.' + 'With the transfer action, only one of --archive and --match-archives/match_archives can be used.', ) logger.info('Transferring archives to repository') diff --git a/borgmatic/borg/borg.py b/borgmatic/borg/borg.py index 3c8408bf..20af8e11 100644 --- a/borgmatic/borg/borg.py +++ b/borgmatic/borg/borg.py @@ -39,9 +39,9 @@ def run_arbitrary_borg( borg_command = tuple(options[:command_options_start_index]) command_options = tuple(options[command_options_start_index:]) - if borg_command and borg_command[0] in borgmatic.commands.arguments.ACTION_ALIASES.keys(): + if borg_command and borg_command[0] in borgmatic.commands.arguments.ACTION_ALIASES: logger.warning( - f"Borg's {borg_command[0]} subcommand is supported natively by borgmatic. Try this instead: borgmatic {borg_command[0]}" + f"Borg's {borg_command[0]} subcommand is supported natively by borgmatic. Try this instead: borgmatic {borg_command[0]}", ) except IndexError: borg_command = () @@ -57,16 +57,14 @@ def run_arbitrary_borg( + command_options ) - return execute_command( + return execute_command( # noqa: S604 tuple(shlex.quote(part) for part in full_command), output_file=DO_NOT_CAPTURE, - shell=True, # noqa: S604 + shell=True, environment=dict( (environment.make_environment(config) or {}), - **{ - 'BORG_REPO': repository_path, - 'ARCHIVE': archive if archive else '', - }, + BORG_REPO=repository_path, + ARCHIVE=archive if archive else '', ), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, diff --git a/borgmatic/borg/change_passphrase.py b/borgmatic/borg/change_passphrase.py index 1ec3800f..8f495253 100644 --- a/borgmatic/borg/change_passphrase.py +++ b/borgmatic/borg/change_passphrase.py @@ -49,7 +49,7 @@ def change_passphrase( config_without_passphrase = { option_name: value for (option_name, value) in config.items() - if option_name not in ('encryption_passphrase', 'encryption_passcommand') + if option_name not in {'encryption_passphrase', 'encryption_passcommand'} } borgmatic.execute.execute_command( @@ -63,5 +63,5 @@ def change_passphrase( ) logger.answer( - f"{repository_path}: Don't forget to update your encryption_passphrase option (if needed)" + f"{repository_path}: Don't forget to update your encryption_passphrase option (if needed)", ) diff --git a/borgmatic/borg/check.py b/borgmatic/borg/check.py index 6d664c47..4f7fc75e 100644 --- a/borgmatic/borg/check.py +++ b/borgmatic/borg/check.py @@ -42,12 +42,12 @@ def make_archive_filter_flags(local_borg_version, config, checks, check_argument if check_last: logger.warning( - 'Ignoring check_last option, as "archives" or "data" are not in consistency checks' + 'Ignoring check_last option, as "archives" or "data" are not in consistency checks', ) if prefix: logger.warning( - 'Ignoring consistency prefix option, as "archives" or "data" are not in consistency checks' + 'Ignoring consistency prefix option, as "archives" or "data" are not in consistency checks', ) return () @@ -77,13 +77,18 @@ def make_check_name_flags(checks, archive_filter_flags): return common_flags return ( - tuple(f'--{check}-only' for check in checks if check in ('repository', 'archives')) + tuple(f'--{check}-only' for check in checks if check in {'repository', 'archives'}) + common_flags ) def get_repository_id( - repository_path, config, local_borg_version, global_arguments, local_path, remote_path + repository_path, + config, + local_borg_version, + global_arguments, + local_path, + remote_path, ): ''' Given a local or remote repository path, a configuration dict, the local Borg version, global @@ -101,7 +106,7 @@ def get_repository_id( global_arguments, local_path, remote_path, - ) + ), )['repository']['id'] except (json.JSONDecodeError, KeyError): raise ValueError(f'Cannot determine Borg repository ID for {repository_path}') diff --git a/borgmatic/borg/compact.py b/borgmatic/borg/compact.py index ba6cb400..103a3d6a 100644 --- a/borgmatic/borg/compact.py +++ b/borgmatic/borg/compact.py @@ -48,7 +48,7 @@ def compact_segments( ) if dry_run and not feature.available(feature.Feature.DRY_RUN_COMPACT, local_borg_version): - logging.info('Skipping compact (dry run)') + logger.info('Skipping compact (dry run)') return execute_command( diff --git a/borgmatic/borg/create.py b/borgmatic/borg/create.py index 820fcea6..2f0bf842 100644 --- a/borgmatic/borg/create.py +++ b/borgmatic/borg/create.py @@ -72,8 +72,13 @@ def collect_special_file_paths( # files including any named pipe we've created. And omit "--filter" because that can break the # paths output parsing below such that path lines no longer start with the expected "- ". paths_output = execute_command_and_capture_output( - flags.omit_flag_and_value(flags.omit_flag(create_command, '--exclude-nodump'), '--filter') - + ('--dry-run', '--list'), + ( + *flags.omit_flag_and_value( + flags.omit_flag(create_command, '--exclude-nodump'), '--filter' + ), + '--dry-run', + '--list', + ), capture_stderr=True, working_directory=working_directory, environment=environment.make_environment(config), @@ -86,7 +91,7 @@ def collect_special_file_paths( paths = tuple( path_line.split(' ', 1)[1] for path_line in paths_output.split('\n') - if path_line and path_line.startswith('- ') or path_line.startswith('+ ') + if path_line and path_line.startswith(('- ', '+ ')) ) # These are the subset of those files that contain the borgmatic runtime directory. @@ -100,7 +105,7 @@ def collect_special_file_paths( # If no paths to backup contain the runtime directory, it must've been excluded. if not paths_containing_runtime_directory and not dry_run: raise ValueError( - f'The runtime directory {os.path.normpath(borgmatic_runtime_directory)} overlaps with the configured excludes or patterns with excludes. Please ensure the runtime directory is not excluded.' + f'The runtime directory {os.path.normpath(borgmatic_runtime_directory)} overlaps with the configured excludes or patterns with excludes. Please ensure the runtime directory is not excluded.', ) return tuple( @@ -142,7 +147,8 @@ def make_base_create_command( borgmatic.borg.pattern.check_all_root_patterns_exist(patterns) patterns_file = borgmatic.borg.pattern.write_patterns_file( - patterns, borgmatic_runtime_directory + patterns, + borgmatic_runtime_directory, ) checkpoint_interval = config.get('checkpoint_interval', None) checkpoint_volume = config.get('checkpoint_volume', None) @@ -218,14 +224,16 @@ def make_base_create_command( ) create_positional_arguments = flags.make_repository_archive_flags( - repository_path, archive_name_format, local_borg_version + repository_path, + archive_name_format, + local_borg_version, ) # If database hooks are enabled (as indicated by streaming processes), exclude files that might # cause Borg to hang. But skip this if the user has explicitly set the "read_special" to True. if stream_processes and not config.get('read_special'): logger.warning( - 'Ignoring configured "read_special" value of false, as true is needed for database hooks.' + 'Ignoring configured "read_special" value of false, as true is needed for database hooks.', ) working_directory = borgmatic.config.paths.get_working_directory(config) @@ -246,7 +254,7 @@ def make_base_create_command( placeholder=' ...', ) logger.warning( - f'Excluding special files to prevent Borg from hanging: {truncated_special_file_paths}' + f'Excluding special files to prevent Borg from hanging: {truncated_special_file_paths}', ) patterns_file = borgmatic.borg.pattern.write_patterns_file( tuple( @@ -298,7 +306,7 @@ def create_archive( working_directory = borgmatic.config.paths.get_working_directory(config) - (create_flags, create_positional_arguments, patterns_file) = make_base_create_command( + (create_flags, create_positional_arguments, _) = make_base_create_command( dry_run, repository_path, config, @@ -345,7 +353,8 @@ def create_archive( borg_local_path=local_path, borg_exit_codes=borg_exit_codes, ) - elif output_log_level is None: + + if output_log_level is None: return execute_command_and_capture_output( create_flags + create_positional_arguments, working_directory=working_directory, @@ -353,13 +362,15 @@ def create_archive( borg_local_path=local_path, borg_exit_codes=borg_exit_codes, ) - else: - execute_command( - create_flags + create_positional_arguments, - output_log_level, - output_file, - working_directory=working_directory, - environment=environment.make_environment(config), - borg_local_path=local_path, - borg_exit_codes=borg_exit_codes, - ) + + execute_command( + create_flags + create_positional_arguments, + output_log_level, + output_file, + working_directory=working_directory, + environment=environment.make_environment(config), + borg_local_path=local_path, + borg_exit_codes=borg_exit_codes, + ) + + return None diff --git a/borgmatic/borg/delete.py b/borgmatic/borg/delete.py index 4f387e12..34486b86 100644 --- a/borgmatic/borg/delete.py +++ b/borgmatic/borg/delete.py @@ -11,6 +11,9 @@ import borgmatic.execute logger = logging.getLogger(__name__) +FORCE_HARDER_FLAG_COUNT = 2 + + def make_delete_command( repository, config, @@ -36,7 +39,10 @@ def make_delete_command( + borgmatic.borg.flags.make_flags('lock-wait', config.get('lock_wait')) + borgmatic.borg.flags.make_flags('list', config.get('list_details')) + ( - (('--force',) + (('--force',) if delete_arguments.force >= 2 else ())) + ( + ('--force',) + + (('--force',) if delete_arguments.force >= FORCE_HARDER_FLAG_COUNT else ()) + ) if delete_arguments.force else () ) @@ -98,10 +104,11 @@ def delete_archives( for argument_name in ARCHIVE_RELATED_ARGUMENT_NAMES ): if borgmatic.borg.feature.available( - borgmatic.borg.feature.Feature.REPO_DELETE, local_borg_version + borgmatic.borg.feature.Feature.REPO_DELETE, + local_borg_version, ): logger.warning( - 'Deleting an entire repository with the delete action is deprecated when using Borg 2.x+. Use the repo-delete action instead.' + 'Deleting an entire repository with the delete action is deprecated when using Borg 2.x+. Use the repo-delete action instead.', ) repo_delete_arguments = argparse.Namespace( diff --git a/borgmatic/borg/environment.py b/borgmatic/borg/environment.py index cb17553a..b7390370 100644 --- a/borgmatic/borg/environment.py +++ b/borgmatic/borg/environment.py @@ -64,7 +64,8 @@ def make_environment(config): environment.pop('BORG_PASSCOMMAND', None) passphrase = borgmatic.hooks.credential.parse.resolve_credential( - config.get('encryption_passphrase'), config + config.get('encryption_passphrase'), + config, ) if passphrase is None: diff --git a/borgmatic/borg/export_key.py b/borgmatic/borg/export_key.py index 1441c87a..df22e82c 100644 --- a/borgmatic/borg/export_key.py +++ b/borgmatic/borg/export_key.py @@ -35,7 +35,7 @@ def export_key( if export_arguments.path and export_arguments.path != '-': if os.path.exists(os.path.join(working_directory or '', export_arguments.path)): raise FileExistsError( - f'Destination path {export_arguments.path} already exists. Aborting.' + f'Destination path {export_arguments.path} already exists. Aborting.', ) output_file = None diff --git a/borgmatic/borg/export_tar.py b/borgmatic/borg/export_tar.py index 7ca11232..891d577c 100644 --- a/borgmatic/borg/export_tar.py +++ b/borgmatic/borg/export_tar.py @@ -56,13 +56,10 @@ def export_tar_archive( + (tuple(paths) if paths else ()) ) - if config.get('list_details'): - output_log_level = logging.ANSWER - else: - output_log_level = logging.INFO + output_log_level = logging.ANSWER if config.get('list_details') else logging.INFO if dry_run: - logging.info('Skipping export to tar file (dry run)') + logger.info('Skipping export to tar file (dry run)') return execute_command( diff --git a/borgmatic/borg/extract.py b/borgmatic/borg/extract.py index d0fc5c4e..21fbd739 100644 --- a/borgmatic/borg/extract.py +++ b/borgmatic/borg/extract.py @@ -52,7 +52,9 @@ def extract_last_archive_dry_run( + verbosity_flags + list_flag + flags.make_repository_archive_flags( - repository_path, last_archive_name, local_borg_version + repository_path, + last_archive_name, + local_borg_version, ) ) @@ -178,3 +180,5 @@ def extract_archive( borg_local_path=local_path, borg_exit_codes=borg_exit_codes, ) + + return None diff --git a/borgmatic/borg/flags.py b/borgmatic/borg/flags.py index c9064901..f83c4939 100644 --- a/borgmatic/borg/flags.py +++ b/borgmatic/borg/flags.py @@ -34,7 +34,7 @@ def make_flags_from_arguments(arguments, excludes=()): make_flags(name, value=getattr(arguments, name)) for name in sorted(vars(arguments)) if name not in excludes and not name.startswith('_') - ) + ), ) @@ -50,7 +50,7 @@ def make_repository_flags(repository_path, local_borg_version): ) + (repository_path,) -ARCHIVE_HASH_PATTERN = re.compile('[0-9a-fA-F]{8,}$') +ARCHIVE_HASH_PATTERN = re.compile(r'[0-9a-fA-F]{8,}$') def make_repository_archive_flags(repository_path, archive, local_borg_version): @@ -76,8 +76,8 @@ def make_repository_archive_flags(repository_path, archive, local_borg_version): ) -DEFAULT_ARCHIVE_NAME_FORMAT_WITHOUT_SERIES = '{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}' # noqa: FS003 -DEFAULT_ARCHIVE_NAME_FORMAT_WITH_SERIES = '{hostname}' # noqa: FS003 +DEFAULT_ARCHIVE_NAME_FORMAT_WITHOUT_SERIES = '{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}' +DEFAULT_ARCHIVE_NAME_FORMAT_WITH_SERIES = '{hostname}' def get_default_archive_name_format(local_borg_version): @@ -90,7 +90,7 @@ def get_default_archive_name_format(local_borg_version): return DEFAULT_ARCHIVE_NAME_FORMAT_WITHOUT_SERIES -def make_match_archives_flags( +def make_match_archives_flags( # noqa: PLR0911 match_archives, archive_name_format, local_borg_version, @@ -115,8 +115,8 @@ def make_match_archives_flags( return ('--match-archives', f'aid:{match_archives}') return ('--match-archives', match_archives) - else: - return ('--glob-archives', re.sub(r'^sh:', '', match_archives)) + + return ('--glob-archives', re.sub(r'^sh:', '', match_archives)) derived_match_archives = re.sub( r'\{(now|utcnow|pid)([:%\w\.-]*)\}', @@ -131,8 +131,8 @@ def make_match_archives_flags( if feature.available(feature.Feature.MATCH_ARCHIVES, local_borg_version): return ('--match-archives', f'sh:{derived_match_archives}') - else: - return ('--glob-archives', f'{derived_match_archives}') + + return ('--glob-archives', f'{derived_match_archives}') def warn_for_aggressive_archive_flags(json_command, json_output): @@ -150,7 +150,7 @@ def warn_for_aggressive_archive_flags(json_command, json_output): if len(json.loads(json_output)['archives']) == 0: logger.warning('An archive filter was applied, but no matching archives were found.') logger.warning( - 'Try adding --match-archives "*" or adjusting archive_name_format/match_archives in configuration.' + 'Try adding --match-archives "*" or adjusting archive_name_format/match_archives in configuration.', ) except json.JSONDecodeError as error: logger.debug(f'Cannot parse JSON output from archive command: {error}') @@ -193,8 +193,8 @@ def omit_flag_and_value(arguments, flag): # its value. return tuple( argument - for (previous_argument, argument) in zip((None,) + arguments, arguments) - if flag not in (previous_argument, argument) + for (previous_argument, argument) in zip((None, *arguments), arguments) + if flag not in {previous_argument, argument} if not argument.startswith(f'{flag}=') ) @@ -209,7 +209,7 @@ def make_exclude_flags(config): itertools.chain.from_iterable( ('--exclude-if-present', if_present) for if_present in config.get('exclude_if_present', ()) - ) + ), ) keep_exclude_tags_flags = ('--keep-exclude-tags',) if config.get('keep_exclude_tags') else () exclude_nodump_flags = ('--exclude-nodump',) if config.get('exclude_nodump') else () @@ -229,10 +229,10 @@ def make_list_filter_flags(local_borg_version, dry_run): if feature.available(feature.Feature.EXCLUDED_FILES_MINUS, local_borg_version): if show_excludes or dry_run: return f'{base_flags}+-' - else: - return base_flags + + return base_flags if show_excludes: return f'{base_flags}x-' - else: - return f'{base_flags}-' + + return f'{base_flags}-' diff --git a/borgmatic/borg/info.py b/borgmatic/borg/info.py index 50e9534a..3b1c6a01 100644 --- a/borgmatic/borg/info.py +++ b/borgmatic/borg/info.py @@ -55,7 +55,8 @@ def make_info_command( ) ) + flags.make_flags_from_arguments( - info_arguments, excludes=('repository', 'archive', 'prefix', 'match_archives') + info_arguments, + excludes=('repository', 'archive', 'prefix', 'match_archives'), ) + flags.make_repository_flags(repository_path, local_borg_version) ) @@ -119,3 +120,5 @@ def display_archives_info( borg_local_path=local_path, borg_exit_codes=borg_exit_codes, ) + + return None diff --git a/borgmatic/borg/list.py b/borgmatic/borg/list.py index e47b6937..f5d720b3 100644 --- a/borgmatic/borg/list.py +++ b/borgmatic/borg/list.py @@ -17,7 +17,8 @@ MAKE_FLAGS_EXCLUDES = ( 'archive', 'paths', 'find_paths', -) + ARCHIVE_FILTER_FLAGS_MOVED_TO_REPO_LIST + *ARCHIVE_FILTER_FLAGS_MOVED_TO_REPO_LIST, +) def make_list_command( @@ -53,7 +54,9 @@ def make_list_command( + flags.make_flags_from_arguments(list_arguments, excludes=MAKE_FLAGS_EXCLUDES) + ( flags.make_repository_archive_flags( - repository_path, list_arguments.archive, local_borg_version + repository_path, + list_arguments.archive, + local_borg_version, ) if list_arguments.archive else flags.make_repository_flags(repository_path, local_borg_version) @@ -115,10 +118,10 @@ def capture_archive_listing( argparse.Namespace( repository=repository_path, archive=archive, - paths=[path for path in list_paths] if list_paths else None, + paths=list(list_paths) if list_paths else None, find_paths=None, json=None, - format=path_format or '{path}{NUL}', # noqa: FS003 + format=path_format or '{path}{NUL}', ), global_arguments, local_path, @@ -130,7 +133,7 @@ def capture_archive_listing( borg_exit_codes=config.get('borg_exit_codes'), ) .strip('\0') - .split('\0') + .split('\0'), ) @@ -156,7 +159,7 @@ def list_archive( if not list_arguments.archive and not list_arguments.find_paths: if feature.available(feature.Feature.REPO_LIST, local_borg_version): logger.warning( - 'Omitting the --archive flag on the list action is deprecated when using Borg 2.x+. Use the repo-list action instead.' + 'Omitting the --archive flag on the list action is deprecated when using Borg 2.x+. Use the repo-list action instead.', ) repo_list_arguments = argparse.Namespace( @@ -184,12 +187,12 @@ def list_archive( for name in ARCHIVE_FILTER_FLAGS_MOVED_TO_REPO_LIST: if getattr(list_arguments, name, None): logger.warning( - f"The --{name.replace('_', '-')} flag on the list action is ignored when using the --archive flag." + f"The --{name.replace('_', '-')} flag on the list action is ignored when using the --archive flag.", ) if list_arguments.json: raise ValueError( - 'The --json flag on the list action is not supported when using the --archive/--find flags.' + 'The --json flag on the list action is not supported when using the --archive/--find flags.', ) borg_exit_codes = config.get('borg_exit_codes') @@ -227,7 +230,7 @@ def list_archive( borg_exit_codes=borg_exit_codes, ) .strip('\n') - .splitlines() + .splitlines(), ) else: archive_lines = (list_arguments.archive,) @@ -262,3 +265,5 @@ def list_archive( borg_local_path=local_path, borg_exit_codes=borg_exit_codes, ) + + return None diff --git a/borgmatic/borg/pattern.py b/borgmatic/borg/pattern.py index f84498a1..aee6a780 100644 --- a/borgmatic/borg/pattern.py +++ b/borgmatic/borg/pattern.py @@ -4,8 +4,6 @@ import logging import os import tempfile -import borgmatic.borg.pattern - logger = logging.getLogger(__name__) @@ -59,9 +57,9 @@ Pattern = collections.namedtuple( def write_patterns_file(patterns, borgmatic_runtime_directory, patterns_file=None): ''' - Given a sequence of patterns as borgmatic.borg.pattern.Pattern instances, write them to a named - temporary file in the given borgmatic runtime directory and return the file object so it can - continue to exist on disk as long as the caller needs it. + Given a sequence of patterns as Pattern instances, write them to a named temporary file in the + given borgmatic runtime directory and return the file object so it can continue to exist on disk + as long as the caller needs it. If an optional open pattern file is given, append to it instead of making a new temporary file. Return None if no patterns are provided. @@ -70,7 +68,9 @@ def write_patterns_file(patterns, borgmatic_runtime_directory, patterns_file=Non return None if patterns_file is None: - patterns_file = tempfile.NamedTemporaryFile('w', dir=borgmatic_runtime_directory) + patterns_file = tempfile.NamedTemporaryFile( + 'w', dir=borgmatic_runtime_directory, encoding='utf-8' + ) operation_name = 'Writing' else: patterns_file.write('\n') @@ -90,17 +90,17 @@ def write_patterns_file(patterns, borgmatic_runtime_directory, patterns_file=Non def check_all_root_patterns_exist(patterns): ''' - Given a sequence of borgmatic.borg.pattern.Pattern instances, check that all root pattern - paths exist. If any don't, raise an exception. + Given a sequence of Pattern instances, check that all root pattern paths exist. If any don't, + raise an exception. ''' missing_paths = [ pattern.path for pattern in patterns - if pattern.type == borgmatic.borg.pattern.Pattern_type.ROOT + if pattern.type == Pattern_type.ROOT if not os.path.exists(pattern.path) ] if missing_paths: raise ValueError( - f"Source directories or root pattern paths do not exist: {', '.join(missing_paths)}" + f"Source directories or root pattern paths do not exist: {', '.join(missing_paths)}", ) diff --git a/borgmatic/borg/recreate.py b/borgmatic/borg/recreate.py index 4b41d9f4..0f62f155 100644 --- a/borgmatic/borg/recreate.py +++ b/borgmatic/borg/recreate.py @@ -38,7 +38,8 @@ def recreate_archive( # Write patterns to a temporary file and use that file with --patterns-from. patterns_file = write_patterns_file( - patterns, borgmatic.config.paths.get_working_directory(config) + patterns, + borgmatic.config.paths.get_working_directory(config), ) recreate_command = ( @@ -80,7 +81,8 @@ def recreate_archive( ) ) if borgmatic.borg.feature.available( - borgmatic.borg.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, local_borg_version + borgmatic.borg.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, + local_borg_version, ) else ( flags.make_repository_archive_flags(repository, archive, local_borg_version) diff --git a/borgmatic/borg/rename.py b/borgmatic/borg/rename.py index 5700c5a9..b351be2b 100644 --- a/borgmatic/borg/rename.py +++ b/borgmatic/borg/rename.py @@ -25,7 +25,9 @@ def make_rename_command( + borgmatic.borg.flags.make_flags('log-json', config.get('log_json')) + borgmatic.borg.flags.make_flags('lock-wait', config.get('lock_wait')) + borgmatic.borg.flags.make_repository_archive_flags( - repository_name, old_archive_name, local_borg_version + repository_name, + old_archive_name, + local_borg_version, ) + (new_archive_name,) ) diff --git a/borgmatic/borg/repo_create.py b/borgmatic/borg/repo_create.py index d5f1076e..88f58e0a 100644 --- a/borgmatic/borg/repo_create.py +++ b/borgmatic/borg/repo_create.py @@ -49,13 +49,13 @@ def create_repository( global_arguments, local_path, remote_path, - ) + ), ) repository_encryption_mode = info_data.get('encryption', {}).get('mode') if repository_encryption_mode != encryption_mode: raise ValueError( - f'Requested encryption mode "{encryption_mode}" does not match existing repository encryption mode "{repository_encryption_mode}"' + f'Requested encryption mode "{encryption_mode}" does not match existing repository encryption mode "{repository_encryption_mode}"', ) logger.info('Repository already exists. Skipping creation.') @@ -92,7 +92,7 @@ def create_repository( ) if dry_run: - logging.info('Skipping repository creation (dry run)') + logger.info('Skipping repository creation (dry run)') return # Do not capture output here, so as to support interactive prompts. diff --git a/borgmatic/borg/repo_delete.py b/borgmatic/borg/repo_delete.py index fc1b1710..652afbb7 100644 --- a/borgmatic/borg/repo_delete.py +++ b/borgmatic/borg/repo_delete.py @@ -9,6 +9,9 @@ import borgmatic.execute logger = logging.getLogger(__name__) +FORCE_HARDER_FLAG_COUNT = 2 + + def make_repo_delete_command( repository, config, @@ -28,7 +31,8 @@ def make_repo_delete_command( + ( ('repo-delete',) if borgmatic.borg.feature.available( - borgmatic.borg.feature.Feature.REPO_DELETE, local_borg_version + borgmatic.borg.feature.Feature.REPO_DELETE, + local_borg_version, ) else ('delete',) ) @@ -41,12 +45,16 @@ def make_repo_delete_command( + borgmatic.borg.flags.make_flags('lock-wait', config.get('lock_wait')) + borgmatic.borg.flags.make_flags('list', config.get('list_details')) + ( - (('--force',) + (('--force',) if repo_delete_arguments.force >= 2 else ())) + ( + ('--force',) + + (('--force',) if repo_delete_arguments.force >= FORCE_HARDER_FLAG_COUNT else ()) + ) if repo_delete_arguments.force else () ) + borgmatic.borg.flags.make_flags_from_arguments( - repo_delete_arguments, excludes=('list_details', 'force', 'repository') + repo_delete_arguments, + excludes=('list_details', 'force', 'repository'), ) + borgmatic.borg.flags.make_repository_flags(repository['path'], local_borg_version) ) diff --git a/borgmatic/borg/repo_info.py b/borgmatic/borg/repo_info.py index c5080d89..cf737513 100644 --- a/borgmatic/borg/repo_info.py +++ b/borgmatic/borg/repo_info.py @@ -61,12 +61,14 @@ def display_repository_info( borg_local_path=local_path, borg_exit_codes=borg_exit_codes, ) - else: - execute_command( - full_command, - output_log_level=logging.ANSWER, - environment=environment.make_environment(config), - working_directory=working_directory, - borg_local_path=local_path, - borg_exit_codes=borg_exit_codes, - ) + + execute_command( + full_command, + output_log_level=logging.ANSWER, + environment=environment.make_environment(config), + working_directory=working_directory, + borg_local_path=local_path, + borg_exit_codes=borg_exit_codes, + ) + + return None diff --git a/borgmatic/borg/repo_list.py b/borgmatic/borg/repo_list.py index e2ec114b..fbbecd8e 100644 --- a/borgmatic/borg/repo_list.py +++ b/borgmatic/borg/repo_list.py @@ -58,22 +58,20 @@ def get_latest_archive( ''' full_command = ( + local_path, ( - local_path, - ( - 'repo-list' - if feature.available(feature.Feature.REPO_LIST, local_borg_version) - else 'list' - ), - ) - + flags.make_flags('remote-path', remote_path) - + flags.make_flags('umask', config.get('umask')) - + flags.make_flags('log-json', config.get('log_json')) - + flags.make_flags('lock-wait', config.get('lock_wait')) - + flags.make_flags('consider-checkpoints', consider_checkpoints) - + flags.make_flags('last', 1) - + ('--json',) - + flags.make_repository_flags(repository_path, local_borg_version) + 'repo-list' + if feature.available(feature.Feature.REPO_LIST, local_borg_version) + else 'list' + ), + *flags.make_flags('remote-path', remote_path), + *flags.make_flags('umask', config.get('umask')), + *flags.make_flags('log-json', config.get('log_json')), + *flags.make_flags('lock-wait', config.get('lock_wait')), + *flags.make_flags('consider-checkpoints', consider_checkpoints), + *flags.make_flags('last', 1), + '--json', + *flags.make_repository_flags(repository_path, local_borg_version), ) json_output = execute_command_and_capture_output( @@ -215,3 +213,5 @@ def list_repository( borg_local_path=local_path, borg_exit_codes=borg_exit_codes, ) + + return None diff --git a/borgmatic/commands/arguments.py b/borgmatic/commands/arguments.py index 3edbfef8..e35cf5a5 100644 --- a/borgmatic/commands/arguments.py +++ b/borgmatic/commands/arguments.py @@ -60,7 +60,7 @@ def get_subactions_for_actions(action_parsers): action: tuple( subaction_name for group_action in action_parser._subparsers._group_actions - for subaction_name in group_action.choices.keys() + for subaction_name in group_action.choices ) for action, action_parser in action_parsers.items() if action_parser._subparsers @@ -77,21 +77,25 @@ def omit_values_colliding_with_action_names(unparsed_arguments, parsed_arguments ''' remaining_arguments = list(unparsed_arguments) - for action_name, parsed in parsed_arguments.items(): + for parsed in parsed_arguments.values(): for value in vars(parsed).values(): if isinstance(value, str): - if value in ACTION_ALIASES.keys() and value in remaining_arguments: + if value in ACTION_ALIASES and value in remaining_arguments: remaining_arguments.remove(value) elif isinstance(value, list): for item in value: - if item in ACTION_ALIASES.keys() and item in remaining_arguments: + if item in ACTION_ALIASES and item in remaining_arguments: remaining_arguments.remove(item) return tuple(remaining_arguments) def parse_and_record_action_arguments( - unparsed_arguments, parsed_arguments, action_parser, action_name, canonical_name=None + unparsed_arguments, + parsed_arguments, + action_parser, + action_name, + canonical_name=None, ): ''' Given unparsed arguments as a sequence of strings, parsed arguments as a dict from action name @@ -102,7 +106,8 @@ def parse_and_record_action_arguments( given action doesn't apply to the given unparsed arguments. ''' filtered_arguments = omit_values_colliding_with_action_names( - unparsed_arguments, parsed_arguments + unparsed_arguments, + parsed_arguments, ) if action_name not in filtered_arguments: @@ -186,12 +191,12 @@ def get_unparsable_arguments(remaining_action_arguments): itertools.chain.from_iterable( argument_group for argument_group in dict.fromkeys( - itertools.chain.from_iterable(grouped_action_arguments) - ).keys() + itertools.chain.from_iterable(grouped_action_arguments), + ) if all( argument_group in action_arguments for action_arguments in grouped_action_arguments ) - ) + ), ) @@ -244,7 +249,7 @@ def parse_arguments_for_actions(unparsed_arguments, action_parsers, global_parse subaction_name, ) if argument != action_name - ) + ), ) if subaction_name in arguments: @@ -256,14 +261,18 @@ def parse_arguments_for_actions(unparsed_arguments, action_parsers, global_parse sys.exit(0) else: raise ValueError( - f"Missing sub-action after {action_name} action. Expected one of: {', '.join(get_subactions_for_actions(action_parsers)[action_name])}" + f"Missing sub-action after {action_name} action. Expected one of: {', '.join(get_subactions_for_actions(action_parsers)[action_name])}", ) # Otherwise, parse with the main action parser. else: remaining_action_arguments.append( parse_and_record_action_arguments( - unparsed_arguments, arguments, action_parser, action_name, canonical_name - ) + unparsed_arguments, + arguments, + action_parser, + action_name, + canonical_name, + ), ) # If no actions were explicitly requested, assume defaults. @@ -272,11 +281,11 @@ def parse_arguments_for_actions(unparsed_arguments, action_parsers, global_parse default_action_parser = action_parsers[default_action_name] remaining_action_arguments.append( parse_and_record_action_arguments( - tuple(unparsed_arguments) + (default_action_name,), + (*unparsed_arguments, default_action_name), arguments, default_action_parser, default_action_name, - ) + ), ) arguments['global'], remaining = global_parser.parse_known_args(unparsed_arguments) @@ -304,10 +313,10 @@ def make_argument_description(schema, flag_name): if '[0]' in flag_name: pieces.append( - ' To specify a different list element, replace the "[0]" with another array index ("[1]", "[2]", etc.).' + ' To specify a different list element, replace the "[0]" with another array index ("[1]", "[2]", etc.).', ) - if example and schema_type in ('array', 'object'): + if example and schema_type in ('array', 'object'): # noqa: PLR6201 example_buffer = io.StringIO() yaml = ruamel.yaml.YAML(typ='safe') yaml.default_flow_style = True @@ -387,7 +396,7 @@ def add_array_element_arguments(arguments_group, unparsed_arguments, flag_name): if not pattern.match(unparsed_flag_name) or unparsed_flag_name == existing_flag_name: continue - if action_registry_name in ('store_true', 'store_false'): + if action_registry_name in {'store_true', 'store_false'}: arguments_group.add_argument( unparsed_flag_name, action=action_registry_name, @@ -408,7 +417,7 @@ def add_array_element_arguments(arguments_group, unparsed_arguments, flag_name): ) -def add_arguments_from_schema(arguments_group, schema, unparsed_arguments, names=None): +def add_arguments_from_schema(arguments_group, schema, unparsed_arguments, names=None): # noqa: PLR0912 ''' Given an argparse._ArgumentGroup instance, a configuration schema dict, and a sequence of unparsed argument strings, convert the entire schema into corresponding command-line flags and @@ -466,7 +475,10 @@ def add_arguments_from_schema(arguments_group, schema, unparsed_arguments, names if properties: for name, child in properties.items(): add_arguments_from_schema( - arguments_group, child, unparsed_arguments, names + (name,) + arguments_group, + child, + unparsed_arguments, + (*names, name), ) return @@ -483,12 +495,15 @@ def add_arguments_from_schema(arguments_group, schema, unparsed_arguments, names arguments_group, child, unparsed_arguments, - names[:-1] + (f'{names[-1]}[0]',) + (name,), + (*names[:-1], f'{names[-1]}[0]', name), ) # If there aren't any children, then this is an array of scalars. Recurse accordingly. else: add_arguments_from_schema( - arguments_group, items, unparsed_arguments, names[:-1] + (f'{names[-1]}[0]',) + arguments_group, + items, + unparsed_arguments, + (*names[:-1], f'{names[-1]}[0]'), ) flag_name = '.'.join(names).replace('_', '-') @@ -515,9 +530,9 @@ def add_arguments_from_schema(arguments_group, schema, unparsed_arguments, names ) if names[-1].startswith('no_'): - no_flag_name = '.'.join(names[:-1] + (names[-1][len('no_') :],)).replace('_', '-') + no_flag_name = '.'.join((*names[:-1], names[-1][len('no_') :])).replace('_', '-') else: - no_flag_name = '.'.join(names[:-1] + ('no-' + names[-1],)).replace('_', '-') + no_flag_name = '.'.join((*names[:-1], 'no-' + names[-1])).replace('_', '-') arguments_group.add_argument( f'--{no_flag_name}', @@ -545,7 +560,7 @@ def add_arguments_from_schema(arguments_group, schema, unparsed_arguments, names add_array_element_arguments(arguments_group, unparsed_arguments, flag_name) -def make_parsers(schema, unparsed_arguments): +def make_parsers(schema, unparsed_arguments): # noqa: PLR0915 ''' Given a configuration schema dict and unparsed arguments as a sequence of strings, build a global arguments parser, individual action parsers, and a combined parser containing both. @@ -670,7 +685,10 @@ def make_parsers(schema, unparsed_arguments): help='Create any missing parent directories of the repository directory [Borg 1.x only]', ) repo_create_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) transfer_parser = action_parsers.add_parser( @@ -712,7 +730,9 @@ def make_parsers(schema, unparsed_arguments): help='Only transfer archives with names, hashes, or series matching this pattern', ) transfer_group.add_argument( - '--sort-by', metavar='KEYS', help='Comma-separated list of sorting keys' + '--sort-by', + metavar='KEYS', + help='Comma-separated list of sorting keys', ) transfer_group.add_argument( '--first', @@ -720,7 +740,9 @@ def make_parsers(schema, unparsed_arguments): help='Only transfer first N archives after other filters are applied', ) transfer_group.add_argument( - '--last', metavar='N', help='Only transfer last N archives after other filters are applied' + '--last', + metavar='N', + help='Only transfer last N archives after other filters are applied', ) transfer_group.add_argument( '--oldest', @@ -743,7 +765,10 @@ def make_parsers(schema, unparsed_arguments): help='Transfer archives that are newer than the specified time range (e.g. 7d or 12m) from the current time [Borg 2.x+ only]', ) transfer_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) prune_parser = action_parsers.add_parser( @@ -833,7 +858,10 @@ def make_parsers(schema, unparsed_arguments): help='Minimum saved space percentage threshold for compacting a segment, defaults to 10', ) compact_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) create_parser = action_parsers.add_parser( @@ -870,7 +898,11 @@ def make_parsers(schema, unparsed_arguments): help='Show per-file details', ) create_group.add_argument( - '--json', dest='json', default=False, action='store_true', help='Output results as JSON' + '--json', + dest='json', + default=False, + action='store_true', + help='Output results as JSON', ) create_group.add_argument( '--comment', @@ -996,13 +1028,19 @@ def make_parsers(schema, unparsed_arguments): help='Only delete archives with names, hashes, or series matching this pattern', ) delete_group.add_argument( - '--sort-by', metavar='KEYS', help='Comma-separated list of sorting keys' + '--sort-by', + metavar='KEYS', + help='Comma-separated list of sorting keys', ) delete_group.add_argument( - '--first', metavar='N', help='Delete first N archives after other filters are applied' + '--first', + metavar='N', + help='Delete first N archives after other filters are applied', ) delete_group.add_argument( - '--last', metavar='N', help='Delete last N archives after other filters are applied' + '--last', + metavar='N', + help='Delete last N archives after other filters are applied', ) delete_group.add_argument( '--oldest', @@ -1039,7 +1077,9 @@ def make_parsers(schema, unparsed_arguments): help='Path of repository to extract, defaults to the configured repository if there is only one, quoted globs supported', ) extract_group.add_argument( - '--archive', help='Name or hash of a single archive to extract (or "latest")', required=True + '--archive', + help='Name or hash of a single archive to extract (or "latest")', + required=True, ) extract_group.add_argument( '--path', @@ -1068,7 +1108,10 @@ def make_parsers(schema, unparsed_arguments): help='Display progress for each file as it is extracted', ) extract_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) config_parser = action_parsers.add_parser( @@ -1093,7 +1136,7 @@ def make_parsers(schema, unparsed_arguments): add_help=False, ) config_bootstrap_group = config_bootstrap_parser.add_argument_group( - 'config bootstrap arguments' + 'config bootstrap arguments', ) config_bootstrap_group.add_argument( '--repository', @@ -1148,7 +1191,10 @@ def make_parsers(schema, unparsed_arguments): help='Command to use instead of "ssh"', ) config_bootstrap_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) config_generate_parser = config_parsers.add_parser( @@ -1178,7 +1224,10 @@ def make_parsers(schema, unparsed_arguments): help='Whether to overwrite any existing destination file, defaults to false', ) config_generate_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) config_validate_parser = config_parsers.add_parser( @@ -1195,7 +1244,10 @@ def make_parsers(schema, unparsed_arguments): help='Show the validated configuration after all include merging has occurred', ) config_validate_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) export_tar_parser = action_parsers.add_parser( @@ -1211,7 +1263,9 @@ def make_parsers(schema, unparsed_arguments): help='Path of repository to export from, defaults to the configured repository if there is only one, quoted globs supported', ) export_tar_group.add_argument( - '--archive', help='Name or hash of a single archive to export (or "latest")', required=True + '--archive', + help='Name or hash of a single archive to export (or "latest")', + required=True, ) export_tar_group.add_argument( '--path', @@ -1228,7 +1282,8 @@ def make_parsers(schema, unparsed_arguments): required=True, ) export_tar_group.add_argument( - '--tar-filter', help='Name of filter program to pipe data through' + '--tar-filter', + help='Name of filter program to pipe data through', ) export_tar_group.add_argument( '--list', @@ -1246,7 +1301,10 @@ def make_parsers(schema, unparsed_arguments): help='Number of leading path components to remove from each exported path. Skip paths with fewer elements', ) export_tar_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) mount_parser = action_parsers.add_parser( @@ -1262,7 +1320,8 @@ def make_parsers(schema, unparsed_arguments): help='Path of repository to use, defaults to the configured repository if there is only one, quoted globs supported', ) mount_group.add_argument( - '--archive', help='Name or hash of a single archive to mount (or "latest")' + '--archive', + help='Name or hash of a single archive to mount (or "latest")', ) mount_group.add_argument( '--mount-point', @@ -1291,7 +1350,9 @@ def make_parsers(schema, unparsed_arguments): help='Mount first N archives after other filters are applied', ) mount_group.add_argument( - '--last', metavar='N', help='Mount last N archives after other filters are applied' + '--last', + metavar='N', + help='Mount last N archives after other filters are applied', ) mount_group.add_argument( '--oldest', @@ -1368,7 +1429,10 @@ def make_parsers(schema, unparsed_arguments): help='Do not delete the local security info when deleting a repository', ) repo_delete_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) restore_parser = action_parsers.add_parser( @@ -1437,7 +1501,10 @@ def make_parsers(schema, unparsed_arguments): help='The name of the data source hook for the dump to restore, only necessary if you need to disambiguate dumps', ) restore_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) repo_list_parser = action_parsers.add_parser( @@ -1453,14 +1520,22 @@ def make_parsers(schema, unparsed_arguments): help='Path of repository to list, defaults to the configured repositories, quoted globs supported', ) repo_list_group.add_argument( - '--short', default=False, action='store_true', help='Output only archive names' + '--short', + default=False, + action='store_true', + help='Output only archive names', ) repo_list_group.add_argument('--format', help='Format for archive listing') repo_list_group.add_argument( - '--json', default=False, action='store_true', help='Output results as JSON' + '--json', + default=False, + action='store_true', + help='Output results as JSON', ) repo_list_group.add_argument( - '-P', '--prefix', help='Deprecated. Only list archive names starting with this prefix' + '-P', + '--prefix', + help='Deprecated. Only list archive names starting with this prefix', ) repo_list_group.add_argument( '-a', @@ -1470,13 +1545,19 @@ def make_parsers(schema, unparsed_arguments): help='Only list archive names, hashes, or series matching this pattern', ) repo_list_group.add_argument( - '--sort-by', metavar='KEYS', help='Comma-separated list of sorting keys' + '--sort-by', + metavar='KEYS', + help='Comma-separated list of sorting keys', ) repo_list_group.add_argument( - '--first', metavar='N', help='List first N archives after other filters are applied' + '--first', + metavar='N', + help='List first N archives after other filters are applied', ) repo_list_group.add_argument( - '--last', metavar='N', help='List last N archives after other filters are applied' + '--last', + metavar='N', + help='List last N archives after other filters are applied', ) repo_list_group.add_argument( '--oldest', @@ -1505,7 +1586,10 @@ def make_parsers(schema, unparsed_arguments): help="List only deleted archives that haven't yet been compacted [Borg 2.x+ only]", ) repo_list_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) list_parser = action_parsers.add_parser( @@ -1521,7 +1605,8 @@ def make_parsers(schema, unparsed_arguments): help='Path of repository containing archive to list, defaults to the configured repositories, quoted globs supported', ) list_group.add_argument( - '--archive', help='Name or hash of a single archive to list (or "latest")' + '--archive', + help='Name or hash of a single archive to list (or "latest")', ) list_group.add_argument( '--path', @@ -1538,14 +1623,22 @@ def make_parsers(schema, unparsed_arguments): help='Partial path or pattern to search for and list across multiple archives, can specify flag multiple times', ) list_group.add_argument( - '--short', default=False, action='store_true', help='Output only path names' + '--short', + default=False, + action='store_true', + help='Output only path names', ) list_group.add_argument('--format', help='Format for file listing') list_group.add_argument( - '--json', default=False, action='store_true', help='Output results as JSON' + '--json', + default=False, + action='store_true', + help='Output results as JSON', ) list_group.add_argument( - '-P', '--prefix', help='Deprecated. Only list archive names starting with this prefix' + '-P', + '--prefix', + help='Deprecated. Only list archive names starting with this prefix', ) list_group.add_argument( '-a', @@ -1555,19 +1648,30 @@ def make_parsers(schema, unparsed_arguments): help='Only list archive names matching this pattern', ) list_group.add_argument( - '--sort-by', metavar='KEYS', help='Comma-separated list of sorting keys' + '--sort-by', + metavar='KEYS', + help='Comma-separated list of sorting keys', ) list_group.add_argument( - '--first', metavar='N', help='List first N archives after other filters are applied' + '--first', + metavar='N', + help='List first N archives after other filters are applied', ) list_group.add_argument( - '--last', metavar='N', help='List last N archives after other filters are applied' + '--last', + metavar='N', + help='List last N archives after other filters are applied', ) list_group.add_argument( - '-e', '--exclude', metavar='PATTERN', help='Exclude paths matching the pattern' + '-e', + '--exclude', + metavar='PATTERN', + help='Exclude paths matching the pattern', ) list_group.add_argument( - '--exclude-from', metavar='FILENAME', help='Exclude paths from exclude file, one per line' + '--exclude-from', + metavar='FILENAME', + help='Exclude paths from exclude file, one per line', ) list_group.add_argument('--pattern', help='Include or exclude paths matching a pattern') list_group.add_argument( @@ -1590,10 +1694,17 @@ def make_parsers(schema, unparsed_arguments): help='Path of repository to show info for, defaults to the configured repository if there is only one, quoted globs supported', ) repo_info_group.add_argument( - '--json', dest='json', default=False, action='store_true', help='Output results as JSON' + '--json', + dest='json', + default=False, + action='store_true', + help='Output results as JSON', ) repo_info_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) info_parser = action_parsers.add_parser( @@ -1609,10 +1720,15 @@ def make_parsers(schema, unparsed_arguments): help='Path of repository containing archive to show info for, defaults to the configured repository if there is only one, quoted globs supported', ) info_group.add_argument( - '--archive', help='Archive name, hash, or series to show info for (or "latest")' + '--archive', + help='Archive name, hash, or series to show info for (or "latest")', ) info_group.add_argument( - '--json', dest='json', default=False, action='store_true', help='Output results as JSON' + '--json', + dest='json', + default=False, + action='store_true', + help='Output results as JSON', ) info_group.add_argument( '-P', @@ -1627,7 +1743,9 @@ def make_parsers(schema, unparsed_arguments): help='Only show info for archive names, hashes, or series matching this pattern', ) info_group.add_argument( - '--sort-by', metavar='KEYS', help='Comma-separated list of sorting keys' + '--sort-by', + metavar='KEYS', + help='Comma-separated list of sorting keys', ) info_group.add_argument( '--first', @@ -1635,7 +1753,9 @@ def make_parsers(schema, unparsed_arguments): help='Show info for first N archives after other filters are applied', ) info_group.add_argument( - '--last', metavar='N', help='Show info for last N archives after other filters are applied' + '--last', + metavar='N', + help='Show info for last N archives after other filters are applied', ) info_group.add_argument( '--oldest', @@ -1672,7 +1792,10 @@ def make_parsers(schema, unparsed_arguments): help='Path of repository to break the lock for, defaults to the configured repository if there is only one, quoted globs supported', ) break_lock_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) key_parser = action_parsers.add_parser( @@ -1717,7 +1840,10 @@ def make_parsers(schema, unparsed_arguments): help='Path to export the key to, defaults to stdout (but be careful about dirtying the output with --verbosity)', ) key_export_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) key_import_parser = key_parsers.add_parser( @@ -1742,7 +1868,10 @@ def make_parsers(schema, unparsed_arguments): help='Path to import the key from backup, defaults to stdin', ) key_import_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) key_change_passphrase_parser = key_parsers.add_parser( @@ -1752,14 +1881,17 @@ def make_parsers(schema, unparsed_arguments): add_help=False, ) key_change_passphrase_group = key_change_passphrase_parser.add_argument_group( - 'key change-passphrase arguments' + 'key change-passphrase arguments', ) key_change_passphrase_group.add_argument( '--repository', help='Path of repository to change the passphrase for, defaults to the configured repository if there is only one, quoted globs supported', ) key_change_passphrase_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) recreate_parser = action_parsers.add_parser( @@ -1809,7 +1941,10 @@ def make_parsers(schema, unparsed_arguments): help='Only consider archive names, hashes, or series matching this pattern [Borg 2.x+ only]', ) recreate_group.add_argument( - '-h', '--help', action='help', help='Show this help message and exit' + '-h', + '--help', + action='help', + help='Show this help message and exit', ) borg_parser = action_parsers.add_parser( @@ -1825,7 +1960,8 @@ def make_parsers(schema, unparsed_arguments): help='Path of repository to pass to Borg, defaults to the configured repositories, quoted globs supported', ) borg_group.add_argument( - '--archive', help='Archive name, hash, or series to pass to Borg (or "latest")' + '--archive', + help='Archive name, hash, or series to pass to Borg (or "latest")', ) borg_group.add_argument( '--', @@ -1839,6 +1975,9 @@ def make_parsers(schema, unparsed_arguments): return global_parser, action_parsers, global_plus_action_parser +HIGHLANDER_ACTION_ARGUMENTS_COUNT = 2 # 1 for "global" + 1 for the action + + def parse_arguments(schema, *unparsed_arguments): ''' Given a configuration schema dict and the command-line arguments with which this script was @@ -1849,21 +1988,22 @@ def parse_arguments(schema, *unparsed_arguments): Raise SystemExit with an error code of 0 if "--help" was requested. ''' global_parser, action_parsers, global_plus_action_parser = make_parsers( - schema, unparsed_arguments + schema, + unparsed_arguments, ) arguments, remaining_action_arguments = parse_arguments_for_actions( - unparsed_arguments, action_parsers.choices, global_parser + unparsed_arguments, + action_parsers.choices, + global_parser, ) if not arguments['global'].config_paths: arguments['global'].config_paths = collect.get_default_config_paths(expand_home=True) for action_name in ('bootstrap', 'generate', 'validate'): - if ( - action_name in arguments.keys() and len(arguments.keys()) > 2 - ): # 2 = 1 for 'global' + 1 for the action + if action_name in arguments and len(arguments) > HIGHLANDER_ACTION_ARGUMENTS_COUNT: raise ValueError( - f'The {action_name} action cannot be combined with other actions. Please run it separately.' + f'The {action_name} action cannot be combined with other actions. Please run it separately.', ) unknown_arguments = get_unparsable_arguments(remaining_action_arguments) @@ -1875,11 +2015,11 @@ def parse_arguments(schema, *unparsed_arguments): global_plus_action_parser.print_usage() raise ValueError( - f"Unrecognized argument{'s' if len(unknown_arguments) > 1 else ''}: {' '.join(unknown_arguments)}" + f"Unrecognized argument{'s' if len(unknown_arguments) > 1 else ''}: {' '.join(unknown_arguments)}", ) if ( - ('list' in arguments and 'repo-info' in arguments and arguments['list'].json) + ('list' in arguments and 'repo-info' in arguments and arguments['list'].json) # noqa: PLR0916 or ('list' in arguments and 'info' in arguments and arguments['list'].json) or ('repo-info' in arguments and 'info' in arguments and arguments['repo-info'].json) ): @@ -1887,23 +2027,23 @@ def parse_arguments(schema, *unparsed_arguments): if 'list' in arguments and (arguments['list'].prefix and arguments['list'].match_archives): raise ValueError( - 'With the list action, only one of --prefix or --match-archives flags can be used.' + 'With the list action, only one of --prefix or --match-archives flags can be used.', ) if 'repo-list' in arguments and ( arguments['repo-list'].prefix and arguments['repo-list'].match_archives ): raise ValueError( - 'With the repo-list action, only one of --prefix or --match-archives flags can be used.' + 'With the repo-list action, only one of --prefix or --match-archives flags can be used.', ) - if 'info' in arguments and ( + if 'info' in arguments and ( # noqa: PLR0916 (arguments['info'].archive and arguments['info'].prefix) or (arguments['info'].archive and arguments['info'].match_archives) or (arguments['info'].prefix and arguments['info'].match_archives) ): raise ValueError( - 'With the info action, only one of --archive, --prefix, or --match-archives flags can be used.' + 'With the info action, only one of --archive, --prefix, or --match-archives flags can be used.', ) if 'borg' in arguments and arguments['global'].dry_run: diff --git a/borgmatic/commands/borgmatic.py b/borgmatic/commands/borgmatic.py index 34f7001b..e2e59d76 100644 --- a/borgmatic/commands/borgmatic.py +++ b/borgmatic/commands/borgmatic.py @@ -96,7 +96,7 @@ class Monitoring_hooks: self.config = config self.dry_run = global_arguments.dry_run self.monitoring_log_level = verbosity_to_log_level( - get_verbosity({config_filename: config}, 'monitoring_verbosity') + get_verbosity({config_filename: config}, 'monitoring_verbosity'), ) self.monitoring_hooks_are_activated = ( using_primary_action and self.monitoring_log_level != DISABLED @@ -182,7 +182,7 @@ class Monitoring_hooks: ) -def run_configuration(config_filename, config, config_paths, arguments): +def run_configuration(config_filename, config, config_paths, arguments): # noqa: PLR0912, PLR0915 ''' Given a config filename, the corresponding parsed config dict, a sequence of loaded configuration paths, and command-line arguments as a dict from subparser name to a namespace of @@ -206,12 +206,13 @@ def run_configuration(config_filename, config, config_paths, arguments): if skip_actions: logger.debug( - f"Skipping {'/'.join(skip_actions)} action{'s' if len(skip_actions) > 1 else ''} due to configured skip_actions" + f"Skipping {'/'.join(skip_actions)} action{'s' if len(skip_actions) > 1 else ''} due to configured skip_actions", ) - try: - with Monitoring_hooks(config_filename, config, arguments, global_arguments): - with borgmatic.hooks.command.Before_after_hooks( + try: # noqa: PLR1702 + with ( + Monitoring_hooks(config_filename, config, arguments, global_arguments), + borgmatic.hooks.command.Before_after_hooks( command_hooks=config.get('commands'), before_after='configuration', umask=config.get('umask'), @@ -220,75 +221,77 @@ def run_configuration(config_filename, config, config_paths, arguments): action_names=arguments.keys(), configuration_filename=config_filename, log_file=config.get('log_file', ''), - ): - try: - local_borg_version = borg_version.local_borg_version(config, local_path) - logger.debug(f'Borg {local_borg_version}') - except (OSError, CalledProcessError, ValueError) as error: - yield from log_error_records( - f'{config_filename}: Error getting local Borg version', error - ) - raise + ), + ): + try: + local_borg_version = borg_version.local_borg_version(config, local_path) + logger.debug(f'Borg {local_borg_version}') + except (OSError, CalledProcessError, ValueError) as error: + yield from log_error_records( + f'{config_filename}: Error getting local Borg version', + error, + ) + raise - for repo in config['repositories']: - repo_queue.put( - (repo, 0), - ) + for repo in config['repositories']: + repo_queue.put( + (repo, 0), + ) - while not repo_queue.empty(): - repository, retry_num = repo_queue.get() + while not repo_queue.empty(): + repository, retry_num = repo_queue.get() - with Log_prefix(repository.get('label', repository['path'])): - logger.debug('Running actions for repository') - timeout = retry_num * retry_wait + with Log_prefix(repository.get('label', repository['path'])): + logger.debug('Running actions for repository') + timeout = retry_num * retry_wait - if timeout: - logger.warning(f'Sleeping {timeout}s before next retry') - time.sleep(timeout) + if timeout: + logger.warning(f'Sleeping {timeout}s before next retry') + time.sleep(timeout) - try: - yield from run_actions( - arguments=arguments, - config_filename=config_filename, - config=config, - config_paths=config_paths, - local_path=local_path, - remote_path=remote_path, - local_borg_version=local_borg_version, - repository=repository, + try: + yield from run_actions( + arguments=arguments, + config_filename=config_filename, + config=config, + config_paths=config_paths, + local_path=local_path, + remote_path=remote_path, + local_borg_version=local_borg_version, + repository=repository, + ) + except (OSError, CalledProcessError, ValueError) as error: + if retry_num < retries: + repo_queue.put( + (repository, retry_num + 1), ) - except (OSError, CalledProcessError, ValueError) as error: - if retry_num < retries: - repo_queue.put( - (repository, retry_num + 1), - ) - tuple( # Consume the generator so as to trigger logging. - log_error_records( - 'Error running actions for repository', - error, - levelno=logging.WARNING, - log_command_error_output=True, - ) - ) - logger.warning(f'Retrying... attempt {retry_num + 1}/{retries}') - continue - - if command.considered_soft_failure(error): - continue - - yield from log_error_records( - 'Error running actions for repository', - error, + tuple( # Consume the generator so as to trigger logging. + log_error_records( + 'Error running actions for repository', + error, + levelno=logging.WARNING, + log_command_error_output=True, + ), ) - encountered_error = error - error_repository = repository + logger.warning(f'Retrying... attempt {retry_num + 1}/{retries}') + continue - # Re-raise any error, so that the Monitoring_hooks context manager wrapping this - # code can see the error and act accordingly. Do this here rather than as soon as - # the error is encountered so that an error with one repository doesn't prevent - # other repositories from running. - if encountered_error: - raise encountered_error + if command.considered_soft_failure(error): + continue + + yield from log_error_records( + 'Error running actions for repository', + error, + ) + encountered_error = error + error_repository = repository + + # Re-raise any error, so that the Monitoring_hooks context manager wrapping this + # code can see the error and act accordingly. Do this here rather than as soon as + # the error is encountered so that an error with one repository doesn't prevent + # other repositories from running. + if encountered_error: + raise encountered_error except (OSError, CalledProcessError, ValueError) as error: yield from log_error_records('Error running configuration') @@ -323,7 +326,7 @@ def run_configuration(config_filename, config, config_paths, arguments): yield from log_error_records(f'{config_filename}: Error running after error hook', error) -def run_actions( +def run_actions( # noqa: PLR0912, PLR0915 *, arguments, config_filename, @@ -641,9 +644,9 @@ def load_configurations(config_filenames, arguments, overrides=None, resolve_env levelno=logging.DEBUG, levelname='DEBUG', msg=f'{config_filename}: Loading configuration file', - ) + ), ), - ] + ], ) try: configs[config_filename], paths, parse_logs = validate.parse_configuration( @@ -663,9 +666,9 @@ def load_configurations(config_filenames, arguments, overrides=None, resolve_env levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: Insufficient permissions to read configuration file', - ) + ), ), - ] + ], ) except (ValueError, OSError, validate.Validation_error) as error: logs.extend( @@ -675,12 +678,12 @@ def load_configurations(config_filenames, arguments, overrides=None, resolve_env levelno=logging.CRITICAL, levelname='CRITICAL', msg=f'{config_filename}: Error parsing configuration file', - ) + ), ), logging.makeLogRecord( - dict(levelno=logging.CRITICAL, levelname='CRITICAL', msg=str(error)) + dict(levelno=logging.CRITICAL, levelname='CRITICAL', msg=str(error)), ), - ] + ], ) return (configs, sorted(config_paths), logs) @@ -703,7 +706,10 @@ BORG_REPOSITORY_ACCESS_ABORTED_EXIT_CODE = 62 def log_error_records( - message, error=None, levelno=logging.CRITICAL, log_command_error_output=False + message, + error=None, + levelno=logging.CRITICAL, + log_command_error_output=False, ): ''' Given error message text, an optional exception object, an optional log level, and whether to @@ -721,14 +727,14 @@ def log_error_records( try: raise error - except CalledProcessError as error: + except CalledProcessError as called_process_error: yield log_record(levelno=levelno, levelname=level_name, msg=str(message)) - if error.output: + if called_process_error.output: try: - output = error.output.decode('utf-8') + output = called_process_error.output.decode('utf-8') except (UnicodeDecodeError, AttributeError): - output = error.output + output = called_process_error.output # Suppress these logs for now and save the error output for the log summary at the end. # Log a separate record per line, as some errors can be really verbose and overflow the @@ -741,17 +747,17 @@ def log_error_records( suppress_log=True, ) - yield log_record(levelno=levelno, levelname=level_name, msg=str(error)) + yield log_record(levelno=levelno, levelname=level_name, msg=str(called_process_error)) - if error.returncode == BORG_REPOSITORY_ACCESS_ABORTED_EXIT_CODE: + if called_process_error.returncode == BORG_REPOSITORY_ACCESS_ABORTED_EXIT_CODE: yield log_record( levelno=levelno, levelname=level_name, msg='\nTo work around this, set either the "relocated_repo_access_is_ok" or "unknown_unencrypted_repo_access_is_ok" option to "true", as appropriate.', ) - except (ValueError, OSError) as error: + except (ValueError, OSError) as other_error: yield log_record(levelno=levelno, levelname=level_name, msg=str(message)) - yield log_record(levelno=levelno, levelname=level_name, msg=str(error)) + yield log_record(levelno=levelno, levelname=level_name, msg=str(other_error)) except: # noqa: E722, S110 # Raising above only as a means of determining the error type. Swallow the exception here # because we don't want the exception to propagate out of this function. @@ -783,7 +789,8 @@ def collect_highlander_action_summary_logs(configs, arguments, configuration_par try: # No configuration file is needed for bootstrap. local_borg_version = borg_version.local_borg_version( - {}, arguments['bootstrap'].local_path + {}, + arguments['bootstrap'].local_path, ) except (OSError, CalledProcessError, ValueError) as error: yield from log_error_records('Error getting local Borg version', error) @@ -791,14 +798,16 @@ def collect_highlander_action_summary_logs(configs, arguments, configuration_par try: borgmatic.actions.config.bootstrap.run_bootstrap( - arguments['bootstrap'], arguments['global'], local_borg_version + arguments['bootstrap'], + arguments['global'], + local_borg_version, ) yield logging.makeLogRecord( dict( levelno=logging.ANSWER, levelname='ANSWER', msg='Bootstrap successful', - ) + ), ) except ( CalledProcessError, @@ -812,14 +821,15 @@ def collect_highlander_action_summary_logs(configs, arguments, configuration_par if 'generate' in arguments: try: borgmatic.actions.config.generate.run_generate( - arguments['generate'], arguments['global'] + arguments['generate'], + arguments['global'], ) yield logging.makeLogRecord( dict( levelno=logging.ANSWER, levelname='ANSWER', msg='Generate successful', - ) + ), ) except ( CalledProcessError, @@ -837,7 +847,7 @@ def collect_highlander_action_summary_logs(configs, arguments, configuration_par levelno=logging.CRITICAL, levelname='CRITICAL', msg='Configuration validation failed', - ) + ), ) return @@ -850,7 +860,7 @@ def collect_highlander_action_summary_logs(configs, arguments, configuration_par levelno=logging.ANSWER, levelname='ANSWER', msg='All configuration files are valid', - ) + ), ) except ( CalledProcessError, @@ -862,7 +872,7 @@ def collect_highlander_action_summary_logs(configs, arguments, configuration_par return -def collect_configuration_run_summary_logs(configs, config_paths, arguments, log_file_path): +def collect_configuration_run_summary_logs(configs, config_paths, arguments, log_file_path): # noqa: PLR0912 ''' Given a dict of configuration filename to corresponding parsed configuration, a sequence of loaded configuration paths, parsed command-line arguments as a dict from subparser name to a @@ -875,9 +885,9 @@ def collect_configuration_run_summary_logs(configs, config_paths, arguments, log # Run cross-file validation checks. repository = None - for action_name, action_arguments in arguments.items(): + for action_arguments in arguments.values(): if hasattr(action_arguments, 'repository'): - repository = getattr(action_arguments, 'repository') + repository = action_arguments.repository break try: @@ -942,7 +952,7 @@ def collect_configuration_run_summary_logs(configs, config_paths, arguments, log levelno=logging.INFO, levelname='INFO', msg=f'{config_filename}: Successfully ran configuration file', - ) + ), ) if results: json_results.extend(results) @@ -1031,17 +1041,17 @@ def get_singular_option_value(configs, option_name): configure_logging(logging.CRITICAL) joined_values = ', '.join(str(value) for value in distinct_values) logger.critical( - f'The {option_name} option has conflicting values across configuration files: {joined_values}' + f'The {option_name} option has conflicting values across configuration files: {joined_values}', ) exit_with_help_link() try: - return tuple(distinct_values)[0] - except IndexError: + return next(iter(distinct_values)) + except StopIteration: return None -def main(extra_summary_logs=[]): # pragma: no cover +def main(extra_summary_logs=()): # pragma: no cover configure_signals() configure_delayed_logging() schema_filename = validate.schema_filename() @@ -1070,15 +1080,15 @@ def main(extra_summary_logs=[]): # pragma: no cover global_arguments = arguments['global'] if global_arguments.version: - print(importlib.metadata.version('borgmatic')) + print(importlib.metadata.version('borgmatic')) # noqa: T201 sys.exit(0) if global_arguments.bash_completion: - print(borgmatic.commands.completion.bash.bash_completion()) + print(borgmatic.commands.completion.bash.bash_completion()) # noqa: T201 sys.exit(0) if global_arguments.fish_completion: - print(borgmatic.commands.completion.fish.fish_completion()) + print(borgmatic.commands.completion.fish.fish_completion()) # noqa: T201 sys.exit(0) config_filenames = tuple(collect.collect_config_filenames(global_arguments.config_paths)) @@ -1117,18 +1127,23 @@ def main(extra_summary_logs=[]): # pragma: no cover exit_with_help_link() summary_logs = ( - extra_summary_logs + list(extra_summary_logs) + parse_logs + ( list( collect_highlander_action_summary_logs( - configs, arguments, configuration_parse_errors - ) + configs, + arguments, + configuration_parse_errors, + ), ) or list( collect_configuration_run_summary_logs( - configs, config_paths, arguments, log_file_path - ) + configs, + config_paths, + arguments, + log_file_path, + ), ) ) ) diff --git a/borgmatic/commands/completion/actions.py b/borgmatic/commands/completion/actions.py index 1f0e2f36..2bf43795 100644 --- a/borgmatic/commands/completion/actions.py +++ b/borgmatic/commands/completion/actions.py @@ -22,15 +22,15 @@ def available_actions(subparsers, current_action=None): action of "config" but not "list". ''' action_to_subactions = borgmatic.commands.arguments.get_subactions_for_actions( - subparsers.choices + subparsers.choices, ) current_subactions = action_to_subactions.get(current_action) if current_subactions: return current_subactions - all_subactions = set( + all_subactions = { subaction for subactions in action_to_subactions.values() for subaction in subactions - ) + } - return tuple(action for action in subparsers.choices.keys() if action not in all_subactions) + return tuple(action for action in subparsers.choices if action not in all_subactions) diff --git a/borgmatic/commands/completion/bash.py b/borgmatic/commands/completion/bash.py index c72fbbec..e662aaea 100644 --- a/borgmatic/commands/completion/bash.py +++ b/borgmatic/commands/completion/bash.py @@ -23,7 +23,7 @@ def bash_completion(): borgmatic's command-line argument parsers. ''' ( - unused_global_parser, + _, action_parsers, global_plus_action_parser, ) = borgmatic.commands.arguments.make_parsers( @@ -33,6 +33,7 @@ def bash_completion(): global_flags = parser_flags(global_plus_action_parser) # Avert your eyes. + # fmt: off return '\n'.join( ( 'check_version() {', @@ -47,24 +48,22 @@ def bash_completion(): ' fi', '}', 'complete_borgmatic() {', - ) - + tuple( + *tuple( ''' if [[ " ${COMP_WORDS[*]} " =~ " %s " ]]; then COMPREPLY=($(compgen -W "%s %s %s" -- "${COMP_WORDS[COMP_CWORD]}")) return 0 - fi''' + fi''' # noqa: UP031 % ( action, parser_flags(action_parser), ' '.join( - borgmatic.commands.completion.actions.available_actions(action_parsers, action) + borgmatic.commands.completion.actions.available_actions(action_parsers, action), ), global_flags, ) for action, action_parser in reversed(action_parsers.choices.items()) - ) - + ( - ' COMPREPLY=($(compgen -W "%s %s" -- "${COMP_WORDS[COMP_CWORD]}"))' # noqa: FS003 + ), + ' COMPREPLY=($(compgen -W "%s %s" -- "${COMP_WORDS[COMP_CWORD]}"))' # noqa: UP031 % ( ' '.join(borgmatic.commands.completion.actions.available_actions(action_parsers)), global_flags, @@ -72,5 +71,5 @@ def bash_completion(): ' (check_version &)', '}', '\ncomplete -o bashdefault -o default -F complete_borgmatic borgmatic', - ) + ), ) diff --git a/borgmatic/commands/completion/fish.py b/borgmatic/commands/completion/fish.py index 31b83e9c..4ad6accb 100644 --- a/borgmatic/commands/completion/fish.py +++ b/borgmatic/commands/completion/fish.py @@ -11,10 +11,10 @@ def has_file_options(action: Action): ''' Given an argparse.Action instance, return True if it takes a file argument. ''' - return action.metavar in ( + return action.metavar in { 'FILENAME', 'PATH', - ) or action.dest in ('config_paths',) + } or action.dest in {'config_paths'} def has_choice_options(action: Action): @@ -36,11 +36,11 @@ def has_unknown_required_param_options(action: Action): return ( action.required is True or action.nargs - in ( + in { '+', '*', - ) - or action.metavar in ('PATTERN', 'KEYS', 'N') + } + or action.metavar in {'PATTERN', 'KEYS', 'N'} or (action.type is not None and action.default is None) ) @@ -77,7 +77,7 @@ def exact_options_completion(action: Action): return f'''\ncomplete -c borgmatic -x -n "__borgmatic_current_arg {args}"''' raise ValueError( - f'Unexpected action: {action} passes has_exact_options but has no choices produced' + f'Unexpected action: {action} passes has_exact_options but has no choices produced', ) @@ -96,7 +96,7 @@ def fish_completion(): borgmatic's command-line argument parsers. ''' ( - unused_global_parser, + _, action_parsers, global_plus_action_parser, ) = borgmatic.commands.arguments.make_parsers( @@ -104,7 +104,7 @@ def fish_completion(): unparsed_arguments=(), ) - all_action_parsers = ' '.join(action for action in action_parsers.choices.keys()) + all_action_parsers = ' '.join(action for action in action_parsers.choices) exact_option_args = tuple( ' '.join(action.option_strings) @@ -119,8 +119,9 @@ def fish_completion(): ) # Avert your eyes. - return '\n'.join( - dedent_strip_as_tuple( + # fmt: off + return '\n'.join(( + *dedent_strip_as_tuple( f''' function __borgmatic_check_version set -fx this_filename (status current-filename) @@ -157,27 +158,27 @@ def fish_completion(): set --local action_parser_condition "not __fish_seen_subcommand_from {all_action_parsers}" set --local exact_option_condition "not __borgmatic_current_arg {' '.join(exact_option_args)}" - ''' - ) - + ('\n# action_parser completions',) - + tuple( + ''', + ), + '\n# action_parser completions', + *tuple( f'''complete -c borgmatic -f -n "$action_parser_condition" -n "$exact_option_condition" -a '{action_name}' -d {shlex.quote(action_parser.description)}''' for action_name, action_parser in action_parsers.choices.items() - ) - + ('\n# global flags',) - + tuple( + ), + '\n# global flags', + *tuple( # -n is checked in order, so put faster / more likely to be true checks first f'''complete -c borgmatic -f -n "$exact_option_condition" -a '{' '.join(action.option_strings)}' -d {shlex.quote(action.help)}{exact_options_completion(action)}''' for action in global_plus_action_parser._actions # ignore the noargs action, as this is an impossible completion for fish if len(action.option_strings) > 0 if 'Deprecated' not in action.help - ) - + ('\n# action_parser flags',) - + tuple( + ), + '\n# action_parser flags', + *tuple( f'''complete -c borgmatic -f -n "$exact_option_condition" -a '{' '.join(action.option_strings)}' -d {shlex.quote(action.help)} -n "__fish_seen_subcommand_from {action_name}"{exact_options_completion(action)}''' for action_name, action_parser in action_parsers.choices.items() for action in action_parser._actions if 'Deprecated' not in (action.help or ()) - ) - ) + ), + )) diff --git a/borgmatic/commands/completion/flag.py b/borgmatic/commands/completion/flag.py index 5a6bc797..32e90718 100644 --- a/borgmatic/commands/completion/flag.py +++ b/borgmatic/commands/completion/flag.py @@ -5,7 +5,7 @@ def variants(flag_name): "--foo[9].bar". ''' if '[0]' in flag_name: - for index in range(0, 10): + for index in range(10): yield flag_name.replace('[0]', f'[{index}]') return diff --git a/borgmatic/commands/generate_config.py b/borgmatic/commands/generate_config.py index f95b3094..5c0bad23 100644 --- a/borgmatic/commands/generate_config.py +++ b/borgmatic/commands/generate_config.py @@ -10,8 +10,8 @@ def main(): levelno=logging.WARNING, levelname='WARNING', msg='generate-borgmatic-config is deprecated and will be removed from a future release. Please use "borgmatic config generate" instead.', - ) + ), ) - sys.argv = ['borgmatic', 'config', 'generate'] + sys.argv[1:] + sys.argv = ['borgmatic', 'config', 'generate', *sys.argv[1:]] borgmatic.commands.borgmatic.main([warning_log]) diff --git a/borgmatic/commands/validate_config.py b/borgmatic/commands/validate_config.py index 0b3dd1ff..c5fff952 100644 --- a/borgmatic/commands/validate_config.py +++ b/borgmatic/commands/validate_config.py @@ -10,8 +10,8 @@ def main(): levelno=logging.WARNING, levelname='WARNING', msg='validate-borgmatic-config is deprecated and will be removed from a future release. Please use "borgmatic config validate" instead.', - ) + ), ) - sys.argv = ['borgmatic', 'config', 'validate'] + sys.argv[1:] + sys.argv = ['borgmatic', 'config', 'validate', *sys.argv[1:]] borgmatic.commands.borgmatic.main([warning_log]) diff --git a/borgmatic/config/arguments.py b/borgmatic/config/arguments.py index d5996f0a..e50314ae 100644 --- a/borgmatic/config/arguments.py +++ b/borgmatic/config/arguments.py @@ -155,7 +155,7 @@ def prepare_arguments_for_config(global_arguments, schema): ( keys, convert_value_type(value, option_type), - ) + ), ) return tuple(prepared_values) diff --git a/borgmatic/config/collect.py b/borgmatic/config/collect.py index 80c6c5c0..2677f5b1 100644 --- a/borgmatic/config/collect.py +++ b/borgmatic/config/collect.py @@ -49,6 +49,6 @@ def collect_config_filenames(config_paths): for filename in sorted(os.listdir(path)): full_filename = os.path.join(path, filename) - matching_filetype = full_filename.endswith('.yaml') or full_filename.endswith('.yml') + matching_filetype = full_filename.endswith(('.yaml', '.yml')) if matching_filetype and not os.path.isdir(full_filename): yield os.path.abspath(full_filename) diff --git a/borgmatic/config/constants.py b/borgmatic/config/constants.py index bb9fd215..876d986e 100644 --- a/borgmatic/config/constants.py +++ b/borgmatic/config/constants.py @@ -1,3 +1,4 @@ +import contextlib import shlex @@ -6,18 +7,18 @@ def coerce_scalar(value): Given a configuration value, coerce it to an integer or a boolean as appropriate and return the result. ''' - try: + with contextlib.suppress(TypeError, ValueError): return int(value) - except (TypeError, ValueError): - pass - if value == 'true' or value == 'True': - return True - - if value == 'false' or value == 'False': - return False - - return value + try: + return { + 'true': True, + 'True': True, + 'false': False, + 'False': False, + }.get(value, value) + except TypeError: # e.g. for an unhashable type + return value def apply_constants(value, constants, shell_escape=False): @@ -56,8 +57,7 @@ def apply_constants(value, constants, shell_escape=False): constants, shell_escape=( shell_escape - or option_name.startswith('before_') - or option_name.startswith('after_') + or option_name.startswith(('before_', 'after_')) or option_name == 'on_error' ), ) diff --git a/borgmatic/config/environment.py b/borgmatic/config/environment.py index fd595846..11601ccb 100644 --- a/borgmatic/config/environment.py +++ b/borgmatic/config/environment.py @@ -2,7 +2,7 @@ import os import re VARIABLE_PATTERN = re.compile( - r'(?P\\)?(?P\$\{(?P[A-Za-z0-9_]+)((:?-)(?P[^}]+))?\})' + r'(?P\\)?(?P\$\{(?P[A-Za-z0-9_]+)((:?-)(?P[^}]+))?\})', ) diff --git a/borgmatic/config/generate.py b/borgmatic/config/generate.py index 6321a785..fd287482 100644 --- a/borgmatic/config/generate.py +++ b/borgmatic/config/generate.py @@ -1,4 +1,5 @@ import collections +import contextlib import io import os import re @@ -18,7 +19,8 @@ def insert_newline_before_comment(config, field_name): field and its comments. ''' config.ca.items[field_name][1].insert( - 0, ruamel.yaml.tokens.CommentToken('\n', ruamel.yaml.error.CommentMark(0), None) + 0, + ruamel.yaml.tokens.CommentToken('\n', ruamel.yaml.error.CommentMark(0), None), ) @@ -40,13 +42,17 @@ def schema_to_sample_configuration(schema, source_config=None, level=0, parent_i config = ruamel.yaml.comments.CommentedSeq( example if borgmatic.config.schema.compare_types( - schema['items'].get('type'), SCALAR_SCHEMA_TYPES + schema['items'].get('type'), + SCALAR_SCHEMA_TYPES, ) else [ schema_to_sample_configuration( - schema['items'], source_config, level, parent_is_sequence=True - ) - ] + schema['items'], + source_config, + level, + parent_is_sequence=True, + ), + ], ) add_comments_to_configuration_sequence(config, schema, indent=(level * INDENT)) elif borgmatic.config.schema.compare_types(schema_type, {'object'}): @@ -59,19 +65,25 @@ def schema_to_sample_configuration(schema, source_config=None, level=0, parent_i ( field_name, schema_to_sample_configuration( - sub_schema, (source_config or {}).get(field_name, {}), level + 1 + sub_schema, + (source_config or {}).get(field_name, {}), + level + 1, ), ) for field_name, sub_schema in borgmatic.config.schema.get_properties( - schema + schema, ).items() - ] + ], ) or example ) indent = (level * INDENT) + (SEQUENCE_INDENT if parent_is_sequence else 0) add_comments_to_configuration_object( - config, schema, source_config, indent=indent, skip_first_field=parent_is_sequence + config, + schema, + source_config, + indent=indent, + skip_first_field=parent_is_sequence, ) elif borgmatic.config.schema.compare_types(schema_type, SCALAR_SCHEMA_TYPES, match=all): return example @@ -121,12 +133,8 @@ def comment_out_optional_configuration(rendered_config): indent_characters_at_sentinel = indent_characters continue - # Hit a blank line, so reset commenting. - if not line.strip(): - optional = False - indent_characters_at_sentinel = None - # Dedented, so reset commenting. - elif ( + # Hit a blank line or dedented, so reset commenting. + if not line.strip() or ( indent_characters_at_sentinel is not None and indent_characters < indent_characters_at_sentinel ): @@ -158,15 +166,13 @@ def write_configuration(config_filename, rendered_config, mode=0o600, overwrite= ''' if not overwrite and os.path.exists(config_filename): raise FileExistsError( - f'{config_filename} already exists. Aborting. Use --overwrite to replace the file.' + f'{config_filename} already exists. Aborting. Use --overwrite to replace the file.', ) - try: + with contextlib.suppress(FileExistsError, FileNotFoundError): os.makedirs(os.path.dirname(config_filename), mode=0o700) - except (FileExistsError, FileNotFoundError): - pass - with open(config_filename, 'w') as config_file: + with open(config_filename, 'w', encoding='utf-8') as config_file: config_file.write(rendered_config) os.chmod(config_filename, mode) @@ -191,7 +197,7 @@ def add_comments_to_configuration_sequence(config, schema, indent=0): if schema['items'].get('type') != 'object': return - for field_name in config[0].keys(): + for field_name in config[0]: field_schema = borgmatic.config.schema.get_properties(schema['items']).get(field_name, {}) description = field_schema.get('description') @@ -211,7 +217,11 @@ COMMENTED_OUT_SENTINEL = 'COMMENT_OUT' def add_comments_to_configuration_object( - config, schema, source_config=None, indent=0, skip_first_field=False + config, + schema, + source_config=None, + indent=0, + skip_first_field=False, ): ''' Using descriptions from a schema as a source, add those descriptions as comments to the given @@ -239,7 +249,7 @@ def add_comments_to_configuration_object( source_config is None or field_name not in source_config ): description = ( - '\n'.join((description, COMMENTED_OUT_SENTINEL)) + f'{description}\n{COMMENTED_OUT_SENTINEL}' if description else COMMENTED_OUT_SENTINEL ) @@ -275,7 +285,8 @@ def merge_source_configuration_into_destination(destination_config, source_confi # This is a mapping. Recurse for this key/value. if isinstance(source_value, collections.abc.Mapping): destination_config[field_name] = merge_source_configuration_into_destination( - destination_config[field_name], source_value + destination_config[field_name], + source_value, ) continue @@ -289,18 +300,22 @@ def merge_source_configuration_into_destination(destination_config, source_confi source_item, ) for index, source_item in enumerate(source_value) - ] + ], ) continue # This is some sort of scalar. Set it into the destination. - destination_config[field_name] = source_config[field_name] + destination_config[field_name] = source_value return destination_config def generate_sample_configuration( - dry_run, source_filename, destination_filename, schema_filename, overwrite=False + dry_run, + source_filename, + destination_filename, + schema_filename, + overwrite=False, ): ''' Given an optional source configuration filename, and a required destination configuration @@ -309,7 +324,7 @@ def generate_sample_configuration( schema. If a source filename is provided, merge the parsed contents of that configuration into the generated configuration. ''' - schema = ruamel.yaml.YAML(typ='safe').load(open(schema_filename)) + schema = ruamel.yaml.YAML(typ='safe').load(open(schema_filename, encoding='utf-8')) source_config = None if source_filename: @@ -323,7 +338,8 @@ def generate_sample_configuration( del source_config['bootstrap'] destination_config = merge_source_configuration_into_destination( - schema_to_sample_configuration(schema, source_config), source_config + schema_to_sample_configuration(schema, source_config), + source_config, ) if dry_run: diff --git a/borgmatic/config/load.py b/borgmatic/config/load.py index 864bf3e5..d16d7ad9 100644 --- a/borgmatic/config/load.py +++ b/borgmatic/config/load.py @@ -31,7 +31,7 @@ def probe_and_include_file(filename, include_directories, config_paths): return load_configuration(candidate_filename, config_paths) raise FileNotFoundError( - f'Could not find include {filename} at {" or ".join(candidate_filenames)}' + f'Could not find include {filename} at {" or ".join(candidate_filenames)}', ) @@ -69,7 +69,7 @@ def include_configuration(loader, filename_node, include_directory, config_paths ] raise ValueError( - 'The value given for the !include tag is invalid; use a single filename or a list of filenames instead' + 'The value given for the !include tag is invalid; use a single filename or a list of filenames instead', ) @@ -85,7 +85,7 @@ def raise_retain_node_error(loader, node): ''' if isinstance(node, (ruamel.yaml.nodes.MappingNode, ruamel.yaml.nodes.SequenceNode)): raise ValueError( - 'The !retain tag may only be used within a configuration file containing a merged !include tag.' + 'The !retain tag may only be used within a configuration file containing a merged !include tag.', ) raise ValueError('The !retain tag may only be used on a mapping or list.') @@ -100,7 +100,7 @@ def raise_omit_node_error(loader, node): tags are handled by deep_merge_nodes() below. ''' raise ValueError( - 'The !omit tag may only be used on a scalar (e.g., string) or list element within a configuration file containing a merged !include tag.' + 'The !omit tag may only be used on a scalar (e.g., string) or list element within a configuration file containing a merged !include tag.', ) @@ -111,9 +111,13 @@ class Include_constructor(ruamel.yaml.SafeConstructor): ''' def __init__( - self, preserve_quotes=None, loader=None, include_directory=None, config_paths=None + self, + preserve_quotes=None, + loader=None, + include_directory=None, + config_paths=None, ): - super(Include_constructor, self).__init__(preserve_quotes, loader) + super().__init__(preserve_quotes, loader) self.add_constructor( '!include', functools.partial( @@ -147,7 +151,7 @@ class Include_constructor(ruamel.yaml.SafeConstructor): representer = ruamel.yaml.representer.SafeRepresenter() for index, (key_node, value_node) in enumerate(node.value): - if key_node.tag == u'tag:yaml.org,2002:merge' and value_node.tag == '!include': + if key_node.tag == 'tag:yaml.org,2002:merge' and value_node.tag == '!include': # Replace the merge include with a sequence of included configuration nodes ready # for merging. The construct_object() call here triggers include_configuration() # among other constructors. @@ -157,7 +161,7 @@ class Include_constructor(ruamel.yaml.SafeConstructor): ) # This super().flatten_mapping() call actually performs "<<" merges. - super(Include_constructor, self).flatten_mapping(node) + super().flatten_mapping(node) node.value = deep_merge_nodes(node.value) @@ -179,7 +183,7 @@ def load_configuration(filename, config_paths=None): # because yaml.Constructor has to be an actual class.) class Include_constructor_with_extras(Include_constructor): def __init__(self, preserve_quotes=None, loader=None): - super(Include_constructor_with_extras, self).__init__( + super().__init__( preserve_quotes, loader, include_directory=os.path.dirname(filename), @@ -190,7 +194,7 @@ def load_configuration(filename, config_paths=None): yaml.Constructor = Include_constructor_with_extras config_paths.add(filename) - with open(filename) as file: + with open(filename, encoding='utf-8') as file: return yaml.load(file.read()) @@ -318,17 +322,18 @@ def deep_merge_nodes(nodes): # Bucket the nodes by their keys. Then merge all of the values sharing the same key. for key_name, grouped_nodes in itertools.groupby( - sorted(nodes, key=get_node_key_name), get_node_key_name + sorted(nodes, key=get_node_key_name), + get_node_key_name, ): - grouped_nodes = list(grouped_nodes) + grouped_nodes = list(grouped_nodes) # noqa: PLW2901 # The merged node inherits its attributes from the final node in the group. (last_node_key, last_node_value) = grouped_nodes[-1] - value_types = set(type(value) for (_, value) in grouped_nodes) + value_types = {type(value) for (_, value) in grouped_nodes} if len(value_types) > 1: raise ValueError( - f'Incompatible types found when trying to merge "{key_name}:" values across configuration files: {", ".join(value_type.id for value_type in value_types)}' + f'Incompatible types found when trying to merge "{key_name}:" values across configuration files: {", ".join(value_type.id for value_type in value_types)}', ) # If we're dealing with MappingNodes, recurse and merge its values as well. @@ -351,7 +356,7 @@ def deep_merge_nodes(nodes): comment=last_node_value.comment, anchor=last_node_value.anchor, ), - ) + ), ) continue @@ -374,7 +379,7 @@ def deep_merge_nodes(nodes): comment=last_node_value.comment, anchor=last_node_value.anchor, ), - ) + ), ) continue diff --git a/borgmatic/config/normalize.py b/borgmatic/config/normalize.py index dc8998c4..6a251954 100644 --- a/borgmatic/config/normalize.py +++ b/borgmatic/config/normalize.py @@ -25,12 +25,12 @@ def normalize_sections(config_filename, config): and location.get('prefix') != consistency.get('prefix') ): raise ValueError( - 'The retention prefix and the consistency prefix cannot have different values (unless one is not set).' + 'The retention prefix and the consistency prefix cannot have different values (unless one is not set).', ) if storage.get('umask') and hooks.get('umask') and storage.get('umask') != hooks.get('umask'): raise ValueError( - 'The storage umask and the hooks umask cannot have different values (unless one is not set).' + 'The storage umask and the hooks umask cannot have different values (unless one is not set).', ) any_section_upgraded = False @@ -51,8 +51,8 @@ def normalize_sections(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: Configuration sections (like location:, storage:, retention:, consistency:, and hooks:) are deprecated and support will be removed from a future release. To prepare for this, move your options out of sections to the global scope.', - ) - ) + ), + ), ] return [] @@ -68,7 +68,7 @@ def make_command_hook_deprecation_log(config_filename, option_name): # pragma: levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: {option_name} is deprecated and support will be removed from a future release. Use commands: instead.', - ) + ), ) @@ -90,7 +90,7 @@ def normalize_commands(config_filename, config): { preposition: 'repository', 'run': commands, - } + }, ) # Normalize "before_backup", "before_prune", "after_backup", "after_prune", etc. @@ -108,7 +108,7 @@ def normalize_commands(config_filename, config): preposition: 'action', 'when': [action_name], 'run': commands, - } + }, ) # Normalize "on_error". @@ -121,7 +121,7 @@ def normalize_commands(config_filename, config): 'after': 'error', 'when': ['create', 'prune', 'compact', 'check'], 'run': commands, - } + }, ) # Normalize "before_everything" and "after_everything". @@ -136,13 +136,13 @@ def normalize_commands(config_filename, config): preposition: 'everything', 'when': ['create'], 'run': commands, - } + }, ) return logs -def normalize(config_filename, config): +def normalize(config_filename, config): # noqa: PLR0912, PLR0915 ''' Given a configuration filename and a configuration dict of its loaded contents, apply particular hard-coded rules to normalize the configuration to adhere to the current schema. Return any log @@ -160,8 +160,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The borgmatic_source_directory option is deprecated and will be removed from a future release. Use user_runtime_directory and user_state_directory instead.', - ) - ) + ), + ), ) # Upgrade exclude_if_present from a string to a list. @@ -173,8 +173,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The exclude_if_present option now expects a list value. String values for this option are deprecated and support will be removed from a future release.', - ) - ) + ), + ), ) config['exclude_if_present'] = [exclude_if_present] @@ -191,8 +191,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The store_config_files option has moved under the bootstrap hook. Specifying store_config_files at the global scope is deprecated and support will be removed from a future release.', - ) - ) + ), + ), ) del config['store_config_files'] config['bootstrap']['store_config_files'] = store_config_files @@ -206,8 +206,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The healthchecks hook now expects a key/value pair with "ping_url" as a key. String values for this option are deprecated and support will be removed from a future release.', - ) - ) + ), + ), ) config['healthchecks'] = {'ping_url': healthchecks} @@ -219,8 +219,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The healthchecks hook now expects key/value pairs. String values for this option are deprecated and support will be removed from a future release.', - ) - ) + ), + ), ) config['cronitor'] = {'ping_url': cronitor} @@ -232,8 +232,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The healthchecks hook now expects key/value pairs. String values for this option are deprecated and support will be removed from a future release.', - ) - ) + ), + ), ) config['pagerduty'] = {'integration_key': pagerduty} @@ -245,8 +245,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The healthchecks hook now expects key/value pairs. String values for this option are deprecated and support will be removed from a future release.', - ) - ) + ), + ), ) config['cronhub'] = {'ping_url': cronhub} @@ -259,8 +259,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The checks option now expects a list of key/value pairs. Lists of strings for this option are deprecated and support will be removed from a future release.', - ) - ) + ), + ), ) config['checks'] = [{'name': check_type} for check_type in checks] @@ -273,8 +273,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The numeric_owner option has been renamed to numeric_ids. numeric_owner is deprecated and support will be removed from a future release.', - ) - ) + ), + ), ) config['numeric_ids'] = numeric_owner @@ -286,8 +286,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The bsd_flags option has been renamed to flags. bsd_flags is deprecated and support will be removed from a future release.', - ) - ) + ), + ), ) config['flags'] = bsd_flags @@ -299,8 +299,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The remote_rate_limit option has been renamed to upload_rate_limit. remote_rate_limit is deprecated and support will be removed from a future release.', - ) - ) + ), + ), ) config['upload_rate_limit'] = remote_rate_limit @@ -314,8 +314,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The repositories option now expects a list of key/value pairs. Lists of strings for this option are deprecated and support will be removed from a future release.', - ) - ) + ), + ), ) config['repositories'] = [ {'path': repository} if isinstance(repository, str) else repository @@ -338,28 +338,22 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: Repository paths containing "~" are deprecated in borgmatic and support will be removed from a future release.', - ) - ) + ), + ), ) if ':' in repository_path: if repository_path.startswith('file://'): updated_repository_path = os.path.abspath( - repository_path.partition('file://')[-1] + repository_path.partition('file://')[-1], ) config['repositories'].append( dict( repository_dict, path=updated_repository_path, - ) + ), ) - elif ( - repository_path.startswith('ssh://') - or repository_path.startswith('sftp://') - or repository_path.startswith('rclone:') - or repository_path.startswith('s3:') - or repository_path.startswith('b2:') - ): + elif repository_path.startswith(('ssh://', 'sftp://', 'rclone:', 's3:', 'b2:')): config['repositories'].append(repository_dict) else: rewritten_repository_path = f"ssh://{repository_path.replace(':~', '/~').replace(':/', '/').replace(':', '/./')}" @@ -369,14 +363,14 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: Remote repository paths without ssh://, sftp://, rclone:, s3:, or b2:, syntax are deprecated and support will be removed from a future release. Interpreting "{repository_path}" as "{rewritten_repository_path}"', - ) - ) + ), + ), ) config['repositories'].append( dict( repository_dict, path=rewritten_repository_path, - ) + ), ) else: config['repositories'].append(repository_dict) @@ -388,8 +382,8 @@ def normalize(config_filename, config): levelno=logging.WARNING, levelname='WARNING', msg=f'{config_filename}: The prefix option is deprecated and support will be removed from a future release. Use archive_name_format or match_archives instead.', - ) - ) + ), + ), ) return logs diff --git a/borgmatic/config/override.py b/borgmatic/config/override.py index 9067e6f9..9218b41d 100644 --- a/borgmatic/config/override.py +++ b/borgmatic/config/override.py @@ -18,7 +18,7 @@ def set_values(config, keys, value): if len(keys) == 1: if isinstance(config, list): raise ValueError( - 'When overriding a list option, the value must use list syntax (e.g., "[foo, bar]" or "[{key: value}]" as appropriate)' + 'When overriding a list option, the value must use list syntax (e.g., "[foo, bar]" or "[{key: value}]" as appropriate)', ) config[first_key] = value @@ -69,11 +69,11 @@ def type_for_option(schema, option_keys): ''' option_schema = schema - for key in option_keys: - try: + try: + for key in option_keys: option_schema = option_schema['properties'][key] - except KeyError: - return None + except KeyError: + return None try: return option_schema['type'] @@ -103,8 +103,8 @@ def parse_overrides(raw_overrides, schema): parsed_overrides = [] - for raw_override in raw_overrides: - try: + try: + for raw_override in raw_overrides: raw_keys, value = raw_override.split('=', 1) keys = tuple(raw_keys.split('.')) option_type = type_for_option(schema, keys) @@ -113,14 +113,14 @@ def parse_overrides(raw_overrides, schema): ( keys, convert_value_type(value, option_type), - ) + ), ) - except ValueError: - raise ValueError( - f"Invalid override '{raw_override}'. Make sure you use the form: OPTION=VALUE or OPTION.SUBOPTION=VALUE" - ) - except ruamel.yaml.error.YAMLError as error: - raise ValueError(f"Invalid override '{raw_override}': {error.problem}") + except ValueError: + raise ValueError( + f"Invalid override '{raw_override}'. Make sure you use the form: OPTION=VALUE or OPTION.SUBOPTION=VALUE", + ) + except ruamel.yaml.error.YAMLError as error: + raise ValueError(f"Invalid override '{raw_override}': {error.problem}") return tuple(parsed_overrides) @@ -139,7 +139,7 @@ def apply_overrides(config, schema, raw_overrides): if overrides: logger.warning( - "The --override flag is deprecated and will be removed from a future release. Instead, use a command-line flag corresponding to the configuration option you'd like to set." + "The --override flag is deprecated and will be removed from a future release. Instead, use a command-line flag corresponding to the configuration option you'd like to set.", ) for keys, value in overrides: diff --git a/borgmatic/config/paths.py b/borgmatic/config/paths.py index fd15cdcd..8ce930cd 100644 --- a/borgmatic/config/paths.py +++ b/borgmatic/config/paths.py @@ -1,3 +1,4 @@ +import contextlib import logging import os import tempfile @@ -34,7 +35,8 @@ TEMPORARY_DIRECTORY_PREFIX = 'borgmatic-' def replace_temporary_subdirectory_with_glob( - path, temporary_directory_prefix=TEMPORARY_DIRECTORY_PREFIX + path, + temporary_directory_prefix=TEMPORARY_DIRECTORY_PREFIX, ): ''' Given an absolute temporary directory path and an optional temporary directory prefix, look for @@ -124,7 +126,7 @@ class Runtime_directory: base_path if final_directory == 'borgmatic' else runtime_directory, '.', # Borg 1.4+ "slashdot" hack. 'borgmatic', - ) + ), ) os.makedirs(self.runtime_path, mode=0o700, exist_ok=True) @@ -141,13 +143,11 @@ class Runtime_directory: Delete any temporary directory that was created as part of initialization. ''' if self.temporary_directory: - try: - self.temporary_directory.cleanup() # The cleanup() call errors if, for instance, there's still a # mounted filesystem within the temporary directory. There's # nothing we can do about that here, so swallow the error. - except OSError: - pass + with contextlib.suppress(OSError): + self.temporary_directory.cleanup() def make_runtime_directory_glob(borgmatic_runtime_directory): @@ -160,7 +160,7 @@ def make_runtime_directory_glob(borgmatic_runtime_directory): *( '*' if subdirectory.startswith(TEMPORARY_DIRECTORY_PREFIX) else subdirectory for subdirectory in os.path.normpath(borgmatic_runtime_directory).split(os.path.sep) - ) + ), ) @@ -177,5 +177,5 @@ def get_borgmatic_state_directory(config): or os.environ.get('STATE_DIRECTORY') # Set by systemd if configured. or '~/.local/state', 'borgmatic', - ) + ), ) diff --git a/borgmatic/config/schema.py b/borgmatic/config/schema.py index 3d13c0c2..1a7b0a75 100644 --- a/borgmatic/config/schema.py +++ b/borgmatic/config/schema.py @@ -14,8 +14,8 @@ def get_properties(schema): item for item in itertools.chain( *itertools.zip_longest( - *[sub_schema['properties'].items() for sub_schema in schema['oneOf']] - ) + *[sub_schema['properties'].items() for sub_schema in schema['oneOf']], + ), ) if item is not None ) @@ -61,12 +61,6 @@ def compare_types(schema_type, target_types, match=any): list must be in the target types. ''' if isinstance(schema_type, list): - if match(element_schema_type in target_types for element_schema_type in schema_type): - return True + return match(element_schema_type in target_types for element_schema_type in schema_type) - return False - - if schema_type in target_types: - return True - - return False + return schema_type in target_types diff --git a/borgmatic/config/validate.py b/borgmatic/config/validate.py index dcf2cd0f..eae2a8d2 100644 --- a/borgmatic/config/validate.py +++ b/borgmatic/config/validate.py @@ -17,7 +17,7 @@ def schema_filename(): ''' schema_path = os.path.join(os.path.dirname(borgmatic.config.__file__), 'schema.yaml') - with open(schema_path): + with open(schema_path, encoding='utf-8'): return schema_path @@ -97,7 +97,11 @@ def apply_logical_validation(config_filename, parsed_configuration): def parse_configuration( - config_filename, schema_filename, arguments, overrides=None, resolve_env=True + config_filename, + schema_filename, + arguments, + overrides=None, + resolve_env=True, ): ''' Given the path to a config filename in YAML format, the path to a schema filename in a YAML @@ -147,7 +151,8 @@ def parse_configuration( if validation_errors: raise Validation_error( - config_filename, tuple(format_json_error(error) for error in validation_errors) + config_filename, + tuple(format_json_error(error) for error in validation_errors), ) apply_logical_validation(config_filename, config) @@ -166,13 +171,14 @@ def normalize_repository_path(repository, base=None): return ( os.path.abspath(os.path.join(base, repository)) if base else os.path.abspath(repository) ) - elif repository.startswith('file://'): + + if repository.startswith('file://'): local_path = repository.partition('file://')[-1] return ( os.path.abspath(os.path.join(base, local_path)) if base else os.path.abspath(local_path) ) - else: - return repository + + return repository def glob_match(first, second): @@ -199,7 +205,8 @@ def repositories_match(first, second): second = {'path': second, 'label': second} return glob_match(first.get('label'), second.get('label')) or glob_match( - normalize_repository_path(first.get('path')), normalize_repository_path(second.get('path')) + normalize_repository_path(first.get('path')), + normalize_repository_path(second.get('path')), ) @@ -220,7 +227,7 @@ def guard_configuration_contains_repository(repository, configurations): for config in configurations.values() for config_repository in config['repositories'] if repositories_match(config_repository, repository) - ) + ), ) if count == 0: diff --git a/borgmatic/execute.py b/borgmatic/execute.py index 93642556..d5b4820e 100644 --- a/borgmatic/execute.py +++ b/borgmatic/execute.py @@ -43,12 +43,13 @@ def interpret_exit_code(command, exit_code, borg_local_path=None, borg_exit_code if treat_as == 'error': logger.error( - f'Treating exit code {exit_code} as an error, as per configuration' + f'Treating exit code {exit_code} as an error, as per configuration', ) return Exit_status.ERROR - elif treat_as == 'warning': + + if treat_as == 'warning': logger.warning( - f'Treating exit code {exit_code} as a warning, as per configuration' + f'Treating exit code {exit_code} as a warning, as per configuration', ) return Exit_status.WARNING @@ -103,7 +104,7 @@ def append_last_lines(last_lines, captured_output, line, output_log_level): logger.log(output_log_level, line) -def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path, borg_exit_codes): +def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path, borg_exit_codes): # noqa: PLR0912 ''' Given a sequence of subprocess.Popen() instances for multiple processes, log the output for each process with the requested log level. Additionally, raise a CalledProcessError if a process @@ -132,7 +133,7 @@ def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path, b still_running = True # Log output for each process until they all exit. - while True: + while True: # noqa: PLR1702 if output_buffers: (ready_buffers, _, _) = select.select(output_buffers, [], []) @@ -182,7 +183,7 @@ def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path, b command = process.args.split(' ') if isinstance(process.args, str) else process.args exit_status = interpret_exit_code(command, exit_code, borg_local_path, borg_exit_codes) - if exit_status in (Exit_status.ERROR, Exit_status.WARNING): + if exit_status in {Exit_status.ERROR, Exit_status.WARNING}: # If an error occurs, include its output in the raised exception so that we don't # inadvertently hide error output. output_buffer = output_buffer_for_process(process, exclude_stdouts) @@ -195,7 +196,10 @@ def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path, b break append_last_lines( - last_lines, captured_outputs[process], line, output_log_level=logging.ERROR + last_lines, + captured_outputs[process], + line, + output_log_level=logging.ERROR, ) if len(last_lines) == ERROR_OUTPUT_MAX_LINE_COUNT: @@ -210,7 +214,9 @@ def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path, b if exit_status == Exit_status.ERROR: raise subprocess.CalledProcessError( - exit_code, command_for_process(process), '\n'.join(last_lines) + exit_code, + command_for_process(process), + '\n'.join(last_lines), ) still_running = False @@ -221,6 +227,8 @@ def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path, b process: '\n'.join(output_lines) for process, output_lines in captured_outputs.items() } + return None + SECRET_COMMAND_FLAG_NAMES = {'--password'} @@ -256,19 +264,19 @@ def log_command(full_command, input_file=None, output_file=None, environment=Non ' '.join( tuple( f'{key}=***' - for key in (environment or {}).keys() + for key in (environment or {}) if any( key.startswith(prefix) for prefix in PREFIXES_OF_ENVIRONMENT_VARIABLES_TO_LOG ) ) - + mask_command_secrets(full_command) + + mask_command_secrets(full_command), ), width=MAX_LOGGED_COMMAND_LENGTH, placeholder=' ...', ) + (f" < {getattr(input_file, 'name', input_file)}" if input_file else '') - + (f" > {getattr(output_file, 'name', output_file)}" if output_file else '') + + (f" > {getattr(output_file, 'name', output_file)}" if output_file else ''), ) @@ -309,12 +317,12 @@ def execute_command( do_not_capture = bool(output_file is DO_NOT_CAPTURE) command = ' '.join(full_command) if shell else full_command - process = subprocess.Popen( + process = subprocess.Popen( # noqa: S603 command, stdin=input_file, stdout=None if do_not_capture else (output_file or subprocess.PIPE), stderr=None if do_not_capture else (subprocess.PIPE if output_file else subprocess.STDOUT), - shell=shell, # noqa: S602 + shell=shell, env=environment, cwd=working_directory, close_fds=close_fds, @@ -331,6 +339,8 @@ def execute_command( borg_exit_codes, ) + return None + def execute_command_and_capture_output( full_command, @@ -360,11 +370,11 @@ def execute_command_and_capture_output( command = ' '.join(full_command) if shell else full_command try: - output = subprocess.check_output( + output = subprocess.check_output( # noqa: S603 command, stdin=input_file, stderr=subprocess.STDOUT if capture_stderr else None, - shell=shell, # noqa: S602 + shell=shell, env=environment, cwd=working_directory, close_fds=close_fds, @@ -418,14 +428,14 @@ def execute_command_with_processes( command = ' '.join(full_command) if shell else full_command try: - command_process = subprocess.Popen( + command_process = subprocess.Popen( # noqa: S603 command, stdin=input_file, stdout=None if do_not_capture else (output_file or subprocess.PIPE), stderr=( None if do_not_capture else (subprocess.PIPE if output_file else subprocess.STDOUT) ), - shell=shell, # noqa: S602 + shell=shell, env=environment, cwd=working_directory, close_fds=close_fds, @@ -442,7 +452,7 @@ def execute_command_with_processes( with borgmatic.logger.Log_prefix(None): # Log command output without any prefix. captured_outputs = log_outputs( - tuple(processes) + (command_process,), + (*processes, command_process), (input_file, output_file), output_log_level, borg_local_path, @@ -451,3 +461,5 @@ def execute_command_with_processes( if output_log_level is None: return captured_outputs.get(command_process) + + return None diff --git a/borgmatic/hooks/command.py b/borgmatic/hooks/command.py index 080724bc..6140d0bc 100644 --- a/borgmatic/hooks/command.py +++ b/borgmatic/hooks/command.py @@ -42,7 +42,7 @@ def interpolate_context(hook_description, command, context): # be a Borg placeholder, as Borg should hopefully consume it. if unsupported_variable not in BORG_PLACEHOLDERS: logger.warning( - f'Variable "{unsupported_variable}" is not supported in the {hook_description} hook' + f'Variable "{unsupported_variable}" is not supported in the {hook_description} hook', ) return command @@ -86,7 +86,7 @@ def filter_hooks(command_hooks, before=None, after=None, action_names=None, stat ) -def execute_hooks(command_hooks, umask, working_directory, dry_run, **context): +def execute_hooks(command_hooks, umask, working_directory, dry_run, **context): # noqa: PLR0912 ''' Given a sequence of command hook dicts from configuration, a umask to execute with (or None), a working directory to execute with, and whether this is a dry run, run the commands for each @@ -139,12 +139,12 @@ def execute_hooks(command_hooks, umask, working_directory, dry_run, **context): if dry_run: continue - borgmatic.execute.execute_command( + borgmatic.execute.execute_command( # noqa: S604 [command], output_log_level=( logging.ERROR if hook_config.get('after') == 'error' else logging.ANSWER ), - shell=True, # noqa: S604 + shell=True, environment=make_environment(os.environ), working_directory=working_directory, ) diff --git a/borgmatic/hooks/credential/container.py b/borgmatic/hooks/credential/container.py index a38e6d35..24c019bb 100644 --- a/borgmatic/hooks/credential/container.py +++ b/borgmatic/hooks/credential/container.py @@ -34,7 +34,8 @@ def load_credential(hook_config, config, credential_parameters): config.get('working_directory', ''), (hook_config or {}).get('secrets_directory', DEFAULT_SECRETS_DIRECTORY), secret_name, - ) + ), + encoding='utf-8', ) as secret_file: return secret_file.read().rstrip(os.linesep) except (FileNotFoundError, OSError) as error: diff --git a/borgmatic/hooks/credential/file.py b/borgmatic/hooks/credential/file.py index 366a7d4a..62db0b7e 100644 --- a/borgmatic/hooks/credential/file.py +++ b/borgmatic/hooks/credential/file.py @@ -23,7 +23,8 @@ def load_credential(hook_config, config, credential_parameters): try: with open( - os.path.join(config.get('working_directory', ''), expanded_credential_path) + os.path.join(config.get('working_directory', ''), expanded_credential_path), + encoding='utf-8', ) as credential_file: return credential_file.read().rstrip(os.linesep) except (FileNotFoundError, OSError) as error: diff --git a/borgmatic/hooks/credential/parse.py b/borgmatic/hooks/credential/parse.py index 2b7b2543..b2d0833d 100644 --- a/borgmatic/hooks/credential/parse.py +++ b/borgmatic/hooks/credential/parse.py @@ -120,5 +120,8 @@ def resolve_credential(value, config): raise ValueError(f'Cannot load credential with invalid syntax "{value}"') return borgmatic.hooks.dispatch.call_hook( - 'load_credential', config, hook_name, tuple(credential_parameters) + 'load_credential', + config, + hook_name, + tuple(credential_parameters), ) diff --git a/borgmatic/hooks/credential/systemd.py b/borgmatic/hooks/credential/systemd.py index 9cce0d7b..4a9dd9ed 100644 --- a/borgmatic/hooks/credential/systemd.py +++ b/borgmatic/hooks/credential/systemd.py @@ -28,14 +28,16 @@ def load_credential(hook_config, config, credential_parameters): if not credentials_directory: raise ValueError( - f'Cannot load credential "{credential_name}" because the systemd CREDENTIALS_DIRECTORY environment variable is not set' + f'Cannot load credential "{credential_name}" because the systemd CREDENTIALS_DIRECTORY environment variable is not set', ) if not CREDENTIAL_NAME_PATTERN.match(credential_name): raise ValueError(f'Cannot load invalid credential name "{credential_name}"') try: - with open(os.path.join(credentials_directory, credential_name)) as credential_file: + with open( + os.path.join(credentials_directory, credential_name), encoding='utf-8' + ) as credential_file: return credential_file.read().rstrip(os.linesep) except (FileNotFoundError, OSError) as error: logger.warning(error) diff --git a/borgmatic/hooks/data_source/bootstrap.py b/borgmatic/hooks/data_source/bootstrap.py index fe779f0e..b5d5ba14 100644 --- a/borgmatic/hooks/data_source/bootstrap.py +++ b/borgmatic/hooks/data_source/bootstrap.py @@ -1,3 +1,4 @@ +import contextlib import glob import importlib import json @@ -38,7 +39,9 @@ def dump_data_sources( return [] borgmatic_manifest_path = os.path.join( - borgmatic_runtime_directory, 'bootstrap', 'manifest.json' + borgmatic_runtime_directory, + 'bootstrap', + 'manifest.json', ) if dry_run: @@ -46,7 +49,7 @@ def dump_data_sources( os.makedirs(os.path.dirname(borgmatic_manifest_path), exist_ok=True) - with open(borgmatic_manifest_path, 'w') as manifest_file: + with open(borgmatic_manifest_path, 'w', encoding='utf-8') as manifest_file: json.dump( { 'borgmatic_version': importlib.metadata.version('borgmatic'), @@ -57,7 +60,8 @@ def dump_data_sources( patterns.extend( borgmatic.borg.pattern.Pattern( - config_path, source=borgmatic.borg.pattern.Pattern_source.HOOK + config_path, + source=borgmatic.borg.pattern.Pattern_source.HOOK, ) for config_path in config_paths ) @@ -65,7 +69,7 @@ def dump_data_sources( borgmatic.borg.pattern.Pattern( os.path.join(borgmatic_runtime_directory, 'bootstrap'), source=borgmatic.borg.pattern.Pattern_source.HOOK, - ) + ), ) return [] @@ -86,7 +90,7 @@ def remove_data_source_dumps(hook_config, config, borgmatic_runtime_directory, d 'bootstrap', ) logger.debug( - f'Looking for bootstrap manifest files to remove in {manifest_glob}{dry_run_label}' + f'Looking for bootstrap manifest files to remove in {manifest_glob}{dry_run_label}', ) for manifest_directory in glob.glob(manifest_glob): @@ -96,19 +100,18 @@ def remove_data_source_dumps(hook_config, config, borgmatic_runtime_directory, d if dry_run: continue - try: + with contextlib.suppress(FileNotFoundError): os.remove(manifest_file_path) - except FileNotFoundError: - pass - try: + with contextlib.suppress(FileNotFoundError): os.rmdir(manifest_directory) - except FileNotFoundError: - pass def make_data_source_dump_patterns( - hook_config, config, borgmatic_runtime_directory, name=None + hook_config, + config, + borgmatic_runtime_directory, + name=None, ): # pragma: no cover ''' Restores are implemented via the separate, purpose-specific "bootstrap" action rather than the diff --git a/borgmatic/hooks/data_source/btrfs.py b/borgmatic/hooks/data_source/btrfs.py index 340763d7..85adb245 100644 --- a/borgmatic/hooks/data_source/btrfs.py +++ b/borgmatic/hooks/data_source/btrfs.py @@ -31,8 +31,8 @@ def get_contained_subvolume_paths(btrfs_command, subvolume_path): ''' try: btrfs_output = borgmatic.execute.execute_command_and_capture_output( - tuple(btrfs_command.split(' ')) - + ( + ( + *btrfs_command.split(' '), 'subvolume', 'list', subvolume_path, @@ -41,15 +41,18 @@ def get_contained_subvolume_paths(btrfs_command, subvolume_path): ) except subprocess.CalledProcessError as error: logger.debug( - f'Ignoring Btrfs subvolume {subvolume_path} because of error listing its subvolumes: {error}' + f'Ignoring Btrfs subvolume {subvolume_path} because of error listing its subvolumes: {error}', ) return () - return (subvolume_path,) + tuple( - os.path.join(subvolume_path, line.split(' ')[-1]) - for line in btrfs_output.splitlines() - if line.strip() + return ( + subvolume_path, + *tuple( + os.path.join(subvolume_path, line.split(' ')[-1]) + for line in btrfs_output.splitlines() + if line.strip() + ), ) @@ -62,8 +65,8 @@ def get_all_subvolume_paths(btrfs_command, findmnt_command): system. ''' findmnt_output = borgmatic.execute.execute_command_and_capture_output( - tuple(findmnt_command.split(' ')) - + ( + ( + *findmnt_command.split(' '), '-t', # Filesystem type. 'btrfs', '--json', @@ -88,8 +91,8 @@ def get_all_subvolume_paths(btrfs_command, findmnt_command): else (filesystem['target'],) ) for filesystem in json.loads(findmnt_output)['filesystems'] - ) - ) + ), + ), ) except json.JSONDecodeError as error: raise ValueError(f'Invalid {findmnt_command} JSON output: {error}') @@ -108,8 +111,8 @@ def get_subvolume_property(btrfs_command, subvolume_path, property_name): Raise subprocess.CalledProcessError if the btrfs command errors. ''' output = borgmatic.execute.execute_command_and_capture_output( - tuple(btrfs_command.split(' ')) - + ( + ( + *btrfs_command.split(' '), 'property', 'get', '-t', # Type. @@ -145,9 +148,9 @@ def omit_read_only_subvolume_paths(btrfs_command, subvolume_paths): logger.debug(f'Ignoring Btrfs subvolume {subvolume_path} because it is read-only') else: retained_subvolume_paths.append(subvolume_path) - except subprocess.CalledProcessError as error: + except subprocess.CalledProcessError as error: # noqa: PERF203 logger.debug( - f'Error determining read-only status of Btrfs subvolume {subvolume_path}: {error}' + f'Error determining read-only status of Btrfs subvolume {subvolume_path}: {error}', ) return tuple(retained_subvolume_paths) @@ -174,14 +177,16 @@ def get_subvolumes(btrfs_command, findmnt_command, patterns=None): # this process, so no two subvolumes end up with the same contained patterns.) for subvolume_path in reversed( omit_read_only_subvolume_paths( - btrfs_command, get_all_subvolume_paths(btrfs_command, findmnt_command) - ) + btrfs_command, + get_all_subvolume_paths(btrfs_command, findmnt_command), + ), ): subvolumes.extend( Subvolume(subvolume_path, contained_patterns) for contained_patterns in ( borgmatic.hooks.data_source.snapshot.get_contained_patterns( - subvolume_path, candidate_patterns + subvolume_path, + candidate_patterns, ), ) if patterns is None @@ -282,8 +287,8 @@ def snapshot_subvolume(btrfs_command, subvolume_path, snapshot_path): # pragma: os.makedirs(os.path.dirname(snapshot_path), mode=0o700, exist_ok=True) borgmatic.execute.execute_command( - tuple(btrfs_command.split(' ')) - + ( + ( + *btrfs_command.split(' '), 'subvolume', 'snapshot', '-r', # Read-only. @@ -356,8 +361,8 @@ def delete_snapshot(btrfs_command, snapshot_path): # pragma: no cover Given a Btrfs command to run and the name of a snapshot path, delete it. ''' borgmatic.execute.execute_command( - tuple(btrfs_command.split(' ')) - + ( + ( + *btrfs_command.split(' '), 'subvolume', 'delete', snapshot_path, @@ -399,7 +404,7 @@ def remove_data_source_dumps(hook_config, config, borgmatic_runtime_directory, d ) logger.debug( - f'Looking for snapshots to remove in {subvolume_snapshots_glob}{dry_run_label}' + f'Looking for snapshots to remove in {subvolume_snapshots_glob}{dry_run_label}', ) for snapshot_path in glob.glob(subvolume_snapshots_glob): @@ -429,7 +434,10 @@ def remove_data_source_dumps(hook_config, config, borgmatic_runtime_directory, d def make_data_source_dump_patterns( - hook_config, config, borgmatic_runtime_directory, name=None + hook_config, + config, + borgmatic_runtime_directory, + name=None, ): # pragma: no cover ''' Restores aren't implemented, because stored files can be extracted directly with "extract". diff --git a/borgmatic/hooks/data_source/dump.py b/borgmatic/hooks/data_source/dump.py index 11ec2409..205b70c3 100644 --- a/borgmatic/hooks/data_source/dump.py +++ b/borgmatic/hooks/data_source/dump.py @@ -27,7 +27,9 @@ def make_data_source_dump_filename(dump_path, name, hostname=None, port=None): raise ValueError(f'Invalid data source name {name}') return os.path.join( - dump_path, (hostname or 'localhost') + ('' if port is None else f':{port}'), name + dump_path, + (hostname or 'localhost') + ('' if port is None else f':{port}'), + name, ) diff --git a/borgmatic/hooks/data_source/lvm.py b/borgmatic/hooks/data_source/lvm.py index 65a2b6bf..8a8306b0 100644 --- a/borgmatic/hooks/data_source/lvm.py +++ b/borgmatic/hooks/data_source/lvm.py @@ -24,7 +24,8 @@ def use_streaming(hook_config, config): # pragma: no cover BORGMATIC_SNAPSHOT_PREFIX = 'borgmatic-' Logical_volume = collections.namedtuple( - 'Logical_volume', ('name', 'device_path', 'mount_point', 'contained_patterns') + 'Logical_volume', + ('name', 'device_path', 'mount_point', 'contained_patterns'), ) @@ -44,15 +45,15 @@ def get_logical_volumes(lsblk_command, patterns=None): devices_info = json.loads( borgmatic.execute.execute_command_and_capture_output( # Use lsblk instead of lvs here because lvs can't show active mounts. - tuple(lsblk_command.split(' ')) - + ( + ( + *lsblk_command.split(' '), '--output', 'name,path,mountpoint,type', '--json', '--list', ), close_fds=True, - ) + ), ) except json.JSONDecodeError as error: raise ValueError(f'Invalid {lsblk_command} JSON output: {error}') @@ -73,7 +74,8 @@ def get_logical_volumes(lsblk_command, patterns=None): if device['mountpoint'] and device['type'] == 'lvm' for contained_patterns in ( borgmatic.hooks.data_source.snapshot.get_contained_patterns( - device['mountpoint'], candidate_patterns + device['mountpoint'], + candidate_patterns, ), ) if not patterns @@ -98,8 +100,8 @@ def snapshot_logical_volume( snapshot, and a snapshot size string, create a new LVM snapshot. ''' borgmatic.execute.execute_command( - tuple(lvcreate_command.split(' ')) - + ( + ( + *lvcreate_command.split(' '), '--snapshot', ('--extents' if '%' in snapshot_size else '--size'), snapshot_size, @@ -123,8 +125,8 @@ def mount_snapshot(mount_command, snapshot_device, snapshot_mount_path): # prag os.makedirs(snapshot_mount_path, mode=0o700, exist_ok=True) borgmatic.execute.execute_command( - tuple(mount_command.split(' ')) - + ( + ( + *mount_command.split(' '), '-o', 'ro', snapshot_device, @@ -162,7 +164,7 @@ def make_borg_snapshot_pattern(pattern, logical_volume, normalized_runtime_direc # /var/spool would result in overlapping snapshot patterns and therefore colliding mount # attempts. hashlib.shake_256(logical_volume.mount_point.encode('utf-8')).hexdigest( - MOUNT_POINT_HASH_LENGTH + MOUNT_POINT_HASH_LENGTH, ), '.', # Borg 1.4+ "slashdot" hack. # Included so that the source directory ends up in the Borg archive at its "original" path. @@ -218,7 +220,7 @@ def dump_data_sources( for logical_volume in requested_logical_volumes: snapshot_name = f'{logical_volume.name}_{snapshot_suffix}' logger.debug( - f'Creating LVM snapshot {snapshot_name} of {logical_volume.mount_point}{dry_run_label}' + f'Creating LVM snapshot {snapshot_name} of {logical_volume.mount_point}{dry_run_label}', ) if not dry_run: @@ -233,7 +235,8 @@ def dump_data_sources( if not dry_run: try: snapshot = get_snapshots( - hook_config.get('lvs_command', 'lvs'), snapshot_name=snapshot_name + hook_config.get('lvs_command', 'lvs'), + snapshot_name=snapshot_name, )[0] except IndexError: raise ValueError(f'Cannot find LVM snapshot {snapshot_name}') @@ -244,25 +247,29 @@ def dump_data_sources( normalized_runtime_directory, 'lvm_snapshots', hashlib.shake_256(logical_volume.mount_point.encode('utf-8')).hexdigest( - MOUNT_POINT_HASH_LENGTH + MOUNT_POINT_HASH_LENGTH, ), logical_volume.mount_point.lstrip(os.path.sep), ) logger.debug( - f'Mounting LVM snapshot {snapshot_name} at {snapshot_mount_path}{dry_run_label}' + f'Mounting LVM snapshot {snapshot_name} at {snapshot_mount_path}{dry_run_label}', ) if dry_run: continue mount_snapshot( - hook_config.get('mount_command', 'mount'), snapshot.device_path, snapshot_mount_path + hook_config.get('mount_command', 'mount'), + snapshot.device_path, + snapshot_mount_path, ) for pattern in logical_volume.contained_patterns: snapshot_pattern = make_borg_snapshot_pattern( - pattern, logical_volume, normalized_runtime_directory + pattern, + logical_volume, + normalized_runtime_directory, ) # Attempt to update the pattern in place, since pattern order matters to Borg. @@ -279,7 +286,7 @@ def unmount_snapshot(umount_command, snapshot_mount_path): # pragma: no cover Given a umount command to run and the mount path of a snapshot, unmount it. ''' borgmatic.execute.execute_command( - tuple(umount_command.split(' ')) + (snapshot_mount_path,), + (*umount_command.split(' '), snapshot_mount_path), output_log_level=logging.DEBUG, close_fds=True, ) @@ -290,8 +297,8 @@ def remove_snapshot(lvremove_command, snapshot_device_path): # pragma: no cover Given an lvremove command to run and the device path of a snapshot, remove it it. ''' borgmatic.execute.execute_command( - tuple(lvremove_command.split(' ')) - + ( + ( + *lvremove_command.split(' '), '--force', # Suppress an interactive "are you sure?" type prompt. snapshot_device_path, ), @@ -316,8 +323,8 @@ def get_snapshots(lvs_command, snapshot_name=None): snapshot_info = json.loads( borgmatic.execute.execute_command_and_capture_output( # Use lvs instead of lsblk here because lsblk can't filter to just snapshots. - tuple(lvs_command.split(' ')) - + ( + ( + *lvs_command.split(' '), '--report-format', 'json', '--options', @@ -326,7 +333,7 @@ def get_snapshots(lvs_command, snapshot_name=None): 'lv_attr =~ ^s', # Filter to just snapshots. ), close_fds=True, - ) + ), ) except json.JSONDecodeError as error: raise ValueError(f'Invalid {lvs_command} JSON output: {error}') @@ -343,7 +350,7 @@ def get_snapshots(lvs_command, snapshot_name=None): raise ValueError(f'Invalid {lvs_command} output: Missing key "{error}"') -def remove_data_source_dumps(hook_config, config, borgmatic_runtime_directory, dry_run): +def remove_data_source_dumps(hook_config, config, borgmatic_runtime_directory, dry_run): # noqa: PLR0912 ''' Given an LVM configuration dict, a configuration dict, the borgmatic runtime directory, and whether this is a dry run, unmount and delete any LVM snapshots created by borgmatic. If this is @@ -381,7 +388,8 @@ def remove_data_source_dumps(hook_config, config, borgmatic_runtime_directory, d for logical_volume in logical_volumes: snapshot_mount_path = os.path.join( - snapshots_directory, logical_volume.mount_point.lstrip(os.path.sep) + snapshots_directory, + logical_volume.mount_point.lstrip(os.path.sep), ) # If the snapshot mount path is empty, this is probably just a "shadow" of a nested @@ -440,7 +448,10 @@ def remove_data_source_dumps(hook_config, config, borgmatic_runtime_directory, d def make_data_source_dump_patterns( - hook_config, config, borgmatic_runtime_directory, name=None + hook_config, + config, + borgmatic_runtime_directory, + name=None, ): # pragma: no cover ''' Restores aren't implemented, because stored files can be extracted directly with "extract". diff --git a/borgmatic/hooks/data_source/mariadb.py b/borgmatic/hooks/data_source/mariadb.py index a39a6f4a..b7770a42 100644 --- a/borgmatic/hooks/data_source/mariadb.py +++ b/borgmatic/hooks/data_source/mariadb.py @@ -24,7 +24,7 @@ def make_dump_path(base_directory): # pragma: no cover return dump.make_data_source_dump_path(base_directory, 'mariadb_databases') -DEFAULTS_EXTRA_FILE_FLAG_PATTERN = re.compile('^--defaults-extra-file=(?P.*)$') +DEFAULTS_EXTRA_FILE_FLAG_PATTERN = re.compile(r'^--defaults-extra-file=(?P.*)$') def parse_extra_options(extra_options): @@ -71,7 +71,7 @@ def make_defaults_file_options(username=None, password=None, defaults_extra_file ( (f'user={username}' if username is not None else ''), (f'password="{escaped_password}"' if escaped_password is not None else ''), - ) + ), ).strip() if not values: @@ -94,7 +94,7 @@ def make_defaults_file_options(username=None, password=None, defaults_extra_file include = f'!include {defaults_extra_filename}\n' if defaults_extra_filename else '' read_file_descriptor, write_file_descriptor = os.pipe() - os.write(write_file_descriptor, f'{include}[client]\n{values}'.encode('utf-8')) + os.write(write_file_descriptor, f'{include}[client]\n{values}'.encode()) os.close(write_file_descriptor) # This plus subprocess.Popen(..., close_fds=False) in execute.py is necessary for the database @@ -182,7 +182,7 @@ def execute_dump_command( if os.path.exists(dump_filename): logger.warning( - f'Skipping duplicate dump of MariaDB database "{database_name}" to {dump_filename}' + f'Skipping duplicate dump of MariaDB database "{database_name}" to {dump_filename}', ) return None @@ -263,10 +263,12 @@ def dump_data_sources( for database in databases: dump_path = make_dump_path(borgmatic_runtime_directory) username = borgmatic.hooks.credential.parse.resolve_credential( - database.get('username'), config + database.get('username'), + config, ) password = borgmatic.hooks.credential.parse.resolve_credential( - database.get('password'), config + database.get('password'), + config, ) environment = dict( os.environ, @@ -277,7 +279,12 @@ def dump_data_sources( ), ) dump_database_names = database_names_to_dump( - database, config, username, password, environment, dry_run + database, + config, + username, + password, + environment, + dry_run, ) if not dump_database_names: @@ -301,7 +308,7 @@ def dump_data_sources( environment, dry_run, dry_run_label, - ) + ), ) else: processes.append( @@ -315,7 +322,7 @@ def dump_data_sources( environment, dry_run, dry_run_label, - ) + ), ) if not dry_run: @@ -323,14 +330,17 @@ def dump_data_sources( borgmatic.borg.pattern.Pattern( os.path.join(borgmatic_runtime_directory, 'mariadb_databases'), source=borgmatic.borg.pattern.Pattern_source.HOOK, - ) + ), ) return [process for process in processes if process] def remove_data_source_dumps( - databases, config, borgmatic_runtime_directory, dry_run + databases, + config, + borgmatic_runtime_directory, + dry_run, ): # pragma: no cover ''' Remove all database dump files for this hook regardless of the given databases. Use the @@ -341,7 +351,10 @@ def remove_data_source_dumps( def make_data_source_dump_patterns( - databases, config, borgmatic_runtime_directory, name=None + databases, + config, + borgmatic_runtime_directory, + name=None, ): # pragma: no cover ''' Given a sequence of configurations dicts, a configuration dict, the borgmatic runtime directory, @@ -353,10 +366,14 @@ def make_data_source_dump_patterns( return ( dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, hostname='*'), dump.make_data_source_dump_filename( - make_dump_path(borgmatic_runtime_directory), name, hostname='*' + make_dump_path(borgmatic_runtime_directory), + name, + hostname='*', ), dump.make_data_source_dump_filename( - make_dump_path(borgmatic_source_directory), name, hostname='*' + make_dump_path(borgmatic_source_directory), + name, + hostname='*', ), ) @@ -378,10 +395,11 @@ def restore_data_source_dump( ''' dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else '' hostname = connection_params['hostname'] or data_source.get( - 'restore_hostname', data_source.get('hostname') + 'restore_hostname', + data_source.get('hostname'), ) port = str( - connection_params['port'] or data_source.get('restore_port', data_source.get('port', '')) + connection_params['port'] or data_source.get('restore_port', data_source.get('port', '')), ) tls = data_source.get('restore_tls', data_source.get('tls')) username = borgmatic.hooks.credential.parse.resolve_credential( diff --git a/borgmatic/hooks/data_source/mongodb.py b/borgmatic/hooks/data_source/mongodb.py index b1488f75..b10dc46c 100644 --- a/borgmatic/hooks/data_source/mongodb.py +++ b/borgmatic/hooks/data_source/mongodb.py @@ -78,7 +78,7 @@ def dump_data_sources( else: dump.create_named_pipe_for_dump(dump_filename) processes.append( - execute_command(command, shell=True, run_to_completion=False) # noqa: S604 + execute_command(command, shell=True, run_to_completion=False), # noqa: S604 ) if not dry_run: @@ -86,7 +86,7 @@ def dump_data_sources( borgmatic.borg.pattern.Pattern( os.path.join(borgmatic_runtime_directory, 'mongodb_databases'), source=borgmatic.borg.pattern.Pattern_source.HOOK, - ) + ), ) return processes @@ -104,7 +104,7 @@ def make_password_config_file(password): logger.debug('Writing MongoDB password to configuration file pipe') read_file_descriptor, write_file_descriptor = os.pipe() - os.write(write_file_descriptor, f'password: {password}'.encode('utf-8')) + os.write(write_file_descriptor, f'password: {password}'.encode()) os.close(write_file_descriptor) # This plus subprocess.Popen(..., close_fds=False) in execute.py is necessary for the database @@ -135,8 +135,9 @@ def build_dump_command(database, config, dump_filename, dump_format): '--username', shlex.quote( borgmatic.hooks.credential.parse.resolve_credential( - database['username'], config - ) + database['username'], + config, + ), ), ) if 'username' in database @@ -159,7 +160,10 @@ def build_dump_command(database, config, dump_filename, dump_format): def remove_data_source_dumps( - databases, config, borgmatic_runtime_directory, dry_run + databases, + config, + borgmatic_runtime_directory, + dry_run, ): # pragma: no cover ''' Remove all database dump files for this hook regardless of the given databases. Use the @@ -170,7 +174,10 @@ def remove_data_source_dumps( def make_data_source_dump_patterns( - databases, config, borgmatic_runtime_directory, name=None + databases, + config, + borgmatic_runtime_directory, + name=None, ): # pragma: no cover ''' Given a sequence of configurations dicts, a configuration dict, the borgmatic runtime directory, @@ -182,10 +189,14 @@ def make_data_source_dump_patterns( return ( dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, hostname='*'), dump.make_data_source_dump_filename( - make_dump_path(borgmatic_runtime_directory), name, hostname='*' + make_dump_path(borgmatic_runtime_directory), + name, + hostname='*', ), dump.make_data_source_dump_filename( - make_dump_path(borgmatic_source_directory), name, hostname='*' + make_dump_path(borgmatic_source_directory), + name, + hostname='*', ), ) @@ -216,7 +227,11 @@ def restore_data_source_dump( data_source.get('hostname'), ) restore_command = build_restore_command( - extract_process, data_source, config, dump_filename, connection_params + extract_process, + data_source, + config, + dump_filename, + connection_params, ) logger.debug(f"Restoring MongoDB database {data_source['name']}{dry_run_label}") @@ -238,7 +253,8 @@ def build_restore_command(extract_process, database, config, dump_filename, conn Return the custom mongorestore_command from a single database configuration. ''' hostname = connection_params['hostname'] or database.get( - 'restore_hostname', database.get('hostname') + 'restore_hostname', + database.get('hostname'), ) port = str(connection_params['port'] or database.get('restore_port', database.get('port', ''))) username = borgmatic.hooks.credential.parse.resolve_credential( @@ -256,10 +272,10 @@ def build_restore_command(extract_process, database, config, dump_filename, conn config, ) - command = list( + command = [ shlex.quote(part) for part in shlex.split(database.get('mongorestore_command') or 'mongorestore') - ) + ] if extract_process: command.append('--archive') diff --git a/borgmatic/hooks/data_source/mysql.py b/borgmatic/hooks/data_source/mysql.py index 1fb6f976..579bf869 100644 --- a/borgmatic/hooks/data_source/mysql.py +++ b/borgmatic/hooks/data_source/mysql.py @@ -51,7 +51,9 @@ def database_names_to_dump(database, config, username, password, environment, dr mysql_show_command + ( borgmatic.hooks.data_source.mariadb.make_defaults_file_options( - username, password, defaults_extra_filename + username, + password, + defaults_extra_filename, ) if password_transport == 'pipe' else () @@ -106,7 +108,7 @@ def execute_dump_command( if os.path.exists(dump_filename): logger.warning( - f'Skipping duplicate dump of MySQL database "{database_name}" to {dump_filename}' + f'Skipping duplicate dump of MySQL database "{database_name}" to {dump_filename}', ) return None @@ -121,7 +123,9 @@ def execute_dump_command( mysql_dump_command + ( borgmatic.hooks.data_source.mariadb.make_defaults_file_options( - username, password, defaults_extra_filename + username, + password, + defaults_extra_filename, ) if password_transport == 'pipe' else () @@ -190,10 +194,12 @@ def dump_data_sources( for database in databases: dump_path = make_dump_path(borgmatic_runtime_directory) username = borgmatic.hooks.credential.parse.resolve_credential( - database.get('username'), config + database.get('username'), + config, ) password = borgmatic.hooks.credential.parse.resolve_credential( - database.get('password'), config + database.get('password'), + config, ) environment = dict( os.environ, @@ -204,7 +210,12 @@ def dump_data_sources( ), ) dump_database_names = database_names_to_dump( - database, config, username, password, environment, dry_run + database, + config, + username, + password, + environment, + dry_run, ) if not dump_database_names: @@ -228,7 +239,7 @@ def dump_data_sources( environment, dry_run, dry_run_label, - ) + ), ) else: processes.append( @@ -242,7 +253,7 @@ def dump_data_sources( environment, dry_run, dry_run_label, - ) + ), ) if not dry_run: @@ -250,14 +261,17 @@ def dump_data_sources( borgmatic.borg.pattern.Pattern( os.path.join(borgmatic_runtime_directory, 'mysql_databases'), source=borgmatic.borg.pattern.Pattern_source.HOOK, - ) + ), ) return [process for process in processes if process] def remove_data_source_dumps( - databases, config, borgmatic_runtime_directory, dry_run + databases, + config, + borgmatic_runtime_directory, + dry_run, ): # pragma: no cover ''' Remove all database dump files for this hook regardless of the given databases. Use the @@ -268,7 +282,10 @@ def remove_data_source_dumps( def make_data_source_dump_patterns( - databases, config, borgmatic_runtime_directory, name=None + databases, + config, + borgmatic_runtime_directory, + name=None, ): # pragma: no cover ''' Given a sequence of configurations dicts, a configuration dict, the borgmatic runtime directory, @@ -280,10 +297,14 @@ def make_data_source_dump_patterns( return ( dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, hostname='*'), dump.make_data_source_dump_filename( - make_dump_path(borgmatic_runtime_directory), name, hostname='*' + make_dump_path(borgmatic_runtime_directory), + name, + hostname='*', ), dump.make_data_source_dump_filename( - make_dump_path(borgmatic_source_directory), name, hostname='*' + make_dump_path(borgmatic_source_directory), + name, + hostname='*', ), ) @@ -305,10 +326,11 @@ def restore_data_source_dump( ''' dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else '' hostname = connection_params['hostname'] or data_source.get( - 'restore_hostname', data_source.get('hostname') + 'restore_hostname', + data_source.get('hostname'), ) port = str( - connection_params['port'] or data_source.get('restore_port', data_source.get('port', '')) + connection_params['port'] or data_source.get('restore_port', data_source.get('port', '')), ) tls = data_source.get('restore_tls', data_source.get('tls')) username = borgmatic.hooks.credential.parse.resolve_credential( @@ -337,7 +359,9 @@ def restore_data_source_dump( mysql_restore_command + ( borgmatic.hooks.data_source.mariadb.make_defaults_file_options( - username, password, defaults_extra_filename + username, + password, + defaults_extra_filename, ) if password_transport == 'pipe' else () diff --git a/borgmatic/hooks/data_source/postgresql.py b/borgmatic/hooks/data_source/postgresql.py index 6e426cd5..123b79a2 100644 --- a/borgmatic/hooks/data_source/postgresql.py +++ b/borgmatic/hooks/data_source/postgresql.py @@ -43,7 +43,8 @@ def make_environment(database, config, restore_connection_params=None): ) else: environment['PGPASSWORD'] = borgmatic.hooks.credential.parse.resolve_credential( - database['password'], config + database['password'], + config, ) except (AttributeError, KeyError): pass @@ -179,7 +180,7 @@ def dump_data_sources( ) if os.path.exists(dump_filename): logger.warning( - f'Skipping duplicate dump of PostgreSQL database "{database_name}" to {dump_filename}' + f'Skipping duplicate dump of PostgreSQL database "{database_name}" to {dump_filename}', ) continue @@ -197,8 +198,9 @@ def dump_data_sources( '--username', shlex.quote( borgmatic.hooks.credential.parse.resolve_credential( - database['username'], config - ) + database['username'], + config, + ), ), ) if 'username' in database @@ -221,27 +223,27 @@ def dump_data_sources( ) logger.debug( - f'Dumping PostgreSQL database "{database_name}" to {dump_filename}{dry_run_label}' + f'Dumping PostgreSQL database "{database_name}" to {dump_filename}{dry_run_label}', ) if dry_run: continue if dump_format == 'directory': dump.create_parent_directory_for_dump(dump_filename) - execute_command( + execute_command( # noqa: S604 command, - shell=True, # noqa: S604 + shell=True, environment=environment, ) else: dump.create_named_pipe_for_dump(dump_filename) processes.append( - execute_command( + execute_command( # noqa: S604 command, - shell=True, # noqa: S604 + shell=True, environment=environment, run_to_completion=False, - ) + ), ) if not dry_run: @@ -249,14 +251,17 @@ def dump_data_sources( borgmatic.borg.pattern.Pattern( os.path.join(borgmatic_runtime_directory, 'postgresql_databases'), source=borgmatic.borg.pattern.Pattern_source.HOOK, - ) + ), ) return processes def remove_data_source_dumps( - databases, config, borgmatic_runtime_directory, dry_run + databases, + config, + borgmatic_runtime_directory, + dry_run, ): # pragma: no cover ''' Remove all database dump files for this hook regardless of the given databases. Use the @@ -264,12 +269,17 @@ def remove_data_source_dumps( actually remove anything. ''' dump.remove_data_source_dumps( - make_dump_path(borgmatic_runtime_directory), 'PostgreSQL', dry_run + make_dump_path(borgmatic_runtime_directory), + 'PostgreSQL', + dry_run, ) def make_data_source_dump_patterns( - databases, config, borgmatic_runtime_directory, name=None + databases, + config, + borgmatic_runtime_directory, + name=None, ): # pragma: no cover ''' Given a sequence of configurations dicts, a configuration dict, the borgmatic runtime directory, @@ -281,10 +291,14 @@ def make_data_source_dump_patterns( return ( dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, hostname='*'), dump.make_data_source_dump_filename( - make_dump_path(borgmatic_runtime_directory), name, hostname='*' + make_dump_path(borgmatic_runtime_directory), + name, + hostname='*', ), dump.make_data_source_dump_filename( - make_dump_path(borgmatic_source_directory), name, hostname='*' + make_dump_path(borgmatic_source_directory), + name, + hostname='*', ), ) @@ -313,10 +327,11 @@ def restore_data_source_dump( ''' dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else '' hostname = connection_params['hostname'] or data_source.get( - 'restore_hostname', data_source.get('hostname') + 'restore_hostname', + data_source.get('hostname'), ) port = str( - connection_params['port'] or data_source.get('restore_port', data_source.get('port', '')) + connection_params['port'] or data_source.get('restore_port', data_source.get('port', '')), ) username = borgmatic.hooks.credential.parse.resolve_credential( ( @@ -372,7 +387,7 @@ def restore_data_source_dump( + tuple( itertools.chain.from_iterable(('--schema', schema) for schema in data_source['schemas']) if data_source.get('schemas') - else () + else (), ) ) diff --git a/borgmatic/hooks/data_source/sqlite.py b/borgmatic/hooks/data_source/sqlite.py index 959014ba..9ac6f2d3 100644 --- a/borgmatic/hooks/data_source/sqlite.py +++ b/borgmatic/hooks/data_source/sqlite.py @@ -60,7 +60,7 @@ def dump_data_sources( if not os.path.exists(database_path): logger.warning( - f'No SQLite database at {database_path}; an empty database will be created and dumped' + f'No SQLite database at {database_path}; an empty database will be created and dumped', ) dump_path = make_dump_path(borgmatic_runtime_directory) @@ -68,14 +68,15 @@ def dump_data_sources( if os.path.exists(dump_filename): logger.warning( - f'Skipping duplicate dump of SQLite database at {database_path} to {dump_filename}' + f'Skipping duplicate dump of SQLite database at {database_path} to {dump_filename}', ) continue sqlite_command = tuple( shlex.quote(part) for part in shlex.split(database.get('sqlite_command') or 'sqlite3') ) - command = sqlite_command + ( + command = ( + *sqlite_command, shlex.quote(database_path), '.dump', '>', @@ -83,14 +84,14 @@ def dump_data_sources( ) logger.debug( - f'Dumping SQLite database at {database_path} to {dump_filename}{dry_run_label}' + f'Dumping SQLite database at {database_path} to {dump_filename}{dry_run_label}', ) if dry_run: continue dump.create_named_pipe_for_dump(dump_filename) processes.append( - execute_command(command, shell=True, run_to_completion=False) # noqa: S604 + execute_command(command, shell=True, run_to_completion=False), # noqa: S604 ) if not dry_run: @@ -98,14 +99,17 @@ def dump_data_sources( borgmatic.borg.pattern.Pattern( os.path.join(borgmatic_runtime_directory, 'sqlite_databases'), source=borgmatic.borg.pattern.Pattern_source.HOOK, - ) + ), ) return processes def remove_data_source_dumps( - databases, config, borgmatic_runtime_directory, dry_run + databases, + config, + borgmatic_runtime_directory, + dry_run, ): # pragma: no cover ''' Remove all database dump files for this hook regardless of the given databases. Use the @@ -116,7 +120,10 @@ def remove_data_source_dumps( def make_data_source_dump_patterns( - databases, config, borgmatic_runtime_directory, name=None + databases, + config, + borgmatic_runtime_directory, + name=None, ): # pragma: no cover ''' Given a sequence of configurations dicts, a configuration dict, the borgmatic runtime directory, @@ -128,10 +135,14 @@ def make_data_source_dump_patterns( return ( dump.make_data_source_dump_filename(make_dump_path('borgmatic'), name, hostname='*'), dump.make_data_source_dump_filename( - make_dump_path(borgmatic_runtime_directory), name, hostname='*' + make_dump_path(borgmatic_runtime_directory), + name, + hostname='*', ), dump.make_data_source_dump_filename( - make_dump_path(borgmatic_source_directory), name, hostname='*' + make_dump_path(borgmatic_source_directory), + name, + hostname='*', ), ) @@ -153,7 +164,8 @@ def restore_data_source_dump( ''' dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else '' database_path = connection_params['restore_path'] or data_source.get( - 'restore_path', data_source.get('path') + 'restore_path', + data_source.get('path'), ) logger.debug(f'Restoring SQLite database at {database_path}{dry_run_label}') @@ -170,7 +182,7 @@ def restore_data_source_dump( shlex.quote(part) for part in shlex.split(data_source.get('sqlite_restore_command') or 'sqlite3') ) - restore_command = sqlite_restore_command + (shlex.quote(database_path),) + restore_command = (*sqlite_restore_command, shlex.quote(database_path)) # Don't give Borg local path so as to error on warnings, as "borg extract" only gives a warning # if the restore paths don't exist in the archive. execute_command_with_processes( diff --git a/borgmatic/hooks/data_source/zfs.py b/borgmatic/hooks/data_source/zfs.py index 1c0162c8..a9745483 100644 --- a/borgmatic/hooks/data_source/zfs.py +++ b/borgmatic/hooks/data_source/zfs.py @@ -45,8 +45,8 @@ def get_datasets_to_backup(zfs_command, patterns): Return the result as a sequence of Dataset instances, sorted by mount point. ''' list_output = borgmatic.execute.execute_command_and_capture_output( - tuple(zfs_command.split(' ')) - + ( + ( + *zfs_command.split(' '), 'list', '-H', '-t', @@ -103,7 +103,8 @@ def get_datasets_to_backup(zfs_command, patterns): else () ) + borgmatic.hooks.data_source.snapshot.get_contained_patterns( - dataset.mount_point, candidate_patterns + dataset.mount_point, + candidate_patterns, ) ), ) @@ -115,7 +116,7 @@ def get_datasets_to_backup(zfs_command, patterns): ) ), key=lambda dataset: dataset.mount_point, - ) + ), ) @@ -124,8 +125,8 @@ def get_all_dataset_mount_points(zfs_command): Given a ZFS command to run, return all ZFS datasets as a sequence of sorted mount points. ''' list_output = borgmatic.execute.execute_command_and_capture_output( - tuple(zfs_command.split(' ')) - + ( + ( + *zfs_command.split(' '), 'list', '-H', '-t', @@ -143,8 +144,8 @@ def get_all_dataset_mount_points(zfs_command): for line in list_output.splitlines() for mount_point in (line.rstrip(),) if mount_point != 'none' - } - ) + }, + ), ) @@ -154,8 +155,8 @@ def snapshot_dataset(zfs_command, full_snapshot_name): # pragma: no cover snapshot. ''' borgmatic.execute.execute_command( - tuple(zfs_command.split(' ')) - + ( + ( + *zfs_command.split(' '), 'snapshot', full_snapshot_name, ), @@ -173,8 +174,8 @@ def mount_snapshot(mount_command, full_snapshot_name, snapshot_mount_path): # p os.makedirs(snapshot_mount_path, mode=0o700, exist_ok=True) borgmatic.execute.execute_command( - tuple(mount_command.split(' ')) - + ( + ( + *mount_command.split(' '), '-t', 'zfs', '-o', @@ -265,7 +266,7 @@ def dump_data_sources( for dataset in requested_datasets: full_snapshot_name = f'{dataset.name}@{snapshot_name}' logger.debug( - f'Creating ZFS snapshot {full_snapshot_name} of {dataset.mount_point}{dry_run_label}' + f'Creating ZFS snapshot {full_snapshot_name} of {dataset.mount_point}{dry_run_label}', ) if not dry_run: @@ -277,25 +278,29 @@ def dump_data_sources( normalized_runtime_directory, 'zfs_snapshots', hashlib.shake_256(dataset.mount_point.encode('utf-8')).hexdigest( - MOUNT_POINT_HASH_LENGTH + MOUNT_POINT_HASH_LENGTH, ), dataset.mount_point.lstrip(os.path.sep), ) logger.debug( - f'Mounting ZFS snapshot {full_snapshot_name} at {snapshot_mount_path}{dry_run_label}' + f'Mounting ZFS snapshot {full_snapshot_name} at {snapshot_mount_path}{dry_run_label}', ) if dry_run: continue mount_snapshot( - hook_config.get('mount_command', 'mount'), full_snapshot_name, snapshot_mount_path + hook_config.get('mount_command', 'mount'), + full_snapshot_name, + snapshot_mount_path, ) for pattern in dataset.contained_patterns: snapshot_pattern = make_borg_snapshot_pattern( - pattern, dataset, normalized_runtime_directory + pattern, + dataset, + normalized_runtime_directory, ) # Attempt to update the pattern in place, since pattern order matters to Borg. @@ -312,7 +317,7 @@ def unmount_snapshot(umount_command, snapshot_mount_path): # pragma: no cover Given a umount command to run and the mount path of a snapshot, unmount it. ''' borgmatic.execute.execute_command( - tuple(umount_command.split(' ')) + (snapshot_mount_path,), + (*umount_command.split(' '), snapshot_mount_path), output_log_level=logging.DEBUG, close_fds=True, ) @@ -324,8 +329,8 @@ def destroy_snapshot(zfs_command, full_snapshot_name): # pragma: no cover it. ''' borgmatic.execute.execute_command( - tuple(zfs_command.split(' ')) - + ( + ( + *tuple(zfs_command.split(' ')), 'destroy', full_snapshot_name, ), @@ -340,8 +345,8 @@ def get_all_snapshots(zfs_command): form "dataset@snapshot". ''' list_output = borgmatic.execute.execute_command_and_capture_output( - tuple(zfs_command.split(' ')) - + ( + ( + *tuple(zfs_command.split(' ')), 'list', '-H', '-t', @@ -355,7 +360,7 @@ def get_all_snapshots(zfs_command): return tuple(line.rstrip() for line in list_output.splitlines()) -def remove_data_source_dumps(hook_config, config, borgmatic_runtime_directory, dry_run): +def remove_data_source_dumps(hook_config, config, borgmatic_runtime_directory, dry_run): # noqa: PLR0912 ''' Given a ZFS configuration dict, a configuration dict, the borgmatic runtime directory, and whether this is a dry run, unmount and destroy any ZFS snapshots created by borgmatic. If this @@ -444,7 +449,10 @@ def remove_data_source_dumps(hook_config, config, borgmatic_runtime_directory, d def make_data_source_dump_patterns( - hook_config, config, borgmatic_runtime_directory, name=None + hook_config, + config, + borgmatic_runtime_directory, + name=None, ): # pragma: no cover ''' Restores aren't implemented, because stored files can be extracted directly with "extract". diff --git a/borgmatic/hooks/dispatch.py b/borgmatic/hooks/dispatch.py index e12e70a0..072f279f 100644 --- a/borgmatic/hooks/dispatch.py +++ b/borgmatic/hooks/dispatch.py @@ -86,7 +86,7 @@ def call_hooks(function_name, config, hook_type, *args, **kwargs): return { hook_name: call_hook(function_name, config, hook_name, *args, **kwargs) for hook_name in get_submodule_names( - importlib.import_module(f'borgmatic.hooks.{hook_type.value}') + importlib.import_module(f'borgmatic.hooks.{hook_type.value}'), ) if hook_name in config or f'{hook_name}_databases' in config } @@ -105,6 +105,6 @@ def call_hooks_even_if_unconfigured(function_name, config, hook_type, *args, **k return { hook_name: call_hook(function_name, config, hook_name, *args, **kwargs) for hook_name in get_submodule_names( - importlib.import_module(f'borgmatic.hooks.{hook_type.value}') + importlib.import_module(f'borgmatic.hooks.{hook_type.value}'), ) } diff --git a/borgmatic/hooks/monitoring/apprise.py b/borgmatic/hooks/monitoring/apprise.py index b873c6cd..c39787c9 100644 --- a/borgmatic/hooks/monitoring/apprise.py +++ b/borgmatic/hooks/monitoring/apprise.py @@ -28,8 +28,10 @@ def initialize_monitor(hook_config, config, config_filename, monitoring_log_leve borgmatic.hooks.monitoring.logs.add_handler( borgmatic.hooks.monitoring.logs.Forgetful_buffering_handler( - HANDLER_IDENTIFIER, logs_size_limit, monitoring_log_level - ) + HANDLER_IDENTIFIER, + logs_size_limit, + monitoring_log_level, + ), ) @@ -39,8 +41,8 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev entries. If this is a dry run, then don't actually ping anything. ''' try: - import apprise - from apprise import NotifyFormat, NotifyType + import apprise # noqa: PLC0415 + from apprise import NotifyFormat, NotifyType # noqa: PLC0415 except ImportError: # pragma: no cover logger.warning('Unable to import Apprise in monitoring hook') return @@ -81,13 +83,13 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev body = state_config.get('body') - if state in ( + if state in { borgmatic.hooks.monitoring.monitor.State.FINISH, borgmatic.hooks.monitoring.monitor.State.FAIL, borgmatic.hooks.monitoring.monitor.State.LOG, - ): + }: formatted_logs = borgmatic.hooks.monitoring.logs.format_buffered_logs_for_payload( - HANDLER_IDENTIFIER + HANDLER_IDENTIFIER, ) if formatted_logs: body += f'\n\n{formatted_logs}' diff --git a/borgmatic/hooks/monitoring/cronhub.py b/borgmatic/hooks/monitoring/cronhub.py index d2c2d79c..6fbd83c1 100644 --- a/borgmatic/hooks/monitoring/cronhub.py +++ b/borgmatic/hooks/monitoring/cronhub.py @@ -15,12 +15,15 @@ TIMEOUT_SECONDS = 10 def initialize_monitor( - ping_url, config, config_filename, monitoring_log_level, dry_run + ping_url, + config, + config_filename, + monitoring_log_level, + dry_run, ): # pragma: no cover ''' No initialization is necessary for this monitor. ''' - pass def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run): @@ -57,4 +60,3 @@ def destroy_monitor(ping_url_or_uuid, config, monitoring_log_level, dry_run): # ''' No destruction is necessary for this monitor. ''' - pass diff --git a/borgmatic/hooks/monitoring/cronitor.py b/borgmatic/hooks/monitoring/cronitor.py index bb94fa31..89c89999 100644 --- a/borgmatic/hooks/monitoring/cronitor.py +++ b/borgmatic/hooks/monitoring/cronitor.py @@ -15,12 +15,15 @@ TIMEOUT_SECONDS = 10 def initialize_monitor( - ping_url, config, config_filename, monitoring_log_level, dry_run + ping_url, + config, + config_filename, + monitoring_log_level, + dry_run, ): # pragma: no cover ''' No initialization is necessary for this monitor. ''' - pass def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run): @@ -52,4 +55,3 @@ def destroy_monitor(ping_url_or_uuid, config, monitoring_log_level, dry_run): # ''' No destruction is necessary for this monitor. ''' - pass diff --git a/borgmatic/hooks/monitoring/healthchecks.py b/borgmatic/hooks/monitoring/healthchecks.py index ec7c529d..2caa3947 100644 --- a/borgmatic/hooks/monitoring/healthchecks.py +++ b/borgmatic/hooks/monitoring/healthchecks.py @@ -37,8 +37,10 @@ def initialize_monitor(hook_config, config, config_filename, monitoring_log_leve borgmatic.hooks.monitoring.logs.add_handler( borgmatic.hooks.monitoring.logs.Forgetful_buffering_handler( - HANDLER_IDENTIFIER, ping_body_limit, monitoring_log_level - ) + HANDLER_IDENTIFIER, + ping_body_limit, + monitoring_log_level, + ), ) @@ -74,9 +76,9 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev logger.info(f'Pinging Healthchecks {state.name.lower()}{dry_run_label}') logger.debug(f'Using Healthchecks ping URL {ping_url}') - if state in (monitor.State.FINISH, monitor.State.FAIL, monitor.State.LOG): + if state in {monitor.State.FINISH, monitor.State.FAIL, monitor.State.LOG}: payload = borgmatic.hooks.monitoring.logs.format_buffered_logs_for_payload( - HANDLER_IDENTIFIER + HANDLER_IDENTIFIER, ) else: payload = '' diff --git a/borgmatic/hooks/monitoring/logs.py b/borgmatic/hooks/monitoring/logs.py index 5b8a49ce..ec36bd94 100644 --- a/borgmatic/hooks/monitoring/logs.py +++ b/borgmatic/hooks/monitoring/logs.py @@ -1,3 +1,4 @@ +import contextlib import logging IS_A_HOOK = False @@ -88,9 +89,7 @@ def remove_handler(identifier): ''' logger = logging.getLogger() - try: + with contextlib.suppress(ValueError): logger.removeHandler(get_handler(identifier)) - except ValueError: - pass logger.setLevel(min(handler.level for handler in logger.handlers)) diff --git a/borgmatic/hooks/monitoring/loki.py b/borgmatic/hooks/monitoring/loki.py index 7029d940..7024edd5 100644 --- a/borgmatic/hooks/monitoring/loki.py +++ b/borgmatic/hooks/monitoring/loki.py @@ -71,7 +71,10 @@ class Loki_log_buffer: try: result = requests.post( - self.url, headers=request_header, data=request_body, timeout=TIMEOUT_SECONDS + self.url, + headers=request_header, + data=request_body, + timeout=TIMEOUT_SECONDS, ) result.raise_for_status() except requests.RequestException: @@ -140,9 +143,8 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev Add an entry to the loki logger with the current state. ''' for handler in tuple(logging.getLogger().handlers): - if isinstance(handler, Loki_log_handler): - if state in MONITOR_STATE_TO_LOKI.keys(): - handler.raw(f'{MONITOR_STATE_TO_LOKI[state]} backup') + if isinstance(handler, Loki_log_handler) and state in MONITOR_STATE_TO_LOKI: + handler.raw(f'{MONITOR_STATE_TO_LOKI[state]} backup') def destroy_monitor(hook_config, config, monitoring_log_level, dry_run): diff --git a/borgmatic/hooks/monitoring/ntfy.py b/borgmatic/hooks/monitoring/ntfy.py index 9a66ec0a..b11ff5ee 100644 --- a/borgmatic/hooks/monitoring/ntfy.py +++ b/borgmatic/hooks/monitoring/ntfy.py @@ -11,12 +11,15 @@ TIMEOUT_SECONDS = 10 def initialize_monitor( - ping_url, config, config_filename, monitoring_log_level, dry_run + ping_url, + config, + config_filename, + monitoring_log_level, + dry_run, ): # pragma: no cover ''' No initialization is necessary for this monitor. ''' - pass def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run): @@ -54,13 +57,16 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev try: username = borgmatic.hooks.credential.parse.resolve_credential( - hook_config.get('username'), config + hook_config.get('username'), + config, ) password = borgmatic.hooks.credential.parse.resolve_credential( - hook_config.get('password'), config + hook_config.get('password'), + config, ) access_token = borgmatic.hooks.credential.parse.resolve_credential( - hook_config.get('access_token'), config + hook_config.get('access_token'), + config, ) except ValueError as error: logger.warning(f'Ntfy credential error: {error}') @@ -71,7 +77,7 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev if access_token is not None: if username or password: logger.warning( - 'ntfy access_token is set but so is username/password, only using access_token' + 'ntfy access_token is set but so is username/password, only using access_token', ) auth = requests.auth.HTTPBasicAuth('', access_token) @@ -87,7 +93,10 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev logging.getLogger('urllib3').setLevel(logging.ERROR) try: response = requests.post( - f'{base_url}/{topic}', headers=headers, auth=auth, timeout=TIMEOUT_SECONDS + f'{base_url}/{topic}', + headers=headers, + auth=auth, + timeout=TIMEOUT_SECONDS, ) if not response.ok: response.raise_for_status() @@ -99,4 +108,3 @@ def destroy_monitor(ping_url_or_uuid, config, monitoring_log_level, dry_run): # ''' No destruction is necessary for this monitor. ''' - pass diff --git a/borgmatic/hooks/monitoring/pagerduty.py b/borgmatic/hooks/monitoring/pagerduty.py index eb58aec0..69cf4133 100644 --- a/borgmatic/hooks/monitoring/pagerduty.py +++ b/borgmatic/hooks/monitoring/pagerduty.py @@ -34,8 +34,10 @@ def initialize_monitor(hook_config, config, config_filename, monitoring_log_leve borgmatic.hooks.monitoring.logs.add_handler( borgmatic.hooks.monitoring.logs.Forgetful_buffering_handler( - HANDLER_IDENTIFIER, ping_body_limit, monitoring_log_level - ) + HANDLER_IDENTIFIER, + ping_body_limit, + monitoring_log_level, + ), ) @@ -56,14 +58,15 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev try: integration_key = borgmatic.hooks.credential.parse.resolve_credential( - hook_config.get('integration_key'), config + hook_config.get('integration_key'), + config, ) except ValueError as error: logger.warning(f'PagerDuty credential error: {error}') return logs_payload = borgmatic.hooks.monitoring.logs.format_buffered_logs_for_payload( - HANDLER_IDENTIFIER + HANDLER_IDENTIFIER, ) hostname = platform.node() @@ -87,7 +90,7 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev 'logs': logs_payload, }, }, - } + }, ) if dry_run: @@ -96,7 +99,9 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev logging.getLogger('urllib3').setLevel(logging.ERROR) try: response = requests.post( - EVENTS_API_URL, data=payload.encode('utf-8'), timeout=TIMEOUT_SECONDS + EVENTS_API_URL, + data=payload.encode('utf-8'), + timeout=TIMEOUT_SECONDS, ) if not response.ok: response.raise_for_status() diff --git a/borgmatic/hooks/monitoring/pushover.py b/borgmatic/hooks/monitoring/pushover.py index d8ffc791..0fd96e60 100644 --- a/borgmatic/hooks/monitoring/pushover.py +++ b/borgmatic/hooks/monitoring/pushover.py @@ -12,12 +12,15 @@ TIMEOUT_SECONDS = 10 def initialize_monitor( - ping_url, config, config_filename, monitoring_log_level, dry_run + ping_url, + config, + config_filename, + monitoring_log_level, + dry_run, ): # pragma: no cover ''' No initialization is necessary for this monitor. ''' - pass def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run): @@ -37,7 +40,8 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev try: token = borgmatic.hooks.credential.parse.resolve_credential( - hook_config.get('token'), config + hook_config.get('token'), + config, ) user = borgmatic.hooks.credential.parse.resolve_credential(hook_config.get('user'), config) except ValueError as error: @@ -54,11 +58,10 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev if 'retry' not in state_config: logger.info('Setting retry to default (30 sec)') state_config['retry'] = 30 - else: - if 'expire' in state_config or 'retry' in state_config: - raise ValueError( - 'The configuration parameters retry and expire should not be set when priority is not equal to 2. Please remove them from the configuration.' - ) + elif 'expire' in state_config or 'retry' in state_config: + raise ValueError( + 'The configuration parameters retry and expire should not be set when priority is not equal to 2. Please remove them from the configuration.', + ) state_config = { key: (int(value) if key == 'html' else value) for key, value in state_config.items() @@ -93,4 +96,3 @@ def destroy_monitor(ping_url_or_uuid, config, monitoring_log_level, dry_run): # ''' No destruction is necessary for this monitor. ''' - pass diff --git a/borgmatic/hooks/monitoring/sentry.py b/borgmatic/hooks/monitoring/sentry.py index e31dfe12..c245c8e9 100644 --- a/borgmatic/hooks/monitoring/sentry.py +++ b/borgmatic/hooks/monitoring/sentry.py @@ -10,16 +10,19 @@ TIMEOUT_SECONDS = 10 def initialize_monitor( - ping_url, config, config_filename, monitoring_log_level, dry_run + ping_url, + config, + config_filename, + monitoring_log_level, + dry_run, ): # pragma: no cover ''' No initialization is necessary for this monitor. ''' - pass DATA_SOURCE_NAME_URL_PATTERN = re.compile( - '^(?P.+)://(?P.+)@(?P.+)/(?P.+)$' + r'^(?P.+)://(?P.+)@(?P.+)/(?P.+)$', ) @@ -31,7 +34,7 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev ''' run_states = hook_config.get('states', ['start', 'finish', 'fail']) - if not state.name.lower() in run_states: + if state.name.lower() not in run_states: return dry_run_label = ' (dry run; not actually pinging)' if dry_run else '' @@ -75,4 +78,3 @@ def destroy_monitor(ping_url_or_uuid, config, monitoring_log_level, dry_run): # ''' No destruction is necessary for this monitor. ''' - pass diff --git a/borgmatic/hooks/monitoring/uptime_kuma.py b/borgmatic/hooks/monitoring/uptime_kuma.py index 98c89ec4..2887d388 100644 --- a/borgmatic/hooks/monitoring/uptime_kuma.py +++ b/borgmatic/hooks/monitoring/uptime_kuma.py @@ -9,12 +9,15 @@ TIMEOUT_SECONDS = 10 def initialize_monitor( - push_url, config, config_filename, monitoring_log_level, dry_run + push_url, + config, + config_filename, + monitoring_log_level, + dry_run, ): # pragma: no cover ''' No initialization is necessary for this monitor. ''' - pass def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run): @@ -55,4 +58,3 @@ def destroy_monitor(push_url_or_uuid, config, monitoring_log_level, dry_run): # ''' No destruction is necessary for this monitor. ''' - pass diff --git a/borgmatic/hooks/monitoring/zabbix.py b/borgmatic/hooks/monitoring/zabbix.py index b514f003..ddb66a8d 100644 --- a/borgmatic/hooks/monitoring/zabbix.py +++ b/borgmatic/hooks/monitoring/zabbix.py @@ -11,12 +11,15 @@ TIMEOUT_SECONDS = 10 def initialize_monitor( - ping_url, config, config_filename, monitoring_log_level, dry_run + ping_url, + config, + config_filename, + monitoring_log_level, + dry_run, ): # pragma: no cover ''' No initialization is necessary for this monitor. ''' - pass def send_zabbix_request(server, headers, data): @@ -55,7 +58,7 @@ def send_zabbix_request(server, headers, data): return None -def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run): +def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run): # noqa: PLR0911, PLR0912, PLR0915 ''' Update the configured Zabbix item using either the itemid, or a host and key. If this is a dry run, then don't actually update anything. @@ -77,13 +80,16 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev try: username = borgmatic.hooks.credential.parse.resolve_credential( - hook_config.get('username'), config + hook_config.get('username'), + config, ) password = borgmatic.hooks.credential.parse.resolve_credential( - hook_config.get('password'), config + hook_config.get('password'), + config, ) api_key = borgmatic.hooks.credential.parse.resolve_credential( - hook_config.get('api_key'), config + hook_config.get('api_key'), + config, ) except ValueError as error: logger.warning(f'Zabbix credential error: {error}') @@ -184,4 +190,3 @@ def destroy_monitor(ping_url_or_uuid, config, monitoring_log_level, dry_run): # ''' No destruction is necessary for this monitor. ''' - pass diff --git a/borgmatic/logger.py b/borgmatic/logger.py index 55e67290..9deee00e 100644 --- a/borgmatic/logger.py +++ b/borgmatic/logger.py @@ -15,10 +15,7 @@ def to_bool(arg): if isinstance(arg, str): arg = arg.lower() - if arg in ('yes', 'on', '1', 'true', 1): - return True - - return False + return arg in {'yes', 'on', '1', 'true', 1} def interactive_console(): @@ -59,12 +56,12 @@ class Multi_stream_handler(logging.Handler): ''' def __init__(self, log_level_to_stream_handler): - super(Multi_stream_handler, self).__init__() + super().__init__() self.log_level_to_handler = log_level_to_stream_handler self.handlers = set(self.log_level_to_handler.values()) def flush(self): # pragma: no cover - super(Multi_stream_handler, self).flush() + super().flush() for handler in self.handlers: handler.flush() @@ -75,29 +72,29 @@ class Multi_stream_handler(logging.Handler): ''' self.log_level_to_handler[record.levelno].emit(record) - def setFormatter(self, formatter): # pragma: no cover - super(Multi_stream_handler, self).setFormatter(formatter) + def setFormatter(self, formatter): # pragma: no cover # noqa: N802 + super().setFormatter(formatter) for handler in self.handlers: handler.setFormatter(formatter) - def setLevel(self, level): # pragma: no cover - super(Multi_stream_handler, self).setLevel(level) + def setLevel(self, level): # pragma: no cover # noqa: N802 + super().setLevel(level) for handler in self.handlers: handler.setLevel(level) class Log_prefix_formatter(logging.Formatter): - def __init__(self, fmt='{prefix}{message}', style='{', *args, **kwargs): # pragma: no cover + def __init__(self, fmt='{prefix}{message}', *args, style='{', **kwargs): self.prefix = None - super(Log_prefix_formatter, self).__init__(fmt=fmt, style=style, *args, **kwargs) + super().__init__(*args, fmt=fmt, style=style, **kwargs) def format(self, record): # pragma: no cover record.prefix = f'{self.prefix}: ' if self.prefix else '' - return super(Log_prefix_formatter, self).format(record) + return super().format(record) class Color(enum.Enum): @@ -112,28 +109,27 @@ class Color(enum.Enum): class Console_color_formatter(logging.Formatter): def __init__(self, *args, **kwargs): self.prefix = None - super(Console_color_formatter, self).__init__( - '{prefix}{message}', style='{', *args, **kwargs + super().__init__( + '{prefix}{message}', + *args, + style='{', + **kwargs, ) def format(self, record): add_custom_log_levels() - color = ( - { - logging.CRITICAL: Color.RED, - logging.ERROR: Color.RED, - logging.WARN: Color.YELLOW, - logging.ANSWER: Color.MAGENTA, - logging.INFO: Color.GREEN, - logging.DEBUG: Color.CYAN, - } - .get(record.levelno) - .value - ) + color = { + logging.CRITICAL: Color.RED, + logging.ERROR: Color.RED, + logging.WARNING: Color.YELLOW, + logging.ANSWER: Color.MAGENTA, + logging.INFO: Color.GREEN, + logging.DEBUG: Color.CYAN, + }.get(record.levelno).value record.prefix = f'{self.prefix}: ' if self.prefix else '' - return color_text(color, super(Console_color_formatter, self).format(record)) + return color_text(color, super().format(record)) def ansi_escape_code(color): # pragma: no cover @@ -177,18 +173,18 @@ def add_logging_level(level_name, level_number): if not hasattr(logging.getLoggerClass(), method_name): def log_to_root(message, *args, **kwargs): # pragma: no cover - logging.log(level_number, message, *args, **kwargs) + logging.log(level_number, message, *args, **kwargs) # noqa: LOG015 setattr(logging, method_name, log_to_root) -ANSWER = logging.WARN - 5 +ANSWER = logging.WARNING - 5 DISABLED = logging.CRITICAL + 10 def add_custom_log_levels(): # pragma: no cover ''' - Add a custom log level between WARN and INFO for user-requested answers. + Add a custom log level between WARNING and INFO for user-requested answers. ''' add_logging_level('ANSWER', ANSWER) add_logging_level('DISABLED', DISABLED) @@ -277,11 +273,11 @@ class Delayed_logging_handler(logging.handlers.BufferingHandler): ''' def __init__(self): - super(Delayed_logging_handler, self).__init__(capacity=0) + super().__init__(capacity=0) self.targets = None - def shouldFlush(self, record): + def shouldFlush(self, record): # noqa: N802 return self.targets is not None def flush(self): @@ -361,11 +357,11 @@ def configure_logging( logging.DISABLED: console_disabled, logging.CRITICAL: console_error_handler, logging.ERROR: console_error_handler, - logging.WARN: console_error_handler, + logging.WARNING: console_error_handler, logging.ANSWER: console_standard_handler, logging.INFO: console_standard_handler, logging.DEBUG: console_standard_handler, - } + }, ) if color_enabled: @@ -390,8 +386,8 @@ def configure_logging( syslog_handler = logging.handlers.SysLogHandler(address=syslog_path) syslog_handler.setFormatter( Log_prefix_formatter( - 'borgmatic: {levelname} {prefix}{message}', # noqa: FS003 - ) + 'borgmatic: {levelname} {prefix}{message}', + ), ) syslog_handler.setLevel(syslog_log_level) handlers.append(syslog_handler) @@ -400,8 +396,8 @@ def configure_logging( file_handler = logging.handlers.WatchedFileHandler(log_file) file_handler.setFormatter( Log_prefix_formatter( - log_file_format or '[{asctime}] {levelname}: {prefix}{message}', # noqa: FS003 - ) + log_file_format or '[{asctime}] {levelname}: {prefix}{message}', + ), ) file_handler.setLevel(log_file_log_level) handlers.append(file_handler) diff --git a/docs/how-to/develop-on-borgmatic.md b/docs/how-to/develop-on-borgmatic.md index bfacd8e5..0b8da933 100644 --- a/docs/how-to/develop-on-borgmatic.md +++ b/docs/how-to/develop-on-borgmatic.md @@ -50,38 +50,44 @@ code reference](https://torsion.org/borgmatic/docs/reference/source-code/). ## Automated tests Assuming you've cloned the borgmatic source code as described above and you're -in the `borgmatic/` working copy, install tox, which is used for setting up -testing environments. You can either install a system package of tox (likely -called `tox` or `python-tox`) or you can install tox with pipx: +in the `borgmatic/` working copy, install [tox](https://tox.wiki/), which is +used for setting up testing environments. You can either install a system +package of tox (likely called `tox` or `python-tox`) or you can install tox with +pipx: ```bash pipx install tox ``` +Also install [Ruff](https://docs.astral.sh/ruff/), which tox calls for code +linting and formatting: + +```bash +pipx install ruff +``` + Finally, to actually run tests, run tox from inside the borgmatic -sourcedirectory: +source directory: ```bash tox ``` -### Code formatting +### Code style -If when running tests, you get an error from the -[Black](https://black.readthedocs.io/en/stable/) code formatter about files -that would be reformatted, you can ask Black to format them for you via the -following: +If when running tests, you get an error from Ruff's linter about files that +don't meet linting requirements, you can ask Ruff to attempt to fix them for you +via the following: ```bash -tox -e black +tox -e lint ``` -And if you get a complaint from the -[isort](https://github.com/timothycrosley/isort) Python import orderer, you -can ask isort to order your imports for you: +And if you get an error from the Ruff's code formatter about files that would be +reformatted, you can ask Ruff to format them for you: ```bash -tox -e isort +tox -e format ``` Similarly, if you get errors about spelling mistakes in source code, you can @@ -89,7 +95,7 @@ ask [codespell](https://github.com/codespell-project/codespell) to correct them: ```bash -tox -e codespell +tox -e spell ``` @@ -162,11 +168,8 @@ the following deviations from it: * Prefer functional code where it makes sense, e.g. when constructing a command (to subsequently execute imperatively). -borgmatic uses the [Black](https://black.readthedocs.io/en/stable/) code -formatter, the [Flake8](http://flake8.pycqa.org/en/latest/) code checker, and -the [isort](https://github.com/timothycrosley/isort) import orderer, so -certain code style requirements are enforced when running automated tests. See -the Black, Flake8, and isort documentation for more information. +Since borgmatic uses Ruff for code lining and formatting, many other code style +requirements are also enforced when running automated tests. ## Continuous integration diff --git a/pyproject.toml b/pyproject.toml index 88a09749..3d51ce6f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,19 +42,93 @@ build-backend = "setuptools.build_meta" include = ["borgmatic*"] namespaces = false -[tool.black] -line-length = 100 -skip-string-normalization = true - [tool.pytest.ini_options] testpaths = "tests" addopts = "--cov-report term-missing:skip-covered --cov=borgmatic --no-cov-on-fail --cov-fail-under=100 --ignore=tests/end-to-end" -[tool.isort] -profile = "black" -known_first_party = "borgmatic" -line_length = 100 -skip = ".tox" +[tool.ruff] +line-length = 100 +exclude = ["*.*/*"] + +[tool.ruff.format] +quote-style = "preserve" + +[tool.ruff.lint] +preview = true +extend-select = [ + "A", # flake8-builtins: builtin shadowing + "B", # flake8-bugbear: bugs and design problems + "BLE", # flak8-blind-except: "except:" without exception type + "C4", # flake8-comprehensions: generators and comprehensions + "COM", # flake8-commas: trailing commas + "DTZ", # flake8-datetimez: naive datetime + "E", # pycodestyle: errors + "F", # pyflakes: various linting + "ERA", # eradicate: find commented out code + "FLY", # flynt: f-string instead of string join + "FIX", # flake8-fixme: leftover FIXMEs and TODOs + "I", # isort: import ordering + "ISC", # flake8-implicit-str-concat: implicit string concatenation + "LOG", # flake8-logging: standard library logging + "N", # pep8-naming: PEP-8 naming conventions + "PERF", # perflint: performance linting + "PIE", # flake8-pie: various linting + "PL", # pylint: various linting + "Q", # flake8-quotes: string quoting + "RET", # flake-return: return statement + "RUF", # Ruff-specific rules + "S", # flake8-bandit: security testing + "SIM", # flake-simplify: code simplifications + "T20", # flake8-print: print statements + "TID", # flake8-tidy-imports: absolute imports + "UP", # pyupgrade: upgrade syntax for newer versions of Python + "W", # pycodestyle: warnings + "YTT", # flake8-202: sys.version misuse +] +ignore = [ + "C408", # unnecessary dict() call (conflicts with makeLogRecord()) + "COM812", # trailing comma missing (conflicts with formatter) + "B904", # unchained exception raised within "except:" clause + "E501", # line too long + "ISC001", # implicit string concatenation on one line (conflicts with formatter) + "N801", # class name not title case + "N818", # exception class name doesn't end in "Error" + "PLR0913", # too many positional arguments in function definition + "PLR0914", # too many local variables + "PLR0917", # too many positional arguments + "S105", # hard-coded password + "S404", # subprocess import + "SIM115", # open() without context manager + "SIM905", # split() on literal string +] + +[tool.ruff.lint.flake8-quotes] +docstring-quotes = "single" +inline-quotes = "single" +multiline-quotes = "single" + +[tool.ruff.lint.isort] +known-first-party = ["borgmatic"] + +[tool.ruff.lint.per-file-ignores] +"tests/**/*.py" = [ + "C406", # unnecessary list literal + "N802", # uppercase in function name + "PLC1901", # comparison to empty string + "PLR2004", # magic value + "PLW1514", # open() without encoding + "S101", # asserts + "S106", # hard-coded password + "S108", # insecure usage of temporary file + "S602", # shell=True + "S603", # subprocess call + "S604", # shell=True + "S607", # executing a relative path + "TID252", # relative import from parent +] +"tests/end-to-end/commands/**/*.py" = [ + "T201", # print statement +] [tool.codespell] skip = ".git,.tox,build" diff --git a/scripts/run-full-tests b/scripts/run-full-tests index 0bc18406..66c26a51 100755 --- a/scripts/run-full-tests +++ b/scripts/run-full-tests @@ -18,7 +18,7 @@ if [ -z "$TEST_CONTAINER" ]; then fi apk add --no-cache python3 py3-pip borgbackup postgresql17-client mariadb-client mongodb-tools \ - py3-mongo py3-regex py3-ruamel.yaml py3-ruamel.yaml.clib py3-tox py3-yaml bash sqlite fish + py3-mongo py3-regex py3-ruamel.yaml py3-ruamel.yaml.clib py3-tox py3-yaml ruff sqlite bash fish export COVERAGE_FILE=/tmp/.coverage tox --workdir /tmp/.tox --sitepackages diff --git a/test_requirements.txt b/test_requirements.txt index 57c46106..65e03126 100644 --- a/test_requirements.txt +++ b/test_requirements.txt @@ -1,37 +1,26 @@ -appdirs==1.4.4 apprise==1.9.3 attrs==25.3.0 -bandit==1.8.5 -black==25.1.0 -certifi==2025.6.15 -chardet==5.2.0 +certifi==2025.7.14 +charset-normalizer==3.4.2 click==8.2.1 codespell==2.4.1 -coverage==7.9.1 -flake8==7.3.0 -flake8-bandit==4.1.1 -flake8-clean-block==0.1.2 -flake8-eradicate==1.5.0 -flake8-quotes==3.4.0 -flake8-use-fstring==1.4 -flake8-variables-names==0.0.6 -flexmock==0.12.1 +coverage==7.9.2 +flexmock==0.12.2 idna==3.10 -isort==6.0.1 -jsonschema==4.24.0 +iniconfig==2.1.0 +jsonschema==4.24.1 +jsonschema-specifications==2025.4.1 Markdown==3.8.2 -mccabe==0.7.0 +oauthlib==3.3.1 packaging==25.0 -pathspec==0.12.1 -pbr==6.1.1 pluggy==1.6.0 -py==1.11.0 -pycodestyle==2.14.0 -pyflakes==3.4.0 +Pygments==2.19.2 pytest==8.4.1 pytest-cov==6.2.1 PyYAML>5.0.0 -regex +referencing==0.36.2 requests==2.32.4 +requests-oauthlib==2.0.0 +rpds-py==0.26.0 ruamel.yaml>0.15.0 -toml==0.10.2 +urllib3==2.5.0 diff --git a/tests/end-to-end/commands/fake_btrfs.py b/tests/end-to-end/commands/fake_btrfs.py index fd823e72..4902b66a 100644 --- a/tests/end-to-end/commands/fake_btrfs.py +++ b/tests/end-to-end/commands/fake_btrfs.py @@ -62,7 +62,7 @@ def print_subvolume_list(arguments, snapshot_paths): for snapshot_path in snapshot_paths: print( SUBVOLUME_LIST_LINE_PREFIX - + snapshot_path[snapshot_path.index('.borgmatic-snapshot-') :] + + snapshot_path[snapshot_path.index('.borgmatic-snapshot-') :], ) diff --git a/tests/end-to-end/commands/fake_lsblk.py b/tests/end-to-end/commands/fake_lsblk.py index 9c59b41d..29771e6a 100644 --- a/tests/end-to-end/commands/fake_lsblk.py +++ b/tests/end-to-end/commands/fake_lsblk.py @@ -29,7 +29,7 @@ BUILTIN_BLOCK_DEVICES = { 'mountpoint': None, 'type': 'lvm', }, - ] + ], } diff --git a/tests/end-to-end/commands/fake_lvs.py b/tests/end-to-end/commands/fake_lvs.py index 79f3bd97..78ce121b 100644 --- a/tests/end-to-end/commands/fake_lvs.py +++ b/tests/end-to-end/commands/fake_lvs.py @@ -31,11 +31,11 @@ def print_snapshots_json(arguments, snapshots): 'report': [ { 'lv': snapshots, - } + }, ], 'log': [], - } - ) + }, + ), ) diff --git a/tests/end-to-end/docker-compose.yaml b/tests/end-to-end/docker-compose.yaml index ab85bfc9..e62a00ae 100644 --- a/tests/end-to-end/docker-compose.yaml +++ b/tests/end-to-end/docker-compose.yaml @@ -44,7 +44,7 @@ services: MONGO_INITDB_ROOT_PASSWORD: test2 command: docker-entrypoint.sh --port=27018 tests: - image: docker.io/alpine:3.21 + image: docker.io/alpine:3.22 environment: TEST_CONTAINER: true volumes: diff --git a/tests/end-to-end/hooks/credential/test_systemd.py b/tests/end-to-end/hooks/credential/test_systemd.py index 9a263398..375eb476 100644 --- a/tests/end-to-end/hooks/credential/test_systemd.py +++ b/tests/end-to-end/hooks/credential/test_systemd.py @@ -48,17 +48,17 @@ def test_systemd_credential(): subprocess.check_call( f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' '), - env=dict(os.environ, **{'CREDENTIALS_DIRECTORY': temporary_directory}), + env=dict(os.environ, CREDENTIALS_DIRECTORY=temporary_directory), ) # Run borgmatic to generate a backup archive, and then list it to make sure it exists. subprocess.check_call( f'borgmatic --config {config_path}'.split(' '), - env=dict(os.environ, **{'CREDENTIALS_DIRECTORY': temporary_directory}), + env=dict(os.environ, CREDENTIALS_DIRECTORY=temporary_directory), ) output = subprocess.check_output( f'borgmatic --config {config_path} list --json'.split(' '), - env=dict(os.environ, **{'CREDENTIALS_DIRECTORY': temporary_directory}), + env=dict(os.environ, CREDENTIALS_DIRECTORY=temporary_directory), ).decode(sys.stdout.encoding) parsed_output = json.loads(output) diff --git a/tests/end-to-end/hooks/data_source/test_btrfs.py b/tests/end-to-end/hooks/data_source/test_btrfs.py index d49eb796..5dfb2655 100644 --- a/tests/end-to-end/hooks/data_source/test_btrfs.py +++ b/tests/end-to-end/hooks/data_source/test_btrfs.py @@ -40,7 +40,7 @@ def test_btrfs_create_and_list(): generate_configuration(config_path, repository_path) subprocess.check_call( - f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' ') + f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' '), ) # Run a create action to exercise Btrfs snapshotting and backup. @@ -48,7 +48,7 @@ def test_btrfs_create_and_list(): # List the resulting archive and assert that the snapshotted files are there. output = subprocess.check_output( - f'borgmatic --config {config_path} list --archive latest'.split(' ') + f'borgmatic --config {config_path} list --archive latest'.split(' '), ).decode(sys.stdout.encoding) assert 'e2e/mnt/subvolume/subdir/file.txt' in output @@ -56,8 +56,8 @@ def test_btrfs_create_and_list(): # Assert that the snapshot has been deleted. assert not subprocess.check_output( 'python3 /app/tests/end-to-end/commands/fake_btrfs.py subvolume list -s /e2e/mnt/subvolume'.split( - ' ' - ) + ' ', + ), ) finally: shutil.rmtree(temporary_directory) diff --git a/tests/end-to-end/hooks/data_source/test_database.py b/tests/end-to-end/hooks/data_source/test_database.py index 1af436ec..90d0c264 100644 --- a/tests/end-to-end/hooks/data_source/test_database.py +++ b/tests/end-to-end/hooks/data_source/test_database.py @@ -213,14 +213,14 @@ postgresql_databases: def get_connection_params(database, use_restore_options=False): hostname = (database.get('restore_hostname') if use_restore_options else None) or database.get( - 'hostname' + 'hostname', ) port = (database.get('restore_port') if use_restore_options else None) or database.get('port') username = (database.get('restore_username') if use_restore_options else None) or database.get( - 'username' + 'username', ) password = (database.get('restore_password') if use_restore_options else None) or database.get( - 'password' + 'password', ) return (hostname, port, username, password) @@ -228,7 +228,8 @@ def get_connection_params(database, use_restore_options=False): def run_postgresql_command(command, config, use_restore_options=False): (hostname, port, username, password) = get_connection_params( - config['postgresql_databases'][0], use_restore_options + config['postgresql_databases'][0], + use_restore_options, ) subprocess.check_call( @@ -246,7 +247,8 @@ def run_postgresql_command(command, config, use_restore_options=False): def run_mariadb_command(command, config, use_restore_options=False, binary_name='mariadb'): (hostname, port, username, password) = get_connection_params( - config[f'{binary_name}_databases'][0], use_restore_options + config[f'{binary_name}_databases'][0], + use_restore_options, ) subprocess.check_call( @@ -264,7 +266,8 @@ def run_mariadb_command(command, config, use_restore_options=False, binary_name= def get_mongodb_database_client(config, use_restore_options=False): (hostname, port, username, password) = get_connection_params( - config['mongodb_databases'][0], use_restore_options + config['mongodb_databases'][0], + use_restore_options, ) return pymongo.MongoClient(f'mongodb://{username}:{password}@{hostname}:{port or 27017}').test @@ -352,7 +355,7 @@ def select_test_tables(config, use_restore_options=False): if 'mongodb_databases' in config: assert ( get_mongodb_database_client(config, use_restore_options)['test4'].count_documents( - filter={} + filter={}, ) > 0 ) @@ -374,7 +377,10 @@ def test_database_dump_and_restore(): try: config_path = os.path.join(temporary_directory, 'test.yaml') config = write_configuration( - temporary_directory, config_path, repository_path, temporary_directory + temporary_directory, + config_path, + repository_path, + temporary_directory, ) create_test_tables(config) select_test_tables(config) @@ -389,7 +395,7 @@ def test_database_dump_and_restore(): 'repo-create', '--encryption', 'repokey', - ] + ], ) # Run borgmatic to generate a backup archive including database dumps. @@ -397,7 +403,7 @@ def test_database_dump_and_restore(): # Get the created archive name. output = subprocess.check_output( - ['borgmatic', '--config', config_path, 'list', '--json'] + ['borgmatic', '--config', config_path, 'list', '--json'], ).decode(sys.stdout.encoding) parsed_output = json.loads(output) @@ -408,7 +414,7 @@ def test_database_dump_and_restore(): # Restore the databases from the archive. drop_test_tables(config) subprocess.check_call( - ['borgmatic', '-v', '2', '--config', config_path, 'restore', '--archive', archive_name] + ['borgmatic', '-v', '2', '--config', config_path, 'restore', '--archive', archive_name], ) # Ensure the test tables have actually been restored. @@ -429,7 +435,10 @@ def test_database_dump_and_restore_with_restore_cli_flags(): try: config_path = os.path.join(temporary_directory, 'test.yaml') config = write_simple_custom_restore_configuration( - temporary_directory, config_path, repository_path, temporary_directory + temporary_directory, + config_path, + repository_path, + temporary_directory, ) create_test_tables(config) select_test_tables(config) @@ -444,7 +453,7 @@ def test_database_dump_and_restore_with_restore_cli_flags(): 'repo-create', '--encryption', 'repokey', - ] + ], ) # Run borgmatic to generate a backup archive including a database dump. @@ -452,7 +461,7 @@ def test_database_dump_and_restore_with_restore_cli_flags(): # Get the created archive name. output = subprocess.check_output( - ['borgmatic', '--config', config_path, 'list', '--json'] + ['borgmatic', '--config', config_path, 'list', '--json'], ).decode(sys.stdout.encoding) parsed_output = json.loads(output) @@ -478,7 +487,7 @@ def test_database_dump_and_restore_with_restore_cli_flags(): '5433', '--password', 'test2', - ] + ], ) # Ensure the test tables have actually been restored. But first modify the config to contain @@ -507,7 +516,10 @@ def test_database_dump_and_restore_with_restore_configuration_options(): try: config_path = os.path.join(temporary_directory, 'test.yaml') config = write_custom_restore_configuration( - temporary_directory, config_path, repository_path, temporary_directory + temporary_directory, + config_path, + repository_path, + temporary_directory, ) create_test_tables(config) select_test_tables(config) @@ -522,7 +534,7 @@ def test_database_dump_and_restore_with_restore_configuration_options(): 'repo-create', '--encryption', 'repokey', - ] + ], ) # Run borgmatic to generate a backup archive including a database dump. @@ -530,7 +542,7 @@ def test_database_dump_and_restore_with_restore_configuration_options(): # Get the created archive name. output = subprocess.check_output( - ['borgmatic', '--config', config_path, 'list', '--json'] + ['borgmatic', '--config', config_path, 'list', '--json'], ).decode(sys.stdout.encoding) parsed_output = json.loads(output) @@ -541,7 +553,7 @@ def test_database_dump_and_restore_with_restore_configuration_options(): # Restore the database from the archive. drop_test_tables(config) subprocess.check_call( - ['borgmatic', '-v', '2', '--config', config_path, 'restore', '--archive', archive_name] + ['borgmatic', '-v', '2', '--config', config_path, 'restore', '--archive', archive_name], ) # Ensure the test tables have actually been restored. @@ -583,7 +595,7 @@ def test_database_dump_and_restore_with_directory_format(): 'repo-create', '--encryption', 'repokey', - ] + ], ) # Run borgmatic to generate a backup archive including a database dump. @@ -592,7 +604,7 @@ def test_database_dump_and_restore_with_directory_format(): # Restore the database from the archive. drop_test_tables(config) subprocess.check_call( - ['borgmatic', '--config', config_path, 'restore', '--archive', 'latest'] + ['borgmatic', '--config', config_path, 'restore', '--archive', 'latest'], ) # Ensure the test tables have actually been restored. @@ -624,7 +636,7 @@ def test_database_dump_with_error_causes_borgmatic_to_exit(): 'repo-create', '--encryption', 'repokey', - ] + ], ) # Run borgmatic with a config override such that the database dump fails. @@ -638,8 +650,8 @@ def test_database_dump_with_error_causes_borgmatic_to_exit(): '-v', '2', '--override', - "hooks.postgresql_databases=[{'name': 'nope'}]", # noqa: FS003 - ] + "hooks.postgresql_databases=[{'name': 'nope'}]", + ], ) finally: os.chdir(original_working_directory) diff --git a/tests/end-to-end/hooks/data_source/test_lvm.py b/tests/end-to-end/hooks/data_source/test_lvm.py index ec3fec2e..b8d08b0c 100644 --- a/tests/end-to-end/hooks/data_source/test_lvm.py +++ b/tests/end-to-end/hooks/data_source/test_lvm.py @@ -45,7 +45,7 @@ def test_lvm_create_and_list(): generate_configuration(config_path, repository_path) subprocess.check_call( - f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' ') + f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' '), ) # Run a create action to exercise LVM snapshotting and backup. @@ -53,7 +53,7 @@ def test_lvm_create_and_list(): # List the resulting archive and assert that the snapshotted files are there. output = subprocess.check_output( - f'borgmatic --config {config_path} list --archive latest'.split(' ') + f'borgmatic --config {config_path} list --archive latest'.split(' '), ).decode(sys.stdout.encoding) assert 'e2e/mnt/lvolume/subdir/file.txt' in output @@ -61,11 +61,13 @@ def test_lvm_create_and_list(): # Assert that the snapshot has been deleted. assert not json.loads( subprocess.check_output( - 'python3 /app/tests/end-to-end/commands/fake_lvs.py --report-format json --options lv_name,lv_path --select'.split( - ' ' - ) - + ['lv_attr =~ ^s'] - ) + [ + *'python3 /app/tests/end-to-end/commands/fake_lvs.py --report-format json --options lv_name,lv_path --select'.split( + ' ', + ), + 'lv_attr =~ ^s', + ], + ), )['report'][0]['lv'] finally: shutil.rmtree(temporary_directory) diff --git a/tests/end-to-end/hooks/data_source/test_zfs.py b/tests/end-to-end/hooks/data_source/test_zfs.py index 4906c412..ba258325 100644 --- a/tests/end-to-end/hooks/data_source/test_zfs.py +++ b/tests/end-to-end/hooks/data_source/test_zfs.py @@ -41,7 +41,7 @@ def test_zfs_create_and_list(): generate_configuration(config_path, repository_path) subprocess.check_call( - f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' ') + f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' '), ) # Run a create action to exercise ZFS snapshotting and backup. @@ -49,14 +49,14 @@ def test_zfs_create_and_list(): # List the resulting archive and assert that the snapshotted files are there. output = subprocess.check_output( - f'borgmatic --config {config_path} list --archive latest'.split(' ') + f'borgmatic --config {config_path} list --archive latest'.split(' '), ).decode(sys.stdout.encoding) assert 'e2e/pool/dataset/subdir/file.txt' in output # Assert that the snapshot has been deleted. assert not subprocess.check_output( - 'python3 /app/tests/end-to-end/commands/fake_zfs.py list -H -t snapshot'.split(' ') + 'python3 /app/tests/end-to-end/commands/fake_zfs.py list -H -t snapshot'.split(' '), ) finally: shutil.rmtree(temporary_directory) diff --git a/tests/end-to-end/hooks/monitoring/test_monitoring.py b/tests/end-to-end/hooks/monitoring/test_monitoring.py index 5aa264e8..b4f43423 100644 --- a/tests/end-to-end/hooks/monitoring/test_monitoring.py +++ b/tests/end-to-end/hooks/monitoring/test_monitoring.py @@ -40,7 +40,7 @@ class Web_server(http.server.BaseHTTPRequestHandler): self.send_response(http.HTTPStatus.OK) self.send_header('Content-type', 'text/html') self.end_headers() - self.wfile.write(''.encode('utf-8')) + self.wfile.write(b'') def do_GET(self): self.handle_method() @@ -50,7 +50,7 @@ class Web_server(http.server.BaseHTTPRequestHandler): def serve_web_request(count): - for index in range(0, count): + for _ in range(count): with http.server.HTTPServer(('localhost', 12345), Web_server) as server: server.handle_request() @@ -61,7 +61,7 @@ class Background_web_server: def __enter__(self): self.thread = threading.Thread( - target=lambda: serve_web_request(count=self.expected_request_count) + target=lambda: serve_web_request(count=self.expected_request_count), ) self.thread.start() @@ -125,14 +125,14 @@ def test_borgmatic_command(monitoring_hook_configuration, expected_request_count generate_configuration(config_path, repository_path, monitoring_hook_configuration) subprocess.check_call( - f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' ') + f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' '), ) with Background_web_server(expected_request_count): # Run borgmatic to generate a backup archive, and then list it to make sure it exists. subprocess.check_call(f'borgmatic -v 2 --config {config_path}'.split(' ')) output = subprocess.check_output( - f'borgmatic --config {config_path} list --json'.split(' ') + f'borgmatic --config {config_path} list --json'.split(' '), ).decode(sys.stdout.encoding) parsed_output = json.loads(output) diff --git a/tests/end-to-end/test_borgmatic.py b/tests/end-to-end/test_borgmatic.py index d0621c6f..e16fdb09 100644 --- a/tests/end-to-end/test_borgmatic.py +++ b/tests/end-to-end/test_borgmatic.py @@ -81,13 +81,13 @@ def test_borgmatic_command(generate_configuration): generate_configuration(config_path, repository_path) subprocess.check_call( - f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' ') + f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' '), ) # Run borgmatic to generate a backup archive, and then list it to make sure it exists. subprocess.check_call(f'borgmatic --config {config_path}'.split(' ')) output = subprocess.check_output( - f'borgmatic --config {config_path} list --json'.split(' ') + f'borgmatic --config {config_path} list --json'.split(' '), ).decode(sys.stdout.encoding) parsed_output = json.loads(output) diff --git a/tests/end-to-end/test_config_flag.py b/tests/end-to-end/test_config_flag.py index 279a1c6e..58732a4a 100644 --- a/tests/end-to-end/test_config_flag.py +++ b/tests/end-to-end/test_config_flag.py @@ -16,7 +16,7 @@ def generate_configuration(config_path): config = ( open(config_path) .read() - .replace('- ssh://user@backupserver/./{fqdn}', '') # noqa: FS003 + .replace('- ssh://user@backupserver/./{fqdn}', '') .replace('- /var/local/backups/local.borg', '') .replace('- /home/user/path with spaces', '') .replace('- /home', f'- {config_path}') @@ -41,14 +41,14 @@ def test_config_flags_do_not_error(): subprocess.check_call( shlex.split( - f'borgmatic -v 2 --config {config_path} --repositories "[{{path: {repository_path}, label: repo}}]" repo-create --encryption repokey' - ) + f'borgmatic -v 2 --config {config_path} --repositories "[{{path: {repository_path}, label: repo}}]" repo-create --encryption repokey', + ), ) subprocess.check_call( shlex.split( - f'borgmatic create --config {config_path} --repositories[0].path "{repository_path}"' - ) + f'borgmatic create --config {config_path} --repositories[0].path "{repository_path}"', + ), ) finally: os.chdir(original_working_directory) diff --git a/tests/end-to-end/test_environment_variable.py b/tests/end-to-end/test_environment_variable.py index 20a7599d..83d87e8e 100644 --- a/tests/end-to-end/test_environment_variable.py +++ b/tests/end-to-end/test_environment_variable.py @@ -42,7 +42,7 @@ def test_borgmatic_command(): original_working_directory = os.getcwd() os.mkdir(extract_path) os.chdir(extract_path) - environment = dict(os.environ, **{'PASSPHRASE': 'test'}) + environment = dict(os.environ, PASSPHRASE='test') try: config_path = os.path.join(temporary_directory, 'test.yaml') diff --git a/tests/end-to-end/test_generate_config.py b/tests/end-to-end/test_generate_config.py index c9293b7e..418ace24 100644 --- a/tests/end-to-end/test_generate_config.py +++ b/tests/end-to-end/test_generate_config.py @@ -11,6 +11,6 @@ def test_generate_borgmatic_config_with_merging_succeeds(): subprocess.check_call(f'borgmatic config generate --destination {config_path}'.split(' ')) subprocess.check_call( f'borgmatic config generate --source {config_path} --destination {new_config_path}'.split( - ' ' - ) + ' ', + ), ) diff --git a/tests/end-to-end/test_invalid_flag.py b/tests/end-to-end/test_invalid_flag.py index a813dbf2..5687c1e9 100644 --- a/tests/end-to-end/test_invalid_flag.py +++ b/tests/end-to-end/test_invalid_flag.py @@ -3,8 +3,10 @@ import sys def test_borgmatic_command_with_invalid_flag_shows_error_but_not_traceback(): - output = subprocess.run( - 'borgmatic -v 2 --invalid'.split(' '), stdout=subprocess.PIPE, stderr=subprocess.STDOUT + output = subprocess.run( # noqa: PLW1510 + 'borgmatic -v 2 --invalid'.split(' '), + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, ).stdout.decode(sys.stdout.encoding) assert 'Unrecognized argument' in output diff --git a/tests/end-to-end/test_override.py b/tests/end-to-end/test_override.py index ee8a64fe..d2fedff7 100644 --- a/tests/end-to-end/test_override.py +++ b/tests/end-to-end/test_override.py @@ -15,7 +15,7 @@ def generate_configuration(config_path, repository_path): open(config_path) .read() .replace('ssh://user@backupserver/./sourcehostname.borg', repository_path) - .replace('- ssh://user@backupserver/./{fqdn}', '') # noqa: FS003 + .replace('- ssh://user@backupserver/./{fqdn}', '') .replace('- /var/local/backups/local.borg', '') .replace('- /home/user/path with spaces', '') .replace('- /home', f'- {config_path}') @@ -39,15 +39,15 @@ def test_override_gets_normalized(): generate_configuration(config_path, repository_path) subprocess.check_call( - f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' ') + f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' '), ) # Run borgmatic with an override structured for an outdated config file format. If # normalization is working, it should get normalized and shouldn't error. subprocess.check_call( f'borgmatic create --config {config_path} --override hooks.healthchecks=http://localhost:8888/someuuid'.split( - ' ' - ) + ' ', + ), ) finally: os.chdir(original_working_directory) diff --git a/tests/end-to-end/test_passcommand.py b/tests/end-to-end/test_passcommand.py index 2d05baa7..d650d82d 100644 --- a/tests/end-to-end/test_passcommand.py +++ b/tests/end-to-end/test_passcommand.py @@ -45,13 +45,13 @@ def test_borgmatic_command(): generate_configuration(config_path, repository_path) subprocess.check_call( - f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' ') + f'borgmatic -v 2 --config {config_path} repo-create --encryption repokey'.split(' '), ) # Run borgmatic to generate a backup archive, and then list it to make sure it exists. subprocess.check_call(f'borgmatic -v 2 --config {config_path}'.split(' ')) output = subprocess.check_output( - f'borgmatic --config {config_path} list --json'.split(' ') + f'borgmatic --config {config_path} list --json'.split(' '), ).decode(sys.stdout.encoding) parsed_output = json.loads(output) diff --git a/tests/end-to-end/test_validate_config.py b/tests/end-to-end/test_validate_config.py index ec35c063..89e8b473 100644 --- a/tests/end-to-end/test_validate_config.py +++ b/tests/end-to-end/test_validate_config.py @@ -35,7 +35,7 @@ def test_validate_config_command_with_show_flag_displays_configuration(): subprocess.check_call(f'borgmatic config generate --destination {config_path}'.split(' ')) output = subprocess.check_output( - f'borgmatic config validate --config {config_path} --show'.split(' ') + f'borgmatic config validate --config {config_path} --show'.split(' '), ).decode(sys.stdout.encoding) assert 'repositories:' in output diff --git a/tests/integration/borg/test_commands.py b/tests/integration/borg/test_commands.py index 80de7dcd..513ab680 100644 --- a/tests/integration/borg/test_commands.py +++ b/tests/integration/borg/test_commands.py @@ -28,13 +28,15 @@ def assert_command_does_not_duplicate_flags(command, *args, **kwargs): else: flag_counts[flag_name] = 1 - assert flag_counts == { - flag_name: 1 for flag_name in flag_counts - }, f"Duplicate flags found in: {' '.join(command)}" + assert flag_counts == dict.fromkeys(flag_counts, 1), ( + f"Duplicate flags found in: {' '.join(command)}" + ) if '--json' in command: return '{}' + return None + def fuzz_argument(arguments, argument_name): ''' @@ -53,10 +55,13 @@ def fuzz_argument(arguments, argument_name): def test_transfer_archives_command_does_not_duplicate_flags_or_raise(): arguments = borgmatic.commands.arguments.parse_arguments( - {}, 'transfer', '--source-repository', 'foo' + {}, + 'transfer', + '--source-repository', + 'foo', )['transfer'] flexmock(borgmatic.borg.transfer).should_receive('execute_command').replace_with( - assert_command_does_not_duplicate_flags + assert_command_does_not_duplicate_flags, ) for argument_name in dir(arguments): @@ -76,7 +81,7 @@ def test_transfer_archives_command_does_not_duplicate_flags_or_raise(): def test_prune_archives_command_does_not_duplicate_flags_or_raise(): arguments = borgmatic.commands.arguments.parse_arguments({}, 'prune')['prune'] flexmock(borgmatic.borg.prune).should_receive('execute_command').replace_with( - assert_command_does_not_duplicate_flags + assert_command_does_not_duplicate_flags, ) for argument_name in dir(arguments): @@ -98,7 +103,7 @@ def test_mount_archive_command_does_not_duplicate_flags_or_raise(): 'mount' ] flexmock(borgmatic.borg.mount).should_receive('execute_command').replace_with( - assert_command_does_not_duplicate_flags + assert_command_does_not_duplicate_flags, ) for argument_name in dir(arguments): @@ -154,10 +159,10 @@ def test_make_repo_list_command_does_not_duplicate_flags_or_raise(): def test_display_archives_info_command_does_not_duplicate_flags_or_raise(): arguments = borgmatic.commands.arguments.parse_arguments({}, 'info')['info'] flexmock(borgmatic.borg.info).should_receive('execute_command_and_capture_output').replace_with( - assert_command_does_not_duplicate_flags + assert_command_does_not_duplicate_flags, ) flexmock(borgmatic.borg.info).should_receive('execute_command').replace_with( - assert_command_does_not_duplicate_flags + assert_command_does_not_duplicate_flags, ) for argument_name in dir(arguments): diff --git a/tests/integration/commands/completion/test_actions.py b/tests/integration/commands/completion/test_actions.py index 52dfd268..d86050ca 100644 --- a/tests/integration/commands/completion/test_actions.py +++ b/tests/integration/commands/completion/test_actions.py @@ -5,9 +5,9 @@ from borgmatic.commands.completion import actions as module def test_available_actions_uses_only_subactions_for_action_with_subactions(): ( - unused_global_parser, + _, action_parsers, - unused_combined_parser, + _, ) = borgmatic.commands.arguments.make_parsers( schema=borgmatic.config.validate.load_schema(borgmatic.config.validate.schema_filename()), unparsed_arguments=(), @@ -21,9 +21,9 @@ def test_available_actions_uses_only_subactions_for_action_with_subactions(): def test_available_actions_omits_subactions_for_action_without_subactions(): ( - unused_global_parser, + _, action_parsers, - unused_combined_parser, + _, ) = borgmatic.commands.arguments.make_parsers( schema=borgmatic.config.validate.load_schema(borgmatic.config.validate.schema_filename()), unparsed_arguments=(), diff --git a/tests/integration/commands/test_arguments.py b/tests/integration/commands/test_arguments.py index f6d10ca3..261131ac 100644 --- a/tests/integration/commands/test_arguments.py +++ b/tests/integration/commands/test_arguments.py @@ -16,7 +16,7 @@ def test_make_argument_description_with_object_adds_example(): ) # Apparently different versions of ruamel.yaml serialize this # differently. - in ('Thing. Example value: "bar: baz"' 'Thing. Example value: "{bar: baz}"') + in ('Thing. Example value: "bar: baz"Thing. Example value: "{bar: baz}"') ) @@ -90,7 +90,7 @@ def test_add_arguments_from_schema_with_nested_object_adds_flag_for_each_option( 'bar': {'type': 'integer', 'description': 'help 1'}, 'baz': {'type': 'string', 'description': 'help 2'}, }, - } + }, }, }, unparsed_arguments=(), @@ -126,11 +126,11 @@ def test_add_arguments_from_schema_with_array_and_nested_object_adds_multiple_fl 'bar': { 'type': 'integer', 'description': 'help 1', - } + }, }, }, 'description': 'help 2', - } + }, }, }, unparsed_arguments=(), @@ -171,7 +171,12 @@ def test_parse_arguments_with_action_after_config_path_omits_aliased_action(): flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) arguments = module.parse_arguments( - {}, '--config', 'myconfig', 'init', '--encryption', 'repokey' + {}, + '--config', + 'myconfig', + 'init', + '--encryption', + 'repokey', ) global_arguments = arguments['global'] @@ -204,7 +209,13 @@ def test_parse_arguments_with_multiple_overrides_flags_parses(): flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) arguments = module.parse_arguments( - {}, '--override', 'foo.bar=baz', '--override', 'foo.quux=7', '--override', 'this.that=8' + {}, + '--override', + 'foo.bar=baz', + '--override', + 'foo.quux=7', + '--override', + 'this.that=8', ) global_arguments = arguments['global'] @@ -245,10 +256,11 @@ def test_parse_arguments_with_no_actions_passes_argument_to_relevant_actions(): def test_parse_arguments_with_help_and_no_actions_shows_global_help(capsys): flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) - with pytest.raises(SystemExit) as exit: + with pytest.raises(SystemExit) as system_exit: module.parse_arguments({}, '--help') - assert exit.value.code == 0 + assert system_exit.value.code == 0 + captured = capsys.readouterr() assert 'global arguments:' in captured.out assert 'actions:' in captured.out @@ -257,10 +269,11 @@ def test_parse_arguments_with_help_and_no_actions_shows_global_help(capsys): def test_parse_arguments_with_help_and_action_shows_action_help(capsys): flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) - with pytest.raises(SystemExit) as exit: + with pytest.raises(SystemExit) as system_exit: module.parse_arguments({}, 'create', '--help') - assert exit.value.code == 0 + assert system_exit.value.code == 0 + captured = capsys.readouterr() assert 'global arguments:' not in captured.out assert 'actions:' not in captured.out @@ -355,7 +368,14 @@ def test_parse_arguments_allows_repository_with_extract(): flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) module.parse_arguments( - {}, '--config', 'myconfig', 'extract', '--repository', 'test.borg', '--archive', 'test' + {}, + '--config', + 'myconfig', + 'extract', + '--repository', + 'test.borg', + '--archive', + 'test', ) @@ -413,7 +433,14 @@ def test_parse_arguments_allows_archive_with_mount(): flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) module.parse_arguments( - {}, '--config', 'myconfig', 'mount', '--archive', 'test', '--mount-point', '/mnt' + {}, + '--config', + 'myconfig', + 'mount', + '--archive', + 'test', + '--mount-point', + '/mnt', ) @@ -618,10 +645,11 @@ def test_parse_arguments_config_with_no_subaction_errors(): def test_parse_arguments_config_with_help_shows_config_help(capsys): flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) - with pytest.raises(SystemExit) as exit: + with pytest.raises(SystemExit) as system_exit: module.parse_arguments({}, 'config', '--help') - assert exit.value.code == 0 + assert system_exit.value.code == 0 + captured = capsys.readouterr() assert 'global arguments:' not in captured.out assert 'config arguments:' in captured.out @@ -631,19 +659,20 @@ def test_parse_arguments_config_with_help_shows_config_help(capsys): def test_parse_arguments_config_with_subaction_but_missing_flags_errors(): flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) - with pytest.raises(SystemExit) as exit: + with pytest.raises(SystemExit) as system_exit: module.parse_arguments({}, 'config', 'bootstrap') - assert exit.value.code == 2 + assert system_exit.value.code == 2 def test_parse_arguments_config_with_subaction_and_help_shows_subaction_help(capsys): flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) - with pytest.raises(SystemExit) as exit: + with pytest.raises(SystemExit) as system_exit: module.parse_arguments({}, 'config', 'bootstrap', '--help') - assert exit.value.code == 0 + assert system_exit.value.code == 0 + captured = capsys.readouterr() assert 'config bootstrap arguments:' in captured.out @@ -670,7 +699,13 @@ def test_parse_arguments_config_with_subaction_and_explicit_config_file_does_not flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) module.parse_arguments( - {}, 'config', 'bootstrap', '--repository', 'repo.borg', '--config', 'test.yaml' + {}, + 'config', + 'bootstrap', + '--repository', + 'repo.borg', + '--config', + 'test.yaml', ) diff --git a/tests/integration/config/test_generate.py b/tests/integration/config/test_generate.py index 5e0f98e5..25448449 100644 --- a/tests/integration/config/test_generate.py +++ b/tests/integration/config/test_generate.py @@ -371,7 +371,7 @@ def test_add_comments_to_configuration_object_with_skip_first_field_does_not_com def test_generate_sample_configuration_does_not_raise(): builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('schema.yaml').and_return('') + builtins.should_receive('open').with_args('schema.yaml', encoding='utf-8').and_return('') flexmock(module.ruamel.yaml).should_receive('YAML').and_return( flexmock(load=lambda filename: {}) ) @@ -386,7 +386,7 @@ def test_generate_sample_configuration_does_not_raise(): def test_generate_sample_configuration_with_source_filename_omits_empty_bootstrap_field(): builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('schema.yaml').and_return('') + builtins.should_receive('open').with_args('schema.yaml', encoding='utf-8').and_return('') flexmock(module.ruamel.yaml).should_receive('YAML').and_return( flexmock(load=lambda filename: {}) ) @@ -407,7 +407,7 @@ def test_generate_sample_configuration_with_source_filename_omits_empty_bootstra def test_generate_sample_configuration_with_source_filename_keeps_non_empty_bootstrap_field(): builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('schema.yaml').and_return('') + builtins.should_receive('open').with_args('schema.yaml', encoding='utf-8').and_return('') flexmock(module.ruamel.yaml).should_receive('YAML').and_return( flexmock(load=lambda filename: {}) ) @@ -427,7 +427,7 @@ def test_generate_sample_configuration_with_source_filename_keeps_non_empty_boot def test_generate_sample_configuration_with_dry_run_does_not_write_file(): builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('schema.yaml').and_return('') + builtins.should_receive('open').with_args('schema.yaml', encoding='utf-8').and_return('') flexmock(module.ruamel.yaml).should_receive('YAML').and_return( flexmock(load=lambda filename: {}) ) diff --git a/tests/integration/config/test_load.py b/tests/integration/config/test_load.py index e13c69c8..a7b9ab37 100644 --- a/tests/integration/config/test_load.py +++ b/tests/integration/config/test_load.py @@ -11,7 +11,9 @@ def test_load_configuration_parses_contents(): builtins = flexmock(sys.modules['builtins']) config_file = io.StringIO('key: value') config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = {'other.yaml'} assert module.load_configuration('config.yaml', config_paths) == {'key': 'value'} @@ -22,7 +24,9 @@ def test_load_configuration_with_only_integer_value_does_not_raise(): builtins = flexmock(sys.modules['builtins']) config_file = io.StringIO('33') config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = {'other.yaml'} assert module.load_configuration('config.yaml', config_paths) == 33 @@ -36,10 +40,14 @@ def test_load_configuration_inlines_include_relative_to_current_directory(): flexmock(module.os.path).should_receive('exists').and_return(True) include_file = io.StringIO('value') include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO('key: !include include.yaml') config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = {'other.yaml'} assert module.load_configuration('config.yaml', config_paths) == {'key': 'value'} @@ -53,17 +61,21 @@ def test_load_configuration_inlines_include_relative_to_config_parent_directory( flexmock(module.os.path).should_receive('isabs').with_args('/etc/config.yaml').and_return(True) flexmock(module.os.path).should_receive('isabs').with_args('include.yaml').and_return(False) flexmock(module.os.path).should_receive('exists').with_args('/tmp/include.yaml').and_return( - False + False, ) flexmock(module.os.path).should_receive('exists').with_args('/etc/include.yaml').and_return( - True + True, ) include_file = io.StringIO('value') include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/etc/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/etc/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO('key: !include include.yaml') config_file.name = '/etc/config.yaml' - builtins.should_receive('open').with_args('/etc/config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('/etc/config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = {'other.yaml'} assert module.load_configuration('/etc/config.yaml', config_paths) == {'key': 'value'} @@ -79,7 +91,9 @@ def test_load_configuration_raises_if_relative_include_does_not_exist(): flexmock(module.os.path).should_receive('exists').and_return(False) config_file = io.StringIO('key: !include include.yaml') config_file.name = '/etc/config.yaml' - builtins.should_receive('open').with_args('/etc/config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('/etc/config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = set() with pytest.raises(FileNotFoundError): @@ -93,10 +107,14 @@ def test_load_configuration_inlines_absolute_include(): flexmock(module.os.path).should_receive('exists').never() include_file = io.StringIO('value') include_file.name = '/root/include.yaml' - builtins.should_receive('open').with_args('/root/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/root/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO('key: !include /root/include.yaml') config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = {'other.yaml'} assert module.load_configuration('config.yaml', config_paths) == {'key': 'value'} @@ -107,10 +125,14 @@ def test_load_configuration_raises_if_absolute_include_does_not_exist(): builtins = flexmock(sys.modules['builtins']) flexmock(module.os).should_receive('getcwd').and_return('/tmp') flexmock(module.os.path).should_receive('isabs').and_return(True) - builtins.should_receive('open').with_args('/root/include.yaml').and_raise(FileNotFoundError) + builtins.should_receive('open').with_args('/root/include.yaml', encoding='utf-8').and_raise( + FileNotFoundError + ) config_file = io.StringIO('key: !include /root/include.yaml') config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = set() with pytest.raises(FileNotFoundError): @@ -124,13 +146,19 @@ def test_load_configuration_inlines_multiple_file_include_as_list(): flexmock(module.os.path).should_receive('exists').never() include1_file = io.StringIO('value1') include1_file.name = '/root/include1.yaml' - builtins.should_receive('open').with_args('/root/include1.yaml').and_return(include1_file) + builtins.should_receive('open').with_args('/root/include1.yaml', encoding='utf-8').and_return( + include1_file + ) include2_file = io.StringIO('value2') include2_file.name = '/root/include2.yaml' - builtins.should_receive('open').with_args('/root/include2.yaml').and_return(include2_file) + builtins.should_receive('open').with_args('/root/include2.yaml', encoding='utf-8').and_return( + include2_file + ) config_file = io.StringIO('key: !include [/root/include1.yaml, /root/include2.yaml]') config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = {'other.yaml'} assert module.load_configuration('config.yaml', config_paths) == {'key': ['value2', 'value1']} @@ -149,7 +177,9 @@ def test_load_configuration_include_with_unsupported_filename_type_raises(): flexmock(module.os.path).should_receive('exists').never() config_file = io.StringIO('key: !include {path: /root/include.yaml}') config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = set() with pytest.raises(ValueError): @@ -165,18 +195,22 @@ def test_load_configuration_merges_include(): ''' foo: bar baz: quux - ''' + ''', ) include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO( ''' foo: override <<: !include include.yaml - ''' + ''', ) config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = {'other.yaml'} assert module.load_configuration('config.yaml', config_paths) == { @@ -196,25 +230,31 @@ def test_load_configuration_merges_multiple_file_include(): foo: bar baz: quux original: yes - ''' + ''', ) include1_file.name = 'include1.yaml' - builtins.should_receive('open').with_args('/tmp/include1.yaml').and_return(include1_file) + builtins.should_receive('open').with_args('/tmp/include1.yaml', encoding='utf-8').and_return( + include1_file + ) include2_file = io.StringIO( ''' baz: second - ''' + ''', ) include2_file.name = 'include2.yaml' - builtins.should_receive('open').with_args('/tmp/include2.yaml').and_return(include2_file) + builtins.should_receive('open').with_args('/tmp/include2.yaml', encoding='utf-8').and_return( + include2_file + ) config_file = io.StringIO( ''' foo: override <<: !include [include1.yaml, include2.yaml] - ''' + ''', ) config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = {'other.yaml'} assert module.load_configuration('config.yaml', config_paths) == { @@ -239,10 +279,12 @@ def test_load_configuration_with_retain_tag_merges_include_but_keeps_local_value other: a: b c: d - ''' + ''', ) include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO( ''' stuff: !retain @@ -251,10 +293,12 @@ def test_load_configuration_with_retain_tag_merges_include_but_keeps_local_value other: a: override <<: !include include.yaml - ''' + ''', ) config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = {'other.yaml'} assert module.load_configuration('config.yaml', config_paths) == { @@ -274,19 +318,23 @@ def test_load_configuration_with_retain_tag_but_without_merge_include_raises(): stuff: !retain foo: bar baz: quux - ''' + ''', ) include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO( ''' stuff: foo: override <<: !include include.yaml - ''' + ''', ) config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = set() with pytest.raises(ValueError): @@ -303,19 +351,23 @@ def test_load_configuration_with_retain_tag_on_scalar_raises(): stuff: foo: bar baz: quux - ''' + ''', ) include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO( ''' stuff: foo: !retain override <<: !include include.yaml - ''' + ''', ) config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = set() with pytest.raises(ValueError): @@ -333,10 +385,12 @@ def test_load_configuration_with_omit_tag_merges_include_and_omits_requested_val - a - b - c - ''' + ''', ) include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO( ''' stuff: @@ -344,10 +398,12 @@ def test_load_configuration_with_omit_tag_merges_include_and_omits_requested_val - !omit b - y <<: !include include.yaml - ''' + ''', ) config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = {'other.yaml'} assert module.load_configuration('config.yaml', config_paths) == {'stuff': ['a', 'c', 'x', 'y']} @@ -365,10 +421,12 @@ def test_load_configuration_with_omit_tag_on_unknown_value_merges_include_and_do - a - b - c - ''' + ''', ) include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO( ''' stuff: @@ -376,14 +434,16 @@ def test_load_configuration_with_omit_tag_on_unknown_value_merges_include_and_do - !omit q - y <<: !include include.yaml - ''' + ''', ) config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = {'other.yaml'} assert module.load_configuration('config.yaml', config_paths) == { - 'stuff': ['a', 'b', 'c', 'x', 'y'] + 'stuff': ['a', 'b', 'c', 'x', 'y'], } assert config_paths == {'config.yaml', '/tmp/include.yaml', 'other.yaml'} @@ -399,20 +459,24 @@ def test_load_configuration_with_omit_tag_on_non_list_item_raises(): - a - b - c - ''' + ''', ) include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO( ''' stuff: !omit - x - y <<: !include include.yaml - ''' + ''', ) config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = set() with pytest.raises(ValueError): @@ -429,20 +493,24 @@ def test_load_configuration_with_omit_tag_on_non_scalar_list_item_raises(): stuff: - foo: bar baz: quux - ''' + ''', ) include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO( ''' stuff: - !omit foo: bar baz: quux <<: !include include.yaml - ''' + ''', ) config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = set() with pytest.raises(ValueError): @@ -460,20 +528,24 @@ def test_load_configuration_with_omit_tag_but_without_merge_raises(): - a - !omit b - c - ''' + ''', ) include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO( ''' stuff: - x - y <<: !include include.yaml - ''' + ''', ) config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = set() with pytest.raises(ValueError): @@ -489,19 +561,23 @@ def test_load_configuration_does_not_merge_include_list(): ''' - one - two - ''' + ''', ) include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config_file = io.StringIO( ''' foo: bar repositories: <<: !include include.yaml - ''' + ''', ) config_file.name = 'config.yaml' - builtins.should_receive('open').with_args('config.yaml').and_return(config_file) + builtins.should_receive('open').with_args('config.yaml', encoding='utf-8').and_return( + config_file + ) config_paths = set() with pytest.raises(module.ruamel.yaml.error.YAMLError): @@ -519,7 +595,8 @@ def test_load_configuration_does_not_merge_include_list(): def test_raise_retain_node_error_raises(node_class): with pytest.raises(ValueError): module.raise_retain_node_error( - loader=flexmock(), node=node_class(tag=flexmock(), value=flexmock()) + loader=flexmock(), + node=node_class(tag=flexmock(), value=flexmock()), ) @@ -569,15 +646,18 @@ def test_merge_values_combines_mapping_values(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_hourly' + tag='tag:yaml.org,2002:str', + value='keep_hourly', ), module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:int', value='24' + tag='tag:yaml.org,2002:int', + value='24', ), ), ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_daily' + tag='tag:yaml.org,2002:str', + value='keep_daily', ), module.ruamel.yaml.nodes.ScalarNode(tag='tag:yaml.org,2002:int', value='7'), ), @@ -591,10 +671,12 @@ def test_merge_values_combines_mapping_values(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_daily' + tag='tag:yaml.org,2002:str', + value='keep_daily', ), module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:int', value='25' + tag='tag:yaml.org,2002:int', + value='25', ), ), ], @@ -607,10 +689,12 @@ def test_merge_values_combines_mapping_values(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_nanosecondly' + tag='tag:yaml.org,2002:str', + value='keep_nanosecondly', ), module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:int', value='1000' + tag='tag:yaml.org,2002:int', + value='1000', ), ), ], @@ -681,15 +765,18 @@ def test_deep_merge_nodes_replaces_colliding_scalar_values(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_hourly' + tag='tag:yaml.org,2002:str', + value='keep_hourly', ), module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:int', value='24' + tag='tag:yaml.org,2002:int', + value='24', ), ), ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_daily' + tag='tag:yaml.org,2002:str', + value='keep_daily', ), module.ruamel.yaml.nodes.ScalarNode(tag='tag:yaml.org,2002:int', value='7'), ), @@ -703,7 +790,8 @@ def test_deep_merge_nodes_replaces_colliding_scalar_values(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_daily' + tag='tag:yaml.org,2002:str', + value='keep_daily', ), module.ruamel.yaml.nodes.ScalarNode(tag='tag:yaml.org,2002:int', value='5'), ), @@ -733,15 +821,18 @@ def test_deep_merge_nodes_keeps_non_colliding_scalar_values(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_hourly' + tag='tag:yaml.org,2002:str', + value='keep_hourly', ), module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:int', value='24' + tag='tag:yaml.org,2002:int', + value='24', ), ), ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_daily' + tag='tag:yaml.org,2002:str', + value='keep_daily', ), module.ruamel.yaml.nodes.ScalarNode(tag='tag:yaml.org,2002:int', value='7'), ), @@ -755,10 +846,12 @@ def test_deep_merge_nodes_keeps_non_colliding_scalar_values(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_minutely' + tag='tag:yaml.org,2002:str', + value='keep_minutely', ), module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:int', value='10' + tag='tag:yaml.org,2002:int', + value='10', ), ), ], @@ -789,23 +882,27 @@ def test_deep_merge_nodes_keeps_deeply_nested_values(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='lock_wait' + tag='tag:yaml.org,2002:str', + value='lock_wait', ), module.ruamel.yaml.nodes.ScalarNode(tag='tag:yaml.org,2002:int', value='5'), ), ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='extra_borg_options' + tag='tag:yaml.org,2002:str', + value='extra_borg_options', ), module.ruamel.yaml.nodes.MappingNode( tag='tag:yaml.org,2002:map', value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='init' + tag='tag:yaml.org,2002:str', + value='init', ), module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='--init-option' + tag='tag:yaml.org,2002:str', + value='--init-option', ), ), ], @@ -821,17 +918,20 @@ def test_deep_merge_nodes_keeps_deeply_nested_values(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='extra_borg_options' + tag='tag:yaml.org,2002:str', + value='extra_borg_options', ), module.ruamel.yaml.nodes.MappingNode( tag='tag:yaml.org,2002:map', value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='prune' + tag='tag:yaml.org,2002:str', + value='prune', ), module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='--prune-option' + tag='tag:yaml.org,2002:str', + value='--prune-option', ), ), ], @@ -868,16 +968,19 @@ def test_deep_merge_nodes_appends_colliding_sequence_values(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='before_backup' + tag='tag:yaml.org,2002:str', + value='before_backup', ), module.ruamel.yaml.nodes.SequenceNode( tag='tag:yaml.org,2002:seq', value=[ module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 1' + tag='tag:yaml.org,2002:str', + value='echo 1', ), module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 2' + tag='tag:yaml.org,2002:str', + value='echo 2', ), ], ), @@ -892,16 +995,19 @@ def test_deep_merge_nodes_appends_colliding_sequence_values(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='before_backup' + tag='tag:yaml.org,2002:str', + value='before_backup', ), module.ruamel.yaml.nodes.SequenceNode( tag='tag:yaml.org,2002:seq', value=[ module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 3' + tag='tag:yaml.org,2002:str', + value='echo 3', ), module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 4' + tag='tag:yaml.org,2002:str', + value='echo 4', ), ], ), @@ -930,10 +1036,12 @@ def test_deep_merge_nodes_errors_on_colliding_values_of_different_types(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='before_backup' + tag='tag:yaml.org,2002:str', + value='before_backup', ), module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo oopsie daisy' + tag='tag:yaml.org,2002:str', + value='echo oopsie daisy', ), ), ], @@ -946,16 +1054,19 @@ def test_deep_merge_nodes_errors_on_colliding_values_of_different_types(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='before_backup' + tag='tag:yaml.org,2002:str', + value='before_backup', ), module.ruamel.yaml.nodes.SequenceNode( tag='tag:yaml.org,2002:seq', value=[ module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 3' + tag='tag:yaml.org,2002:str', + value='echo 3', ), module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 4' + tag='tag:yaml.org,2002:str', + value='echo 4', ), ], ), @@ -978,15 +1089,18 @@ def test_deep_merge_nodes_only_keeps_mapping_values_tagged_with_retain(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_hourly' + tag='tag:yaml.org,2002:str', + value='keep_hourly', ), module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:int', value='24' + tag='tag:yaml.org,2002:int', + value='24', ), ), ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_daily' + tag='tag:yaml.org,2002:str', + value='keep_daily', ), module.ruamel.yaml.nodes.ScalarNode(tag='tag:yaml.org,2002:int', value='7'), ), @@ -1000,7 +1114,8 @@ def test_deep_merge_nodes_only_keeps_mapping_values_tagged_with_retain(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='keep_daily' + tag='tag:yaml.org,2002:str', + value='keep_daily', ), module.ruamel.yaml.nodes.ScalarNode(tag='tag:yaml.org,2002:int', value='5'), ), @@ -1029,16 +1144,19 @@ def test_deep_merge_nodes_only_keeps_sequence_values_tagged_with_retain(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='before_backup' + tag='tag:yaml.org,2002:str', + value='before_backup', ), module.ruamel.yaml.nodes.SequenceNode( tag='tag:yaml.org,2002:seq', value=[ module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 1' + tag='tag:yaml.org,2002:str', + value='echo 1', ), module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 2' + tag='tag:yaml.org,2002:str', + value='echo 2', ), ], ), @@ -1053,16 +1171,19 @@ def test_deep_merge_nodes_only_keeps_sequence_values_tagged_with_retain(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='before_backup' + tag='tag:yaml.org,2002:str', + value='before_backup', ), module.ruamel.yaml.nodes.SequenceNode( tag='!retain', value=[ module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 3' + tag='tag:yaml.org,2002:str', + value='echo 3', ), module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 4' + tag='tag:yaml.org,2002:str', + value='echo 4', ), ], ), @@ -1092,16 +1213,19 @@ def test_deep_merge_nodes_skips_sequence_values_tagged_with_omit(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='before_backup' + tag='tag:yaml.org,2002:str', + value='before_backup', ), module.ruamel.yaml.nodes.SequenceNode( tag='tag:yaml.org,2002:seq', value=[ module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 1' + tag='tag:yaml.org,2002:str', + value='echo 1', ), module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 2' + tag='tag:yaml.org,2002:str', + value='echo 2', ), ], ), @@ -1116,14 +1240,16 @@ def test_deep_merge_nodes_skips_sequence_values_tagged_with_omit(): value=[ ( module.ruamel.yaml.nodes.ScalarNode( - tag='tag:yaml.org,2002:str', value='before_backup' + tag='tag:yaml.org,2002:str', + value='before_backup', ), module.ruamel.yaml.nodes.SequenceNode( tag='tag:yaml.org,2002:seq', value=[ module.ruamel.yaml.ScalarNode(tag='!omit', value='echo 2'), module.ruamel.yaml.ScalarNode( - tag='tag:yaml.org,2002:str', value='echo 3' + tag='tag:yaml.org,2002:str', + value='echo 3', ), ], ), diff --git a/tests/integration/config/test_override.py b/tests/integration/config/test_override.py index a09380ca..a5819015 100644 --- a/tests/integration/config/test_override.py +++ b/tests/integration/config/test_override.py @@ -41,8 +41,8 @@ def test_apply_overrides_updates_config(): } schema = { 'properties': { - 'new': {'properties': {'mylist': {'type': 'array'}, 'nonlist': {'type': 'string'}}} - } + 'new': {'properties': {'mylist': {'type': 'array'}, 'nonlist': {'type': 'string'}}}, + }, } module.apply_overrides(config, schema, raw_overrides) diff --git a/tests/integration/config/test_validate.py b/tests/integration/config/test_validate.py index e74989c6..f0358b2d 100644 --- a/tests/integration/config/test_validate.py +++ b/tests/integration/config/test_validate.py @@ -34,8 +34,12 @@ def mock_config_and_schema(config_yaml, schema_yaml=None): flexmock(module.os).should_receive('getcwd').and_return('/tmp') flexmock(module.os.path).should_receive('isabs').and_return(False) flexmock(module.os.path).should_receive('exists').and_return(True) - builtins.should_receive('open').with_args('/tmp/config.yaml').and_return(config_stream) - builtins.should_receive('open').with_args('/tmp/schema.yaml').and_return(schema_stream) + builtins.should_receive('open').with_args('/tmp/config.yaml', encoding='utf-8').and_return( + config_stream + ) + builtins.should_receive('open').with_args('/tmp/schema.yaml', encoding='utf-8').and_return( + schema_stream + ) def test_parse_configuration_transforms_file_into_mapping(): @@ -55,11 +59,13 @@ def test_parse_configuration_transforms_file_into_mapping(): checks: - name: repository - name: archives - ''' + ''', ) config, config_paths, logs = module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} + '/tmp/config.yaml', + '/tmp/schema.yaml', + arguments={'global': flexmock()}, ) assert config == { @@ -85,11 +91,13 @@ def test_parse_configuration_passes_through_quoted_punctuation(): repositories: - path: test.borg - ''' + ''', ) config, config_paths, logs = module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} + '/tmp/config.yaml', + '/tmp/schema.yaml', + arguments={'global': flexmock()}, ) assert config == { @@ -124,7 +132,9 @@ def test_parse_configuration_with_schema_lacking_examples_does_not_raise(): ) module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} + '/tmp/config.yaml', + '/tmp/schema.yaml', + arguments={'global': flexmock()}, ) @@ -139,20 +149,24 @@ def test_parse_configuration_inlines_include_inside_deprecated_section(): retention: !include include.yaml - ''' + ''', ) builtins = flexmock(sys.modules['builtins']) include_file = io.StringIO( ''' keep_daily: 7 keep_hourly: 24 - ''' + ''', ) include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config, config_paths, logs = module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} + '/tmp/config.yaml', + '/tmp/schema.yaml', + arguments={'global': flexmock()}, ) assert config == { @@ -177,20 +191,24 @@ def test_parse_configuration_merges_include(): keep_daily: 1 <<: !include include.yaml - ''' + ''', ) builtins = flexmock(sys.modules['builtins']) include_file = io.StringIO( ''' keep_daily: 7 keep_hourly: 24 - ''' + ''', ) include_file.name = 'include.yaml' - builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file) + builtins.should_receive('open').with_args('/tmp/include.yaml', encoding='utf-8').and_return( + include_file + ) config, config_paths, logs = module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} + '/tmp/config.yaml', + '/tmp/schema.yaml', + arguments={'global': flexmock()}, ) assert config == { @@ -207,21 +225,27 @@ def test_parse_configuration_merges_include(): def test_parse_configuration_raises_for_missing_config_file(): with pytest.raises(FileNotFoundError): module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} + '/tmp/config.yaml', + '/tmp/schema.yaml', + arguments={'global': flexmock()}, ) def test_parse_configuration_raises_for_missing_schema_file(): mock_config_and_schema('') builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('/tmp/config.yaml').and_return( - io.StringIO('foo: bar') + builtins.should_receive('open').with_args('/tmp/config.yaml', encoding='utf-8').and_return( + io.StringIO('foo: bar'), + ) + builtins.should_receive('open').with_args('/tmp/schema.yaml', encoding='utf-8').and_raise( + FileNotFoundError ) - builtins.should_receive('open').with_args('/tmp/schema.yaml').and_raise(FileNotFoundError) with pytest.raises(FileNotFoundError): module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} + '/tmp/config.yaml', + '/tmp/schema.yaml', + arguments={'global': flexmock()}, ) @@ -230,7 +254,9 @@ def test_parse_configuration_raises_for_syntax_error(): with pytest.raises(ValueError): module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} + '/tmp/config.yaml', + '/tmp/schema.yaml', + arguments={'global': flexmock()}, ) @@ -240,12 +266,14 @@ def test_parse_configuration_raises_for_validation_error(): source_directories: yes repositories: - path: hostname.borg - ''' + ''', ) with pytest.raises(module.Validation_error): module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} + '/tmp/config.yaml', + '/tmp/schema.yaml', + arguments={'global': flexmock()}, ) @@ -259,7 +287,7 @@ def test_parse_configuration_applies_overrides(): - path: hostname.borg local_path: borg1 - ''' + ''', ) config, config_paths, logs = module.parse_configuration( @@ -290,12 +318,14 @@ def test_parse_configuration_applies_normalization_after_environment_variable_in - ${NO_EXIST:-user@hostname:repo} exclude_if_present: .nobackup - ''' + ''', ) flexmock(os).should_receive('getenv').replace_with(lambda variable_name, default: default) config, config_paths, logs = module.parse_configuration( - '/tmp/config.yaml', '/tmp/schema.yaml', arguments={'global': flexmock()} + '/tmp/config.yaml', + '/tmp/schema.yaml', + arguments={'global': flexmock()}, ) assert config == { diff --git a/tests/integration/hooks/monitoring/test_apprise.py b/tests/integration/hooks/monitoring/test_apprise.py index f0f45c13..db5b8114 100644 --- a/tests/integration/hooks/monitoring/test_apprise.py +++ b/tests/integration/hooks/monitoring/test_apprise.py @@ -13,11 +13,16 @@ def test_destroy_monitor_removes_apprise_handler(): flexmock(logger).should_receive('setLevel') module.borgmatic.hooks.monitoring.logs.add_handler( module.borgmatic.hooks.monitoring.logs.Forgetful_buffering_handler( - identifier=module.HANDLER_IDENTIFIER, byte_capacity=100, log_level=1 - ) + identifier=module.HANDLER_IDENTIFIER, + byte_capacity=100, + log_level=1, + ), ) module.destroy_monitor( - hook_config=flexmock(), config=flexmock(), monitoring_log_level=1, dry_run=False + hook_config=flexmock(), + config=flexmock(), + monitoring_log_level=1, + dry_run=False, ) assert logger.handlers == original_handlers @@ -30,7 +35,10 @@ def test_destroy_monitor_without_apprise_handler_does_not_raise(): # Don't mess with the actual log level because it can impact downstream tests. flexmock(logger).should_receive('setLevel') module.destroy_monitor( - hook_config=flexmock(), config=flexmock(), monitoring_log_level=1, dry_run=False + hook_config=flexmock(), + config=flexmock(), + monitoring_log_level=1, + dry_run=False, ) assert logger.handlers == original_handlers diff --git a/tests/integration/hooks/monitoring/test_healthchecks.py b/tests/integration/hooks/monitoring/test_healthchecks.py index 73a7fb60..f13f61d6 100644 --- a/tests/integration/hooks/monitoring/test_healthchecks.py +++ b/tests/integration/hooks/monitoring/test_healthchecks.py @@ -13,12 +13,17 @@ def test_destroy_monitor_removes_healthchecks_handler(): flexmock(logger).should_receive('setLevel') module.borgmatic.hooks.monitoring.logs.add_handler( module.borgmatic.hooks.monitoring.logs.Forgetful_buffering_handler( - identifier=module.HANDLER_IDENTIFIER, byte_capacity=100, log_level=1 - ) + identifier=module.HANDLER_IDENTIFIER, + byte_capacity=100, + log_level=1, + ), ) module.destroy_monitor( - hook_config=flexmock(), config=flexmock(), monitoring_log_level=1, dry_run=False + hook_config=flexmock(), + config=flexmock(), + monitoring_log_level=1, + dry_run=False, ) assert logger.handlers == original_handlers @@ -31,7 +36,10 @@ def test_destroy_monitor_without_healthchecks_handler_does_not_raise(): # Don't mess with the actual log level because it can impact downstream tests. flexmock(logger).should_receive('setLevel') module.destroy_monitor( - hook_config=flexmock(), config=flexmock(), monitoring_log_level=1, dry_run=False + hook_config=flexmock(), + config=flexmock(), + monitoring_log_level=1, + dry_run=False, ) assert logger.handlers == original_handlers diff --git a/tests/integration/hooks/monitoring/test_loki.py b/tests/integration/hooks/monitoring/test_loki.py index a25a325f..c35c672c 100644 --- a/tests/integration/hooks/monitoring/test_loki.py +++ b/tests/integration/hooks/monitoring/test_loki.py @@ -25,7 +25,7 @@ def test_initialize_monitor_replaces_labels(): assert handler.buffer.root['streams'][0]['stream']['config_full'] == config_filename return - assert False + raise AssertionError() def test_initialize_monitor_adds_log_handler(): @@ -45,7 +45,7 @@ def test_initialize_monitor_adds_log_handler(): if isinstance(handler, module.Loki_log_handler): return - assert False + raise AssertionError() def test_ping_monitor_adds_log_message(): @@ -57,21 +57,23 @@ def test_ping_monitor_adds_log_message(): dry_run = True module.initialize_monitor(hook_config, flexmock(), config_filename, flexmock(), dry_run) module.ping_monitor( - hook_config, flexmock(), config_filename, module.monitor.State.FINISH, flexmock(), dry_run + hook_config, + flexmock(), + config_filename, + module.monitor.State.FINISH, + flexmock(), + dry_run, ) for handler in tuple(logging.getLogger().handlers): if isinstance(handler, module.Loki_log_handler): assert any( - map( - lambda log: log - == f'{module.MONITOR_STATE_TO_LOKI[module.monitor.State.FINISH]} backup', - map(lambda value: value[1], handler.buffer.root['streams'][0]['values']), - ) + value[1] == f'{module.MONITOR_STATE_TO_LOKI[module.monitor.State.FINISH]} backup' + for value in handler.buffer.root['streams'][0]['values'] ) return - assert False + raise AssertionError() def test_destroy_monitor_removes_log_handler(): @@ -86,4 +88,4 @@ def test_destroy_monitor_removes_log_handler(): for handler in tuple(logging.getLogger().handlers): if isinstance(handler, module.Loki_log_handler): - assert False + raise AssertionError() diff --git a/tests/integration/test_execute.py b/tests/integration/test_execute.py index 21b442d5..d2c29532 100644 --- a/tests/integration/test_execute.py +++ b/tests/integration/test_execute.py @@ -15,12 +15,14 @@ def test_log_outputs_logs_each_line_separately(): hi_process = subprocess.Popen(['echo', 'hi'], stdout=subprocess.PIPE) flexmock(module).should_receive('output_buffer_for_process').with_args( - hi_process, () + hi_process, + (), ).and_return(hi_process.stdout) there_process = subprocess.Popen(['echo', 'there'], stdout=subprocess.PIPE) flexmock(module).should_receive('output_buffer_for_process').with_args( - there_process, () + there_process, + (), ).and_return(there_process.stdout) module.log_outputs( @@ -39,12 +41,14 @@ def test_log_outputs_skips_logs_for_process_with_none_stdout(): hi_process = subprocess.Popen(['echo', 'hi'], stdout=None) flexmock(module).should_receive('output_buffer_for_process').with_args( - hi_process, () + hi_process, + (), ).and_return(hi_process.stdout) there_process = subprocess.Popen(['echo', 'there'], stdout=subprocess.PIPE) flexmock(module).should_receive('output_buffer_for_process').with_args( - there_process, () + there_process, + (), ).and_return(there_process.stdout) module.log_outputs( @@ -62,12 +66,14 @@ def test_log_outputs_returns_output_without_logging_for_output_log_level_none(): hi_process = subprocess.Popen(['echo', 'hi'], stdout=subprocess.PIPE) flexmock(module).should_receive('output_buffer_for_process').with_args( - hi_process, () + hi_process, + (), ).and_return(hi_process.stdout) there_process = subprocess.Popen(['echo', 'there'], stdout=subprocess.PIPE) flexmock(module).should_receive('output_buffer_for_process').with_args( - there_process, () + there_process, + (), ).and_return(there_process.stdout) captured_outputs = module.log_outputs( @@ -111,7 +117,9 @@ def test_log_outputs_logs_multiline_error_output(): flexmock(module).should_receive('command_for_process').and_return('grep') process = subprocess.Popen( - ['python', '-c', 'foopydoo'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ['python', '-c', 'foopydoo'], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, ) flexmock(module).should_receive('output_buffer_for_process').and_return(process.stdout) flexmock(module.logger).should_call('log').at_least().times(3) @@ -165,7 +173,9 @@ def test_log_outputs_kills_other_processes_and_raises_when_one_errors(): None, ).and_return(module.Exit_status.ERROR) other_process = subprocess.Popen( - ['sleep', '2'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ['sleep', '2'], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, ) flexmock(module).should_receive('interpret_exit_code').with_args( ['sleep', '2'], @@ -174,10 +184,11 @@ def test_log_outputs_kills_other_processes_and_raises_when_one_errors(): None, ).and_return(module.Exit_status.SUCCESS) flexmock(module).should_receive('output_buffer_for_process').with_args(process, ()).and_return( - process.stdout + process.stdout, ) flexmock(module).should_receive('output_buffer_for_process').with_args( - other_process, () + other_process, + (), ).and_return(other_process.stdout) flexmock(other_process).should_receive('kill').once() @@ -212,7 +223,9 @@ def test_log_outputs_kills_other_processes_and_returns_when_one_exits_with_warni None, ).and_return(module.Exit_status.WARNING) other_process = subprocess.Popen( - ['sleep', '2'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ['sleep', '2'], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, ) flexmock(module).should_receive('interpret_exit_code').with_args( ['sleep', '2'], @@ -221,10 +234,11 @@ def test_log_outputs_kills_other_processes_and_returns_when_one_exits_with_warni None, ).and_return(module.Exit_status.SUCCESS) flexmock(module).should_receive('output_buffer_for_process').with_args(process, ()).and_return( - process.stdout + process.stdout, ) flexmock(module).should_receive('output_buffer_for_process').with_args( - other_process, () + other_process, + (), ).and_return(other_process.stdout) flexmock(other_process).should_receive('kill').once() @@ -257,13 +271,18 @@ def test_log_outputs_vents_other_processes_when_one_exits(): stderr=subprocess.PIPE, ) other_process = subprocess.Popen( - ['true'], stdin=process.stdout, stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ['true'], + stdin=process.stdout, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, ) flexmock(module).should_receive('output_buffer_for_process').with_args( - process, (process.stdout,) + process, + (process.stdout,), ).and_return(process.stderr) flexmock(module).should_receive('output_buffer_for_process').with_args( - other_process, (process.stdout,) + other_process, + (process.stdout,), ).and_return(other_process.stdout) flexmock(process.stdout).should_call('readline').at_least().once() @@ -290,13 +309,18 @@ def test_log_outputs_does_not_error_when_one_process_exits(): stderr=None, ) other_process = subprocess.Popen( - ['true'], stdin=process.stdout, stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ['true'], + stdin=process.stdout, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, ) flexmock(module).should_receive('output_buffer_for_process').with_args( - process, (process.stdout,) + process, + (process.stdout,), ).and_return(process.stderr) flexmock(module).should_receive('output_buffer_for_process').with_args( - other_process, (process.stdout,) + other_process, + (process.stdout,), ).and_return(other_process.stdout) module.log_outputs( diff --git a/tests/unit/actions/config/test_bootstrap.py b/tests/unit/actions/config/test_bootstrap.py index ece91197..07a81329 100644 --- a/tests/unit/actions/config/test_bootstrap.py +++ b/tests/unit/actions/config/test_bootstrap.py @@ -14,7 +14,7 @@ def test_make_bootstrap_config_uses_ssh_command_argument(): def test_get_config_paths_returns_list_of_config_paths(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/source') flexmock(module).should_receive('make_bootstrap_config').and_return({}) bootstrap_arguments = flexmock( @@ -31,10 +31,10 @@ def test_get_config_paths_returns_list_of_config_paths(): ) local_borg_version = flexmock() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) extract_process = flexmock( stdout=flexmock( @@ -42,17 +42,20 @@ def test_get_config_paths_returns_list_of_config_paths(): ), ) flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return( - extract_process + extract_process, ) assert module.get_config_paths( - 'archive', bootstrap_arguments, global_arguments, local_borg_version + 'archive', + bootstrap_arguments, + global_arguments, + local_borg_version, ) == ['/borgmatic/config.yaml'] def test_get_config_paths_probes_for_manifest(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/source') flexmock(module).should_receive('make_bootstrap_config').and_return({}) bootstrap_arguments = flexmock( @@ -73,16 +76,22 @@ def test_get_config_paths_probes_for_manifest(): borgmatic_runtime_directory, ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) flexmock(module.os.path).should_receive('join').with_args( - 'borgmatic', 'bootstrap', 'manifest.json' + 'borgmatic', + 'bootstrap', + 'manifest.json', ).and_return('borgmatic/bootstrap/manifest.json').once() flexmock(module.os.path).should_receive('join').with_args( - borgmatic_runtime_directory, 'bootstrap', 'manifest.json' + borgmatic_runtime_directory, + 'bootstrap', + 'manifest.json', ).and_return('run/borgmatic/bootstrap/manifest.json').once() flexmock(module.os.path).should_receive('join').with_args( - '/source', 'bootstrap', 'manifest.json' + '/source', + 'bootstrap', + 'manifest.json', ).and_return('/source/bootstrap/manifest.json').once() manifest_missing_extract_process = flexmock( stdout=flexmock(read=lambda: None), @@ -93,17 +102,20 @@ def test_get_config_paths_probes_for_manifest(): ), ) flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return( - manifest_missing_extract_process + manifest_missing_extract_process, ).and_return(manifest_missing_extract_process).and_return(manifest_found_extract_process) assert module.get_config_paths( - 'archive', bootstrap_arguments, global_arguments, local_borg_version + 'archive', + bootstrap_arguments, + global_arguments, + local_borg_version, ) == ['/borgmatic/config.yaml'] def test_get_config_paths_translates_ssh_command_argument_to_config(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/source') config = {} flexmock(module).should_receive('make_bootstrap_config').and_return(config) @@ -121,10 +133,10 @@ def test_get_config_paths_translates_ssh_command_argument_to_config(): ) local_borg_version = flexmock() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) extract_process = flexmock( stdout=flexmock( @@ -145,13 +157,16 @@ def test_get_config_paths_translates_ssh_command_argument_to_config(): ).and_return(extract_process) assert module.get_config_paths( - 'archive', bootstrap_arguments, global_arguments, local_borg_version + 'archive', + bootstrap_arguments, + global_arguments, + local_borg_version, ) == ['/borgmatic/config.yaml'] def test_get_config_paths_with_missing_manifest_raises_value_error(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/source') flexmock(module).should_receive('make_bootstrap_config').and_return({}) bootstrap_arguments = flexmock( @@ -168,26 +183,29 @@ def test_get_config_paths_with_missing_manifest_raises_value_error(): ) local_borg_version = flexmock() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) flexmock(module.os.path).should_receive('join').and_return('run/borgmatic') extract_process = flexmock(stdout=flexmock(read=lambda: '')) flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return( - extract_process + extract_process, ) with pytest.raises(ValueError): module.get_config_paths( - 'archive', bootstrap_arguments, global_arguments, local_borg_version + 'archive', + bootstrap_arguments, + global_arguments, + local_borg_version, ) def test_get_config_paths_with_broken_json_raises_value_error(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/source') flexmock(module).should_receive('make_bootstrap_config').and_return({}) bootstrap_arguments = flexmock( @@ -204,27 +222,30 @@ def test_get_config_paths_with_broken_json_raises_value_error(): ) local_borg_version = flexmock() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) extract_process = flexmock( stdout=flexmock(read=lambda: '{"config_paths": ["/oops'), ) flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return( - extract_process + extract_process, ) with pytest.raises(ValueError): module.get_config_paths( - 'archive', bootstrap_arguments, global_arguments, local_borg_version + 'archive', + bootstrap_arguments, + global_arguments, + local_borg_version, ) def test_get_config_paths_with_json_missing_key_raises_value_error(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/source') flexmock(module).should_receive('make_bootstrap_config').and_return({}) bootstrap_arguments = flexmock( @@ -241,21 +262,24 @@ def test_get_config_paths_with_json_missing_key_raises_value_error(): ) local_borg_version = flexmock() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) extract_process = flexmock( stdout=flexmock(read=lambda: '{}'), ) flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return( - extract_process + extract_process, ) with pytest.raises(ValueError): module.get_config_paths( - 'archive', bootstrap_arguments, global_arguments, local_borg_version + 'archive', + bootstrap_arguments, + global_arguments, + local_borg_version, ) @@ -278,10 +302,10 @@ def test_run_bootstrap_does_not_raise(): ) local_borg_version = flexmock() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) extract_process = flexmock( stdout=flexmock( @@ -289,10 +313,10 @@ def test_run_bootstrap_does_not_raise(): ), ) flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return( - extract_process + extract_process, ).once() flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - 'archive' + 'archive', ) module.run_bootstrap(bootstrap_arguments, global_arguments, local_borg_version) @@ -318,10 +342,10 @@ def test_run_bootstrap_translates_ssh_command_argument_to_config(): ) local_borg_version = flexmock() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) extract_process = flexmock( stdout=flexmock( diff --git a/tests/unit/actions/test_borg.py b/tests/unit/actions/test_borg.py index fd8aa28e..e3e0e3ab 100644 --- a/tests/unit/actions/test_borg.py +++ b/tests/unit/actions/test_borg.py @@ -7,7 +7,7 @@ def test_run_borg_does_not_raise(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.borg).should_receive('run_arbitrary_borg') borg_arguments = flexmock(repository=flexmock(), archive=flexmock(), options=flexmock()) diff --git a/tests/unit/actions/test_check.py b/tests/unit/actions/test_check.py index e63bfdab..3334a3d2 100644 --- a/tests/unit/actions/test_check.py +++ b/tests/unit/actions/test_check.py @@ -37,7 +37,8 @@ def test_parse_checks_with_disabled_returns_no_checks(): def test_parse_checks_prefers_override_checks_to_configured_checks(): checks = module.parse_checks( - {'checks': [{'name': 'archives'}]}, only_checks=['repository', 'extract'] + {'checks': [{'name': 'archives'}]}, + only_checks=['repository', 'extract'], ) assert checks == ('repository', 'extract') @@ -79,7 +80,7 @@ def test_parse_frequency_raises_on_parse_error(frequency): def test_filter_checks_on_frequency_without_config_uses_default_checks(): flexmock(module).should_receive('parse_frequency').and_return( - module.datetime.timedelta(weeks=4) + module.datetime.timedelta(weeks=4), ) flexmock(module).should_receive('make_check_time_path') flexmock(module).should_receive('probe_for_check_time').and_return(None) @@ -184,11 +185,11 @@ def test_filter_checks_on_frequency_skips_check_with_only_run_on_not_matching_to def test_filter_checks_on_frequency_retains_check_with_elapsed_frequency(): flexmock(module).should_receive('parse_frequency').and_return( - module.datetime.timedelta(hours=1) + module.datetime.timedelta(hours=1), ) flexmock(module).should_receive('make_check_time_path') flexmock(module).should_receive('probe_for_check_time').and_return( - module.datetime.datetime(year=module.datetime.MINYEAR, month=1, day=1) + module.datetime.datetime(year=module.datetime.MINYEAR, month=1, day=1), ) assert module.filter_checks_on_frequency( @@ -202,7 +203,7 @@ def test_filter_checks_on_frequency_retains_check_with_elapsed_frequency(): def test_filter_checks_on_frequency_retains_check_with_missing_check_time_file(): flexmock(module).should_receive('parse_frequency').and_return( - module.datetime.timedelta(hours=1) + module.datetime.timedelta(hours=1), ) flexmock(module).should_receive('make_check_time_path') flexmock(module).should_receive('probe_for_check_time').and_return(None) @@ -218,11 +219,11 @@ def test_filter_checks_on_frequency_retains_check_with_missing_check_time_file() def test_filter_checks_on_frequency_skips_check_with_unelapsed_frequency(): flexmock(module).should_receive('parse_frequency').and_return( - module.datetime.timedelta(hours=1) + module.datetime.timedelta(hours=1), ) flexmock(module).should_receive('make_check_time_path') flexmock(module).should_receive('probe_for_check_time').and_return( - module.datetime.datetime.now() + module.datetime.datetime.now(), ) assert ( @@ -270,7 +271,7 @@ def test_make_archives_check_id_with_empty_flags_returns_none(): def test_make_check_time_path_with_borgmatic_source_directory_includes_it(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_state_directory' + 'get_borgmatic_state_directory', ).and_return( '/home/user/.local/state/borgmatic', ) @@ -283,7 +284,7 @@ def test_make_check_time_path_with_borgmatic_source_directory_includes_it(): def test_make_check_time_path_with_archives_check_and_no_archives_check_id_defaults_to_all(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_state_directory' + 'get_borgmatic_state_directory', ).and_return( '/home/user/.local/state/borgmatic', ) @@ -300,7 +301,7 @@ def test_make_check_time_path_with_archives_check_and_no_archives_check_id_defau def test_make_check_time_path_with_repositories_check_ignores_archives_check_id(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_state_directory' + 'get_borgmatic_state_directory', ).and_return( '/home/user/.local/state/borgmatic', ) @@ -325,7 +326,7 @@ def test_read_check_time_on_missing_file_does_not_raise(): def test_probe_for_check_time_uses_maximum_of_multiple_check_times(): flexmock(module).should_receive('make_check_time_path').and_return( - '~/.borgmatic/checks/1234/archives/5678' + '~/.borgmatic/checks/1234/archives/5678', ).and_return('~/.borgmatic/checks/1234/archives/all') flexmock(module).should_receive('read_check_time').and_return(1).and_return(2) @@ -334,7 +335,7 @@ def test_probe_for_check_time_uses_maximum_of_multiple_check_times(): def test_probe_for_check_time_deduplicates_identical_check_time_paths(): flexmock(module).should_receive('make_check_time_path').and_return( - '~/.borgmatic/checks/1234/archives/5678' + '~/.borgmatic/checks/1234/archives/5678', ).and_return('~/.borgmatic/checks/1234/archives/5678') flexmock(module).should_receive('read_check_time').and_return(1).once() @@ -343,7 +344,7 @@ def test_probe_for_check_time_deduplicates_identical_check_time_paths(): def test_probe_for_check_time_skips_none_check_time(): flexmock(module).should_receive('make_check_time_path').and_return( - '~/.borgmatic/checks/1234/archives/5678' + '~/.borgmatic/checks/1234/archives/5678', ).and_return('~/.borgmatic/checks/1234/archives/all') flexmock(module).should_receive('read_check_time').and_return(None).and_return(2) @@ -352,7 +353,7 @@ def test_probe_for_check_time_skips_none_check_time(): def test_probe_for_check_time_uses_single_check_time(): flexmock(module).should_receive('make_check_time_path').and_return( - '~/.borgmatic/checks/1234/archives/5678' + '~/.borgmatic/checks/1234/archives/5678', ).and_return('~/.borgmatic/checks/1234/archives/all') flexmock(module).should_receive('read_check_time').and_return(1).and_return(None) @@ -361,7 +362,7 @@ def test_probe_for_check_time_uses_single_check_time(): def test_probe_for_check_time_returns_none_when_no_check_time_found(): flexmock(module).should_receive('make_check_time_path').and_return( - '~/.borgmatic/checks/1234/archives/5678' + '~/.borgmatic/checks/1234/archives/5678', ).and_return('~/.borgmatic/checks/1234/archives/all') flexmock(module).should_receive('read_check_time').and_return(None).and_return(None) @@ -370,24 +371,25 @@ def test_probe_for_check_time_returns_none_when_no_check_time_found(): def test_upgrade_check_times_moves_checks_from_borgmatic_source_directory_to_state_directory(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/home/user/.borgmatic') flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_state_directory' + 'get_borgmatic_state_directory', ).and_return('/home/user/.local/state/borgmatic') flexmock(module.os.path).should_receive('exists').with_args( - '/home/user/.borgmatic/checks' + '/home/user/.borgmatic/checks', ).and_return(True) flexmock(module.os.path).should_receive('exists').with_args( - '/home/user/.local/state/borgmatic/checks' + '/home/user/.local/state/borgmatic/checks', ).and_return(False) flexmock(module.os).should_receive('makedirs') flexmock(module.shutil).should_receive('move').with_args( - '/home/user/.borgmatic/checks', '/home/user/.local/state/borgmatic/checks' + '/home/user/.borgmatic/checks', + '/home/user/.local/state/borgmatic/checks', ).once() flexmock(module).should_receive('make_check_time_path').and_return( - '/home/user/.local/state/borgmatic/checks/1234/archives/all' + '/home/user/.local/state/borgmatic/checks/1234/archives/all', ) flexmock(module.os.path).should_receive('isfile').and_return(False) flexmock(module.os).should_receive('mkdir').never() @@ -397,22 +399,22 @@ def test_upgrade_check_times_moves_checks_from_borgmatic_source_directory_to_sta def test_upgrade_check_times_with_checks_already_in_borgmatic_state_directory_does_not_move_anything(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/home/user/.borgmatic') flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_state_directory' + 'get_borgmatic_state_directory', ).and_return('/home/user/.local/state/borgmatic') flexmock(module.os.path).should_receive('exists').with_args( - '/home/user/.borgmatic/checks' + '/home/user/.borgmatic/checks', ).and_return(True) flexmock(module.os.path).should_receive('exists').with_args( - '/home/user/.local/state/borgmatic/checks' + '/home/user/.local/state/borgmatic/checks', ).and_return(True) flexmock(module.os).should_receive('makedirs').never() flexmock(module.shutil).should_receive('move').never() flexmock(module).should_receive('make_check_time_path').and_return( - '/home/user/.local/state/borgmatic/checks/1234/archives/all' + '/home/user/.local/state/borgmatic/checks/1234/archives/all', ) flexmock(module.os.path).should_receive('isfile').and_return(False) flexmock(module.shutil).should_receive('move').never() @@ -423,38 +425,46 @@ def test_upgrade_check_times_with_checks_already_in_borgmatic_state_directory_do def test_upgrade_check_times_renames_old_check_paths_to_all(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/home/user/.borgmatic') flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_state_directory' + 'get_borgmatic_state_directory', ).and_return('/home/user/.local/state/borgmatic') flexmock(module.os.path).should_receive('exists').and_return(False) base_path = '/home/user/.local/state/borgmatic/checks/1234' flexmock(module).should_receive('make_check_time_path').with_args( - object, object, 'archives', 'all' + object, + object, + 'archives', + 'all', ).and_return(f'{base_path}/archives/all') flexmock(module).should_receive('make_check_time_path').with_args( - object, object, 'data', 'all' + object, + object, + 'data', + 'all', ).and_return(f'{base_path}/data/all') flexmock(module.os.path).should_receive('isfile').with_args(f'{base_path}/archives').and_return( - True + True, ) flexmock(module.os.path).should_receive('isfile').with_args( - f'{base_path}/archives.temp' + f'{base_path}/archives.temp', ).and_return(False) flexmock(module.os.path).should_receive('isfile').with_args(f'{base_path}/data').and_return( - False + False, ) flexmock(module.os.path).should_receive('isfile').with_args( - f'{base_path}/data.temp' + f'{base_path}/data.temp', ).and_return(False) flexmock(module.shutil).should_receive('move').with_args( - f'{base_path}/archives', f'{base_path}/archives.temp' + f'{base_path}/archives', + f'{base_path}/archives.temp', ).once() flexmock(module.os).should_receive('mkdir').with_args(f'{base_path}/archives').once() flexmock(module.shutil).should_receive('move').with_args( - f'{base_path}/archives.temp', f'{base_path}/archives/all' + f'{base_path}/archives.temp', + f'{base_path}/archives/all', ).once() module.upgrade_check_times(flexmock(), flexmock()) @@ -462,35 +472,43 @@ def test_upgrade_check_times_renames_old_check_paths_to_all(): def test_upgrade_check_times_renames_data_check_paths_when_archives_paths_are_already_upgraded(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/home/user/.borgmatic') flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_state_directory' + 'get_borgmatic_state_directory', ).and_return('/home/user/.local/state/borgmatic') flexmock(module.os.path).should_receive('exists').and_return(False) base_path = '/home/user/.local/state/borgmatic/checks/1234' flexmock(module).should_receive('make_check_time_path').with_args( - object, object, 'archives', 'all' + object, + object, + 'archives', + 'all', ).and_return(f'{base_path}/archives/all') flexmock(module).should_receive('make_check_time_path').with_args( - object, object, 'data', 'all' + object, + object, + 'data', + 'all', ).and_return(f'{base_path}/data/all') flexmock(module.os.path).should_receive('isfile').with_args(f'{base_path}/archives').and_return( - False + False, ) flexmock(module.os.path).should_receive('isfile').with_args( - f'{base_path}/archives.temp' + f'{base_path}/archives.temp', ).and_return(False) flexmock(module.os.path).should_receive('isfile').with_args(f'{base_path}/data').and_return( - True + True, ) flexmock(module.shutil).should_receive('move').with_args( - f'{base_path}/data', f'{base_path}/data.temp' + f'{base_path}/data', + f'{base_path}/data.temp', ).once() flexmock(module.os).should_receive('mkdir').with_args(f'{base_path}/data').once() flexmock(module.shutil).should_receive('move').with_args( - f'{base_path}/data.temp', f'{base_path}/data/all' + f'{base_path}/data.temp', + f'{base_path}/data/all', ).once() module.upgrade_check_times(flexmock(), flexmock()) @@ -498,15 +516,15 @@ def test_upgrade_check_times_renames_data_check_paths_when_archives_paths_are_al def test_upgrade_check_times_skips_already_upgraded_check_paths(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/home/user/.borgmatic') flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_state_directory' + 'get_borgmatic_state_directory', ).and_return('/home/user/.local/state/borgmatic') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module).should_receive('make_check_time_path').and_return( - '/home/user/.local/state/borgmatic/checks/1234/archives/all' + '/home/user/.local/state/borgmatic/checks/1234/archives/all', ) flexmock(module.os.path).should_receive('isfile').and_return(False) flexmock(module.shutil).should_receive('move').never() @@ -517,38 +535,46 @@ def test_upgrade_check_times_skips_already_upgraded_check_paths(): def test_upgrade_check_times_renames_stale_temporary_check_path(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/home/user/.borgmatic') flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_state_directory' + 'get_borgmatic_state_directory', ).and_return('/home/user/.local/state/borgmatic') flexmock(module.os.path).should_receive('exists').and_return(False) base_path = '/home/borgmatic/.local/state/checks/1234' flexmock(module).should_receive('make_check_time_path').with_args( - object, object, 'archives', 'all' + object, + object, + 'archives', + 'all', ).and_return(f'{base_path}/archives/all') flexmock(module).should_receive('make_check_time_path').with_args( - object, object, 'data', 'all' + object, + object, + 'data', + 'all', ).and_return(f'{base_path}/data/all') flexmock(module.os.path).should_receive('isfile').with_args(f'{base_path}/archives').and_return( - False + False, ) flexmock(module.os.path).should_receive('isfile').with_args( - f'{base_path}/archives.temp' + f'{base_path}/archives.temp', ).and_return(True) flexmock(module.os.path).should_receive('isfile').with_args(f'{base_path}/data').and_return( - False + False, ) flexmock(module.os.path).should_receive('isfile').with_args( - f'{base_path}/data.temp' + f'{base_path}/data.temp', ).and_return(False) flexmock(module.shutil).should_receive('move').with_args( - f'{base_path}/archives', f'{base_path}/archives.temp' + f'{base_path}/archives', + f'{base_path}/archives.temp', ).and_raise(FileNotFoundError) flexmock(module.os).should_receive('mkdir').with_args(f'{base_path}/archives').once() flexmock(module.shutil).should_receive('move').with_args( - f'{base_path}/archives.temp', f'{base_path}/archives/all' + f'{base_path}/archives.temp', + f'{base_path}/archives/all', ).once() module.upgrade_check_times(flexmock(), flexmock()) @@ -556,16 +582,16 @@ def test_upgrade_check_times_renames_stale_temporary_check_path(): def test_collect_spot_check_source_paths_parses_borg_output(): flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return( - {'hook1': False, 'hook2': True} + {'hook1': False, 'hook2': True}, ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.pattern).should_receive('collect_patterns').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.pattern).should_receive('process_patterns').and_return( - [Pattern('foo'), Pattern('bar')] + [Pattern('foo'), Pattern('bar')], ) flexmock(module.borgmatic.borg.create).should_receive('make_base_create_command').with_args( dry_run=True, @@ -580,11 +606,11 @@ def test_collect_spot_check_source_paths_parses_borg_output(): stream_processes=True, ).and_return((('borg', 'create'), ('repo::archive',), flexmock())) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'warning: stuff\n- /etc/path\n+ /etc/other\n? /nope', ) @@ -603,16 +629,16 @@ def test_collect_spot_check_source_paths_parses_borg_output(): def test_collect_spot_check_source_paths_omits_progress_from_create_dry_run_command(): flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return( - {'hook1': False, 'hook2': False} + {'hook1': False, 'hook2': False}, ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.pattern).should_receive('collect_patterns').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.pattern).should_receive('process_patterns').and_return( - [Pattern('foo'), Pattern('bar')] + [Pattern('foo'), Pattern('bar')], ) flexmock(module.borgmatic.borg.create).should_receive('make_base_create_command').with_args( dry_run=True, @@ -627,11 +653,11 @@ def test_collect_spot_check_source_paths_omits_progress_from_create_dry_run_comm stream_processes=False, ).and_return((('borg', 'create'), ('repo::archive',), flexmock())) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'warning: stuff\n- /etc/path\n+ /etc/other\n? /nope', ) @@ -650,16 +676,16 @@ def test_collect_spot_check_source_paths_omits_progress_from_create_dry_run_comm def test_collect_spot_check_source_paths_passes_through_stream_processes_false(): flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return( - {'hook1': False, 'hook2': False} + {'hook1': False, 'hook2': False}, ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.pattern).should_receive('collect_patterns').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.pattern).should_receive('process_patterns').and_return( - [Pattern('foo'), Pattern('bar')] + [Pattern('foo'), Pattern('bar')], ) flexmock(module.borgmatic.borg.create).should_receive('make_base_create_command').with_args( dry_run=True, @@ -674,11 +700,11 @@ def test_collect_spot_check_source_paths_passes_through_stream_processes_false() stream_processes=False, ).and_return((('borg', 'create'), ('repo::archive',), flexmock())) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'warning: stuff\n- /etc/path\n+ /etc/other\n? /nope', ) @@ -697,16 +723,16 @@ def test_collect_spot_check_source_paths_passes_through_stream_processes_false() def test_collect_spot_check_source_paths_without_working_directory_parses_borg_output(): flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return( - {'hook1': False, 'hook2': True} + {'hook1': False, 'hook2': True}, ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.pattern).should_receive('collect_patterns').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.pattern).should_receive('process_patterns').and_return( - [Pattern('foo'), Pattern('bar')] + [Pattern('foo'), Pattern('bar')], ) flexmock(module.borgmatic.borg.create).should_receive('make_base_create_command').with_args( dry_run=True, @@ -721,11 +747,11 @@ def test_collect_spot_check_source_paths_without_working_directory_parses_borg_o stream_processes=True, ).and_return((('borg', 'create'), ('repo::archive',), flexmock())) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'warning: stuff\n- /etc/path\n+ /etc/other\n? /nope', ) @@ -744,16 +770,16 @@ def test_collect_spot_check_source_paths_without_working_directory_parses_borg_o def test_collect_spot_check_source_paths_skips_directories(): flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return( - {'hook1': False, 'hook2': True} + {'hook1': False, 'hook2': True}, ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.pattern).should_receive('collect_patterns').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.pattern).should_receive('process_patterns').and_return( - [Pattern('foo'), Pattern('bar')] + [Pattern('foo'), Pattern('bar')], ) flexmock(module.borgmatic.borg.create).should_receive('make_base_create_command').with_args( dry_run=True, @@ -768,11 +794,11 @@ def test_collect_spot_check_source_paths_skips_directories(): stream_processes=True, ).and_return((('borg', 'create'), ('repo::archive',), flexmock())) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'warning: stuff\n- /etc/path\n+ /etc/dir\n? /nope', ) @@ -795,7 +821,7 @@ def test_collect_spot_check_source_paths_skips_directories(): def test_collect_spot_check_archive_paths_excludes_directories_and_pipes(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/home/user/.borgmatic') flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( ( @@ -803,7 +829,7 @@ def test_collect_spot_check_archive_paths_excludes_directories_and_pipes(): 'p var/pipe', 'f etc/other', 'd etc/dir', - ) + ), ) assert module.collect_spot_check_archive_paths( @@ -820,13 +846,13 @@ def test_collect_spot_check_archive_paths_excludes_directories_and_pipes(): def test_collect_spot_check_archive_paths_excludes_file_in_borgmatic_runtime_directory_as_stored_with_prefix_truncation(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/root/.borgmatic') flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( ( 'f etc/path', 'f borgmatic/some/thing', - ) + ), ) assert module.collect_spot_check_archive_paths( @@ -843,13 +869,13 @@ def test_collect_spot_check_archive_paths_excludes_file_in_borgmatic_runtime_dir def test_collect_spot_check_archive_paths_excludes_file_in_borgmatic_source_directory(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/root/.borgmatic') flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( ( 'f etc/path', 'f root/.borgmatic/some/thing', - ) + ), ) assert module.collect_spot_check_archive_paths( @@ -866,13 +892,13 @@ def test_collect_spot_check_archive_paths_excludes_file_in_borgmatic_source_dire def test_collect_spot_check_archive_paths_excludes_file_in_borgmatic_runtime_directory(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/root.borgmatic') flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( ( 'f etc/path', 'f run/user/0/borgmatic/some/thing', - ) + ), ) assert module.collect_spot_check_archive_paths( @@ -889,16 +915,16 @@ def test_collect_spot_check_archive_paths_excludes_file_in_borgmatic_runtime_dir def test_collect_spot_check_source_paths_uses_working_directory(): flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return( - {'hook1': False, 'hook2': True} + {'hook1': False, 'hook2': True}, ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.pattern).should_receive('collect_patterns').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.pattern).should_receive('process_patterns').and_return( - [Pattern('foo'), Pattern('bar')] + [Pattern('foo'), Pattern('bar')], ) flexmock(module.borgmatic.borg.create).should_receive('make_base_create_command').with_args( dry_run=True, @@ -913,13 +939,13 @@ def test_collect_spot_check_source_paths_uses_working_directory(): stream_processes=True, ).and_return((('borg', 'create'), ('repo::archive',), flexmock())) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - '/working/dir' + '/working/dir', ) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'warning: stuff\n- foo\n+ bar\n? /nope', ) @@ -939,7 +965,7 @@ def test_collect_spot_check_source_paths_uses_working_directory(): def test_compare_spot_check_hashes_returns_paths_having_failing_hashes(): flexmock(module.random).should_receive('SystemRandom').and_return( - flexmock(sample=lambda population, count: population[:count]) + flexmock(sample=lambda population, count: population[:count]), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( None, @@ -947,12 +973,12 @@ def test_compare_spot_check_hashes_returns_paths_having_failing_hashes(): flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.os.path).should_receive('islink').and_return(False) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args(('xxh64sum', '/foo', '/bar'), working_directory=None).and_return( - 'hash1 /foo\nhash2 /bar' + 'hash1 /foo\nhash2 /bar', ) flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( - ['hash1 foo', 'nothash2 bar'] + ['hash1 foo', 'nothash2 bar'], ) assert module.compare_spot_check_hashes( @@ -968,7 +994,7 @@ def test_compare_spot_check_hashes_returns_paths_having_failing_hashes(): 'name': 'spot', 'data_sample_percentage': 50, }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -980,7 +1006,7 @@ def test_compare_spot_check_hashes_returns_paths_having_failing_hashes(): def test_compare_spot_check_hashes_returns_relative_paths_having_failing_hashes(): flexmock(module.random).should_receive('SystemRandom').and_return( - flexmock(sample=lambda population, count: population[:count]) + flexmock(sample=lambda population, count: population[:count]), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( None, @@ -988,12 +1014,12 @@ def test_compare_spot_check_hashes_returns_relative_paths_having_failing_hashes( flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.os.path).should_receive('islink').and_return(False) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args(('xxh64sum', 'foo', 'bar'), working_directory=None).and_return( - 'hash1 foo\nhash2 bar' + 'hash1 foo\nhash2 bar', ) flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( - ['hash1 foo', 'nothash2 bar'] + ['hash1 foo', 'nothash2 bar'], ) assert module.compare_spot_check_hashes( @@ -1009,7 +1035,7 @@ def test_compare_spot_check_hashes_returns_relative_paths_having_failing_hashes( 'name': 'spot', 'data_sample_percentage': 50, }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1021,7 +1047,7 @@ def test_compare_spot_check_hashes_returns_relative_paths_having_failing_hashes( def test_compare_spot_check_hashes_handles_data_sample_percentage_above_100(): flexmock(module.random).should_receive('SystemRandom').and_return( - flexmock(sample=lambda population, count: population[:count]) + flexmock(sample=lambda population, count: population[:count]), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( None, @@ -1029,12 +1055,12 @@ def test_compare_spot_check_hashes_handles_data_sample_percentage_above_100(): flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.os.path).should_receive('islink').and_return(False) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args(('xxh64sum', '/foo', '/bar'), working_directory=None).and_return( - 'hash1 /foo\nhash2 /bar' + 'hash1 /foo\nhash2 /bar', ) flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( - ['nothash1 foo', 'nothash2 bar'] + ['nothash1 foo', 'nothash2 bar'], ) assert module.compare_spot_check_hashes( @@ -1050,7 +1076,7 @@ def test_compare_spot_check_hashes_handles_data_sample_percentage_above_100(): 'name': 'spot', 'data_sample_percentage': 1000, }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1062,7 +1088,7 @@ def test_compare_spot_check_hashes_handles_data_sample_percentage_above_100(): def test_compare_spot_check_hashes_uses_xxh64sum_command_option(): flexmock(module.random).should_receive('SystemRandom').and_return( - flexmock(sample=lambda population, count: population[:count]) + flexmock(sample=lambda population, count: population[:count]), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( None, @@ -1070,14 +1096,13 @@ def test_compare_spot_check_hashes_uses_xxh64sum_command_option(): flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.os.path).should_receive('islink').and_return(False) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args( - ('/usr/local/bin/xxhsum', '-H64', '/foo', '/bar'), working_directory=None - ).and_return( - 'hash1 /foo\nhash2 /bar' - ) + ('/usr/local/bin/xxhsum', '-H64', '/foo', '/bar'), + working_directory=None, + ).and_return('hash1 /foo\nhash2 /bar') flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( - ['hash1 foo', 'nothash2 bar'] + ['hash1 foo', 'nothash2 bar'], ) assert module.compare_spot_check_hashes( @@ -1090,7 +1115,7 @@ def test_compare_spot_check_hashes_uses_xxh64sum_command_option(): 'data_sample_percentage': 50, 'xxh64sum_command': '/usr/local/bin/xxhsum -H64', }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1102,7 +1127,7 @@ def test_compare_spot_check_hashes_uses_xxh64sum_command_option(): def test_compare_spot_check_hashes_considers_path_missing_from_archive_as_not_matching(): flexmock(module.random).should_receive('SystemRandom').and_return( - flexmock(sample=lambda population, count: population[:count]) + flexmock(sample=lambda population, count: population[:count]), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( None, @@ -1110,12 +1135,12 @@ def test_compare_spot_check_hashes_considers_path_missing_from_archive_as_not_ma flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.os.path).should_receive('islink').and_return(False) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args(('xxh64sum', '/foo', '/bar'), working_directory=None).and_return( - 'hash1 /foo\nhash2 /bar' + 'hash1 /foo\nhash2 /bar', ) flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( - ['hash1 foo'] + ['hash1 foo'], ) assert module.compare_spot_check_hashes( @@ -1127,7 +1152,7 @@ def test_compare_spot_check_hashes_considers_path_missing_from_archive_as_not_ma 'name': 'spot', 'data_sample_percentage': 50, }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1139,7 +1164,7 @@ def test_compare_spot_check_hashes_considers_path_missing_from_archive_as_not_ma def test_compare_spot_check_hashes_considers_symlink_path_as_not_matching(): flexmock(module.random).should_receive('SystemRandom').and_return( - flexmock(sample=lambda population, count: population[:count]) + flexmock(sample=lambda population, count: population[:count]), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( None, @@ -1148,10 +1173,10 @@ def test_compare_spot_check_hashes_considers_symlink_path_as_not_matching(): flexmock(module.os.path).should_receive('islink').with_args('/foo').and_return(False) flexmock(module.os.path).should_receive('islink').with_args('/bar').and_return(True) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args(('xxh64sum', '/foo'), working_directory=None).and_return('hash1 /foo') flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( - ['hash1 foo', 'hash2 bar'] + ['hash1 foo', 'hash2 bar'], ) assert module.compare_spot_check_hashes( @@ -1163,7 +1188,7 @@ def test_compare_spot_check_hashes_considers_symlink_path_as_not_matching(): 'name': 'spot', 'data_sample_percentage': 50, }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1175,7 +1200,7 @@ def test_compare_spot_check_hashes_considers_symlink_path_as_not_matching(): def test_compare_spot_check_hashes_considers_non_existent_path_as_not_matching(): flexmock(module.random).should_receive('SystemRandom').and_return( - flexmock(sample=lambda population, count: population[:count]) + flexmock(sample=lambda population, count: population[:count]), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( None, @@ -1184,10 +1209,10 @@ def test_compare_spot_check_hashes_considers_non_existent_path_as_not_matching() flexmock(module.os.path).should_receive('exists').with_args('/bar').and_return(False) flexmock(module.os.path).should_receive('islink').and_return(False) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args(('xxh64sum', '/foo'), working_directory=None).and_return('hash1 /foo') flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( - ['hash1 foo', 'hash2 bar'] + ['hash1 foo', 'hash2 bar'], ) assert module.compare_spot_check_hashes( @@ -1199,7 +1224,7 @@ def test_compare_spot_check_hashes_considers_non_existent_path_as_not_matching() 'name': 'spot', 'data_sample_percentage': 50, }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1212,7 +1237,7 @@ def test_compare_spot_check_hashes_considers_non_existent_path_as_not_matching() def test_compare_spot_check_hashes_with_too_many_paths_feeds_them_to_commands_in_chunks(): flexmock(module).SAMPLE_PATHS_SUBSET_COUNT = 2 flexmock(module.random).should_receive('SystemRandom').and_return( - flexmock(sample=lambda population, count: population[:count]) + flexmock(sample=lambda population, count: population[:count]), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( None, @@ -1220,17 +1245,17 @@ def test_compare_spot_check_hashes_with_too_many_paths_feeds_them_to_commands_in flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.os.path).should_receive('islink').and_return(False) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args(('xxh64sum', '/foo', '/bar'), working_directory=None).and_return( - 'hash1 /foo\nhash2 /bar' + 'hash1 /foo\nhash2 /bar', ) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args(('xxh64sum', '/baz', '/quux'), working_directory=None).and_return( - 'hash3 /baz\nhash4 /quux' + 'hash3 /baz\nhash4 /quux', ) flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( - ['hash1 foo', 'hash2 bar'] + ['hash1 foo', 'hash2 bar'], ).and_return(['hash3 baz', 'nothash4 quux']) assert module.compare_spot_check_hashes( @@ -1246,7 +1271,7 @@ def test_compare_spot_check_hashes_with_too_many_paths_feeds_them_to_commands_in 'name': 'spot', 'data_sample_percentage': 100, }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1258,7 +1283,7 @@ def test_compare_spot_check_hashes_with_too_many_paths_feeds_them_to_commands_in def test_compare_spot_check_hashes_uses_working_directory_to_access_source_paths(): flexmock(module.random).should_receive('SystemRandom').and_return( - flexmock(sample=lambda population, count: population[:count]) + flexmock(sample=lambda population, count: population[:count]), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( '/working/dir', @@ -1267,12 +1292,12 @@ def test_compare_spot_check_hashes_uses_working_directory_to_access_source_paths flexmock(module.os.path).should_receive('exists').with_args('/working/dir/bar').and_return(True) flexmock(module.os.path).should_receive('islink').and_return(False) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args(('xxh64sum', 'foo', 'bar'), working_directory='/working/dir').and_return( - 'hash1 foo\nhash2 bar' + 'hash1 foo\nhash2 bar', ) flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( - ['hash1 foo', 'nothash2 bar'] + ['hash1 foo', 'nothash2 bar'], ) assert module.compare_spot_check_hashes( @@ -1308,7 +1333,7 @@ def test_spot_check_without_spot_configuration_errors(): { 'name': 'archives', }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1342,7 +1367,7 @@ def test_spot_check_data_tolerance_percentage_greater_than_data_sample_percentag 'data_tolerance_percentage': 7, 'data_sample_percentage': 5, }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1354,13 +1379,13 @@ def test_spot_check_data_tolerance_percentage_greater_than_data_sample_percentag def test_spot_check_with_count_delta_greater_than_count_tolerance_percentage_errors(): flexmock(module).should_receive('collect_spot_check_source_paths').and_return( - ('/foo', '/bar', '/baz', '/quux') + ('/foo', '/bar', '/baz', '/quux'), ) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - 'archive' + 'archive', ) flexmock(module).should_receive('collect_spot_check_archive_paths').and_return( - ('/foo', '/bar') + ('/foo', '/bar'), ).once() with pytest.raises(ValueError): @@ -1374,7 +1399,7 @@ def test_spot_check_with_count_delta_greater_than_count_tolerance_percentage_err 'data_tolerance_percentage': 4, 'data_sample_percentage': 5, }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1386,14 +1411,14 @@ def test_spot_check_with_count_delta_greater_than_count_tolerance_percentage_err def test_spot_check_with_failing_percentage_greater_than_data_tolerance_percentage_errors(): flexmock(module).should_receive('collect_spot_check_source_paths').and_return( - ('/foo', '/bar', '/baz', '/quux') + ('/foo', '/bar', '/baz', '/quux'), ) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - 'archive' + 'archive', ) flexmock(module).should_receive('collect_spot_check_archive_paths').and_return(('/foo', '/bar')) flexmock(module).should_receive('compare_spot_check_hashes').and_return( - ('/bar', '/baz', '/quux') + ('/bar', '/baz', '/quux'), ).once() with pytest.raises(ValueError): @@ -1407,7 +1432,7 @@ def test_spot_check_with_failing_percentage_greater_than_data_tolerance_percenta 'data_tolerance_percentage': 4, 'data_sample_percentage': 5, }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1419,14 +1444,14 @@ def test_spot_check_with_failing_percentage_greater_than_data_tolerance_percenta def test_spot_check_with_high_enough_tolerances_does_not_raise(): flexmock(module).should_receive('collect_spot_check_source_paths').and_return( - ('/foo', '/bar', '/baz', '/quux') + ('/foo', '/bar', '/baz', '/quux'), ) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - 'archive' + 'archive', ) flexmock(module).should_receive('collect_spot_check_archive_paths').and_return(('/foo', '/bar')) flexmock(module).should_receive('compare_spot_check_hashes').and_return( - ('/bar', '/baz', '/quux') + ('/bar', '/baz', '/quux'), ).once() module.spot_check( @@ -1439,7 +1464,7 @@ def test_spot_check_with_high_enough_tolerances_does_not_raise(): 'data_tolerance_percentage': 80, 'data_sample_percentage': 80, }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1452,7 +1477,7 @@ def test_spot_check_with_high_enough_tolerances_does_not_raise(): def test_spot_check_without_any_source_paths_errors(): flexmock(module).should_receive('collect_spot_check_source_paths').and_return(()) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - 'archive' + 'archive', ) flexmock(module).should_receive('collect_spot_check_archive_paths').and_return(('/foo', '/bar')) flexmock(module).should_receive('compare_spot_check_hashes').never() @@ -1468,7 +1493,7 @@ def test_spot_check_without_any_source_paths_errors(): 'data_tolerance_percentage': 40, 'data_sample_percentage': 50, }, - ] + ], }, local_borg_version=flexmock(), global_arguments=flexmock(), @@ -1487,7 +1512,7 @@ def test_run_check_checks_archives_for_configured_repository(): flexmock(module.borgmatic.borg.check).should_receive('make_archive_filter_flags').and_return(()) flexmock(module).should_receive('make_archives_check_id').and_return(None) flexmock(module).should_receive('filter_checks_on_frequency').and_return( - {'repository', 'archives'} + {'repository', 'archives'}, ) flexmock(module.borgmatic.borg.check).should_receive('check_archives').once() flexmock(module).should_receive('make_check_time_path') @@ -1559,7 +1584,7 @@ def test_run_check_runs_configured_spot_check(): flexmock(module).should_receive('filter_checks_on_frequency').and_return({'spot'}) flexmock(module.borgmatic.borg.check).should_receive('check_archives').never() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.check).should_receive('spot_check').once() flexmock(module).should_receive('make_check_time_path') @@ -1622,7 +1647,7 @@ def test_run_check_without_checks_runs_nothing_except_hooks(): def test_run_check_checks_archives_in_selected_repository(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' + 'repositories_match', ).once().and_return(True) flexmock(module.borgmatic.borg.check).should_receive('get_repository_id').and_return(flexmock()) flexmock(module).should_receive('upgrade_check_times') @@ -1630,7 +1655,7 @@ def test_run_check_checks_archives_in_selected_repository(): flexmock(module.borgmatic.borg.check).should_receive('make_archive_filter_flags').and_return(()) flexmock(module).should_receive('make_archives_check_id').and_return(None) flexmock(module).should_receive('filter_checks_on_frequency').and_return( - {'repository', 'archives'} + {'repository', 'archives'}, ) flexmock(module.borgmatic.borg.check).should_receive('check_archives').once() flexmock(module).should_receive('make_check_time_path') @@ -1660,7 +1685,7 @@ def test_run_check_checks_archives_in_selected_repository(): def test_run_check_bails_if_repository_does_not_match(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' + 'repositories_match', ).once().and_return(False) flexmock(module.borgmatic.borg.check).should_receive('check_archives').never() check_arguments = flexmock( diff --git a/tests/unit/actions/test_compact.py b/tests/unit/actions/test_compact.py index 04a3a25e..e6dc2c99 100644 --- a/tests/unit/actions/test_compact.py +++ b/tests/unit/actions/test_compact.py @@ -32,7 +32,7 @@ def test_compact_actions_calls_hooks_for_configured_repository(): def test_compact_runs_with_selected_repository(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' + 'repositories_match', ).once().and_return(True) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.compact).should_receive('compact_segments').once() @@ -61,7 +61,7 @@ def test_compact_bails_if_repository_does_not_match(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' + 'repositories_match', ).once().and_return(False) flexmock(module.borgmatic.borg.compact).should_receive('compact_segments').never() compact_arguments = flexmock( diff --git a/tests/unit/actions/test_create.py b/tests/unit/actions/test_create.py index 585c308b..ff491d73 100644 --- a/tests/unit/actions/test_create.py +++ b/tests/unit/actions/test_create.py @@ -11,12 +11,12 @@ def test_run_create_executes_and_calls_hooks_for_configured_repository(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').never() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.create).should_receive('create_archive').once() flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return({}) flexmock(module.borgmatic.hooks.dispatch).should_receive( - 'call_hooks_even_if_unconfigured' + 'call_hooks_even_if_unconfigured', ).and_return({}) flexmock(module.borgmatic.actions.pattern).should_receive('collect_patterns').and_return(()) flexmock(module.borgmatic.actions.pattern).should_receive('process_patterns').and_return([]) @@ -43,22 +43,22 @@ def test_run_create_executes_and_calls_hooks_for_configured_repository(): dry_run_label='', local_path=None, remote_path=None, - ) + ), ) def test_run_create_runs_with_selected_repository(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' + 'repositories_match', ).once().and_return(True) flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.create).should_receive('create_archive').once() flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return({}) flexmock(module.borgmatic.hooks.dispatch).should_receive( - 'call_hooks_even_if_unconfigured' + 'call_hooks_even_if_unconfigured', ).and_return({}) flexmock(module.borgmatic.actions.pattern).should_receive('collect_patterns').and_return(()) flexmock(module.borgmatic.actions.pattern).should_receive('process_patterns').and_return([]) @@ -85,14 +85,14 @@ def test_run_create_runs_with_selected_repository(): dry_run_label='', local_path=None, remote_path=None, - ) + ), ) def test_run_create_bails_if_repository_does_not_match(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' + 'repositories_match', ).once().and_return(False) flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').never() flexmock(module.borgmatic.borg.create).should_receive('create_archive').never() @@ -118,14 +118,14 @@ def test_run_create_bails_if_repository_does_not_match(): dry_run_label='', local_path=None, remote_path=None, - ) + ), ) def test_run_create_with_both_list_and_json_errors(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' + 'repositories_match', ).once().and_return(True) flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').never() flexmock(module.borgmatic.borg.create).should_receive('create_archive').never() @@ -152,14 +152,14 @@ def test_run_create_with_both_list_and_json_errors(): dry_run_label='', local_path=None, remote_path=None, - ) + ), ) def test_run_create_with_both_list_and_progress_errors(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' + 'repositories_match', ).once().and_return(True) flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').never() flexmock(module.borgmatic.borg.create).should_receive('create_archive').never() @@ -186,26 +186,26 @@ def test_run_create_with_both_list_and_progress_errors(): dry_run_label='', local_path=None, remote_path=None, - ) + ), ) def test_run_create_produces_json(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' + 'repositories_match', ).once().and_return(True) flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.create).should_receive('create_archive').once().and_return( - flexmock() + flexmock(), ) parsed_json = flexmock() flexmock(module.borgmatic.actions.json).should_receive('parse_json').and_return(parsed_json) flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return({}) flexmock(module.borgmatic.hooks.dispatch).should_receive( - 'call_hooks_even_if_unconfigured' + 'call_hooks_even_if_unconfigured', ).and_return({}) flexmock(module.borgmatic.actions.pattern).should_receive('collect_patterns').and_return(()) flexmock(module.borgmatic.actions.pattern).should_receive('process_patterns').and_return([]) @@ -232,7 +232,7 @@ def test_run_create_produces_json(): dry_run_label='', local_path=None, remote_path=None, - ) + ), ) == [parsed_json] @@ -243,20 +243,20 @@ def test_run_create_with_active_dumps_roundtrips_via_checkpoint_archive(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').never() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.create).should_receive('create_archive').once() flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return( - {'dump': mock_dump_process} + {'dump': mock_dump_process}, ) flexmock(module.borgmatic.hooks.dispatch).should_receive( - 'call_hooks_even_if_unconfigured' + 'call_hooks_even_if_unconfigured', ).and_return({}) flexmock(module.borgmatic.actions.pattern).should_receive('collect_patterns').and_return(()) flexmock(module.borgmatic.actions.pattern).should_receive('process_patterns').and_return([]) flexmock(os.path).should_receive('join').and_return('/run/borgmatic/bootstrap') flexmock(module.borgmatic.borg.repo_list).should_receive('get_latest_archive').and_return( - {'id': 'id1', 'name': 'archive.checkpoint'} + {'id': 'id1', 'name': 'archive.checkpoint'}, ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) @@ -290,7 +290,7 @@ def test_run_create_with_active_dumps_roundtrips_via_checkpoint_archive(): dry_run_label='', local_path=None, remote_path=None, - ) + ), ) @@ -323,17 +323,17 @@ def test_run_create_with_active_dumps_json_updates_archive_info(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').never() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.create).should_receive('create_archive').and_return( - json.dumps(borg_create_result) + json.dumps(borg_create_result), ).once() flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').and_return( - {'dump': mock_dump_process} + {'dump': mock_dump_process}, ) flexmock(module.borgmatic.hooks.dispatch).should_receive( - 'call_hooks_even_if_unconfigured' + 'call_hooks_even_if_unconfigured', ).and_return({}) flexmock(module.borgmatic.actions.pattern).should_receive('collect_patterns').and_return(()) flexmock(module.borgmatic.actions.pattern).should_receive('process_patterns').and_return([]) @@ -375,14 +375,14 @@ def test_run_create_with_active_dumps_json_updates_archive_info(): dry_run_label='', local_path=None, remote_path=None, - ) + ), ) == [expected_create_result] def test_rename_checkpoint_archive_renames_archive(): global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) flexmock(module.borgmatic.borg.repo_list).should_receive('get_latest_archive').and_return( - {'id': 'id1', 'name': 'archive.checkpoint'} + {'id': 'id1', 'name': 'archive.checkpoint'}, ) flexmock(module.borgmatic.borg.rename).should_receive('rename_archive').with_args( @@ -409,12 +409,12 @@ def test_rename_checkpoint_archive_renames_archive(): def test_rename_checkpoint_archive_checks_suffix(): global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) flexmock(module.borgmatic.borg.repo_list).should_receive('get_latest_archive').and_return( - {'id': 'id1', 'name': 'unexpected-archive'} + {'id': 'id1', 'name': 'unexpected-archive'}, ) with pytest.raises( ValueError, - match='Latest archive did not have a .checkpoint suffix. Got: unexpected-archive', + match=r'Latest archive did not have a .checkpoint suffix. Got: unexpected-archive', ): module.rename_checkpoint_archive( repository_path='path', diff --git a/tests/unit/actions/test_delete.py b/tests/unit/actions/test_delete.py index 539c6068..bab3948d 100644 --- a/tests/unit/actions/test_delete.py +++ b/tests/unit/actions/test_delete.py @@ -8,7 +8,7 @@ def test_run_delete_does_not_raise(): flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name') flexmock(module.borgmatic.actions.arguments).should_receive('update_arguments').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.delete).should_receive('delete_archives') @@ -28,7 +28,7 @@ def test_run_delete_without_archive_does_not_raise(): flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name') flexmock(module.borgmatic.actions.arguments).should_receive('update_arguments').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.delete).should_receive('delete_archives') diff --git a/tests/unit/actions/test_info.py b/tests/unit/actions/test_info.py index 460a6de1..cb92f727 100644 --- a/tests/unit/actions/test_info.py +++ b/tests/unit/actions/test_info.py @@ -7,10 +7,10 @@ def test_run_info_does_not_raise(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.arguments).should_receive('update_arguments').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.info).should_receive('display_archives_info') info_arguments = flexmock(repository=flexmock(), archive=flexmock(), json=False) @@ -24,7 +24,7 @@ def test_run_info_does_not_raise(): global_arguments=flexmock(log_json=False), local_path=None, remote_path=None, - ) + ), ) @@ -32,13 +32,13 @@ def test_run_info_produces_json(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.arguments).should_receive('update_arguments').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.info).should_receive('display_archives_info').and_return( - flexmock() + flexmock(), ) parsed_json = flexmock() flexmock(module.borgmatic.actions.json).should_receive('parse_json').and_return(parsed_json) @@ -53,5 +53,5 @@ def test_run_info_produces_json(): global_arguments=flexmock(log_json=False), local_path=None, remote_path=None, - ) + ), ) == [parsed_json] diff --git a/tests/unit/actions/test_json.py b/tests/unit/actions/test_json.py index c0b4dec3..db404f32 100644 --- a/tests/unit/actions/test_json.py +++ b/tests/unit/actions/test_json.py @@ -5,7 +5,7 @@ from borgmatic.actions import json as module def test_parse_json_loads_json_from_string(): assert module.parse_json('{"repository": {"id": "foo"}}', label=None) == { - 'repository': {'id': 'foo', 'label': ''} + 'repository': {'id': 'foo', 'label': ''}, } @@ -23,7 +23,7 @@ def test_parse_json_skips_with_invalid_json_raises(): def test_parse_json_injects_label_into_parsed_data(): assert module.parse_json('{"repository": {"id": "foo"}}', label='bar') == { - 'repository': {'id': 'foo', 'label': 'bar'} + 'repository': {'id': 'foo', 'label': 'bar'}, } diff --git a/tests/unit/actions/test_list.py b/tests/unit/actions/test_list.py index 99b1ebf9..a16ee8cf 100644 --- a/tests/unit/actions/test_list.py +++ b/tests/unit/actions/test_list.py @@ -7,14 +7,17 @@ def test_run_list_does_not_raise(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.arguments).should_receive('update_arguments').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.list).should_receive('list_archive') list_arguments = flexmock( - repository=flexmock(), archive=flexmock(), json=False, find_paths=None + repository=flexmock(), + archive=flexmock(), + json=False, + find_paths=None, ) list( @@ -26,7 +29,7 @@ def test_run_list_does_not_raise(): global_arguments=flexmock(log_json=False), local_path=None, remote_path=None, - ) + ), ) @@ -34,10 +37,10 @@ def test_run_list_produces_json(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.actions.arguments).should_receive('update_arguments').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.list).should_receive('list_archive').and_return(flexmock()) parsed_json = flexmock() @@ -53,5 +56,5 @@ def test_run_list_produces_json(): global_arguments=flexmock(log_json=False), local_path=None, remote_path=None, - ) + ), ) == [parsed_json] diff --git a/tests/unit/actions/test_pattern.py b/tests/unit/actions/test_pattern.py index faa84773..399f7728 100644 --- a/tests/unit/actions/test_pattern.py +++ b/tests/unit/actions/test_pattern.py @@ -17,13 +17,16 @@ from borgmatic.borg.pattern import Pattern, Pattern_source, Pattern_style, Patte ( '+ sh:/foo*', Pattern( - '/foo*', Pattern_type.INCLUDE, Pattern_style.SHELL, source=Pattern_source.CONFIG + '/foo*', + Pattern_type.INCLUDE, + Pattern_style.SHELL, + source=Pattern_source.CONFIG, ), ), ), ) def test_parse_pattern_transforms_pattern_line_to_instance(pattern_line, expected_pattern): - module.parse_pattern(pattern_line) == expected_pattern + assert module.parse_pattern(pattern_line) == expected_pattern def test_parse_pattern_with_invalid_pattern_line_errors(): @@ -54,22 +57,33 @@ def test_collect_patterns_parses_config_patterns(): def test_collect_patterns_converts_exclude_patterns(): assert module.collect_patterns({'exclude_patterns': ['/foo', '/bar', 'sh:**/baz']}) == ( Pattern( - '/foo', Pattern_type.NO_RECURSE, Pattern_style.FNMATCH, source=Pattern_source.CONFIG + '/foo', + Pattern_type.NO_RECURSE, + Pattern_style.FNMATCH, + source=Pattern_source.CONFIG, ), Pattern( - '/bar', Pattern_type.NO_RECURSE, Pattern_style.FNMATCH, source=Pattern_source.CONFIG + '/bar', + Pattern_type.NO_RECURSE, + Pattern_style.FNMATCH, + source=Pattern_source.CONFIG, ), Pattern( - '**/baz', Pattern_type.NO_RECURSE, Pattern_style.SHELL, source=Pattern_source.CONFIG + '**/baz', + Pattern_type.NO_RECURSE, + Pattern_style.SHELL, + source=Pattern_source.CONFIG, ), ) def test_collect_patterns_reads_config_patterns_from_file(): builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('file1.txt').and_return(io.StringIO('R /foo')) - builtins.should_receive('open').with_args('file2.txt').and_return( - io.StringIO('R /bar\n# comment\n\n \nR /baz') + builtins.should_receive('open').with_args('file1.txt', encoding='utf-8').and_return( + io.StringIO('R /foo') + ) + builtins.should_receive('open').with_args('file2.txt', encoding='utf-8').and_return( + io.StringIO('R /bar\n# comment\n\n \nR /baz'), ) flexmock(module).should_receive('parse_pattern').with_args('R /foo').and_return(Pattern('/foo')) flexmock(module).should_receive('parse_pattern').with_args('# comment').never() @@ -87,7 +101,9 @@ def test_collect_patterns_reads_config_patterns_from_file(): def test_collect_patterns_errors_on_missing_config_patterns_from_file(): builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('file1.txt').and_raise(FileNotFoundError) + builtins.should_receive('open').with_args('file1.txt', encoding='utf-8').and_raise( + FileNotFoundError + ) flexmock(module).should_receive('parse_pattern').never() with pytest.raises(ValueError): @@ -96,21 +112,26 @@ def test_collect_patterns_errors_on_missing_config_patterns_from_file(): def test_collect_patterns_reads_config_exclude_from_file(): builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('file1.txt').and_return(io.StringIO('/foo')) - builtins.should_receive('open').with_args('file2.txt').and_return( - io.StringIO('/bar\n# comment\n\n \n/baz') + builtins.should_receive('open').with_args('file1.txt', encoding='utf-8').and_return( + io.StringIO('/foo') + ) + builtins.should_receive('open').with_args('file2.txt', encoding='utf-8').and_return( + io.StringIO('/bar\n# comment\n\n \n/baz'), ) flexmock(module).should_receive('parse_pattern').with_args( - '! /foo', default_style=Pattern_style.FNMATCH + '! /foo', + default_style=Pattern_style.FNMATCH, ).and_return(Pattern('/foo', Pattern_type.NO_RECURSE, Pattern_style.FNMATCH)) flexmock(module).should_receive('parse_pattern').with_args( - '! /bar', default_style=Pattern_style.FNMATCH + '! /bar', + default_style=Pattern_style.FNMATCH, ).and_return(Pattern('/bar', Pattern_type.NO_RECURSE, Pattern_style.FNMATCH)) flexmock(module).should_receive('parse_pattern').with_args('# comment').never() flexmock(module).should_receive('parse_pattern').with_args('').never() flexmock(module).should_receive('parse_pattern').with_args(' ').never() flexmock(module).should_receive('parse_pattern').with_args( - '! /baz', default_style=Pattern_style.FNMATCH + '! /baz', + default_style=Pattern_style.FNMATCH, ).and_return(Pattern('/baz', Pattern_type.NO_RECURSE, Pattern_style.FNMATCH)) assert module.collect_patterns({'exclude_from': ['file1.txt', 'file2.txt']}) == ( @@ -122,7 +143,7 @@ def test_collect_patterns_reads_config_exclude_from_file(): def test_collect_patterns_errors_on_missing_config_exclude_from_file(): builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('file1.txt').and_raise(OSError) + builtins.should_receive('open').with_args('file1.txt', encoding='utf-8').and_raise(OSError) flexmock(module).should_receive('parse_pattern').never() with pytest.raises(ValueError): @@ -159,7 +180,7 @@ def test_expand_directory_strips_off_working_directory(): def test_expand_directory_globs_working_directory_and_strips_it_off(): flexmock(module.os.path).should_receive('expanduser').and_return('foo*') flexmock(module.glob).should_receive('glob').with_args('/working/dir/foo*').and_return( - ['/working/dir/foo', '/working/dir/food'] + ['/working/dir/foo', '/working/dir/food'], ).once() paths = module.expand_directory('foo*', working_directory='/working/dir') @@ -170,7 +191,7 @@ def test_expand_directory_globs_working_directory_and_strips_it_off(): def test_expand_directory_with_slashdot_hack_globs_working_directory_and_strips_it_off(): flexmock(module.os.path).should_receive('expanduser').and_return('./foo*') flexmock(module.glob).should_receive('glob').with_args('/working/dir/./foo*').and_return( - ['/working/dir/./foo', '/working/dir/./food'] + ['/working/dir/./foo', '/working/dir/./food'], ).once() paths = module.expand_directory('./foo*', working_directory='/working/dir') @@ -181,7 +202,7 @@ def test_expand_directory_with_slashdot_hack_globs_working_directory_and_strips_ def test_expand_directory_with_working_directory_matching_start_of_directory_does_not_strip_it_off(): flexmock(module.os.path).should_receive('expanduser').and_return('/working/dir/foo') flexmock(module.glob).should_receive('glob').with_args('/working/dir/foo').and_return( - ['/working/dir/foo'] + ['/working/dir/foo'], ).once() paths = module.expand_directory('/working/dir/foo', working_directory='/working/dir') @@ -191,10 +212,10 @@ def test_expand_directory_with_working_directory_matching_start_of_directory_doe def test_expand_patterns_flattens_expanded_directories(): flexmock(module).should_receive('expand_directory').with_args('~/foo', None).and_return( - ['/root/foo'] + ['/root/foo'], ) flexmock(module).should_receive('expand_directory').with_args('bar*', None).and_return( - ['bar', 'barf'] + ['bar', 'barf'], ) paths = module.expand_patterns((Pattern('~/foo'), Pattern('bar*'))) @@ -204,7 +225,7 @@ def test_expand_patterns_flattens_expanded_directories(): def test_expand_patterns_with_working_directory_passes_it_through(): flexmock(module).should_receive('expand_directory').with_args('foo', '/working/dir').and_return( - ['/working/dir/foo'] + ['/working/dir/foo'], ) patterns = module.expand_patterns((Pattern('foo'),), working_directory='/working/dir') @@ -228,7 +249,7 @@ def test_expand_patterns_considers_none_as_no_patterns(): def test_expand_patterns_expands_tildes_and_globs_in_root_patterns(): flexmock(module.os.path).should_receive('expanduser').never() flexmock(module).should_receive('expand_directory').and_return( - ['/root/foo/one', '/root/foo/two'] + ['/root/foo/one', '/root/foo/two'], ) paths = module.expand_patterns((Pattern('~/foo/*'),)) @@ -290,23 +311,26 @@ def test_device_map_patterns_gives_device_id_per_path(): ( Pattern('/foo'), Pattern('^/bar', type=Pattern_type.INCLUDE, style=Pattern_style.REGULAR_EXPRESSION), - ) + ), ) assert device_map == ( Pattern('/foo', device=55), Pattern( - '^/bar', type=Pattern_type.INCLUDE, style=Pattern_style.REGULAR_EXPRESSION, device=66 + '^/bar', + type=Pattern_type.INCLUDE, + style=Pattern_style.REGULAR_EXPRESSION, + device=66, ), ) def test_device_map_patterns_with_missing_path_does_not_error(): flexmock(module).should_receive('get_existent_path_or_parent').with_args('/foo').and_return( - '/foo' + '/foo', ) flexmock(module).should_receive('get_existent_path_or_parent').with_args('/bar').and_return( - None + None, ) flexmock(module.os).should_receive('stat').with_args('/foo').and_return(flexmock(st_dev=55)) flexmock(module.os).should_receive('stat').with_args('/bar').never() @@ -323,11 +347,12 @@ def test_device_map_patterns_uses_working_directory_to_construct_path(): flexmock(module).should_receive('get_existent_path_or_parent').replace_with(lambda path: path) flexmock(module.os).should_receive('stat').with_args('/foo').and_return(flexmock(st_dev=55)) flexmock(module.os).should_receive('stat').with_args('/working/dir/bar').and_return( - flexmock(st_dev=66) + flexmock(st_dev=66), ) device_map = module.device_map_patterns( - (Pattern('/foo'), Pattern('bar')), working_directory='/working/dir' + (Pattern('/foo'), Pattern('bar')), + working_directory='/working/dir', ) assert device_map == ( @@ -519,7 +544,9 @@ def test_device_map_patterns_with_existing_device_id_does_not_overwrite_it(): ), ) def test_deduplicate_patterns_omits_child_paths_based_on_device_and_one_file_system( - patterns, expected_patterns, one_file_system + patterns, + expected_patterns, + one_file_system, ): assert ( module.deduplicate_patterns(patterns, {'one_file_system': one_file_system}) @@ -529,7 +556,7 @@ def test_deduplicate_patterns_omits_child_paths_based_on_device_and_one_file_sys def test_process_patterns_includes_patterns(): flexmock(module).should_receive('deduplicate_patterns').and_return( - (Pattern('foo'), Pattern('bar')) + (Pattern('foo'), Pattern('bar')), ) flexmock(module).should_receive('device_map_patterns').and_return({}) flexmock(module).should_receive('expand_patterns').with_args( @@ -548,7 +575,7 @@ def test_process_patterns_includes_patterns(): def test_process_patterns_skips_expand_for_requested_paths(): skip_paths = {flexmock()} flexmock(module).should_receive('deduplicate_patterns').and_return( - (Pattern('foo'), Pattern('bar')) + (Pattern('foo'), Pattern('bar')), ) flexmock(module).should_receive('device_map_patterns').and_return({}) flexmock(module).should_receive('expand_patterns').with_args( diff --git a/tests/unit/actions/test_prune.py b/tests/unit/actions/test_prune.py index b37e50fb..c881fe81 100644 --- a/tests/unit/actions/test_prune.py +++ b/tests/unit/actions/test_prune.py @@ -26,11 +26,13 @@ def test_run_prune_calls_hooks_for_configured_repository(): def test_run_prune_runs_with_selected_repository(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' + 'repositories_match', ).once().and_return(True) flexmock(module.borgmatic.borg.prune).should_receive('prune_archives').once() prune_arguments = flexmock( - repository=flexmock(), statistics=flexmock(), list_details=flexmock() + repository=flexmock(), + statistics=flexmock(), + list_details=flexmock(), ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) @@ -50,11 +52,13 @@ def test_run_prune_runs_with_selected_repository(): def test_run_prune_bails_if_repository_does_not_match(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive( - 'repositories_match' + 'repositories_match', ).once().and_return(False) flexmock(module.borgmatic.borg.prune).should_receive('prune_archives').never() prune_arguments = flexmock( - repository=flexmock(), statistics=flexmock(), list_details=flexmock() + repository=flexmock(), + statistics=flexmock(), + list_details=flexmock(), ) global_arguments = flexmock(monitoring_verbosity=1, dry_run=False) diff --git a/tests/unit/actions/test_recreate.py b/tests/unit/actions/test_recreate.py index af19b70b..edf46152 100644 --- a/tests/unit/actions/test_recreate.py +++ b/tests/unit/actions/test_recreate.py @@ -8,10 +8,10 @@ def test_run_recreate_does_not_raise(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - None + None, ) flexmock(module.borgmatic.borg.recreate).should_receive('recreate_archive') @@ -30,10 +30,10 @@ def test_run_recreate_with_archive_does_not_raise(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - 'test-archive' + 'test-archive', ) flexmock(module.borgmatic.borg.recreate).should_receive('recreate_archive') @@ -52,10 +52,10 @@ def test_run_recreate_with_leftover_recreate_archive_raises(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - 'test-archive.recreate' + 'test-archive.recreate', ) flexmock(module.borgmatic.borg.recreate).should_receive('recreate_archive') @@ -75,10 +75,10 @@ def test_run_recreate_with_latest_archive_resolving_to_leftover_recreate_archive flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - 'test-archive.recreate' + 'test-archive.recreate', ) flexmock(module.borgmatic.borg.recreate).should_receive('recreate_archive') @@ -98,16 +98,16 @@ def test_run_recreate_with_archive_already_exists_error_raises(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - 'test-archive' + 'test-archive', ) flexmock(module.borgmatic.borg.recreate).should_receive('recreate_archive').and_raise( module.subprocess.CalledProcessError( returncode=module.BORG_EXIT_CODE_ARCHIVE_ALREADY_EXISTS, cmd='borg recreate or whatever', - ) + ), ) with pytest.raises(ValueError): @@ -126,16 +126,16 @@ def test_run_recreate_with_target_and_archive_already_exists_error_raises(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - 'test-archive' + 'test-archive', ) flexmock(module.borgmatic.borg.recreate).should_receive('recreate_archive').and_raise( module.subprocess.CalledProcessError( returncode=module.BORG_EXIT_CODE_ARCHIVE_ALREADY_EXISTS, cmd='borg recreate or whatever', - ) + ), ) with pytest.raises(ValueError): @@ -144,7 +144,9 @@ def test_run_recreate_with_target_and_archive_already_exists_error_raises(): config={}, local_borg_version=None, recreate_arguments=flexmock( - repository=flexmock(), archive='test-archive', target='target-archive' + repository=flexmock(), + archive='test-archive', + target='target-archive', ), global_arguments=flexmock(), local_path=None, @@ -156,16 +158,16 @@ def test_run_recreate_with_other_called_process_error_passes_it_through(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - 'test-archive' + 'test-archive', ) flexmock(module.borgmatic.borg.recreate).should_receive('recreate_archive').and_raise( module.subprocess.CalledProcessError( returncode=1, cmd='borg recreate or whatever', - ) + ), ) with pytest.raises(module.subprocess.CalledProcessError): @@ -174,7 +176,9 @@ def test_run_recreate_with_other_called_process_error_passes_it_through(): config={}, local_borg_version=None, recreate_arguments=flexmock( - repository=flexmock(), archive='test-archive', target='target-archive' + repository=flexmock(), + archive='test-archive', + target='target-archive', ), global_arguments=flexmock(), local_path=None, diff --git a/tests/unit/actions/test_repo_create.py b/tests/unit/actions/test_repo_create.py index 0b54818e..7364f2c7 100644 --- a/tests/unit/actions/test_repo_create.py +++ b/tests/unit/actions/test_repo_create.py @@ -83,7 +83,7 @@ def test_run_repo_create_without_encryption_mode_raises(): def test_run_repo_create_bails_if_repository_does_not_match(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return( - False + False, ) flexmock(module.borgmatic.borg.repo_create).should_receive('create_repository').never() arguments = flexmock( diff --git a/tests/unit/actions/test_repo_delete.py b/tests/unit/actions/test_repo_delete.py index 8ae443b0..871f08d7 100644 --- a/tests/unit/actions/test_repo_delete.py +++ b/tests/unit/actions/test_repo_delete.py @@ -7,7 +7,7 @@ def test_run_repo_delete_does_not_raise(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.actions.arguments).should_receive('update_arguments').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.repo_delete).should_receive('delete_repository') @@ -26,7 +26,7 @@ def test_run_repo_delete_with_cache_only_does_not_raise(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.actions.arguments).should_receive('update_arguments').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.borg.repo_delete).should_receive('delete_repository') diff --git a/tests/unit/actions/test_repo_info.py b/tests/unit/actions/test_repo_info.py index ba9a1703..e400f778 100644 --- a/tests/unit/actions/test_repo_info.py +++ b/tests/unit/actions/test_repo_info.py @@ -18,7 +18,7 @@ def test_run_repo_info_does_not_raise(): global_arguments=flexmock(log_json=False), local_path=None, remote_path=None, - ) + ), ) @@ -26,13 +26,13 @@ def test_run_repo_info_parses_json(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.borg.repo_info).should_receive('display_repository_info').and_return( - flexmock() + flexmock(), ) parsed_json = flexmock() flexmock(module.borgmatic.actions.json).should_receive('parse_json').and_return(parsed_json) repo_info_arguments = flexmock(repository=flexmock(), json=True) - list( + assert list( module.run_repo_info( repository={'path': 'repo'}, config={}, @@ -41,5 +41,5 @@ def test_run_repo_info_parses_json(): global_arguments=flexmock(log_json=False), local_path=None, remote_path=None, - ) + ), ) == [parsed_json] diff --git a/tests/unit/actions/test_repo_list.py b/tests/unit/actions/test_repo_list.py index 7ff7f626..72c6c49c 100644 --- a/tests/unit/actions/test_repo_list.py +++ b/tests/unit/actions/test_repo_list.py @@ -18,7 +18,7 @@ def test_run_repo_list_does_not_raise(): global_arguments=flexmock(), local_path=None, remote_path=None, - ) + ), ) @@ -26,7 +26,7 @@ def test_run_repo_list_produces_json(): flexmock(module.logger).answer = lambda message: None flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) flexmock(module.borgmatic.borg.repo_list).should_receive('list_repository').and_return( - flexmock() + flexmock(), ) parsed_json = flexmock() flexmock(module.borgmatic.actions.json).should_receive('parse_json').and_return(parsed_json) @@ -41,5 +41,5 @@ def test_run_repo_list_produces_json(): global_arguments=flexmock(), local_path=None, remote_path=None, - ) + ), ) == [parsed_json] diff --git a/tests/unit/actions/test_restore.py b/tests/unit/actions/test_restore.py index 4881e715..d0df4811 100644 --- a/tests/unit/actions/test_restore.py +++ b/tests/unit/actions/test_restore.py @@ -99,7 +99,10 @@ import borgmatic.actions.restore as module ), ( module.Dump( - module.UNSPECIFIED, module.UNSPECIFIED, module.UNSPECIFIED, module.UNSPECIFIED + module.UNSPECIFIED, + module.UNSPECIFIED, + module.UNSPECIFIED, + module.UNSPECIFIED, ), module.Dump('postgresql_databases', 'foo', 'myhost', 1234), None, @@ -126,7 +129,10 @@ import borgmatic.actions.restore as module ), ) def test_dumps_match_compares_two_dumps_while_respecting_unspecified_values( - first_dump, second_dump, default_port, expected_result + first_dump, + second_dump, + default_port, + expected_result, ): assert module.dumps_match(first_dump, second_dump, default_port) == expected_result @@ -168,7 +174,10 @@ def test_dumps_match_compares_two_dumps_while_respecting_unspecified_values( ), ( module.Dump( - module.UNSPECIFIED, module.UNSPECIFIED, module.UNSPECIFIED, module.UNSPECIFIED + module.UNSPECIFIED, + module.UNSPECIFIED, + module.UNSPECIFIED, + module.UNSPECIFIED, ), 'unspecified', ), @@ -257,14 +266,16 @@ def test_strip_path_prefix_from_extracted_dump_destination_renames_first_matchin ('/foo/bar', flexmock(), flexmock()), ('/foo/bar/postgresql_databases', flexmock(), flexmock()), ('/foo/bar/mariadb_databases', flexmock(), flexmock()), - ] + ], ) flexmock(module.shutil).should_receive('move').with_args( - '/foo/bar/postgresql_databases', '/run/user/0/borgmatic/postgresql_databases' + '/foo/bar/postgresql_databases', + '/run/user/0/borgmatic/postgresql_databases', ).once() flexmock(module.shutil).should_receive('move').with_args( - '/foo/bar/mariadb_databases', '/run/user/0/borgmatic/mariadb_databases' + '/foo/bar/mariadb_databases', + '/run/user/0/borgmatic/mariadb_databases', ).never() module.strip_path_prefix_from_extracted_dump_destination('/foo', '/run/user/0/borgmatic') @@ -273,14 +284,18 @@ def test_strip_path_prefix_from_extracted_dump_destination_renames_first_matchin def test_restore_single_dump_extracts_and_restores_single_file_dump(): flexmock(module).should_receive('render_dump_metadata').and_return('test') flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').with_args( - 'make_data_source_dump_patterns', object, object, object, object + 'make_data_source_dump_patterns', + object, + object, + object, + object, ).and_return({'postgresql': flexmock()}) flexmock(module.tempfile).should_receive('mkdtemp').never() flexmock(module.borgmatic.hooks.data_source.dump).should_receive( - 'convert_glob_patterns_to_borg_pattern' + 'convert_glob_patterns_to_borg_pattern', ).and_return(flexmock()) flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return( - flexmock() + flexmock(), ).once() flexmock(module).should_receive('strip_path_prefix_from_extracted_dump_destination').never() flexmock(module.shutil).should_receive('rmtree').never() @@ -313,16 +328,20 @@ def test_restore_single_dump_extracts_and_restores_single_file_dump(): def test_restore_single_dump_extracts_and_restores_directory_dump(): flexmock(module).should_receive('render_dump_metadata').and_return('test') flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').with_args( - 'make_data_source_dump_patterns', object, object, object, object + 'make_data_source_dump_patterns', + object, + object, + object, + object, ).and_return({'postgresql': flexmock()}) flexmock(module.tempfile).should_receive('mkdtemp').once().and_return( - '/run/user/0/borgmatic/tmp1234' + '/run/user/0/borgmatic/tmp1234', ) flexmock(module.borgmatic.hooks.data_source.dump).should_receive( - 'convert_glob_patterns_to_borg_pattern' + 'convert_glob_patterns_to_borg_pattern', ).and_return(flexmock()) flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return( - flexmock() + flexmock(), ).once() flexmock(module).should_receive('strip_path_prefix_from_extracted_dump_destination').once() flexmock(module.shutil).should_receive('rmtree').once() @@ -355,16 +374,20 @@ def test_restore_single_dump_extracts_and_restores_directory_dump(): def test_restore_single_dump_with_directory_dump_error_cleans_up_temporary_directory(): flexmock(module).should_receive('render_dump_metadata').and_return('test') flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').with_args( - 'make_data_source_dump_patterns', object, object, object, object + 'make_data_source_dump_patterns', + object, + object, + object, + object, ).and_return({'postgresql': flexmock()}) flexmock(module.tempfile).should_receive('mkdtemp').once().and_return( - '/run/user/0/borgmatic/tmp1234' + '/run/user/0/borgmatic/tmp1234', ) flexmock(module.borgmatic.hooks.data_source.dump).should_receive( - 'convert_glob_patterns_to_borg_pattern' + 'convert_glob_patterns_to_borg_pattern', ).and_return(flexmock()) flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_raise( - ValueError + ValueError, ).once() flexmock(module).should_receive('strip_path_prefix_from_extracted_dump_destination').never() flexmock(module.shutil).should_receive('rmtree').once() @@ -398,14 +421,18 @@ def test_restore_single_dump_with_directory_dump_error_cleans_up_temporary_direc def test_restore_single_dump_with_directory_dump_and_dry_run_skips_directory_move_and_cleanup(): flexmock(module).should_receive('render_dump_metadata').and_return('test') flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks').with_args( - 'make_data_source_dump_patterns', object, object, object, object + 'make_data_source_dump_patterns', + object, + object, + object, + object, ).and_return({'postgresql': flexmock()}) flexmock(module.tempfile).should_receive('mkdtemp').once().and_return('/run/borgmatic/tmp1234') flexmock(module.borgmatic.hooks.data_source.dump).should_receive( - 'convert_glob_patterns_to_borg_pattern' + 'convert_glob_patterns_to_borg_pattern', ).and_return(flexmock()) flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return( - flexmock() + flexmock(), ).once() flexmock(module).should_receive('strip_path_prefix_from_extracted_dump_destination').never() flexmock(module.shutil).should_receive('rmtree').never() @@ -437,17 +464,17 @@ def test_restore_single_dump_with_directory_dump_and_dry_run_skips_directory_mov def test_collect_dumps_from_archive_parses_archive_paths(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/root/.borgmatic') flexmock(module.borgmatic.hooks.data_source.dump).should_receive( - 'make_data_source_dump_path' + 'make_data_source_dump_path', ).and_return('') flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( [ 'borgmatic/postgresql_databases/localhost/foo', 'borgmatic/postgresql_databases/host:1234/bar', 'borgmatic/mysql_databases/localhost/quux', - ] + ], ) archive_dumps = module.collect_dumps_from_archive( @@ -470,10 +497,10 @@ def test_collect_dumps_from_archive_parses_archive_paths(): def test_collect_dumps_from_archive_parses_archive_paths_with_different_base_directories(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/root/.borgmatic') flexmock(module.borgmatic.hooks.data_source.dump).should_receive( - 'make_data_source_dump_path' + 'make_data_source_dump_path', ).and_return('') flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( [ @@ -481,7 +508,7 @@ def test_collect_dumps_from_archive_parses_archive_paths_with_different_base_dir '.borgmatic/postgresql_databases/localhost/bar', '/root/.borgmatic/postgresql_databases/localhost/baz', '/var/run/0/borgmatic/mysql_databases/localhost/quux', - ] + ], ) archive_dumps = module.collect_dumps_from_archive( @@ -505,16 +532,16 @@ def test_collect_dumps_from_archive_parses_archive_paths_with_different_base_dir def test_collect_dumps_from_archive_parses_directory_format_archive_paths(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/root/.borgmatic') flexmock(module.borgmatic.hooks.data_source.dump).should_receive( - 'make_data_source_dump_path' + 'make_data_source_dump_path', ).and_return('') flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( [ 'borgmatic/postgresql_databases/localhost/foo/table1', 'borgmatic/postgresql_databases/localhost/foo/table2', - ] + ], ) archive_dumps = module.collect_dumps_from_archive( @@ -535,10 +562,10 @@ def test_collect_dumps_from_archive_parses_directory_format_archive_paths(): def test_collect_dumps_from_archive_skips_bad_archive_paths_or_bad_path_components(): flexmock(module.borgmatic.config.paths).should_receive( - 'get_borgmatic_source_directory' + 'get_borgmatic_source_directory', ).and_return('/root/.borgmatic') flexmock(module.borgmatic.hooks.data_source.dump).should_receive( - 'make_data_source_dump_path' + 'make_data_source_dump_path', ).and_return('') flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return( [ @@ -547,7 +574,7 @@ def test_collect_dumps_from_archive_skips_bad_archive_paths_or_bad_path_componen 'borgmatic/invalid', 'invalid/as/well', '', - ] + ], ) archive_dumps = module.collect_dumps_from_archive( @@ -869,10 +896,10 @@ def test_ensure_requested_dumps_restored_with_missing_dumps_raises(): with pytest.raises(ValueError): module.ensure_requested_dumps_restored( dumps_to_restore={ - module.Dump(hook_name='postgresql_databases', data_source_name='foo') + module.Dump(hook_name='postgresql_databases', data_source_name='foo'), }, dumps_actually_restored={ - module.Dump(hook_name='postgresql_databases', data_source_name='bar') + module.Dump(hook_name='postgresql_databases', data_source_name='bar'), }, ) @@ -886,19 +913,19 @@ def test_run_restore_restores_each_data_source(): flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) borgmatic_runtime_directory = flexmock() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - borgmatic_runtime_directory + borgmatic_runtime_directory, ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks_even_if_unconfigured') flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - flexmock() + flexmock(), ) flexmock(module).should_receive('collect_dumps_from_archive').and_return(flexmock()) flexmock(module).should_receive('get_dumps_to_restore').and_return(dumps_to_restore) flexmock(module).should_receive('get_configured_data_source').and_return( - {'name': 'foo'} + {'name': 'foo'}, ).and_return({'name': 'bar'}) flexmock(module).should_receive('restore_single_dump').with_args( repository=object, @@ -951,16 +978,16 @@ def test_run_restore_restores_each_data_source(): def test_run_restore_bails_for_non_matching_repository(): flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return( - False + False, ) flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) flexmock(module.borgmatic.hooks.dispatch).should_receive( - 'call_hooks_even_if_unconfigured' + 'call_hooks_even_if_unconfigured', ).never() flexmock(module).should_receive('restore_single_dump').never() @@ -983,19 +1010,19 @@ def test_run_restore_restores_data_source_by_falling_back_to_all_name(): flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) borgmatic_runtime_directory = flexmock() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - borgmatic_runtime_directory + borgmatic_runtime_directory, ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks_even_if_unconfigured') flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - flexmock() + flexmock(), ) flexmock(module).should_receive('collect_dumps_from_archive').and_return(flexmock()) flexmock(module).should_receive('get_dumps_to_restore').and_return(dumps_to_restore) flexmock(module).should_receive('get_configured_data_source').and_return( - {'name': 'foo'} + {'name': 'foo'}, ).and_return({'name': 'all'}) flexmock(module).should_receive('restore_single_dump').with_args( repository=object, @@ -1042,14 +1069,14 @@ def test_run_restore_restores_data_source_configured_with_all_name(): flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) borgmatic_runtime_directory = flexmock() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - borgmatic_runtime_directory + borgmatic_runtime_directory, ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks_even_if_unconfigured') flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - flexmock() + flexmock(), ) flexmock(module).should_receive('collect_dumps_from_archive').and_return(flexmock()) flexmock(module).should_receive('get_dumps_to_restore').and_return(dumps_to_restore) @@ -1123,14 +1150,14 @@ def test_run_restore_skips_missing_data_source(): flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) borgmatic_runtime_directory = flexmock() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - borgmatic_runtime_directory + borgmatic_runtime_directory, ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks_even_if_unconfigured') flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - flexmock() + flexmock(), ) flexmock(module).should_receive('collect_dumps_from_archive').and_return(flexmock()) flexmock(module).should_receive('get_dumps_to_restore').and_return(dumps_to_restore) @@ -1204,14 +1231,14 @@ def test_run_restore_restores_data_sources_from_different_hooks(): flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True) borgmatic_runtime_directory = flexmock() flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return( - borgmatic_runtime_directory + borgmatic_runtime_directory, ) flexmock(module.borgmatic.config.paths).should_receive( - 'make_runtime_directory_glob' + 'make_runtime_directory_glob', ).replace_with(lambda path: path) flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks_even_if_unconfigured') flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return( - flexmock() + flexmock(), ) flexmock(module).should_receive('collect_dumps_from_archive').and_return(flexmock()) flexmock(module).should_receive('get_dumps_to_restore').and_return(dumps_to_restore) diff --git a/tests/unit/borg/test_borg.py b/tests/unit/borg/test_borg.py index 5f346917..df298724 100644 --- a/tests/unit/borg/test_borg.py +++ b/tests/unit/borg/test_borg.py @@ -86,7 +86,7 @@ def test_run_arbitrary_borg_with_lock_wait_calls_borg_with_lock_wait_flags(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER config = {'lock_wait': 5} flexmock(module.flags).should_receive('make_flags').and_return(()).and_return( - ('--lock-wait', '5') + ('--lock-wait', '5'), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -187,7 +187,7 @@ def test_run_arbitrary_borg_with_remote_path_calls_borg_with_remote_path_flags() flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_flags').and_return( - ('--remote-path', 'borg1') + ('--remote-path', 'borg1'), ).and_return(()) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -214,7 +214,7 @@ def test_run_arbitrary_borg_with_remote_path_injection_attack_gets_escaped(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_flags').and_return( - ('--remote-path', 'borg1; naughty-command') + ('--remote-path', 'borg1; naughty-command'), ).and_return(()) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) diff --git a/tests/unit/borg/test_change_passphrase.py b/tests/unit/borg/test_change_passphrase.py index f5b3b790..8bb61397 100644 --- a/tests/unit/borg/test_change_passphrase.py +++ b/tests/unit/borg/test_change_passphrase.py @@ -64,7 +64,9 @@ def test_change_passphrase_calls_borg_using_exit_codes(): borg_exit_codes = flexmock() config = {'borg_exit_codes': borg_exit_codes} insert_execute_command_mock( - ('borg', 'key', 'change-passphrase', 'repo'), config=config, borg_exit_codes=borg_exit_codes + ('borg', 'key', 'change-passphrase', 'repo'), + config=config, + borg_exit_codes=borg_exit_codes, ) module.change_passphrase( @@ -79,7 +81,7 @@ def test_change_passphrase_calls_borg_using_exit_codes(): def test_change_passphrase_calls_borg_with_remote_path_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock( - ('borg', 'key', 'change-passphrase', '--remote-path', 'borg1', 'repo') + ('borg', 'key', 'change-passphrase', '--remote-path', 'borg1', 'repo'), ) module.change_passphrase( @@ -96,7 +98,8 @@ def test_change_passphrase_calls_borg_with_umask_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) config = {'umask': '0770'} insert_execute_command_mock( - ('borg', 'key', 'change-passphrase', '--umask', '0770', 'repo'), config=config + ('borg', 'key', 'change-passphrase', '--umask', '0770', 'repo'), + config=config, ) module.change_passphrase( @@ -112,7 +115,8 @@ def test_change_passphrase_calls_borg_with_log_json_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) config = {'log_json': True} insert_execute_command_mock( - ('borg', 'key', 'change-passphrase', '--log-json', 'repo'), config=config + ('borg', 'key', 'change-passphrase', '--log-json', 'repo'), + config=config, ) module.change_passphrase( @@ -128,7 +132,8 @@ def test_change_passphrase_calls_borg_with_lock_wait_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) config = {'lock_wait': '5'} insert_execute_command_mock( - ('borg', 'key', 'change-passphrase', '--lock-wait', '5', 'repo'), config=config + ('borg', 'key', 'change-passphrase', '--lock-wait', '5', 'repo'), + config=config, ) module.change_passphrase( @@ -157,7 +162,7 @@ def test_change_passphrase_with_log_info_calls_borg_with_info_parameter(): def test_change_passphrase_with_log_debug_calls_borg_with_debug_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock( - ('borg', 'key', 'change-passphrase', '--debug', '--show-rc', 'repo') + ('borg', 'key', 'change-passphrase', '--debug', '--show-rc', 'repo'), ) insert_logging_mock(logging.DEBUG) @@ -187,7 +192,8 @@ def test_change_passphrase_with_dry_run_skips_borg_call(): def test_change_passphrase_calls_borg_without_passphrase(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock( - ('borg', 'key', 'change-passphrase', 'repo'), config={'option': 'foo'} + ('borg', 'key', 'change-passphrase', 'repo'), + config={'option': 'foo'}, ) module.change_passphrase( diff --git a/tests/unit/borg/test_check.py b/tests/unit/borg/test_check.py index 6db8dd68..b6b14edc 100644 --- a/tests/unit/borg/test_check.py +++ b/tests/unit/borg/test_check.py @@ -9,7 +9,10 @@ from ..test_verbosity import insert_logging_mock def insert_execute_command_mock( - command, output_file=None, working_directory=None, borg_exit_codes=None + command, + output_file=None, + working_directory=None, + borg_exit_codes=None, ): flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( @@ -158,12 +161,14 @@ def test_make_archive_filter_flags_with_data_check_and_prefix_includes_match_arc def test_make_archive_filter_flags_with_archives_check_and_empty_prefix_uses_archive_name_format_instead(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, 'bar-{now}', '1.2.3' # noqa: FS003 + None, + 'bar-{now}', + '1.2.3', ).and_return(('--match-archives', 'sh:bar-*')) flags = module.make_archive_filter_flags( '1.2.3', - {'archive_name_format': 'bar-{now}', 'prefix': ''}, # noqa: FS003 + {'archive_name_format': 'bar-{now}', 'prefix': ''}, ('archives',), check_arguments=flexmock(match_archives=None), ) @@ -270,7 +275,7 @@ def test_make_check_name_flags_with_extract_omits_extract_flag(): def test_get_repository_id_with_valid_json_does_not_raise(): config = {} flexmock(module.repo_info).should_receive('display_repository_info').and_return( - '{"repository": {"id": "repo"}}' + '{"repository": {"id": "repo"}}', ) assert module.get_repository_id( @@ -286,7 +291,7 @@ def test_get_repository_id_with_valid_json_does_not_raise(): def test_get_repository_id_with_json_error_raises(): config = {} flexmock(module.repo_info).should_receive('display_repository_info').and_return( - '{"unexpected": {"id": "repo"}}' + '{"unexpected": {"id": "repo"}}', ) with pytest.raises(ValueError): @@ -318,7 +323,8 @@ def test_get_repository_id_with_missing_json_keys_raises(): def test_check_archives_with_progress_passes_through_to_borg(): config = {'progress': True} flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.environment).should_receive('make_environment') @@ -353,7 +359,8 @@ def test_check_archives_with_progress_passes_through_to_borg(): def test_check_archives_with_repair_passes_through_to_borg(): config = {} flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.environment).should_receive('make_environment') @@ -388,7 +395,8 @@ def test_check_archives_with_repair_passes_through_to_borg(): def test_check_archives_with_max_duration_flag_passes_through_to_borg(): config = {} flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.environment).should_receive('make_environment') @@ -423,7 +431,8 @@ def test_check_archives_with_max_duration_flag_passes_through_to_borg(): def test_check_archives_with_max_duration_option_passes_through_to_borg(): config = {'checks': [{'name': 'repository', 'max_duration': 33}]} flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.environment).should_receive('make_environment') @@ -458,15 +467,16 @@ def test_check_archives_with_max_duration_option_passes_through_to_borg(): def test_check_archives_with_max_duration_option_and_archives_check_runs_repository_check_separately(): config = {'checks': [{'name': 'repository', 'max_duration': 33}, {'name': 'archives'}]} flexmock(module).should_receive('make_check_name_flags').with_args({'archives'}, ()).and_return( - ('--archives-only',) + ('--archives-only',), ) flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(('--repository-only',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(('borg', 'check', '--archives-only', 'repo')) insert_execute_command_mock( - ('borg', 'check', '--max-duration', '33', '--repository-only', 'repo') + ('borg', 'check', '--max-duration', '33', '--repository-only', 'repo'), ) module.check_archives( @@ -490,15 +500,16 @@ def test_check_archives_with_max_duration_option_and_archives_check_runs_reposit def test_check_archives_with_max_duration_flag_and_archives_check_runs_repository_check_separately(): config = {'checks': [{'name': 'repository'}, {'name': 'archives'}]} flexmock(module).should_receive('make_check_name_flags').with_args({'archives'}, ()).and_return( - ('--archives-only',) + ('--archives-only',), ) flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(('--repository-only',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(('borg', 'check', '--archives-only', 'repo')) insert_execute_command_mock( - ('borg', 'check', '--max-duration', '33', '--repository-only', 'repo') + ('borg', 'check', '--max-duration', '33', '--repository-only', 'repo'), ) module.check_archives( @@ -522,15 +533,17 @@ def test_check_archives_with_max_duration_flag_and_archives_check_runs_repositor def test_check_archives_with_max_duration_option_and_data_check_runs_repository_check_separately(): config = {'checks': [{'name': 'repository', 'max_duration': 33}, {'name': 'data'}]} flexmock(module).should_receive('make_check_name_flags').with_args( - {'data', 'archives'}, () + {'data', 'archives'}, + (), ).and_return(('--archives-only', '--verify-data')) flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(('--repository-only',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(('borg', 'check', '--archives-only', '--verify-data', 'repo')) insert_execute_command_mock( - ('borg', 'check', '--max-duration', '33', '--repository-only', 'repo') + ('borg', 'check', '--max-duration', '33', '--repository-only', 'repo'), ) module.check_archives( @@ -554,15 +567,17 @@ def test_check_archives_with_max_duration_option_and_data_check_runs_repository_ def test_check_archives_with_max_duration_flag_and_data_check_runs_repository_check_separately(): config = {'checks': [{'name': 'repository'}, {'name': 'data'}]} flexmock(module).should_receive('make_check_name_flags').with_args( - {'data', 'archives'}, () + {'data', 'archives'}, + (), ).and_return(('--archives-only', '--verify-data')) flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(('--repository-only',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(('borg', 'check', '--archives-only', '--verify-data', 'repo')) insert_execute_command_mock( - ('borg', 'check', '--max-duration', '33', '--repository-only', 'repo') + ('borg', 'check', '--max-duration', '33', '--repository-only', 'repo'), ) module.check_archives( @@ -586,7 +601,8 @@ def test_check_archives_with_max_duration_flag_and_data_check_runs_repository_ch def test_check_archives_with_max_duration_flag_overrides_max_duration_option(): config = {'checks': [{'name': 'repository', 'max_duration': 33}]} flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.environment).should_receive('make_environment') @@ -654,7 +670,8 @@ def test_check_archives_calls_borg_with_parameters(checks): def test_check_archives_with_data_check_implies_archives_check_calls_borg_with_parameters(): config = {} flexmock(module).should_receive('make_check_name_flags').with_args( - {'data', 'archives'}, () + {'data', 'archives'}, + (), ).and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock(('borg', 'check', 'repo')) @@ -680,7 +697,8 @@ def test_check_archives_with_data_check_implies_archives_check_calls_borg_with_p def test_check_archives_with_log_info_passes_through_to_borg(): config = {} flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_logging_mock(logging.INFO) @@ -707,7 +725,8 @@ def test_check_archives_with_log_info_passes_through_to_borg(): def test_check_archives_with_log_debug_passes_through_to_borg(): config = {} flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_logging_mock(logging.DEBUG) @@ -913,11 +932,12 @@ def test_check_archives_with_retention_prefix(): def test_check_archives_with_extra_borg_options_passes_through_to_borg(): config = {'extra_borg_options': {'check': '--extra --options "value with space"'}} flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock( - ('borg', 'check', '--extra', '--options', 'value with space', 'repo') + ('borg', 'check', '--extra', '--options', 'value with space', 'repo'), ) module.check_archives( @@ -941,7 +961,8 @@ def test_check_archives_with_extra_borg_options_passes_through_to_borg(): def test_check_archives_with_match_archives_passes_through_to_borg(): config = {'checks': [{'name': 'archives'}]} flexmock(module).should_receive('make_check_name_flags').with_args( - {'archives'}, object + {'archives'}, + object, ).and_return(('--match-archives', 'foo-*')) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.environment).should_receive('make_environment') @@ -976,7 +997,8 @@ def test_check_archives_with_match_archives_passes_through_to_borg(): def test_check_archives_calls_borg_with_working_directory(): config = {'working_directory': '/working/dir'} flexmock(module).should_receive('make_check_name_flags').with_args( - {'repository'}, () + {'repository'}, + (), ).and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.environment).should_receive('make_environment') diff --git a/tests/unit/borg/test_compact.py b/tests/unit/borg/test_compact.py index 58aef463..506e0855 100644 --- a/tests/unit/borg/test_compact.py +++ b/tests/unit/borg/test_compact.py @@ -8,11 +8,14 @@ from ..test_verbosity import insert_logging_mock def insert_execute_command_mock( - compact_command, output_log_level, working_directory=None, borg_exit_codes=None + compact_command, + output_log_level, + working_directory=None, + borg_exit_codes=None, ): flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - working_directory + working_directory, ) flexmock(module).should_receive('execute_command').with_args( compact_command, @@ -29,7 +32,7 @@ COMPACT_COMMAND = ('borg', 'compact') def test_compact_segments_calls_borg_with_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - insert_execute_command_mock(COMPACT_COMMAND + ('repo',), logging.INFO) + insert_execute_command_mock((*COMPACT_COMMAND, 'repo'), logging.INFO) module.compact_segments( dry_run=False, @@ -42,7 +45,7 @@ def test_compact_segments_calls_borg_with_flags(): def test_compact_segments_with_log_info_calls_borg_with_info_flag(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - insert_execute_command_mock(COMPACT_COMMAND + ('--info', 'repo'), logging.INFO) + insert_execute_command_mock((*COMPACT_COMMAND, '--info', 'repo'), logging.INFO) insert_logging_mock(logging.INFO) module.compact_segments( @@ -56,7 +59,7 @@ def test_compact_segments_with_log_info_calls_borg_with_info_flag(): def test_compact_segments_with_log_debug_calls_borg_with_debug_flag(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - insert_execute_command_mock(COMPACT_COMMAND + ('--debug', '--show-rc', 'repo'), logging.INFO) + insert_execute_command_mock((*COMPACT_COMMAND, '--debug', '--show-rc', 'repo'), logging.INFO) insert_logging_mock(logging.DEBUG) module.compact_segments( @@ -71,12 +74,13 @@ def test_compact_segments_with_log_debug_calls_borg_with_debug_flag(): def test_compact_segments_with_dry_run_skips_borg_call_when_feature_unavailable(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.DRY_RUN_COMPACT, '1.2.3' + module.feature.Feature.DRY_RUN_COMPACT, + '1.2.3', ).and_return(False) flexmock(module.environment).should_receive('make_environment').never() flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').never() flexmock(module).should_receive('execute_command').never() - flexmock(logging).should_receive('info').with_args('Skipping compact (dry run)').once() + flexmock(module.logger).should_receive('info').with_args('Skipping compact (dry run)').once() module.compact_segments( repository_path='repo', @@ -90,7 +94,8 @@ def test_compact_segments_with_dry_run_skips_borg_call_when_feature_unavailable( def test_compact_segments_with_dry_run_executes_borg_call_when_feature_available(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.DRY_RUN_COMPACT, '1.4.1' + module.feature.Feature.DRY_RUN_COMPACT, + '1.4.1', ).and_return(True) flexmock(module.environment).should_receive('make_environment').once() flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').once() @@ -107,7 +112,7 @@ def test_compact_segments_with_dry_run_executes_borg_call_when_feature_available def test_compact_segments_with_local_path_calls_borg_via_local_path(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - insert_execute_command_mock(('borg1',) + COMPACT_COMMAND[1:] + ('repo',), logging.INFO) + insert_execute_command_mock(('borg1', *COMPACT_COMMAND[1:], 'repo'), logging.INFO) module.compact_segments( dry_run=False, @@ -123,7 +128,9 @@ def test_compact_segments_with_exit_codes_calls_borg_using_them(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) borg_exit_codes = flexmock() insert_execute_command_mock( - COMPACT_COMMAND + ('repo',), logging.INFO, borg_exit_codes=borg_exit_codes + (*COMPACT_COMMAND, 'repo'), + logging.INFO, + borg_exit_codes=borg_exit_codes, ) module.compact_segments( @@ -137,7 +144,7 @@ def test_compact_segments_with_exit_codes_calls_borg_using_them(): def test_compact_segments_with_remote_path_calls_borg_with_remote_path_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - insert_execute_command_mock(COMPACT_COMMAND + ('--remote-path', 'borg1', 'repo'), logging.INFO) + insert_execute_command_mock((*COMPACT_COMMAND, '--remote-path', 'borg1', 'repo'), logging.INFO) module.compact_segments( dry_run=False, @@ -151,7 +158,7 @@ def test_compact_segments_with_remote_path_calls_borg_with_remote_path_flags(): def test_compact_segments_with_progress_calls_borg_with_progress_flag(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - insert_execute_command_mock(COMPACT_COMMAND + ('--progress', 'repo'), logging.INFO) + insert_execute_command_mock((*COMPACT_COMMAND, '--progress', 'repo'), logging.INFO) module.compact_segments( dry_run=False, @@ -164,7 +171,7 @@ def test_compact_segments_with_progress_calls_borg_with_progress_flag(): def test_compact_segments_with_cleanup_commits_calls_borg_with_cleanup_commits_flag(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - insert_execute_command_mock(COMPACT_COMMAND + ('--cleanup-commits', 'repo'), logging.INFO) + insert_execute_command_mock((*COMPACT_COMMAND, '--cleanup-commits', 'repo'), logging.INFO) module.compact_segments( dry_run=False, @@ -178,7 +185,7 @@ def test_compact_segments_with_cleanup_commits_calls_borg_with_cleanup_commits_f def test_compact_segments_with_threshold_calls_borg_with_threshold_flag(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - insert_execute_command_mock(COMPACT_COMMAND + ('--threshold', '20', 'repo'), logging.INFO) + insert_execute_command_mock((*COMPACT_COMMAND, '--threshold', '20', 'repo'), logging.INFO) module.compact_segments( dry_run=False, @@ -192,7 +199,7 @@ def test_compact_segments_with_threshold_calls_borg_with_threshold_flag(): def test_compact_segments_with_umask_calls_borg_with_umask_flags(): config = {'umask': '077'} flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - insert_execute_command_mock(COMPACT_COMMAND + ('--umask', '077', 'repo'), logging.INFO) + insert_execute_command_mock((*COMPACT_COMMAND, '--umask', '077', 'repo'), logging.INFO) module.compact_segments( dry_run=False, @@ -205,7 +212,7 @@ def test_compact_segments_with_umask_calls_borg_with_umask_flags(): def test_compact_segments_with_log_json_calls_borg_with_log_json_flags(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - insert_execute_command_mock(COMPACT_COMMAND + ('--log-json', 'repo'), logging.INFO) + insert_execute_command_mock((*COMPACT_COMMAND, '--log-json', 'repo'), logging.INFO) module.compact_segments( dry_run=False, @@ -219,7 +226,7 @@ def test_compact_segments_with_log_json_calls_borg_with_log_json_flags(): def test_compact_segments_with_lock_wait_calls_borg_with_lock_wait_flags(): config = {'lock_wait': 5} flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) - insert_execute_command_mock(COMPACT_COMMAND + ('--lock-wait', '5', 'repo'), logging.INFO) + insert_execute_command_mock((*COMPACT_COMMAND, '--lock-wait', '5', 'repo'), logging.INFO) module.compact_segments( dry_run=False, @@ -233,7 +240,8 @@ def test_compact_segments_with_lock_wait_calls_borg_with_lock_wait_flags(): def test_compact_segments_with_extra_borg_options_calls_borg_with_extra_options(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock( - COMPACT_COMMAND + ('--extra', '--options', 'value with space', 'repo'), logging.INFO + (*COMPACT_COMMAND, '--extra', '--options', 'value with space', 'repo'), + logging.INFO, ) module.compact_segments( @@ -248,7 +256,9 @@ def test_compact_segments_with_extra_borg_options_calls_borg_with_extra_options( def test_compact_segments_calls_borg_with_working_directory(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) insert_execute_command_mock( - COMPACT_COMMAND + ('repo',), logging.INFO, working_directory='/working/dir' + (*COMPACT_COMMAND, 'repo'), + logging.INFO, + working_directory='/working/dir', ) module.compact_segments( diff --git a/tests/unit/borg/test_create.py b/tests/unit/borg/test_create.py index 920bad23..08532317 100644 --- a/tests/unit/borg/test_create.py +++ b/tests/unit/borg/test_create.py @@ -38,7 +38,7 @@ def test_special_file_treats_broken_symlink_as_non_special(): def test_special_file_prepends_relative_path_with_working_directory(): flexmock(module.os).should_receive('stat').with_args('/working/dir/relative').and_return( - flexmock(st_mode=flexmock()) + flexmock(st_mode=flexmock()), ) flexmock(module.stat).should_receive('S_ISCHR').and_return(False) flexmock(module.stat).should_receive('S_ISBLK').and_return(False) @@ -61,14 +61,14 @@ def test_any_parent_directories_treats_unrelated_paths_as_non_match(): def test_collect_special_file_paths_parses_special_files_from_borg_dry_run_file_list(): flexmock(module.flags).should_receive('omit_flag').replace_with( - lambda arguments, flag: arguments + lambda arguments, flag: arguments, ) flexmock(module.flags).should_receive('omit_flag_and_value').replace_with( - lambda arguments, flag: arguments + lambda arguments, flag: arguments, ) flexmock(module.environment).should_receive('make_environment').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').and_return( - 'Processing files ...\n- /foo\n+ /bar\n- /baz' + 'Processing files ...\n- /foo\n+ /bar\n- /baz', ) flexmock(module).should_receive('special_file').and_return(True) flexmock(module.os.path).should_receive('exists').and_return(False) @@ -86,25 +86,28 @@ def test_collect_special_file_paths_parses_special_files_from_borg_dry_run_file_ def test_collect_special_file_paths_skips_borgmatic_runtime_directory(): flexmock(module.flags).should_receive('omit_flag').replace_with( - lambda arguments, flag: arguments + lambda arguments, flag: arguments, ) flexmock(module.flags).should_receive('omit_flag_and_value').replace_with( - lambda arguments, flag: arguments + lambda arguments, flag: arguments, ) flexmock(module.environment).should_receive('make_environment').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').and_return( - '+ /foo\n- /run/borgmatic/bar\n- /baz' + '+ /foo\n- /run/borgmatic/bar\n- /baz', ) flexmock(module).should_receive('special_file').and_return(True) flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module).should_receive('any_parent_directories').with_args( - '/foo', ('/run/borgmatic',) + '/foo', + ('/run/borgmatic',), ).and_return(False) flexmock(module).should_receive('any_parent_directories').with_args( - '/run/borgmatic/bar', ('/run/borgmatic',) + '/run/borgmatic/bar', + ('/run/borgmatic',), ).and_return(True) flexmock(module).should_receive('any_parent_directories').with_args( - '/baz', ('/run/borgmatic',) + '/baz', + ('/run/borgmatic',), ).and_return(False) assert module.collect_special_file_paths( @@ -119,14 +122,14 @@ def test_collect_special_file_paths_skips_borgmatic_runtime_directory(): def test_collect_special_file_paths_with_borgmatic_runtime_directory_missing_from_paths_output_errors(): flexmock(module.flags).should_receive('omit_flag').replace_with( - lambda arguments, flag: arguments + lambda arguments, flag: arguments, ) flexmock(module.flags).should_receive('omit_flag_and_value').replace_with( - lambda arguments, flag: arguments + lambda arguments, flag: arguments, ) flexmock(module.environment).should_receive('make_environment').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').and_return( - '+ /foo\n- /bar\n- /baz' + '+ /foo\n- /bar\n- /baz', ) flexmock(module).should_receive('special_file').and_return(True) flexmock(module.os.path).should_receive('exists').and_return(True) @@ -145,14 +148,14 @@ def test_collect_special_file_paths_with_borgmatic_runtime_directory_missing_fro def test_collect_special_file_paths_with_dry_run_and_borgmatic_runtime_directory_missing_from_paths_output_does_not_raise(): flexmock(module.flags).should_receive('omit_flag').replace_with( - lambda arguments, flag: arguments + lambda arguments, flag: arguments, ) flexmock(module.flags).should_receive('omit_flag_and_value').replace_with( - lambda arguments, flag: arguments + lambda arguments, flag: arguments, ) flexmock(module.environment).should_receive('make_environment').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').and_return( - '+ /foo\n- /bar\n- /baz' + '+ /foo\n- /bar\n- /baz', ) flexmock(module).should_receive('special_file').and_return(True) flexmock(module.os.path).should_receive('exists').and_return(True) @@ -170,17 +173,17 @@ def test_collect_special_file_paths_with_dry_run_and_borgmatic_runtime_directory def test_collect_special_file_paths_excludes_non_special_files(): flexmock(module.flags).should_receive('omit_flag').replace_with( - lambda arguments, flag: arguments + lambda arguments, flag: arguments, ) flexmock(module.flags).should_receive('omit_flag_and_value').replace_with( - lambda arguments, flag: arguments + lambda arguments, flag: arguments, ) flexmock(module.environment).should_receive('make_environment').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').and_return( - '+ /foo\n+ /bar\n+ /baz' + '+ /foo\n+ /bar\n+ /baz', ) flexmock(module).should_receive('special_file').and_return(True).and_return(False).and_return( - True + True, ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module).should_receive('any_parent_directories').never() @@ -195,7 +198,7 @@ def test_collect_special_file_paths_excludes_non_special_files(): ) == ('/foo', '/baz') -DEFAULT_ARCHIVE_NAME = '{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}' # noqa: FS003 +DEFAULT_ARCHIVE_NAME = '{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}' REPO_ARCHIVE = (f'repo::{DEFAULT_ARCHIVE_NAME}',) @@ -206,7 +209,7 @@ def test_make_base_create_produces_borg_command(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -231,17 +234,17 @@ def test_make_base_create_command_includes_patterns_file_in_borg_command(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) mock_pattern_file = flexmock(name='/tmp/patterns') flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return( - mock_pattern_file + mock_pattern_file, ).and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) pattern_flags = ('--patterns-from', mock_pattern_file.name) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -258,7 +261,7 @@ def test_make_base_create_command_includes_patterns_file_in_borg_command(): borgmatic_runtime_directory='/run/borgmatic', ) - assert create_flags == ('borg', 'create') + pattern_flags + assert create_flags == ('borg', 'create', *pattern_flags) assert create_positional_arguments == (f'repo::{DEFAULT_ARCHIVE_NAME}',) assert pattern_file == mock_pattern_file @@ -268,12 +271,12 @@ def test_make_base_create_command_with_store_config_false_omits_config_files(): flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -327,18 +330,21 @@ def test_make_base_create_command_with_store_config_false_omits_config_files(): ), ) def test_make_base_create_command_includes_configuration_option_as_command_flag( - option_name, option_value, feature_available, option_flags + option_name, + option_value, + feature_available, + option_flags, ): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(feature_available) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -355,7 +361,7 @@ def test_make_base_create_command_includes_configuration_option_as_command_flag( borgmatic_runtime_directory='/run/borgmatic', ) - assert create_flags == ('borg', 'create') + option_flags + assert create_flags == ('borg', 'create', *option_flags) assert create_positional_arguments == REPO_ARCHIVE assert not pattern_file @@ -365,12 +371,12 @@ def test_make_base_create_command_includes_dry_run_in_borg_command(): flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -397,12 +403,12 @@ def test_make_base_create_command_includes_comment_in_borg_command(): flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -430,12 +436,12 @@ def test_make_base_create_command_includes_local_path_in_borg_command(): flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -462,12 +468,12 @@ def test_make_base_create_command_includes_remote_path_in_borg_command(): flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -494,12 +500,12 @@ def test_make_base_create_command_includes_log_json_in_borg_command(): flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -526,12 +532,12 @@ def test_make_base_create_command_includes_list_flags_in_borg_command(): flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -558,16 +564,17 @@ def test_make_base_create_command_with_stream_processes_ignores_read_special_fal patterns_file = flexmock(name='patterns') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').with_args( - patterns, '/run/borgmatic' + patterns, + '/run/borgmatic', ).and_return(patterns_file) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) flexmock(module.logger).should_receive('warning').twice() flexmock(module.environment).should_receive('make_environment') @@ -609,16 +616,17 @@ def test_make_base_create_command_with_stream_processes_ignores_read_special_fal def test_make_base_create_command_without_patterns_and_with_stream_processes_ignores_read_special_false_and_excludes_special_files(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').with_args( - [], '/run/borgmatic' + [], + '/run/borgmatic', ).and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) flexmock(module.logger).should_receive('warning').twice() flexmock(module.environment).should_receive('make_environment') @@ -662,12 +670,12 @@ def test_make_base_create_command_with_stream_processes_and_read_special_true_sk flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) flexmock(module.logger).should_receive('warning').never() flexmock(module).should_receive('collect_special_file_paths').never() @@ -697,12 +705,12 @@ def test_make_base_create_command_includes_archive_name_format_in_borg_command() flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::ARCHIVE_NAME',) + ('repo::ARCHIVE_NAME',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -729,12 +737,12 @@ def test_make_base_create_command_includes_default_archive_name_format_in_borg_c flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::{hostname}',) + ('repo::{hostname}',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -756,16 +764,16 @@ def test_make_base_create_command_includes_default_archive_name_format_in_borg_c def test_make_base_create_command_includes_archive_name_format_with_placeholders_in_borg_command(): - repository_archive_pattern = 'repo::Documents_{hostname}-{now}' # noqa: FS003 + repository_archive_pattern = 'repo::Documents_{hostname}-{now}' flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (repository_archive_pattern,) + (repository_archive_pattern,), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -774,7 +782,7 @@ def test_make_base_create_command_includes_archive_name_format_with_placeholders config={ 'source_directories': ['foo', 'bar'], 'repositories': ['repo'], - 'archive_name_format': 'Documents_{hostname}-{now}', # noqa: FS003 + 'archive_name_format': 'Documents_{hostname}-{now}', }, patterns=[Pattern('foo'), Pattern('bar')], local_borg_version='1.2.3', @@ -788,25 +796,25 @@ def test_make_base_create_command_includes_archive_name_format_with_placeholders def test_make_base_create_command_includes_repository_and_archive_name_format_with_placeholders_in_borg_command(): - repository_archive_pattern = '{fqdn}::Documents_{hostname}-{now}' # noqa: FS003 + repository_archive_pattern = '{fqdn}::Documents_{hostname}-{now}' flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (repository_archive_pattern,) + (repository_archive_pattern,), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( dry_run=False, - repository_path='{fqdn}', # noqa: FS003 + repository_path='{fqdn}', config={ 'source_directories': ['foo', 'bar'], - 'repositories': ['{fqdn}'], # noqa: FS003 - 'archive_name_format': 'Documents_{hostname}-{now}', # noqa: FS003 + 'repositories': ['{fqdn}'], + 'archive_name_format': 'Documents_{hostname}-{now}', }, patterns=[Pattern('foo'), Pattern('bar')], local_borg_version='1.2.3', @@ -824,7 +832,7 @@ def test_make_base_create_command_includes_archive_suffix_in_borg_command(): flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - DEFAULT_ARCHIVE_NAME + DEFAULT_ARCHIVE_NAME, ) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) @@ -852,12 +860,12 @@ def test_make_base_create_command_includes_extra_borg_options_in_borg_command(): flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('FOO') flexmock(module.flags).should_receive('get_default_archive_name_format').and_return( - '{hostname}' + '{hostname}', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - (f'repo::{DEFAULT_ARCHIVE_NAME}',) + (f'repo::{DEFAULT_ARCHIVE_NAME}',), ) (create_flags, create_positional_arguments, pattern_file) = module.make_base_create_command( @@ -882,7 +890,7 @@ def test_make_base_create_command_includes_extra_borg_options_in_borg_command(): def test_make_base_create_command_with_non_existent_directory_and_source_directories_must_exist_raises(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.borg.pattern).should_receive( - 'check_all_root_patterns_exist' + 'check_all_root_patterns_exist', ).and_raise(ValueError) with pytest.raises(ValueError): @@ -905,12 +913,12 @@ def test_create_archive_calls_borg_with_flags(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + REPO_ARCHIVE, + ('borg', 'create', *REPO_ARCHIVE), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -938,13 +946,13 @@ def test_create_archive_calls_borg_with_environment(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) environment = {'BORG_THINGY': 'YUP'} flexmock(module.environment).should_receive('make_environment').and_return(environment) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + REPO_ARCHIVE, + ('borg', 'create', *REPO_ARCHIVE), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -972,12 +980,12 @@ def test_create_archive_with_log_info_calls_borg_with_info_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--info') + REPO_ARCHIVE, + ('borg', 'create', '--info', *REPO_ARCHIVE), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1006,12 +1014,12 @@ def test_create_archive_with_log_info_and_json_suppresses_most_borg_output(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'create', '--json') + REPO_ARCHIVE, + ('borg', 'create', '--json', *REPO_ARCHIVE), working_directory=None, environment=None, borg_local_path='borg', @@ -1039,12 +1047,12 @@ def test_create_archive_with_log_debug_calls_borg_with_debug_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--debug', '--show-rc') + REPO_ARCHIVE, + ('borg', 'create', '--debug', '--show-rc', *REPO_ARCHIVE), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1073,12 +1081,12 @@ def test_create_archive_with_log_debug_and_json_suppresses_most_borg_output(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'create', '--json') + REPO_ARCHIVE, + ('borg', 'create', '--json', *REPO_ARCHIVE), working_directory=None, environment=None, borg_local_path='borg', @@ -1108,12 +1116,12 @@ def test_create_archive_with_stats_and_dry_run_calls_borg_without_stats(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create', '--dry-run'), REPO_ARCHIVE, flexmock()) + (('borg', 'create', '--dry-run'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--dry-run', '--info') + REPO_ARCHIVE, + ('borg', 'create', '--dry-run', '--info', *REPO_ARCHIVE), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1142,14 +1150,14 @@ def test_create_archive_with_working_directory_calls_borg_with_working_directory flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - '/working/dir' + '/working/dir', ) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + REPO_ARCHIVE, + ('borg', 'create', *REPO_ARCHIVE), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1178,13 +1186,13 @@ def test_create_archive_with_exit_codes_calls_borg_using_them(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') borg_exit_codes = flexmock() flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + REPO_ARCHIVE, + ('borg', 'create', *REPO_ARCHIVE), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1213,12 +1221,12 @@ def test_create_archive_with_stats_calls_borg_with_stats_flag_and_answer_output_ flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--stats') + REPO_ARCHIVE, + ('borg', 'create', '--stats', *REPO_ARCHIVE), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, borg_local_path='borg', @@ -1251,12 +1259,12 @@ def test_create_archive_with_files_calls_borg_with_answer_output_log_level(): ('borg', 'create', '--list', '--filter', 'FOO'), REPO_ARCHIVE, flexmock(), - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--list', '--filter', 'FOO') + REPO_ARCHIVE, + ('borg', 'create', '--list', '--filter', 'FOO', *REPO_ARCHIVE), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, borg_local_path='borg', @@ -1285,12 +1293,12 @@ def test_create_archive_with_progress_and_log_info_calls_borg_with_progress_flag flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--info', '--progress') + REPO_ARCHIVE, + ('borg', 'create', '--info', '--progress', *REPO_ARCHIVE), output_log_level=logging.INFO, output_file=module.DO_NOT_CAPTURE, borg_local_path='borg', @@ -1320,12 +1328,12 @@ def test_create_archive_with_progress_calls_borg_with_progress_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--progress') + REPO_ARCHIVE, + ('borg', 'create', '--progress', *REPO_ARCHIVE), output_log_level=logging.INFO, output_file=module.DO_NOT_CAPTURE, borg_local_path='borg', @@ -1359,18 +1367,13 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr ('borg', 'create', '--read-special'), REPO_ARCHIVE, flexmock(), - ) + ), ) flexmock(module.environment).should_receive('make_environment') - create_command = ( - 'borg', - 'create', - '--read-special', - '--progress', - ) + REPO_ARCHIVE + create_command = ('borg', 'create', '--read-special', '--progress', *REPO_ARCHIVE) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_with_processes').with_args( - create_command + ('--dry-run', '--list'), + (*create_command, '--dry-run', '--list'), processes=processes, output_log_level=logging.INFO, output_file=module.DO_NOT_CAPTURE, @@ -1411,12 +1414,12 @@ def test_create_archive_with_json_calls_borg_with_json_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'create', '--json') + REPO_ARCHIVE, + ('borg', 'create', '--json', *REPO_ARCHIVE), working_directory=None, environment=None, borg_local_path='borg', @@ -1445,12 +1448,12 @@ def test_create_archive_with_stats_and_json_calls_borg_without_stats_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'create', '--json') + REPO_ARCHIVE, + ('borg', 'create', '--json', *REPO_ARCHIVE), working_directory=None, environment=None, borg_local_path='borg', @@ -1479,12 +1482,12 @@ def test_create_archive_with_comment_calls_borg_with_comment_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create', '--comment', 'a comment'), REPO_ARCHIVE, flexmock()) + (('borg', 'create', '--comment', 'a comment'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--comment', 'a comment') + REPO_ARCHIVE, + ('borg', 'create', '--comment', 'a comment', *REPO_ARCHIVE), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1514,14 +1517,14 @@ def test_create_archive_calls_borg_with_working_directory(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_base_create_command').and_return( - (('borg', 'create'), REPO_ARCHIVE, flexmock()) + (('borg', 'create'), REPO_ARCHIVE, flexmock()), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - '/working/dir' + '/working/dir', ) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + REPO_ARCHIVE, + ('borg', 'create', *REPO_ARCHIVE), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', diff --git a/tests/unit/borg/test_delete.py b/tests/unit/borg/test_delete.py index e59c3b3a..5dc9719f 100644 --- a/tests/unit/borg/test_delete.py +++ b/tests/unit/borg/test_delete.py @@ -14,7 +14,7 @@ def test_make_delete_command_includes_log_info(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_delete_command( @@ -36,7 +36,7 @@ def test_make_delete_command_includes_log_debug(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_delete_command( @@ -55,12 +55,13 @@ def test_make_delete_command_includes_log_debug(): def test_make_delete_command_includes_dry_run(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').with_args( - 'dry-run', True + 'dry-run', + True, ).and_return(('--dry-run',)) flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_delete_command( @@ -79,12 +80,13 @@ def test_make_delete_command_includes_dry_run(): def test_make_delete_command_includes_remote_path(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').with_args( - 'remote-path', 'borg1' + 'remote-path', + 'borg1', ).and_return(('--remote-path', 'borg1')) flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_delete_command( @@ -102,12 +104,12 @@ def test_make_delete_command_includes_remote_path(): def test_make_delete_command_includes_umask(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_delete_command( @@ -126,12 +128,13 @@ def test_make_delete_command_includes_umask(): def test_make_delete_command_includes_log_json(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').with_args( - 'log-json', True + 'log-json', + True, ).and_return(('--log-json',)) flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_delete_command( @@ -150,12 +153,13 @@ def test_make_delete_command_includes_log_json(): def test_make_delete_command_includes_lock_wait(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').with_args( - 'lock-wait', 5 + 'lock-wait', + 5, ).and_return(('--lock-wait', '5')) flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_delete_command( @@ -174,12 +178,13 @@ def test_make_delete_command_includes_lock_wait(): def test_make_delete_command_with_list_config_calls_borg_with_list_flag(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').with_args( - 'list', True + 'list', + True, ).and_return(('--list',)) flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_delete_command( @@ -200,7 +205,7 @@ def test_make_delete_command_includes_force(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_delete_command( @@ -221,7 +226,7 @@ def test_make_delete_command_includes_force_twice(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_delete_command( @@ -240,11 +245,11 @@ def test_make_delete_command_includes_force_twice(): def test_make_delete_command_includes_archive(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return( - ('--match-archives', 'archive') + ('--match-archives', 'archive'), ) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_delete_command( @@ -252,7 +257,10 @@ def test_make_delete_command_includes_archive(): config={}, local_borg_version='1.2.3', delete_arguments=flexmock( - list_details=False, force=0, match_archives=None, archive='archive' + list_details=False, + force=0, + match_archives=None, + archive='archive', ), global_arguments=flexmock(dry_run=False), local_path='borg', @@ -265,11 +273,11 @@ def test_make_delete_command_includes_archive(): def test_make_delete_command_includes_match_archives(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return( - ('--match-archives', 'sh:foo*') + ('--match-archives', 'sh:foo*'), ) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_delete_command( @@ -277,7 +285,10 @@ def test_make_delete_command_includes_match_archives(): config={}, local_borg_version='1.2.3', delete_arguments=flexmock( - list_details=False, force=0, match_archives='sh:foo*', archive='archive' + list_details=False, + force=0, + match_archives='sh:foo*', + archive='archive', ), global_arguments=flexmock(dry_run=False), local_path='borg', @@ -296,7 +307,7 @@ def test_delete_archives_with_archive_calls_borg_delete(): flexmock(module.borgmatic.borg.repo_delete).should_receive('delete_repository').never() flexmock(module).should_receive('make_delete_command').and_return(flexmock()) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.execute).should_receive('execute_command').once() @@ -316,7 +327,7 @@ def test_delete_archives_with_match_archives_calls_borg_delete(): flexmock(module.borgmatic.borg.repo_delete).should_receive('delete_repository').never() flexmock(module).should_receive('make_delete_command').and_return(flexmock()) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.execute).should_receive('execute_command').once() @@ -337,7 +348,7 @@ def test_delete_archives_with_archive_related_argument_calls_borg_delete(argumen flexmock(module.borgmatic.borg.repo_delete).should_receive('delete_repository').never() flexmock(module).should_receive('make_delete_command').and_return(flexmock()) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.execute).should_receive('execute_command').once() @@ -366,7 +377,10 @@ def test_delete_archives_without_archive_related_argument_calls_borg_repo_delete config={}, local_borg_version=flexmock(), delete_arguments=flexmock( - list_details=True, force=False, cache_only=False, keep_security_info=False + list_details=True, + force=False, + cache_only=False, + keep_security_info=False, ), global_arguments=flexmock(), ) @@ -380,10 +394,10 @@ def test_delete_archives_calls_borg_delete_with_working_directory(): flexmock(module).should_receive('make_delete_command').and_return(command) environment = flexmock() flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - environment + environment, ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - '/working/dir' + '/working/dir', ) flexmock(module.borgmatic.execute).should_receive('execute_command').with_args( command, diff --git a/tests/unit/borg/test_environment.py b/tests/unit/borg/test_environment.py index 750d50fb..f458cf6a 100644 --- a/tests/unit/borg/test_environment.py +++ b/tests/unit/borg/test_environment.py @@ -5,13 +5,13 @@ from borgmatic.borg import environment as module def test_make_environment_with_passcommand_should_call_it_and_set_passphrase_file_descriptor_in_environment(): flexmock(module.os).should_receive('environ').and_return( - {'USER': 'root', 'BORG_PASSCOMMAND': 'nope'} + {'USER': 'root', 'BORG_PASSCOMMAND': 'nope'}, ) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.borgmatic.borg.passcommand).should_receive( - 'get_passphrase_from_passcommand' + 'get_passphrase_from_passcommand', ).and_return('passphrase') flexmock(module.os).should_receive('pipe').and_return((3, 4)) flexmock(module.os).should_receive('write') @@ -27,13 +27,13 @@ def test_make_environment_with_passcommand_should_call_it_and_set_passphrase_fil def test_make_environment_with_passphrase_should_set_passphrase_file_descriptor_in_environment(): flexmock(module.os).should_receive('environ').and_return( - {'USER': 'root', 'BORG_PASSPHRASE': 'nope', 'BORG_PASSCOMMAND': 'nope'} + {'USER': 'root', 'BORG_PASSPHRASE': 'nope', 'BORG_PASSCOMMAND': 'nope'}, ) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.borg.passcommand).should_receive( - 'get_passphrase_from_passcommand' + 'get_passphrase_from_passcommand', ).and_return(None) flexmock(module.os).should_receive('pipe').and_return((3, 4)) flexmock(module.os).should_receive('write') @@ -54,7 +54,7 @@ def test_make_environment_with_credential_tag_passphrase_should_load_it_and_set_ 'resolve_credential', ).with_args('{credential systemd pass}', config).and_return('pass') flexmock(module.borgmatic.borg.passcommand).should_receive( - 'get_passphrase_from_passcommand' + 'get_passphrase_from_passcommand', ).never() flexmock(module.os).should_receive('pipe').and_return((3, 4)) flexmock(module.os).should_receive('write') @@ -70,7 +70,7 @@ def test_make_environment_with_credential_tag_passphrase_should_load_it_and_set_ def test_make_environment_with_ssh_command_should_set_environment(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'ssh_command': 'ssh -C'}) @@ -81,7 +81,7 @@ def test_make_environment_with_ssh_command_should_set_environment(): def test_make_environment_without_configuration_sets_certain_environment_variables(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({}) @@ -107,10 +107,10 @@ def test_make_environment_without_configuration_passes_through_default_environme 'BORG_USE_CHUNKS_ARCHIVE': 'yup', 'BORG_DEBUG_PASSPHRASE': 'nah', 'BORG_DISPLAY_PASSPHRASE': 'yup', - } + }, ) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({}) @@ -129,7 +129,7 @@ def test_make_environment_without_configuration_passes_through_default_environme def test_make_environment_with_relocated_repo_access_true_should_set_environment_YES(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'relocated_repo_access_is_ok': True}) @@ -140,7 +140,7 @@ def test_make_environment_with_relocated_repo_access_true_should_set_environment def test_make_environment_with_relocated_repo_access_false_should_set_environment_NO(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'relocated_repo_access_is_ok': False}) @@ -151,7 +151,7 @@ def test_make_environment_with_relocated_repo_access_false_should_set_environmen def test_make_environment_check_i_know_what_i_am_doing_true_should_set_environment_YES(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'check_i_know_what_i_am_doing': True}) @@ -162,7 +162,7 @@ def test_make_environment_check_i_know_what_i_am_doing_true_should_set_environme def test_make_environment_check_i_know_what_i_am_doing_false_should_set_environment_NO(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'check_i_know_what_i_am_doing': False}) @@ -173,7 +173,7 @@ def test_make_environment_check_i_know_what_i_am_doing_false_should_set_environm def test_make_environment_debug_passphrase_true_should_set_environment_YES(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'debug_passphrase': True}) @@ -184,7 +184,7 @@ def test_make_environment_debug_passphrase_true_should_set_environment_YES(): def test_make_environment_debug_passphrase_false_should_set_environment_NO(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'debug_passphrase': False}) @@ -195,7 +195,7 @@ def test_make_environment_debug_passphrase_false_should_set_environment_NO(): def test_make_environment_display_passphrase_true_should_set_environment_YES(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'display_passphrase': True}) @@ -206,7 +206,7 @@ def test_make_environment_display_passphrase_true_should_set_environment_YES(): def test_make_environment_display_passphrase_false_should_set_environment_NO(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'display_passphrase': False}) @@ -217,7 +217,7 @@ def test_make_environment_display_passphrase_false_should_set_environment_NO(): def test_make_environment_with_integer_variable_value(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() environment = module.make_environment({'borg_files_cache_ttl': 40}) @@ -228,7 +228,7 @@ def test_make_environment_with_integer_variable_value(): def test_make_environment_with_use_chunks_archive_should_set_correct_environment_value(): flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('pipe').never() diff --git a/tests/unit/borg/test_export_key.py b/tests/unit/borg/test_export_key.py index c9e3751b..e24bd031 100644 --- a/tests/unit/borg/test_export_key.py +++ b/tests/unit/borg/test_export_key.py @@ -10,7 +10,10 @@ from ..test_verbosity import insert_logging_mock def insert_execute_command_mock( - command, output_file=module.DO_NOT_CAPTURE, working_directory=None, borg_exit_codes=None + command, + output_file=module.DO_NOT_CAPTURE, + working_directory=None, + borg_exit_codes=None, ): borgmatic.logger.add_custom_log_levels() @@ -276,7 +279,7 @@ def test_export_key_calls_borg_with_working_directory(): def test_export_key_calls_borg_with_path_argument_and_working_directory(): flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').with_args('/working/dir/dest').and_return( - False + False, ).once() insert_execute_command_mock( ('borg', 'key', 'export', 'repo', 'dest'), diff --git a/tests/unit/borg/test_export_tar.py b/tests/unit/borg/test_export_tar.py index fb09c440..1a1a1e1d 100644 --- a/tests/unit/borg/test_export_tar.py +++ b/tests/unit/borg/test_export_tar.py @@ -34,10 +34,10 @@ def test_export_tar_archive_calls_borg_with_path_flags(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock( - ('borg', 'export-tar', 'repo::archive', 'test.tar', 'path1', 'path2') + ('borg', 'export-tar', 'repo::archive', 'test.tar', 'path1', 'path2'), ) module.export_tar_archive( @@ -56,10 +56,11 @@ def test_export_tar_archive_calls_borg_with_local_path_flags(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock( - ('borg1', 'export-tar', 'repo::archive', 'test.tar'), borg_local_path='borg1' + ('borg1', 'export-tar', 'repo::archive', 'test.tar'), + borg_local_path='borg1', ) module.export_tar_archive( @@ -79,7 +80,7 @@ def test_export_tar_archive_calls_borg_using_exit_codes(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) borg_exit_codes = flexmock() insert_execute_command_mock( @@ -103,10 +104,10 @@ def test_export_tar_archive_calls_borg_with_remote_path_flags(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock( - ('borg', 'export-tar', '--remote-path', 'borg1', 'repo::archive', 'test.tar') + ('borg', 'export-tar', '--remote-path', 'borg1', 'repo::archive', 'test.tar'), ) module.export_tar_archive( @@ -126,10 +127,10 @@ def test_export_tar_archive_calls_borg_with_umask_flags(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock( - ('borg', 'export-tar', '--umask', '0770', 'repo::archive', 'test.tar') + ('borg', 'export-tar', '--umask', '0770', 'repo::archive', 'test.tar'), ) module.export_tar_archive( @@ -148,7 +149,7 @@ def test_export_tar_archive_calls_borg_with_log_json_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock(('borg', 'export-tar', '--log-json', 'repo::archive', 'test.tar')) @@ -168,10 +169,10 @@ def test_export_tar_archive_calls_borg_with_lock_wait_flags(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock( - ('borg', 'export-tar', '--lock-wait', '5', 'repo::archive', 'test.tar') + ('borg', 'export-tar', '--lock-wait', '5', 'repo::archive', 'test.tar'), ) module.export_tar_archive( @@ -190,7 +191,7 @@ def test_export_tar_archive_with_log_info_calls_borg_with_info_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock(('borg', 'export-tar', '--info', 'repo::archive', 'test.tar')) insert_logging_mock(logging.INFO) @@ -211,10 +212,10 @@ def test_export_tar_archive_with_log_debug_calls_borg_with_debug_flags(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock( - ('borg', 'export-tar', '--debug', '--show-rc', 'repo::archive', 'test.tar') + ('borg', 'export-tar', '--debug', '--show-rc', 'repo::archive', 'test.tar'), ) insert_logging_mock(logging.DEBUG) @@ -234,7 +235,7 @@ def test_export_tar_archive_calls_borg_with_dry_run_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module).should_receive('execute_command').never() @@ -254,10 +255,10 @@ def test_export_tar_archive_calls_borg_with_tar_filter_flags(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock( - ('borg', 'export-tar', '--tar-filter', 'bzip2', 'repo::archive', 'test.tar') + ('borg', 'export-tar', '--tar-filter', 'bzip2', 'repo::archive', 'test.tar'), ) module.export_tar_archive( @@ -277,7 +278,7 @@ def test_export_tar_archive_calls_borg_with_list_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock( ('borg', 'export-tar', '--list', 'repo::archive', 'test.tar'), @@ -300,10 +301,10 @@ def test_export_tar_archive_calls_borg_with_strip_components_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock( - ('borg', 'export-tar', '--strip-components', '5', 'repo::archive', 'test.tar') + ('borg', 'export-tar', '--strip-components', '5', 'repo::archive', 'test.tar'), ) module.export_tar_archive( @@ -323,7 +324,7 @@ def test_export_tar_archive_skips_abspath_for_remote_repository_flag(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('server:repo::archive',) + ('server:repo::archive',), ) insert_execute_command_mock(('borg', 'export-tar', 'server:repo::archive', 'test.tar')) @@ -343,7 +344,7 @@ def test_export_tar_archive_calls_borg_with_stdout_destination_path(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock(('borg', 'export-tar', 'repo::archive', '-'), capture=False) @@ -363,7 +364,7 @@ def test_export_tar_archive_calls_borg_with_working_directory(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock( ('borg', 'export-tar', 'repo::archive', 'test.tar'), diff --git a/tests/unit/borg/test_extract.py b/tests/unit/borg/test_extract.py index 4ac985e8..d0197ee0 100644 --- a/tests/unit/borg/test_extract.py +++ b/tests/unit/borg/test_extract.py @@ -23,7 +23,7 @@ def test_extract_last_archive_dry_run_calls_borg_with_last_archive(): flexmock(module.repo_list).should_receive('resolve_archive_name').and_return('archive') insert_execute_command_mock(('borg', 'extract', '--dry-run', 'repo::archive')) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) module.extract_last_archive_dry_run( @@ -53,7 +53,7 @@ def test_extract_last_archive_dry_run_with_log_info_calls_borg_with_info_paramet insert_execute_command_mock(('borg', 'extract', '--dry-run', '--info', 'repo::archive')) insert_logging_mock(logging.INFO) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) module.extract_last_archive_dry_run( @@ -68,11 +68,11 @@ def test_extract_last_archive_dry_run_with_log_info_calls_borg_with_info_paramet def test_extract_last_archive_dry_run_with_log_debug_calls_borg_with_debug_parameter(): flexmock(module.repo_list).should_receive('resolve_archive_name').and_return('archive') insert_execute_command_mock( - ('borg', 'extract', '--dry-run', '--debug', '--show-rc', '--list', 'repo::archive') + ('borg', 'extract', '--dry-run', '--debug', '--show-rc', '--list', 'repo::archive'), ) insert_logging_mock(logging.DEBUG) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) module.extract_last_archive_dry_run( @@ -88,7 +88,7 @@ def test_extract_last_archive_dry_run_calls_borg_via_local_path(): flexmock(module.repo_list).should_receive('resolve_archive_name').and_return('archive') insert_execute_command_mock(('borg1', 'extract', '--dry-run', 'repo::archive')) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) module.extract_last_archive_dry_run( @@ -105,10 +105,11 @@ def test_extract_last_archive_dry_run_calls_borg_using_exit_codes(): flexmock(module.repo_list).should_receive('resolve_archive_name').and_return('archive') borg_exit_codes = flexmock() insert_execute_command_mock( - ('borg', 'extract', '--dry-run', 'repo::archive'), borg_exit_codes=borg_exit_codes + ('borg', 'extract', '--dry-run', 'repo::archive'), + borg_exit_codes=borg_exit_codes, ) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) module.extract_last_archive_dry_run( @@ -123,10 +124,10 @@ def test_extract_last_archive_dry_run_calls_borg_using_exit_codes(): def test_extract_last_archive_dry_run_calls_borg_with_remote_path_flags(): flexmock(module.repo_list).should_receive('resolve_archive_name').and_return('archive') insert_execute_command_mock( - ('borg', 'extract', '--dry-run', '--remote-path', 'borg1', 'repo::archive') + ('borg', 'extract', '--dry-run', '--remote-path', 'borg1', 'repo::archive'), ) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) module.extract_last_archive_dry_run( @@ -143,7 +144,7 @@ def test_extract_last_archive_dry_run_calls_borg_with_log_json_flag(): flexmock(module.repo_list).should_receive('resolve_archive_name').and_return('archive') insert_execute_command_mock(('borg', 'extract', '--dry-run', '--log-json', 'repo::archive')) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) module.extract_last_archive_dry_run( @@ -158,10 +159,10 @@ def test_extract_last_archive_dry_run_calls_borg_with_log_json_flag(): def test_extract_last_archive_dry_run_calls_borg_with_lock_wait_flags(): flexmock(module.repo_list).should_receive('resolve_archive_name').and_return('archive') insert_execute_command_mock( - ('borg', 'extract', '--dry-run', '--lock-wait', '5', 'repo::archive') + ('borg', 'extract', '--dry-run', '--lock-wait', '5', 'repo::archive'), ) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) module.extract_last_archive_dry_run( @@ -179,10 +180,10 @@ def test_extract_archive_calls_borg_with_path_flags(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -202,10 +203,10 @@ def test_extract_archive_calls_borg_with_local_path(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -224,15 +225,16 @@ def test_extract_archive_calls_borg_with_exit_codes(): flexmock(module.os.path).should_receive('abspath').and_return('repo') borg_exit_codes = flexmock() insert_execute_command_mock( - ('borg', 'extract', 'repo::archive'), borg_exit_codes=borg_exit_codes + ('borg', 'extract', 'repo::archive'), + borg_exit_codes=borg_exit_codes, ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -252,10 +254,10 @@ def test_extract_archive_calls_borg_with_remote_path_flags(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -283,10 +285,10 @@ def test_extract_archive_calls_borg_with_numeric_ids_parameter(feature_available flexmock(module.feature).should_receive('available').and_return(feature_available) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -306,10 +308,10 @@ def test_extract_archive_calls_borg_with_umask_flags(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -329,7 +331,7 @@ def test_extract_archive_calls_borg_with_log_json_flags(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) module.extract_archive( @@ -349,10 +351,10 @@ def test_extract_archive_calls_borg_with_lock_wait_flags(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -373,10 +375,10 @@ def test_extract_archive_with_log_info_calls_borg_with_info_parameter(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -393,16 +395,16 @@ def test_extract_archive_with_log_info_calls_borg_with_info_parameter(): def test_extract_archive_with_log_debug_calls_borg_with_debug_flags(): flexmock(module.os.path).should_receive('abspath').and_return('repo') insert_execute_command_mock( - ('borg', 'extract', '--debug', '--list', '--show-rc', 'repo::archive') + ('borg', 'extract', '--debug', '--list', '--show-rc', 'repo::archive'), ) insert_logging_mock(logging.DEBUG) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -422,10 +424,10 @@ def test_extract_archive_calls_borg_with_dry_run_parameter(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -445,10 +447,10 @@ def test_extract_archive_calls_borg_with_destination_path(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -469,10 +471,10 @@ def test_extract_archive_calls_borg_with_strip_components(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -498,15 +500,15 @@ def test_extract_archive_calls_borg_with_strip_components_calculated_from_all(): 'repo::archive', 'foo/bar/baz.txt', 'foo/bar.txt', - ) + ), ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -532,15 +534,15 @@ def test_extract_archive_calls_borg_with_strip_components_calculated_from_all_wi 'repo::archive', '/foo/bar/baz.txt', '/foo/bar.txt', - ) + ), ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -560,10 +562,10 @@ def test_extract_archive_with_strip_components_all_and_no_paths_raises(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') flexmock(module).should_receive('execute_command').never() @@ -595,10 +597,10 @@ def test_extract_archive_calls_borg_with_progress_flag(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -645,10 +647,10 @@ def test_extract_archive_calls_borg_with_stdout_parameter_and_returns_process(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') assert ( @@ -680,10 +682,10 @@ def test_extract_archive_skips_abspath_for_remote_repository(): flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('server:repo::archive',) + ('server:repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).and_return('repo') module.extract_archive( @@ -700,14 +702,15 @@ def test_extract_archive_skips_abspath_for_remote_repository(): def test_extract_archive_uses_configured_working_directory_in_repo_path_and_destination_path(): flexmock(module.os.path).should_receive('abspath').and_return('repo') insert_execute_command_mock( - ('borg', 'extract', '/working/dir/repo::archive'), destination_path='/working/dir/dest' + ('borg', 'extract', '/working/dir/repo::archive'), + destination_path='/working/dir/dest', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('/working/dir/repo::archive',) + ('/working/dir/repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).with_args('repo', '/working/dir').and_return('/working/dir/repo').once() module.extract_archive( @@ -727,10 +730,10 @@ def test_extract_archive_uses_configured_working_directory_in_repo_path_when_des insert_execute_command_mock(('borg', 'extract', '/working/dir/repo::archive')) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('/working/dir/repo::archive',) + ('/working/dir/repo::archive',), ) flexmock(module.borgmatic.config.validate).should_receive( - 'normalize_repository_path' + 'normalize_repository_path', ).with_args('repo', '/working/dir').and_return('/working/dir/repo').once() module.extract_archive( diff --git a/tests/unit/borg/test_flags.py b/tests/unit/borg/test_flags.py index f7bf2f6a..c2130eb1 100644 --- a/tests/unit/borg/test_flags.py +++ b/tests/unit/borg/test_flags.py @@ -27,7 +27,7 @@ def test_make_flags_formats_name_with_underscore(): def test_make_flags_from_arguments_flattens_and_sorts_multiple_arguments(): flexmock(module).should_receive('make_flags').with_args('foo', 'bar').and_return(('foo', 'bar')) flexmock(module).should_receive('make_flags').with_args('baz', 'quux').and_return( - ('baz', 'quux') + ('baz', 'quux'), ) arguments = flexmock(foo='bar', baz='quux') @@ -69,7 +69,9 @@ def test_make_repository_archive_flags_with_borg_features_separates_repository_a flexmock(module.feature).should_receive('available').and_return(True) assert module.make_repository_archive_flags( - repository_path='repo', archive='archive', local_borg_version='1.2.3' + repository_path='repo', + archive='archive', + local_borg_version='1.2.3', ) == ( '--repo', 'repo', @@ -81,7 +83,9 @@ def test_make_repository_archive_flags_with_borg_features_joins_repository_and_a flexmock(module.feature).should_receive('available').and_return(False) assert module.make_repository_archive_flags( - repository_path='repo', archive='archive', local_borg_version='1.2.3' + repository_path='repo', + archive='archive', + local_borg_version='1.2.3', ) == ('repo::archive',) @@ -106,90 +110,90 @@ def test_get_default_archive_name_format_without_archive_series_feature_uses_non @pytest.mark.parametrize( 'match_archives,archive_name_format,feature_available,expected_result', ( - (None, None, True, ('--match-archives', 'sh:{hostname}-*')), # noqa: FS003 - (None, '', True, ('--match-archives', 'sh:{hostname}-*')), # noqa: FS003 + (None, None, True, ('--match-archives', 'sh:{hostname}-*')), + (None, '', True, ('--match-archives', 'sh:{hostname}-*')), ( 're:foo-.*', - '{hostname}-{now}', # noqa: FS003 + '{hostname}-{now}', True, ('--match-archives', 're:foo-.*'), ), ( 'sh:foo-*', - '{hostname}-{now}', # noqa: FS003 + '{hostname}-{now}', False, ('--glob-archives', 'foo-*'), ), ( 'foo-*', - '{hostname}-{now}', # noqa: FS003 + '{hostname}-{now}', False, ('--glob-archives', 'foo-*'), ), ( None, - '{hostname}-docs-{now}', # noqa: FS003 + '{hostname}-docs-{now}', True, - ('--match-archives', 'sh:{hostname}-docs-*'), # noqa: FS003 + ('--match-archives', 'sh:{hostname}-docs-*'), ), ( None, - '{utcnow}-docs-{user}', # noqa: FS003 + '{utcnow}-docs-{user}', True, - ('--match-archives', 'sh:*-docs-{user}'), # noqa: FS003 + ('--match-archives', 'sh:*-docs-{user}'), ), - (None, '{fqdn}-{pid}', True, ('--match-archives', 'sh:{fqdn}-*')), # noqa: FS003 + (None, '{fqdn}-{pid}', True, ('--match-archives', 'sh:{fqdn}-*')), ( None, - 'stuff-{now:%Y-%m-%dT%H:%M:%S.%f}', # noqa: FS003 + 'stuff-{now:%Y-%m-%dT%H:%M:%S.%f}', True, ('--match-archives', 'sh:stuff-*'), ), ( None, - '{hostname}-docs-{now}', # noqa: FS003 + '{hostname}-docs-{now}', False, - ('--glob-archives', '{hostname}-docs-*'), # noqa: FS003 + ('--glob-archives', '{hostname}-docs-*'), ), ( None, - '{now}', # noqa: FS003 + '{now}', False, (), ), ( None, - '{now}', # noqa: FS003 + '{now}', True, (), ), ( None, - '{utcnow}-docs-{user}', # noqa: FS003 + '{utcnow}-docs-{user}', False, - ('--glob-archives', '*-docs-{user}'), # noqa: FS003 + ('--glob-archives', '*-docs-{user}'), ), ( '*', - '{now}', # noqa: FS003 + '{now}', True, (), ), ( '*', - '{now}', # noqa: FS003 + '{now}', False, (), ), ( 're:.*', - '{now}', # noqa: FS003 + '{now}', True, (), ), ( 'sh:*', - '{now}', # noqa: FS003 + '{now}', True, (), ), @@ -208,16 +212,21 @@ def test_get_default_archive_name_format_without_archive_series_feature_uses_non ), ) def test_make_match_archives_flags_makes_flags_with_globs( - match_archives, archive_name_format, feature_available, expected_result + match_archives, + archive_name_format, + feature_available, + expected_result, ): flexmock(module.feature).should_receive('available').and_return(feature_available) flexmock(module).should_receive('get_default_archive_name_format').and_return( - module.DEFAULT_ARCHIVE_NAME_FORMAT_WITHOUT_SERIES + module.DEFAULT_ARCHIVE_NAME_FORMAT_WITHOUT_SERIES, ) assert ( module.make_match_archives_flags( - match_archives, archive_name_format, local_borg_version=flexmock() + match_archives, + archive_name_format, + local_borg_version=flexmock(), ) == expected_result ) @@ -247,7 +256,8 @@ def test_warn_for_aggressive_archive_flags_with_glob_archives_and_zero_archives_ flexmock(module.logger).should_receive('warning').twice() module.warn_for_aggressive_archive_flags( - ('borg', '--glob-archives', 'foo*'), '{"archives": []}' + ('borg', '--glob-archives', 'foo*'), + '{"archives": []}', ) @@ -255,7 +265,8 @@ def test_warn_for_aggressive_archive_flags_with_match_archives_and_zero_archives flexmock(module.logger).should_receive('warning').twice() module.warn_for_aggressive_archive_flags( - ('borg', '--match-archives', 'foo*'), '{"archives": []}' + ('borg', '--match-archives', 'foo*'), + '{"archives": []}', ) @@ -263,7 +274,8 @@ def test_warn_for_aggressive_archive_flags_with_glob_archives_and_one_archive_do flexmock(module.logger).should_receive('warning').never() module.warn_for_aggressive_archive_flags( - ('borg', '--glob-archives', 'foo*'), '{"archives": [{"name": "foo"]}' + ('borg', '--glob-archives', 'foo*'), + '{"archives": [{"name": "foo"]}', ) @@ -271,7 +283,8 @@ def test_warn_for_aggressive_archive_flags_with_match_archives_and_one_archive_d flexmock(module.logger).should_receive('warning').never() module.warn_for_aggressive_archive_flags( - ('borg', '--match-archives', 'foo*'), '{"archives": [{"name": "foo"]}' + ('borg', '--match-archives', 'foo*'), + '{"archives": [{"name": "foo"]}', ) @@ -305,7 +318,8 @@ def test_omit_flag_without_flag_present_passes_through_arguments(): def test_omit_flag_and_value_removes_flag_and_value_from_arguments(): assert module.omit_flag_and_value( - ('borg', 'create', '--flag', 'value', '--other'), '--flag' + ('borg', 'create', '--flag', 'value', '--other'), + '--flag', ) == ( 'borg', 'create', @@ -343,7 +357,7 @@ def test_make_exclude_flags_does_not_include_exclude_caches_when_false_in_config def test_make_exclude_flags_includes_exclude_if_present_when_in_config(): exclude_flags = module.make_exclude_flags( - config={'exclude_if_present': ['exclude_me', 'also_me']} + config={'exclude_if_present': ['exclude_me', 'also_me']}, ) assert exclude_flags == ( diff --git a/tests/unit/borg/test_import_key.py b/tests/unit/borg/test_import_key.py index ab60d41d..f33f9a61 100644 --- a/tests/unit/borg/test_import_key.py +++ b/tests/unit/borg/test_import_key.py @@ -9,9 +9,11 @@ from ..test_verbosity import insert_logging_mock def insert_execute_command_mock( - command, input_file=module.DO_NOT_CAPTURE, working_directory=None, borg_exit_codes=None + command, + input_file=module.DO_NOT_CAPTURE, + working_directory=None, + borg_exit_codes=None, ): - flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( working_directory, @@ -262,7 +264,7 @@ def test_import_key_calls_borg_with_path_argument_and_working_directory(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.os.path).should_receive('exists').with_args('/working/dir/source').and_return( - True + True, ).once() insert_execute_command_mock( ('borg', 'key', 'import', 'repo', 'source'), diff --git a/tests/unit/borg/test_info.py b/tests/unit/borg/test_info.py index e06fe961..fd0ab8d8 100644 --- a/tests/unit/borg/test_info.py +++ b/tests/unit/borg/test_info.py @@ -11,7 +11,9 @@ from ..test_verbosity import insert_logging_mock def test_make_info_command_constructs_borg_info_command(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -32,7 +34,9 @@ def test_make_info_command_constructs_borg_info_command(): def test_make_info_command_with_log_info_passes_through_to_command(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -54,7 +58,9 @@ def test_make_info_command_with_log_info_passes_through_to_command(): def test_make_info_command_with_log_info_and_json_omits_borg_logging_flags(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -76,7 +82,9 @@ def test_make_info_command_with_log_info_and_json_omits_borg_logging_flags(): def test_make_info_command_with_log_debug_passes_through_to_command(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -98,7 +106,9 @@ def test_make_info_command_with_log_debug_passes_through_to_command(): def test_make_info_command_with_log_debug_and_json_omits_borg_logging_flags(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -119,7 +129,9 @@ def test_make_info_command_with_log_debug_and_json_omits_borg_logging_flags(): def test_make_info_command_with_json_passes_through_to_command(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -140,7 +152,9 @@ def test_make_info_command_with_json_passes_through_to_command(): def test_make_info_command_with_archive_uses_match_archives_flags(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - 'archive', None, '2.3.4' + 'archive', + None, + '2.3.4', ).and_return(('--match-archives', 'archive')) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -161,7 +175,9 @@ def test_make_info_command_with_archive_uses_match_archives_flags(): def test_make_info_command_with_local_path_passes_through_to_command(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -176,16 +192,19 @@ def test_make_info_command_with_local_path_passes_through_to_command(): remote_path=None, ) - command == ('borg1', 'info', '--repo', 'repo') + assert command == ('borg1', 'info', '--repo', 'repo') def test_make_info_command_with_remote_path_passes_through_to_command(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').with_args( - 'remote-path', 'borg1' + 'remote-path', + 'borg1', ).and_return(('--remote-path', 'borg1')) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -205,10 +224,12 @@ def test_make_info_command_with_remote_path_passes_through_to_command(): def test_make_info_command_with_umask_passes_through_to_command(): flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -229,10 +250,12 @@ def test_make_info_command_with_umask_passes_through_to_command(): def test_make_info_command_with_log_json_passes_through_to_command(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').with_args('log-json', True).and_return( - ('--log-json',) + ('--log-json',), ) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -253,10 +276,12 @@ def test_make_info_command_with_log_json_passes_through_to_command(): def test_make_info_command_with_lock_wait_passes_through_to_command(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').with_args('lock-wait', 5).and_return( - ('--lock-wait', '5') + ('--lock-wait', '5'), ) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -278,10 +303,13 @@ def test_make_info_command_with_lock_wait_passes_through_to_command(): def test_make_info_command_transforms_prefix_into_match_archives_flags(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').with_args( - 'match-archives', 'sh:foo*' + 'match-archives', + 'sh:foo*', ).and_return(('--match-archives', 'sh:foo*')) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -302,17 +330,20 @@ def test_make_info_command_transforms_prefix_into_match_archives_flags(): def test_make_info_command_prefers_prefix_over_archive_name_format(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').with_args( - 'match-archives', 'sh:foo*' + 'match-archives', + 'sh:foo*', ).and_return(('--match-archives', 'sh:foo*')) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) command = module.make_info_command( repository_path='repo', - config={'archive_name_format': 'bar-{now}'}, # noqa: FS003 + config={'archive_name_format': 'bar-{now}'}, local_borg_version='2.3.4', global_arguments=flexmock(), info_arguments=flexmock(archive=None, json=False, prefix='foo'), @@ -326,14 +357,16 @@ def test_make_info_command_prefers_prefix_over_archive_name_format(): def test_make_info_command_transforms_archive_name_format_into_match_archives_flags(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, 'bar-{now}', '2.3.4' # noqa: FS003 + None, + 'bar-{now}', + '2.3.4', ).and_return(('--match-archives', 'sh:bar-*')) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) command = module.make_info_command( repository_path='repo', - config={'archive_name_format': 'bar-{now}'}, # noqa: FS003 + config={'archive_name_format': 'bar-{now}'}, local_borg_version='2.3.4', global_arguments=flexmock(), info_arguments=flexmock(archive=None, json=False, prefix=None, match_archives=None), @@ -347,7 +380,9 @@ def test_make_info_command_transforms_archive_name_format_into_match_archives_fl def test_make_info_command_with_match_archives_option_passes_through_to_command(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - 'sh:foo-*', 'bar-{now}', '2.3.4' # noqa: FS003 + 'sh:foo-*', + 'bar-{now}', + '2.3.4', ).and_return(('--match-archives', 'sh:foo-*')) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -356,7 +391,7 @@ def test_make_info_command_with_match_archives_option_passes_through_to_command( command = module.make_info_command( repository_path='repo', config={ - 'archive_name_format': 'bar-{now}', # noqa: FS003 + 'archive_name_format': 'bar-{now}', 'match_archives': 'sh:foo-*', }, local_borg_version='2.3.4', @@ -372,7 +407,9 @@ def test_make_info_command_with_match_archives_option_passes_through_to_command( def test_make_info_command_with_match_archives_flag_passes_through_to_command(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - 'sh:foo-*', 'bar-{now}', '2.3.4' # noqa: FS003 + 'sh:foo-*', + 'bar-{now}', + '2.3.4', ).and_return(('--match-archives', 'sh:foo-*')) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -380,7 +417,7 @@ def test_make_info_command_with_match_archives_flag_passes_through_to_command(): command = module.make_info_command( repository_path='repo', - config={'archive_name_format': 'bar-{now}', 'match_archives': 'sh:foo-*'}, # noqa: FS003 + config={'archive_name_format': 'bar-{now}', 'match_archives': 'sh:foo-*'}, local_borg_version='2.3.4', global_arguments=flexmock(), info_arguments=flexmock(archive=None, json=False, prefix=None, match_archives='sh:foo-*'), @@ -396,10 +433,12 @@ def test_make_info_command_passes_arguments_through_to_command(argument_name): flag_name = f"--{argument_name.replace('_', ' ')}" flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return( - (flag_name, 'value') + (flag_name, 'value'), ) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.environment).should_receive('make_environment') @@ -410,7 +449,11 @@ def test_make_info_command_passes_arguments_through_to_command(argument_name): local_borg_version='2.3.4', global_arguments=flexmock(), info_arguments=flexmock( - archive=None, json=False, prefix=None, match_archives=None, **{argument_name: 'value'} + archive=None, + json=False, + prefix=None, + match_archives=None, + **{argument_name: 'value'}, ), local_path='borg', remote_path=None, @@ -422,10 +465,12 @@ def test_make_info_command_passes_arguments_through_to_command(argument_name): def test_make_info_command_with_date_based_matching_passes_through_to_command(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '2.3.4' + None, + None, + '2.3.4', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return( - ('--newer', '1d', '--newest', '1y', '--older', '1m', '--oldest', '1w') + ('--newer', '1d', '--newest', '1y', '--older', '1m', '--oldest', '1w'), ) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) info_arguments = flexmock( diff --git a/tests/unit/borg/test_list.py b/tests/unit/borg/test_list.py index 7d7d7afc..4f6ec0b5 100644 --- a/tests/unit/borg/test_list.py +++ b/tests/unit/borg/test_list.py @@ -95,7 +95,7 @@ def test_make_list_command_includes_json(): def test_make_list_command_includes_log_json(): flexmock(module.flags).should_receive('make_flags').and_return(()).and_return(()).and_return( - ('--log-json',) + ('--log-json',), ) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -113,7 +113,7 @@ def test_make_list_command_includes_log_json(): def test_make_list_command_includes_lock_wait(): flexmock(module.flags).should_receive('make_flags').and_return(()).and_return(()).and_return( - ('--lock-wait', '5') + ('--lock-wait', '5'), ) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -133,7 +133,7 @@ def test_make_list_command_includes_archive(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) command = module.make_list_command( @@ -151,7 +151,7 @@ def test_make_list_command_includes_archive_and_path(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) command = module.make_list_command( @@ -185,10 +185,11 @@ def test_make_list_command_includes_local_path(): def test_make_list_command_includes_remote_path(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').with_args( - 'remote-path', 'borg2' + 'remote-path', + 'borg2', ).and_return(('--remote-path', 'borg2')) flexmock(module.flags).should_receive('make_flags').with_args('log-json', True).and_return( - ('--log-json') + ('--log-json'), ) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -207,7 +208,7 @@ def test_make_list_command_includes_remote_path(): def test_make_list_command_includes_umask(): flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -256,7 +257,7 @@ def test_make_list_command_includes_short(): def test_make_list_command_includes_additional_flags(argument_name): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return( - (f"--{argument_name.replace('_', '-')}", 'value') + (f"--{argument_name.replace('_', '-')}", 'value'), ) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -502,7 +503,7 @@ def test_list_archive_calls_borg_multiple_times_with_find_paths(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.repo_list).should_receive('make_repo_list_command').and_return( - ('borg', 'list', 'repo') + ('borg', 'list', 'repo'), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( @@ -513,12 +514,12 @@ def test_list_archive_calls_borg_multiple_times_with_find_paths(): borg_exit_codes=None, ).and_return('archive1\narchive2').once() flexmock(module).should_receive('make_list_command').and_return( - ('borg', 'list', 'repo::archive1') + ('borg', 'list', 'repo::archive1'), ).and_return(('borg', 'list', 'repo::archive2')) flexmock(module).should_receive('make_find_paths').and_return(glob_paths) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'list', 'repo::archive1') + glob_paths, + ('borg', 'list', 'repo::archive1', *glob_paths), output_log_level=module.borgmatic.logger.ANSWER, environment=None, working_directory=None, @@ -526,7 +527,7 @@ def test_list_archive_calls_borg_multiple_times_with_find_paths(): borg_exit_codes=None, ).once() flexmock(module).should_receive('execute_command').with_args( - ('borg', 'list', 'repo::archive2') + glob_paths, + ('borg', 'list', 'repo::archive2', *glob_paths), output_log_level=module.borgmatic.logger.ANSWER, environment=None, working_directory=None, @@ -677,17 +678,22 @@ def test_list_archive_with_archive_ignores_archive_filter_flag( 'first': None, 'last': None, } - altered_filter_flags = {**default_filter_flags, **{archive_filter_flag: 'foo'}} + altered_filter_flags = {**default_filter_flags, **{archive_filter_flag: 'foo'}} # noqa: PIE800 flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.REPO_LIST, '1.2.3' + module.feature.Feature.REPO_LIST, + '1.2.3', ).and_return(False) flexmock(module).should_receive('make_list_command').with_args( repository_path='repo', config={}, local_borg_version='1.2.3', list_arguments=argparse.Namespace( - archive='archive', paths=None, json=False, find_paths=None, **default_filter_flags + archive='archive', + paths=None, + json=False, + find_paths=None, + **default_filter_flags, ), global_arguments=global_arguments, local_path='borg', @@ -710,7 +716,11 @@ def test_list_archive_with_archive_ignores_archive_filter_flag( config={}, local_borg_version='1.2.3', list_arguments=argparse.Namespace( - archive='archive', paths=None, json=False, find_paths=None, **altered_filter_flags + archive='archive', + paths=None, + json=False, + find_paths=None, + **altered_filter_flags, ), global_arguments=global_arguments, ) @@ -739,7 +749,7 @@ def test_list_archive_with_find_paths_allows_archive_filter_flag_but_only_passes 'first': None, 'last': None, } - altered_filter_flags = {**default_filter_flags, **{archive_filter_flag: 'foo'}} + altered_filter_flags = {**default_filter_flags, **{archive_filter_flag: 'foo'}} # noqa: PIE800 glob_paths = ('**/*foo.txt*/**',) global_arguments = flexmock() flexmock(module.feature).should_receive('available').and_return(True) @@ -749,7 +759,11 @@ def test_list_archive_with_find_paths_allows_archive_filter_flag_but_only_passes config={}, local_borg_version='1.2.3', repo_list_arguments=argparse.Namespace( - repository='repo', short=True, format=None, json=None, **altered_filter_flags + repository='repo', + short=True, + format=None, + json=None, + **altered_filter_flags, ), global_arguments=global_arguments, local_path='borg', @@ -806,7 +820,7 @@ def test_list_archive_with_find_paths_allows_archive_filter_flag_but_only_passes flexmock(module).should_receive('make_find_paths').and_return(glob_paths) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'list', '--repo', 'repo', 'archive1') + glob_paths, + ('borg', 'list', '--repo', 'repo', 'archive1', *glob_paths), output_log_level=module.borgmatic.logger.ANSWER, environment=None, working_directory=None, @@ -814,7 +828,7 @@ def test_list_archive_with_find_paths_allows_archive_filter_flag_but_only_passes borg_exit_codes=None, ).once() flexmock(module).should_receive('execute_command').with_args( - ('borg', 'list', '--repo', 'repo', 'archive2') + glob_paths, + ('borg', 'list', '--repo', 'repo', 'archive2', *glob_paths), output_log_level=module.borgmatic.logger.ANSWER, environment=None, working_directory=None, diff --git a/tests/unit/borg/test_mount.py b/tests/unit/borg/test_mount.py index 0177d3b4..501e8851 100644 --- a/tests/unit/borg/test_mount.py +++ b/tests/unit/borg/test_mount.py @@ -43,10 +43,10 @@ def test_mount_archive_with_borg_features_calls_borg_with_repository_and_match_a ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock( - ('borg', 'mount', '--repo', 'repo', '--match-archives', 'archive', '/mnt') + ('borg', 'mount', '--repo', 'repo', '--match-archives', 'archive', '/mnt'), ) mount_arguments = flexmock(mount_point='/mnt', options=None, paths=None, foreground=False) @@ -63,7 +63,7 @@ def test_mount_archive_with_borg_features_calls_borg_with_repository_and_match_a def test_mount_archive_without_archive_calls_borg_with_repository_flags_only(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock(('borg', 'mount', 'repo::archive', '/mnt')) @@ -81,12 +81,15 @@ def test_mount_archive_without_archive_calls_borg_with_repository_flags_only(): def test_mount_archive_calls_borg_with_path_flags(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock(('borg', 'mount', 'repo::archive', '/mnt', 'path1', 'path2')) mount_arguments = flexmock( - mount_point='/mnt', options=None, paths=['path1', 'path2'], foreground=False + mount_point='/mnt', + options=None, + paths=['path1', 'path2'], + foreground=False, ) module.mount_archive( repository_path='repo', @@ -101,7 +104,7 @@ def test_mount_archive_calls_borg_with_path_flags(): def test_mount_archive_calls_borg_with_local_path(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock(('borg1', 'mount', 'repo::archive', '/mnt')) @@ -120,7 +123,7 @@ def test_mount_archive_calls_borg_with_local_path(): def test_mount_archive_calls_borg_using_exit_codes(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) borg_exit_codes = flexmock() insert_execute_command_mock( @@ -142,10 +145,10 @@ def test_mount_archive_calls_borg_using_exit_codes(): def test_mount_archive_calls_borg_with_remote_path_flags(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock( - ('borg', 'mount', '--remote-path', 'borg1', 'repo::archive', '/mnt') + ('borg', 'mount', '--remote-path', 'borg1', 'repo::archive', '/mnt'), ) mount_arguments = flexmock(mount_point='/mnt', options=None, paths=None, foreground=False) @@ -163,7 +166,7 @@ def test_mount_archive_calls_borg_with_remote_path_flags(): def test_mount_archive_calls_borg_with_umask_flags(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock(('borg', 'mount', '--umask', '0770', 'repo::archive', '/mnt')) @@ -181,7 +184,7 @@ def test_mount_archive_calls_borg_with_umask_flags(): def test_mount_archive_calls_borg_with_log_json_flags(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock(('borg', 'mount', '--log-json', 'repo::archive', '/mnt')) @@ -199,7 +202,7 @@ def test_mount_archive_calls_borg_with_log_json_flags(): def test_mount_archive_calls_borg_with_lock_wait_flags(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock(('borg', 'mount', '--lock-wait', '5', 'repo::archive', '/mnt')) @@ -217,7 +220,7 @@ def test_mount_archive_calls_borg_with_lock_wait_flags(): def test_mount_archive_with_log_info_calls_borg_with_info_parameter(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock(('borg', 'mount', '--info', 'repo::archive', '/mnt')) insert_logging_mock(logging.INFO) @@ -236,7 +239,7 @@ def test_mount_archive_with_log_info_calls_borg_with_info_parameter(): def test_mount_archive_with_log_debug_calls_borg_with_debug_flags(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock(('borg', 'mount', '--debug', '--show-rc', 'repo::archive', '/mnt')) insert_logging_mock(logging.DEBUG) @@ -255,7 +258,7 @@ def test_mount_archive_with_log_debug_calls_borg_with_debug_flags(): def test_mount_archive_calls_borg_with_foreground_parameter(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -282,12 +285,15 @@ def test_mount_archive_calls_borg_with_foreground_parameter(): def test_mount_archive_calls_borg_with_options_flags(): flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_repository_archive_flags').and_return( - ('repo::archive',) + ('repo::archive',), ) insert_execute_command_mock(('borg', 'mount', '-o', 'super_mount', 'repo::archive', '/mnt')) mount_arguments = flexmock( - mount_point='/mnt', options='super_mount', paths=None, foreground=False + mount_point='/mnt', + options='super_mount', + paths=None, + foreground=False, ) module.mount_archive( repository_path='repo', @@ -314,7 +320,7 @@ def test_mount_archive_with_date_based_matching_calls_borg_with_date_based_flags '1w', '--match-archives', None, - ) + ), ) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.environment).should_receive('make_environment') diff --git a/tests/unit/borg/test_passcommand.py b/tests/unit/borg/test_passcommand.py index a6caea2e..c79c3b4d 100644 --- a/tests/unit/borg/test_passcommand.py +++ b/tests/unit/borg/test_passcommand.py @@ -6,7 +6,7 @@ from borgmatic.borg import passcommand as module def test_run_passcommand_does_not_raise(): module.run_passcommand.cache_clear() flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return('passphrase') assert module.run_passcommand('passcommand', working_directory=None) == 'passphrase' @@ -15,10 +15,10 @@ def test_run_passcommand_does_not_raise(): def test_get_passphrase_from_passcommand_with_configured_passcommand_runs_it(): module.run_passcommand.cache_clear() flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - '/working' + '/working', ) flexmock(module).should_receive('run_passcommand').with_args('command', '/working').and_return( - 'passphrase' + 'passphrase', ).once() assert ( @@ -38,7 +38,7 @@ def test_get_passphrase_from_passcommand_without_configured_passcommand_bails(): def test_run_passcommand_caches_passcommand_after_first_call(): module.run_passcommand.cache_clear() flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return('passphrase').once() assert module.run_passcommand('passcommand', working_directory=None) == 'passphrase' diff --git a/tests/unit/borg/test_prune.py b/tests/unit/borg/test_prune.py index 8e456293..49240789 100644 --- a/tests/unit/borg/test_prune.py +++ b/tests/unit/borg/test_prune.py @@ -8,7 +8,10 @@ from ..test_verbosity import insert_logging_mock def insert_execute_command_mock( - prune_command, output_log_level, working_directory=None, borg_exit_codes=None + prune_command, + output_log_level, + working_directory=None, + borg_exit_codes=None, ): flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( @@ -37,7 +40,9 @@ def test_make_prune_flags_returns_flags_from_config(): flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) result = module.make_prune_flags( - config, flexmock(match_archives=None), local_borg_version='1.2.3' + config, + flexmock(match_archives=None), + local_borg_version='1.2.3', ) assert result == BASE_PRUNE_FLAGS @@ -52,7 +57,9 @@ def test_make_prune_flags_with_keep_13weekly_and_keep_3monthly(): flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) result = module.make_prune_flags( - config, flexmock(match_archives=None), local_borg_version='1.2.3' + config, + flexmock(match_archives=None), + local_borg_version='1.2.3', ) expected = ( @@ -68,20 +75,22 @@ def test_make_prune_flags_with_keep_13weekly_and_keep_3monthly(): def test_make_prune_flags_accepts_prefix_with_placeholders(): config = { 'keep_daily': 1, - 'prefix': 'Documents_{hostname}-{now}', # noqa: FS003 + 'prefix': 'Documents_{hostname}-{now}', } flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) result = module.make_prune_flags( - config, flexmock(match_archives=None), local_borg_version='1.2.3' + config, + flexmock(match_archives=None), + local_borg_version='1.2.3', ) expected = ( '--keep-daily', '1', '--match-archives', - 'sh:Documents_{hostname}-{now}*', # noqa: FS003 + 'sh:Documents_{hostname}-{now}*', ) assert result == expected @@ -90,20 +99,22 @@ def test_make_prune_flags_accepts_prefix_with_placeholders(): def test_make_prune_flags_with_prefix_without_borg_features_uses_glob_archives(): config = { 'keep_daily': 1, - 'prefix': 'Documents_{hostname}-{now}', # noqa: FS003 + 'prefix': 'Documents_{hostname}-{now}', } flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) result = module.make_prune_flags( - config, flexmock(match_archives=None), local_borg_version='1.2.3' + config, + flexmock(match_archives=None), + local_borg_version='1.2.3', ) expected = ( '--keep-daily', '1', '--glob-archives', - 'Documents_{hostname}-{now}*', # noqa: FS003 + 'Documents_{hostname}-{now}*', ) assert result == expected @@ -111,7 +122,7 @@ def test_make_prune_flags_with_prefix_without_borg_features_uses_glob_archives() def test_make_prune_flags_prefers_prefix_to_archive_name_format(): config = { - 'archive_name_format': 'bar-{now}', # noqa: FS003 + 'archive_name_format': 'bar-{now}', 'keep_daily': 1, 'prefix': 'bar-', } @@ -119,14 +130,16 @@ def test_make_prune_flags_prefers_prefix_to_archive_name_format(): flexmock(module.flags).should_receive('make_match_archives_flags').never() result = module.make_prune_flags( - config, flexmock(match_archives=None), local_borg_version='1.2.3' + config, + flexmock(match_archives=None), + local_borg_version='1.2.3', ) expected = ( '--keep-daily', '1', '--match-archives', - 'sh:bar-*', # noqa: FS003 + 'sh:bar-*', ) assert result == expected @@ -134,24 +147,28 @@ def test_make_prune_flags_prefers_prefix_to_archive_name_format(): def test_make_prune_flags_without_prefix_uses_archive_name_format_instead(): config = { - 'archive_name_format': 'bar-{now}', # noqa: FS003 + 'archive_name_format': 'bar-{now}', 'keep_daily': 1, 'prefix': None, } flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, 'bar-{now}', '1.2.3' # noqa: FS003 + None, + 'bar-{now}', + '1.2.3', ).and_return(('--match-archives', 'sh:bar-*')).once() result = module.make_prune_flags( - config, flexmock(match_archives=None), local_borg_version='1.2.3' + config, + flexmock(match_archives=None), + local_borg_version='1.2.3', ) expected = ( '--keep-daily', '1', '--match-archives', - 'sh:bar-*', # noqa: FS003 + 'sh:bar-*', ) assert result == expected @@ -159,25 +176,29 @@ def test_make_prune_flags_without_prefix_uses_archive_name_format_instead(): def test_make_prune_flags_without_prefix_uses_match_archives_option(): config = { - 'archive_name_format': 'bar-{now}', # noqa: FS003 + 'archive_name_format': 'bar-{now}', 'match_archives': 'foo*', 'keep_daily': 1, 'prefix': None, } flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - 'foo*', 'bar-{now}', '1.2.3' # noqa: FS003 + 'foo*', + 'bar-{now}', + '1.2.3', ).and_return(('--match-archives', 'sh:bar-*')).once() result = module.make_prune_flags( - config, flexmock(match_archives=None), local_borg_version='1.2.3' + config, + flexmock(match_archives=None), + local_borg_version='1.2.3', ) expected = ( '--keep-daily', '1', '--match-archives', - 'sh:bar-*', # noqa: FS003 + 'sh:bar-*', ) assert result == expected @@ -192,7 +213,9 @@ def test_make_prune_flags_ignores_keep_exclude_tags_in_config(): flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) result = module.make_prune_flags( - config, flexmock(match_archives=None), local_borg_version='1.2.3' + config, + flexmock(match_archives=None), + local_borg_version='1.2.3', ) assert result == ('--keep-daily', '1') @@ -207,9 +230,10 @@ def test_prune_archives_calls_borg_with_flags(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) - insert_execute_command_mock(PRUNE_COMMAND + ('repo',), logging.INFO) + insert_execute_command_mock((*PRUNE_COMMAND, 'repo'), logging.INFO) prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( @@ -228,9 +252,10 @@ def test_prune_archives_with_log_info_calls_borg_with_info_flag(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) - insert_execute_command_mock(PRUNE_COMMAND + ('--info', 'repo'), logging.INFO) + insert_execute_command_mock((*PRUNE_COMMAND, '--info', 'repo'), logging.INFO) insert_logging_mock(logging.INFO) prune_arguments = flexmock(statistics=False, list_details=False) @@ -250,9 +275,10 @@ def test_prune_archives_with_log_debug_calls_borg_with_debug_flag(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) - insert_execute_command_mock(PRUNE_COMMAND + ('--debug', '--show-rc', 'repo'), logging.INFO) + insert_execute_command_mock((*PRUNE_COMMAND, '--debug', '--show-rc', 'repo'), logging.INFO) insert_logging_mock(logging.DEBUG) prune_arguments = flexmock(statistics=False, list_details=False) @@ -272,9 +298,10 @@ def test_prune_archives_with_dry_run_calls_borg_with_dry_run_flag(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) - insert_execute_command_mock(PRUNE_COMMAND + ('--dry-run', 'repo'), logging.INFO) + insert_execute_command_mock((*PRUNE_COMMAND, '--dry-run', 'repo'), logging.INFO) prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( @@ -293,9 +320,10 @@ def test_prune_archives_with_local_path_calls_borg_via_local_path(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) - insert_execute_command_mock(('borg1',) + PRUNE_COMMAND[1:] + ('repo',), logging.INFO) + insert_execute_command_mock(('borg1', *PRUNE_COMMAND[1:], 'repo'), logging.INFO) prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( @@ -315,11 +343,12 @@ def test_prune_archives_with_exit_codes_calls_borg_using_them(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) borg_exit_codes = flexmock() insert_execute_command_mock( - ('borg',) + PRUNE_COMMAND[1:] + ('repo',), + ('borg', *PRUNE_COMMAND[1:], 'repo'), logging.INFO, borg_exit_codes=borg_exit_codes, ) @@ -341,9 +370,10 @@ def test_prune_archives_with_remote_path_calls_borg_with_remote_path_flags(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) - insert_execute_command_mock(PRUNE_COMMAND + ('--remote-path', 'borg1', 'repo'), logging.INFO) + insert_execute_command_mock((*PRUNE_COMMAND, '--remote-path', 'borg1', 'repo'), logging.INFO) prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( @@ -363,9 +393,10 @@ def test_prune_archives_with_stats_config_calls_borg_with_stats_flag(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) - insert_execute_command_mock(PRUNE_COMMAND + ('--stats', 'repo'), module.borgmatic.logger.ANSWER) + insert_execute_command_mock((*PRUNE_COMMAND, '--stats', 'repo'), module.borgmatic.logger.ANSWER) prune_arguments = flexmock(statistics=None, list_details=False) module.prune_archives( @@ -384,9 +415,10 @@ def test_prune_archives_with_list_config_calls_borg_with_list_flag(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) - insert_execute_command_mock(PRUNE_COMMAND + ('--list', 'repo'), module.borgmatic.logger.ANSWER) + insert_execute_command_mock((*PRUNE_COMMAND, '--list', 'repo'), module.borgmatic.logger.ANSWER) prune_arguments = flexmock(statistics=False, list_details=None) module.prune_archives( @@ -406,9 +438,10 @@ def test_prune_archives_with_umask_calls_borg_with_umask_flags(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) - insert_execute_command_mock(PRUNE_COMMAND + ('--umask', '077', 'repo'), logging.INFO) + insert_execute_command_mock((*PRUNE_COMMAND, '--umask', '077', 'repo'), logging.INFO) prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( @@ -427,9 +460,10 @@ def test_prune_archives_with_log_json_calls_borg_with_log_json_flag(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) - insert_execute_command_mock(PRUNE_COMMAND + ('--log-json', 'repo'), logging.INFO) + insert_execute_command_mock((*PRUNE_COMMAND, '--log-json', 'repo'), logging.INFO) prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( @@ -449,9 +483,10 @@ def test_prune_archives_with_lock_wait_calls_borg_with_lock_wait_flags(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) - insert_execute_command_mock(PRUNE_COMMAND + ('--lock-wait', '5', 'repo'), logging.INFO) + insert_execute_command_mock((*PRUNE_COMMAND, '--lock-wait', '5', 'repo'), logging.INFO) prune_arguments = flexmock(statistics=False, list_details=False) module.prune_archives( @@ -470,10 +505,12 @@ def test_prune_archives_with_extra_borg_options_calls_borg_with_extra_options(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) insert_execute_command_mock( - PRUNE_COMMAND + ('--extra', '--options', 'value with space', 'repo'), logging.INFO + (*PRUNE_COMMAND, '--extra', '--options', 'value with space', 'repo'), + logging.INFO, ) prune_arguments = flexmock(statistics=False, list_details=False) @@ -505,11 +542,12 @@ def test_prune_archives_with_date_based_matching_calls_borg_with_date_based_flag '1w', '--match-archives', None, - ) + ), ) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -544,7 +582,12 @@ def test_prune_archives_with_date_based_matching_calls_borg_with_date_based_flag ) prune_arguments = flexmock( - statistics=False, list_details=False, newer='1d', newest='1y', older='1m', oldest='1w' + statistics=False, + list_details=False, + newer='1d', + newest='1y', + older='1m', + oldest='1w', ) module.prune_archives( dry_run=False, @@ -562,10 +605,13 @@ def test_prune_archives_calls_borg_with_working_directory(): flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '1.2.3' + module.feature.Feature.NO_PRUNE_STATS, + '1.2.3', ).and_return(False) insert_execute_command_mock( - PRUNE_COMMAND + ('repo',), logging.INFO, working_directory='/working/dir' + (*PRUNE_COMMAND, 'repo'), + logging.INFO, + working_directory='/working/dir', ) prune_arguments = flexmock(statistics=False, list_details=False) @@ -585,9 +631,10 @@ def test_prune_archives_calls_borg_without_stats_when_feature_is_not_available() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.feature).should_receive('available').with_args( - module.feature.Feature.NO_PRUNE_STATS, '2.0.0b10' + module.feature.Feature.NO_PRUNE_STATS, + '2.0.0b10', ).and_return(True) - insert_execute_command_mock(PRUNE_COMMAND + ('repo',), logging.ANSWER) + insert_execute_command_mock((*PRUNE_COMMAND, 'repo'), logging.ANSWER) prune_arguments = flexmock(statistics=True, list_details=False) module.prune_archives( diff --git a/tests/unit/borg/test_recreate.py b/tests/unit/borg/test_recreate.py index 96a7aafd..8df94a4c 100644 --- a/tests/unit/borg/test_recreate.py +++ b/tests/unit/borg/test_recreate.py @@ -27,12 +27,12 @@ def test_recreate_archive_dry_run_skips_execution(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.borgmatic.execute).should_receive('execute_command').never() @@ -65,12 +65,12 @@ def test_recreate_calls_borg_with_required_flags(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock(('borg', 'recreate', '--repo', 'repo')) @@ -100,12 +100,12 @@ def test_recreate_with_remote_path(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock(('borg', 'recreate', '--remote-path', 'borg1', '--repo', 'repo')) @@ -135,12 +135,12 @@ def test_recreate_with_lock_wait(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock(('borg', 'recreate', '--lock-wait', '5', '--repo', 'repo')) @@ -169,12 +169,12 @@ def test_recreate_with_log_info(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock(('borg', 'recreate', '--info', '--repo', 'repo')) @@ -205,12 +205,12 @@ def test_recreate_with_log_debug(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock(('borg', 'recreate', '--debug', '--show-rc', '--repo', 'repo')) insert_logging_mock(logging.DEBUG) @@ -240,12 +240,12 @@ def test_recreate_with_log_json(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock(('borg', 'recreate', '--log-json', '--repo', 'repo')) @@ -273,18 +273,18 @@ def test_recreate_with_list_config_calls_borg_with_list_flag(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return( - 'AME+-' + 'AME+-', ) insert_execute_command_mock( - ('borg', 'recreate', '--list', '--filter', 'AME+-', '--repo', 'repo') + ('borg', 'recreate', '--list', '--filter', 'AME+-', '--repo', 'repo'), ) module.recreate_archive( @@ -311,17 +311,17 @@ def test_recreate_with_patterns_from_flag(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) mock_patterns_file = flexmock(name='patterns_file') flexmock(module).should_receive('write_patterns_file').and_return(mock_patterns_file) insert_execute_command_mock( - ('borg', 'recreate', '--patterns-from', 'patterns_file', '--repo', 'repo') + ('borg', 'recreate', '--patterns-from', 'patterns_file', '--repo', 'repo'), ) module.recreate_archive( @@ -348,15 +348,15 @@ def test_recreate_with_exclude_flags(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.borgmatic.borg.flags).should_receive('make_exclude_flags').and_return( - ('--exclude', 'pattern') + ('--exclude', 'pattern'), ) insert_execute_command_mock(('borg', 'recreate', '--exclude', 'pattern', '--repo', 'repo')) @@ -385,12 +385,12 @@ def test_recreate_with_target_flag(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock(('borg', 'recreate', '--target', 'new-archive', '--repo', 'repo')) @@ -419,15 +419,15 @@ def test_recreate_with_comment_flag(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock( - ('borg', 'recreate', '--comment', shlex.quote('This is a test comment'), '--repo', 'repo') + ('borg', 'recreate', '--comment', shlex.quote('This is a test comment'), '--repo', 'repo'), ) module.recreate_archive( @@ -455,15 +455,15 @@ def test_recreate_with_timestamp_flag(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock( - ('borg', 'recreate', '--timestamp', '2023-10-01T12:00:00', '--repo', 'repo') + ('borg', 'recreate', '--timestamp', '2023-10-01T12:00:00', '--repo', 'repo'), ) module.recreate_archive( @@ -491,12 +491,12 @@ def test_recreate_with_compression_flag(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock(('borg', 'recreate', '--compression', 'lz4', '--repo', 'repo')) @@ -525,15 +525,15 @@ def test_recreate_with_chunker_params_flag(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock( - ('borg', 'recreate', '--chunker-params', '19,23,21,4095', '--repo', 'repo') + ('borg', 'recreate', '--chunker-params', '19,23,21,4095', '--repo', 'repo'), ) module.recreate_archive( @@ -561,12 +561,12 @@ def test_recreate_with_recompress_flag(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock(('borg', 'recreate', '--recompress', 'always', '--repo', 'repo')) @@ -595,12 +595,12 @@ def test_recreate_with_match_archives_star(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock(('borg', 'recreate', '--repo', 'repo')) @@ -629,12 +629,12 @@ def test_recreate_with_match_archives_regex(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock(('borg', 'recreate', '--repo', 'repo')) @@ -663,12 +663,12 @@ def test_recreate_with_match_archives_shell(): flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return( ( '--repo', 'repo', - ) + ), ) insert_execute_command_mock(('borg', 'recreate', '--repo', 'repo')) @@ -695,11 +695,13 @@ def test_recreate_with_match_archives_and_feature_available_calls_borg_with_matc flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('') flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').with_args( - 'foo-*', None, '1.2.3' + 'foo-*', + None, + '1.2.3', ).and_return(('--match-archives', 'foo-*')) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('--repo', 'repo') + ('--repo', 'repo'), ) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_archive_flags').never() insert_execute_command_mock(('borg', 'recreate', '--repo', 'repo', '--match-archives', 'foo-*')) @@ -727,15 +729,17 @@ def test_recreate_with_archives_flag_and_feature_available_calls_borg_with_match flexmock(module.borgmatic.borg.pattern).should_receive('write_patterns_file').and_return(None) flexmock(module.borgmatic.borg.flags).should_receive('make_list_filter_flags').and_return('') flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').with_args( - 'archive', None, '1.2.3' + 'archive', + None, + '1.2.3', ).and_return(('--match-archives', 'archive')) flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('--repo', 'repo') + ('--repo', 'repo'), ) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_archive_flags').never() insert_execute_command_mock( - ('borg', 'recreate', '--repo', 'repo', '--match-archives', 'archive') + ('borg', 'recreate', '--repo', 'repo', '--match-archives', 'archive'), ) module.recreate_archive( @@ -763,7 +767,7 @@ def test_recreate_with_match_archives_and_feature_not_available_calls_borg_witho flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').never() flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(False) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_archive_flags').never() insert_execute_command_mock(('borg', 'recreate', 'repo')) @@ -793,7 +797,7 @@ def test_recreate_with_archives_flags_and_feature_not_available_calls_borg_with_ flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').never() flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(False) flexmock(module.borgmatic.borg.flags).should_receive( - 'make_repository_archive_flags' + 'make_repository_archive_flags', ).and_return(('repo::archive',)) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').never() insert_execute_command_mock(('borg', 'recreate', 'repo::archive')) diff --git a/tests/unit/borg/test_rename.py b/tests/unit/borg/test_rename.py index dc299328..2589a80b 100644 --- a/tests/unit/borg/test_rename.py +++ b/tests/unit/borg/test_rename.py @@ -11,10 +11,10 @@ def test_rename_archive_calls_borg_rename(): # Note: make_rename_command is tested as integration test. flexmock(module).should_receive('make_rename_command').and_return(('borg', 'fake-command')) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - environment + environment, ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - '/working/dir' + '/working/dir', ) flexmock(module.borgmatic.execute).should_receive('execute_command').with_args( ('borg', 'fake-command'), diff --git a/tests/unit/borg/test_repo_create.py b/tests/unit/borg/test_repo_create.py index 4b7f74e2..50888f55 100644 --- a/tests/unit/borg/test_repo_create.py +++ b/tests/unit/borg/test_repo_create.py @@ -14,20 +14,24 @@ REPO_CREATE_COMMAND = ('borg', 'repo-create', '--encryption', 'repokey') def insert_repo_info_command_found_mock(): flexmock(module.repo_info).should_receive('display_repository_info').and_return( - '{"encryption": {"mode": "repokey"}}' + '{"encryption": {"mode": "repokey"}}', ) def insert_repo_info_command_not_found_mock(): flexmock(module.repo_info).should_receive('display_repository_info').and_raise( subprocess.CalledProcessError( - sorted(module.REPO_INFO_REPOSITORY_NOT_FOUND_EXIT_CODES)[0], [] - ) + sorted(module.REPO_INFO_REPOSITORY_NOT_FOUND_EXIT_CODES)[0], + [], + ), ) def insert_repo_create_command_mock( - repo_create_command, working_directory=None, borg_exit_codes=None, **kwargs + repo_create_command, + working_directory=None, + borg_exit_codes=None, + **kwargs, ): flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( @@ -45,13 +49,13 @@ def insert_repo_create_command_mock( def test_create_repository_calls_borg_with_flags(): insert_repo_info_command_not_found_mock() - insert_repo_create_command_mock(REPO_CREATE_COMMAND + ('--repo', 'repo')) + insert_repo_create_command_mock((*REPO_CREATE_COMMAND, '--repo', 'repo')) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -72,7 +76,7 @@ def test_create_repository_with_dry_run_skips_borg_call(): ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -92,12 +96,12 @@ def test_create_repository_raises_for_borg_repo_create_error(): ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').and_raise( - module.subprocess.CalledProcessError(2, 'borg repo_create') + module.subprocess.CalledProcessError(2, 'borg repo_create'), ) with pytest.raises(subprocess.CalledProcessError): @@ -118,7 +122,7 @@ def test_create_repository_skips_creation_when_repository_already_exists(): ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -138,7 +142,7 @@ def test_create_repository_errors_when_repository_with_differing_encryption_mode ( '--repo', 'repo', - ) + ), ) with pytest.raises(ValueError): @@ -154,7 +158,7 @@ def test_create_repository_errors_when_repository_with_differing_encryption_mode def test_create_repository_raises_for_unknown_repo_info_command_error(): flexmock(module.repo_info).should_receive('display_repository_info').and_raise( - subprocess.CalledProcessError(REPO_INFO_SOME_UNKNOWN_EXIT_CODE, []) + subprocess.CalledProcessError(REPO_INFO_SOME_UNKNOWN_EXIT_CODE, []), ) with pytest.raises(subprocess.CalledProcessError): @@ -171,14 +175,14 @@ def test_create_repository_raises_for_unknown_repo_info_command_error(): def test_create_repository_with_source_repository_calls_borg_with_other_repo_flag(): insert_repo_info_command_not_found_mock() insert_repo_create_command_mock( - REPO_CREATE_COMMAND + ('--other-repo', 'other.borg', '--repo', 'repo') + (*REPO_CREATE_COMMAND, '--other-repo', 'other.borg', '--repo', 'repo'), ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -194,13 +198,13 @@ def test_create_repository_with_source_repository_calls_borg_with_other_repo_fla def test_create_repository_with_copy_crypt_key_calls_borg_with_copy_crypt_key_flag(): insert_repo_info_command_not_found_mock() - insert_repo_create_command_mock(REPO_CREATE_COMMAND + ('--copy-crypt-key', '--repo', 'repo')) + insert_repo_create_command_mock((*REPO_CREATE_COMMAND, '--copy-crypt-key', '--repo', 'repo')) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -216,13 +220,13 @@ def test_create_repository_with_copy_crypt_key_calls_borg_with_copy_crypt_key_fl def test_create_repository_with_append_only_calls_borg_with_append_only_flag(): insert_repo_info_command_not_found_mock() - insert_repo_create_command_mock(REPO_CREATE_COMMAND + ('--append-only', '--repo', 'repo')) + insert_repo_create_command_mock((*REPO_CREATE_COMMAND, '--append-only', '--repo', 'repo')) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -238,13 +242,13 @@ def test_create_repository_with_append_only_calls_borg_with_append_only_flag(): def test_create_repository_with_append_only_config_calls_borg_with_append_only_flag(): insert_repo_info_command_not_found_mock() - insert_repo_create_command_mock(REPO_CREATE_COMMAND + ('--append-only', '--repo', 'repo')) + insert_repo_create_command_mock((*REPO_CREATE_COMMAND, '--append-only', '--repo', 'repo')) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -261,14 +265,14 @@ def test_create_repository_with_append_only_config_calls_borg_with_append_only_f def test_create_repository_with_storage_quota_calls_borg_with_storage_quota_flag(): insert_repo_info_command_not_found_mock() insert_repo_create_command_mock( - REPO_CREATE_COMMAND + ('--storage-quota', '5G', '--repo', 'repo') + (*REPO_CREATE_COMMAND, '--storage-quota', '5G', '--repo', 'repo'), ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -284,13 +288,13 @@ def test_create_repository_with_storage_quota_calls_borg_with_storage_quota_flag def test_create_repository_with_make_parent_dirs_calls_borg_with_make_parent_dirs_flag(): insert_repo_info_command_not_found_mock() - insert_repo_create_command_mock(REPO_CREATE_COMMAND + ('--make-parent-dirs', '--repo', 'repo')) + insert_repo_create_command_mock((*REPO_CREATE_COMMAND, '--make-parent-dirs', '--repo', 'repo')) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -306,14 +310,14 @@ def test_create_repository_with_make_parent_dirs_calls_borg_with_make_parent_dir def test_create_repository_with_log_info_calls_borg_with_info_flag(): insert_repo_info_command_not_found_mock() - insert_repo_create_command_mock(REPO_CREATE_COMMAND + ('--info', '--repo', 'repo')) + insert_repo_create_command_mock((*REPO_CREATE_COMMAND, '--info', '--repo', 'repo')) insert_logging_mock(logging.INFO) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -328,14 +332,14 @@ def test_create_repository_with_log_info_calls_borg_with_info_flag(): def test_create_repository_with_log_debug_calls_borg_with_debug_flag(): insert_repo_info_command_not_found_mock() - insert_repo_create_command_mock(REPO_CREATE_COMMAND + ('--debug', '--repo', 'repo')) + insert_repo_create_command_mock((*REPO_CREATE_COMMAND, '--debug', '--repo', 'repo')) insert_logging_mock(logging.DEBUG) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -350,13 +354,13 @@ def test_create_repository_with_log_debug_calls_borg_with_debug_flag(): def test_create_repository_with_log_json_calls_borg_with_log_json_flag(): insert_repo_info_command_not_found_mock() - insert_repo_create_command_mock(REPO_CREATE_COMMAND + ('--log-json', '--repo', 'repo')) + insert_repo_create_command_mock((*REPO_CREATE_COMMAND, '--log-json', '--repo', 'repo')) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -371,13 +375,13 @@ def test_create_repository_with_log_json_calls_borg_with_log_json_flag(): def test_create_repository_with_lock_wait_calls_borg_with_lock_wait_flag(): insert_repo_info_command_not_found_mock() - insert_repo_create_command_mock(REPO_CREATE_COMMAND + ('--lock-wait', '5', '--repo', 'repo')) + insert_repo_create_command_mock((*REPO_CREATE_COMMAND, '--lock-wait', '5', '--repo', 'repo')) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -392,13 +396,13 @@ def test_create_repository_with_lock_wait_calls_borg_with_lock_wait_flag(): def test_create_repository_with_local_path_calls_borg_via_local_path(): insert_repo_info_command_not_found_mock() - insert_repo_create_command_mock(('borg1',) + REPO_CREATE_COMMAND[1:] + ('--repo', 'repo')) + insert_repo_create_command_mock(('borg1', *REPO_CREATE_COMMAND[1:], '--repo', 'repo')) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -416,14 +420,15 @@ def test_create_repository_with_exit_codes_calls_borg_using_them(): borg_exit_codes = flexmock() insert_repo_info_command_not_found_mock() insert_repo_create_command_mock( - ('borg',) + REPO_CREATE_COMMAND[1:] + ('--repo', 'repo'), borg_exit_codes=borg_exit_codes + ('borg', *REPO_CREATE_COMMAND[1:], '--repo', 'repo'), + borg_exit_codes=borg_exit_codes, ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -439,14 +444,14 @@ def test_create_repository_with_exit_codes_calls_borg_using_them(): def test_create_repository_with_remote_path_calls_borg_with_remote_path_flag(): insert_repo_info_command_not_found_mock() insert_repo_create_command_mock( - REPO_CREATE_COMMAND + ('--remote-path', 'borg1', '--repo', 'repo') + (*REPO_CREATE_COMMAND, '--remote-path', 'borg1', '--repo', 'repo'), ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -462,13 +467,13 @@ def test_create_repository_with_remote_path_calls_borg_with_remote_path_flag(): def test_create_repository_with_umask_calls_borg_with_umask_flag(): insert_repo_info_command_not_found_mock() - insert_repo_create_command_mock(REPO_CREATE_COMMAND + ('--umask', '077', '--repo', 'repo')) + insert_repo_create_command_mock((*REPO_CREATE_COMMAND, '--umask', '077', '--repo', 'repo')) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -484,14 +489,14 @@ def test_create_repository_with_umask_calls_borg_with_umask_flag(): def test_create_repository_with_extra_borg_options_calls_borg_with_extra_options(): insert_repo_info_command_not_found_mock() insert_repo_create_command_mock( - REPO_CREATE_COMMAND + ('--extra', '--options', 'value with space', '--repo', 'repo') + (*REPO_CREATE_COMMAND, '--extra', '--options', 'value with space', '--repo', 'repo'), ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( @@ -507,14 +512,15 @@ def test_create_repository_with_extra_borg_options_calls_borg_with_extra_options def test_create_repository_calls_borg_with_working_directory(): insert_repo_info_command_not_found_mock() insert_repo_create_command_mock( - REPO_CREATE_COMMAND + ('--repo', 'repo'), working_directory='/working/dir' + (*REPO_CREATE_COMMAND, '--repo', 'repo'), + working_directory='/working/dir', ) flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) module.create_repository( diff --git a/tests/unit/borg/test_repo_delete.py b/tests/unit/borg/test_repo_delete.py index 2cc77870..03925b4d 100644 --- a/tests/unit/borg/test_repo_delete.py +++ b/tests/unit/borg/test_repo_delete.py @@ -12,7 +12,7 @@ def test_make_repo_delete_command_with_feature_available_runs_borg_repo_delete() flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_repo_delete_command( @@ -33,7 +33,7 @@ def test_make_repo_delete_command_without_feature_available_runs_borg_delete(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_repo_delete_command( @@ -55,7 +55,7 @@ def test_make_repo_delete_command_includes_log_info(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_repo_delete_command( @@ -77,7 +77,7 @@ def test_make_repo_delete_command_includes_log_debug(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_repo_delete_command( @@ -97,11 +97,12 @@ def test_make_repo_delete_command_includes_dry_run(): flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').with_args( - 'dry-run', True + 'dry-run', + True, ).and_return(('--dry-run',)) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_repo_delete_command( @@ -121,11 +122,12 @@ def test_make_repo_delete_command_includes_remote_path(): flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').with_args( - 'remote-path', 'borg1' + 'remote-path', + 'borg1', ).and_return(('--remote-path', 'borg1')) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_repo_delete_command( @@ -144,11 +146,11 @@ def test_make_repo_delete_command_includes_remote_path(): def test_make_repo_delete_command_includes_umask(): flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_repo_delete_command( @@ -168,11 +170,12 @@ def test_make_repo_delete_command_includes_log_json(): flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').with_args( - 'log-json', True + 'log-json', + True, ).and_return(('--log-json',)) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_repo_delete_command( @@ -192,11 +195,12 @@ def test_make_repo_delete_command_includes_lock_wait(): flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').with_args( - 'lock-wait', 5 + 'lock-wait', + 5, ).and_return(('--lock-wait', '5')) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_repo_delete_command( @@ -216,11 +220,12 @@ def test_make_repo_delete_command_includes_list(): flexmock(module.borgmatic.borg.feature).should_receive('available').and_return(True) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags').with_args( - 'list', True + 'list', + True, ).and_return(('--list',)) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_repo_delete_command( @@ -241,7 +246,7 @@ def test_make_repo_delete_command_includes_force(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_repo_delete_command( @@ -262,7 +267,7 @@ def test_make_repo_delete_command_includes_force_twice(): flexmock(module.borgmatic.borg.flags).should_receive('make_flags').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.borgmatic.borg.flags).should_receive('make_repository_flags').and_return( - ('repo',) + ('repo',), ) command = module.make_repo_delete_command( @@ -283,7 +288,7 @@ def test_delete_repository_with_defaults_does_not_capture_output(): command = flexmock() flexmock(module).should_receive('make_repo_delete_command').and_return(command) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.execute).should_receive('execute_command').with_args( @@ -312,7 +317,7 @@ def test_delete_repository_with_force_captures_output(): command = flexmock() flexmock(module).should_receive('make_repo_delete_command').and_return(command) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.execute).should_receive('execute_command').with_args( @@ -341,7 +346,7 @@ def test_delete_repository_with_cache_only_captures_output(): command = flexmock() flexmock(module).should_receive('make_repo_delete_command').and_return(command) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module.borgmatic.execute).should_receive('execute_command').with_args( @@ -370,7 +375,7 @@ def test_delete_repository_calls_borg_with_working_directory(): command = flexmock() flexmock(module).should_receive('make_repo_delete_command').and_return(command) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - flexmock() + flexmock(), ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( '/working/dir', diff --git a/tests/unit/borg/test_repo_info.py b/tests/unit/borg/test_repo_info.py index 0b5815ef..b4791618 100644 --- a/tests/unit/borg/test_repo_info.py +++ b/tests/unit/borg/test_repo_info.py @@ -12,13 +12,13 @@ def test_display_repository_info_calls_borg_with_flags(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -53,7 +53,7 @@ def test_display_repository_info_without_borg_features_calls_borg_with_info_sub_ flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(False) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.environment).should_receive('make_environment') @@ -89,13 +89,13 @@ def test_display_repository_info_with_log_info_calls_borg_with_info_flag(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -130,13 +130,13 @@ def test_display_repository_info_with_log_info_and_json_suppresses_most_borg_out flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -166,13 +166,13 @@ def test_display_repository_info_with_log_debug_calls_borg_with_debug_flag(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -208,13 +208,13 @@ def test_display_repository_info_with_log_debug_and_json_suppresses_most_borg_ou flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -244,13 +244,13 @@ def test_display_repository_info_with_json_calls_borg_with_json_flag(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -279,13 +279,13 @@ def test_display_repository_info_with_local_path_calls_borg_via_local_path(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -321,13 +321,13 @@ def test_display_repository_info_with_exit_codes_calls_borg_using_them(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -363,13 +363,13 @@ def test_display_repository_info_with_remote_path_calls_borg_with_remote_path_fl flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -405,13 +405,13 @@ def test_display_repository_info_with_umask_calls_borg_with_umask_flags(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -447,16 +447,16 @@ def test_display_repository_info_with_log_json_calls_borg_with_log_json_flags(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_flags').with_args('log-json', True).and_return( - ('--log-json',) + ('--log-json',), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -492,13 +492,13 @@ def test_display_repository_info_with_lock_wait_calls_borg_with_lock_wait_flags( config = {'lock_wait': 5} flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', str(value)) if value else () + lambda name, value: (f'--{name}', str(value)) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -533,13 +533,13 @@ def test_display_repository_info_calls_borg_with_working_directory(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_repository_flags').and_return( ( '--repo', 'repo', - ) + ), ) flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( diff --git a/tests/unit/borg/test_repo_list.py b/tests/unit/borg/test_repo_list.py index 96a6b54d..32a95d70 100644 --- a/tests/unit/borg/test_repo_list.py +++ b/tests/unit/borg/test_repo_list.py @@ -72,7 +72,7 @@ def test_get_latest_archive_calls_borg_with_flags(): flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, + ('borg', 'list', *BORG_LIST_LATEST_ARGUMENTS), borg_local_path='borg', borg_exit_codes=None, environment=None, @@ -95,7 +95,7 @@ def test_get_latest_archive_with_log_info_calls_borg_without_info_flag(): flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, + ('borg', 'list', *BORG_LIST_LATEST_ARGUMENTS), environment=None, working_directory=None, borg_local_path='borg', @@ -119,7 +119,7 @@ def test_get_latest_archive_with_log_debug_calls_borg_without_debug_flag(): flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, + ('borg', 'list', *BORG_LIST_LATEST_ARGUMENTS), environment=None, working_directory=None, borg_local_path='borg', @@ -143,7 +143,7 @@ def test_get_latest_archive_with_local_path_calls_borg_via_local_path(): flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg1', 'list') + BORG_LIST_LATEST_ARGUMENTS, + ('borg1', 'list', *BORG_LIST_LATEST_ARGUMENTS), environment=None, working_directory=None, borg_local_path='borg1', @@ -168,7 +168,7 @@ def test_get_latest_archive_with_exit_codes_calls_borg_using_them(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) borg_exit_codes = flexmock() flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, + ('borg', 'list', *BORG_LIST_LATEST_ARGUMENTS), environment=None, working_directory=None, borg_local_path='borg', @@ -191,7 +191,7 @@ def test_get_latest_archive_with_remote_path_calls_borg_with_remote_path_flags() flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'list', '--remote-path', 'borg1') + BORG_LIST_LATEST_ARGUMENTS, + ('borg', 'list', '--remote-path', 'borg1', *BORG_LIST_LATEST_ARGUMENTS), environment=None, working_directory=None, borg_local_path='borg', @@ -215,7 +215,7 @@ def test_get_latest_archive_with_umask_calls_borg_with_umask_flags(): flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'list', '--umask', '077') + BORG_LIST_LATEST_ARGUMENTS, + ('borg', 'list', '--umask', '077', *BORG_LIST_LATEST_ARGUMENTS), environment=None, working_directory=None, borg_local_path='borg', @@ -237,7 +237,7 @@ def test_get_latest_archive_without_archives_raises(): flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, + ('borg', 'list', *BORG_LIST_LATEST_ARGUMENTS), environment=None, working_directory=None, borg_local_path='borg', @@ -259,7 +259,7 @@ def test_get_latest_archive_with_log_json_calls_borg_with_log_json_flags(): flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'list', '--log-json') + BORG_LIST_LATEST_ARGUMENTS, + ('borg', 'list', '--log-json', *BORG_LIST_LATEST_ARGUMENTS), environment=None, working_directory=None, borg_local_path='borg', @@ -283,7 +283,7 @@ def test_get_latest_archive_with_lock_wait_calls_borg_with_lock_wait_flags(): flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'list', '--lock-wait', 'okay') + BORG_LIST_LATEST_ARGUMENTS, + ('borg', 'list', '--lock-wait', 'okay', *BORG_LIST_LATEST_ARGUMENTS), environment=None, working_directory=None, borg_local_path='borg', @@ -308,7 +308,7 @@ def test_get_latest_archive_calls_borg_with_working_directory(): '/working/dir', ) flexmock(module).should_receive('execute_command_and_capture_output').with_args( - ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, + ('borg', 'list', *BORG_LIST_LATEST_ARGUMENTS), borg_local_path='borg', borg_exit_codes=None, environment=None, @@ -330,7 +330,9 @@ def test_make_repo_list_command_includes_log_info(): insert_logging_mock(logging.INFO) flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -340,7 +342,11 @@ def test_make_repo_list_command_includes_log_info(): config={}, local_borg_version='1.2.3', repo_list_arguments=flexmock( - archive=None, paths=None, json=False, prefix=None, match_archives=None + archive=None, + paths=None, + json=False, + prefix=None, + match_archives=None, ), global_arguments=flexmock(), ) @@ -352,7 +358,9 @@ def test_make_repo_list_command_includes_json_but_not_info(): insert_logging_mock(logging.INFO) flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -362,7 +370,11 @@ def test_make_repo_list_command_includes_json_but_not_info(): config={}, local_borg_version='1.2.3', repo_list_arguments=flexmock( - archive=None, paths=None, json=True, prefix=None, match_archives=None + archive=None, + paths=None, + json=True, + prefix=None, + match_archives=None, ), global_arguments=flexmock(), ) @@ -374,7 +386,9 @@ def test_make_repo_list_command_includes_log_debug(): insert_logging_mock(logging.DEBUG) flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -384,7 +398,11 @@ def test_make_repo_list_command_includes_log_debug(): config={}, local_borg_version='1.2.3', repo_list_arguments=flexmock( - archive=None, paths=None, json=False, prefix=None, match_archives=None + archive=None, + paths=None, + json=False, + prefix=None, + match_archives=None, ), global_arguments=flexmock(), ) @@ -396,7 +414,9 @@ def test_make_repo_list_command_includes_json_but_not_debug(): insert_logging_mock(logging.DEBUG) flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -406,7 +426,11 @@ def test_make_repo_list_command_includes_json_but_not_debug(): config={}, local_borg_version='1.2.3', repo_list_arguments=flexmock( - archive=None, paths=None, json=True, prefix=None, match_archives=None + archive=None, + paths=None, + json=True, + prefix=None, + match_archives=None, ), global_arguments=flexmock(), ) @@ -417,7 +441,9 @@ def test_make_repo_list_command_includes_json_but_not_debug(): def test_make_repo_list_command_includes_json(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -427,7 +453,11 @@ def test_make_repo_list_command_includes_json(): config={}, local_borg_version='1.2.3', repo_list_arguments=flexmock( - archive=None, paths=None, json=True, prefix=None, match_archives=None + archive=None, + paths=None, + json=True, + prefix=None, + match_archives=None, ), global_arguments=flexmock(), ) @@ -437,10 +467,12 @@ def test_make_repo_list_command_includes_json(): def test_make_repo_list_command_includes_log_json(): flexmock(module.flags).should_receive('make_flags').and_return(()).and_return( - ('--log-json',) + ('--log-json',), ).and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -450,7 +482,11 @@ def test_make_repo_list_command_includes_log_json(): config={'log_json': True}, local_borg_version='1.2.3', repo_list_arguments=flexmock( - archive=None, paths=None, json=False, prefix=None, match_archives=None + archive=None, + paths=None, + json=False, + prefix=None, + match_archives=None, ), global_arguments=flexmock(), ) @@ -460,10 +496,12 @@ def test_make_repo_list_command_includes_log_json(): def test_make_repo_list_command_includes_lock_wait(): flexmock(module.flags).should_receive('make_flags').and_return(()).and_return( - ('--lock-wait', '5') + ('--lock-wait', '5'), ).and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -473,7 +511,11 @@ def test_make_repo_list_command_includes_lock_wait(): config={'lock_wait': 5}, local_borg_version='1.2.3', repo_list_arguments=flexmock( - archive=None, paths=None, json=False, prefix=None, match_archives=None + archive=None, + paths=None, + json=False, + prefix=None, + match_archives=None, ), global_arguments=flexmock(), ) @@ -484,7 +526,9 @@ def test_make_repo_list_command_includes_lock_wait(): def test_make_repo_list_command_includes_local_path(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -494,7 +538,11 @@ def test_make_repo_list_command_includes_local_path(): config={}, local_borg_version='1.2.3', repo_list_arguments=flexmock( - archive=None, paths=None, json=False, prefix=None, match_archives=None + archive=None, + paths=None, + json=False, + prefix=None, + match_archives=None, ), global_arguments=flexmock(), local_path='borg2', @@ -505,10 +553,12 @@ def test_make_repo_list_command_includes_local_path(): def test_make_repo_list_command_includes_remote_path(): flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -518,7 +568,11 @@ def test_make_repo_list_command_includes_remote_path(): config={}, local_borg_version='1.2.3', repo_list_arguments=flexmock( - archive=None, paths=None, json=False, prefix=None, match_archives=None + archive=None, + paths=None, + json=False, + prefix=None, + match_archives=None, ), global_arguments=flexmock(), remote_path='borg2', @@ -529,10 +583,12 @@ def test_make_repo_list_command_includes_remote_path(): def test_make_repo_list_command_includes_umask(): flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -542,7 +598,11 @@ def test_make_repo_list_command_includes_umask(): config={'umask': '077'}, local_borg_version='1.2.3', repo_list_arguments=flexmock( - archive=None, paths=None, json=False, prefix=None, match_archives=None + archive=None, + paths=None, + json=False, + prefix=None, + match_archives=None, ), global_arguments=flexmock(), ) @@ -552,10 +612,12 @@ def test_make_repo_list_command_includes_umask(): def test_make_repo_list_command_transforms_prefix_into_match_archives(): flexmock(module.flags).should_receive('make_flags').and_return(()).and_return(()).and_return( - ('--match-archives', 'sh:foo*') + ('--match-archives', 'sh:foo*'), ) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -573,7 +635,7 @@ def test_make_repo_list_command_transforms_prefix_into_match_archives(): def test_make_repo_list_command_prefers_prefix_over_archive_name_format(): flexmock(module.flags).should_receive('make_flags').and_return(()).and_return(()).and_return( - ('--match-archives', 'sh:foo*') + ('--match-archives', 'sh:foo*'), ) flexmock(module.flags).should_receive('make_match_archives_flags').never() flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) @@ -581,7 +643,7 @@ def test_make_repo_list_command_prefers_prefix_over_archive_name_format(): command = module.make_repo_list_command( repository_path='repo', - config={'archive_name_format': 'bar-{now}'}, # noqa: FS003 + config={'archive_name_format': 'bar-{now}'}, local_borg_version='1.2.3', repo_list_arguments=flexmock(archive=None, paths=None, json=False, prefix='foo'), global_arguments=flexmock(), @@ -593,17 +655,23 @@ def test_make_repo_list_command_prefers_prefix_over_archive_name_format(): def test_make_repo_list_command_transforms_archive_name_format_into_match_archives(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, 'bar-{now}', '1.2.3' # noqa: FS003 + None, + 'bar-{now}', + '1.2.3', ).and_return(('--match-archives', 'sh:bar-*')) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) command = module.make_repo_list_command( repository_path='repo', - config={'archive_name_format': 'bar-{now}'}, # noqa: FS003 + config={'archive_name_format': 'bar-{now}'}, local_borg_version='1.2.3', repo_list_arguments=flexmock( - archive=None, paths=None, json=False, prefix=None, match_archives=None + archive=None, + paths=None, + json=False, + prefix=None, + match_archives=None, ), global_arguments=flexmock(), ) @@ -614,7 +682,9 @@ def test_make_repo_list_command_transforms_archive_name_format_into_match_archiv def test_make_repo_list_command_includes_short(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--short',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -624,7 +694,12 @@ def test_make_repo_list_command_includes_short(): config={}, local_borg_version='1.2.3', repo_list_arguments=flexmock( - archive=None, paths=None, json=False, prefix=None, match_archives=None, short=True + archive=None, + paths=None, + json=False, + prefix=None, + match_archives=None, + short=True, ), global_arguments=flexmock(), ) @@ -647,10 +722,12 @@ def test_make_repo_list_command_includes_short(): def test_make_repo_list_command_includes_additional_flags(argument_name): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return( - (f"--{argument_name.replace('_', '-')}", 'value') + (f"--{argument_name.replace('_', '-')}", 'value'), ) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) @@ -677,7 +754,9 @@ def test_make_repo_list_command_includes_additional_flags(argument_name): def test_make_repo_list_command_with_match_archives_calls_borg_with_match_archives_flags(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( 'foo-*', @@ -749,10 +828,12 @@ def test_list_repository_with_json_calls_json_command_only(): def test_make_repo_list_command_with_date_based_matching_calls_borg_with_date_based_flags(): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, None, '1.2.3' + None, + None, + '1.2.3', ).and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return( - ('--newer', '1d', '--newest', '1y', '--older', '1m', '--oldest', '1w') + ('--newer', '1d', '--newest', '1y', '--older', '1m', '--oldest', '1w'), ) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) diff --git a/tests/unit/borg/test_transfer.py b/tests/unit/borg/test_transfer.py index 76452be6..95dc001d 100644 --- a/tests/unit/borg/test_transfer.py +++ b/tests/unit/borg/test_transfer.py @@ -33,7 +33,10 @@ def test_transfer_archives_calls_borg_with_flags(): config={}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), ) @@ -44,7 +47,7 @@ def test_transfer_archives_with_dry_run_calls_borg_with_dry_run_flag(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').with_args('dry-run', True).and_return( - ('--dry-run',) + ('--dry-run',), ) flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) @@ -67,7 +70,10 @@ def test_transfer_archives_with_dry_run_calls_borg_with_dry_run_flag(): config={}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), ) @@ -98,7 +104,10 @@ def test_transfer_archives_with_log_info_calls_borg_with_info_flag(): config={}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), ) @@ -130,7 +139,10 @@ def test_transfer_archives_with_log_debug_calls_borg_with_debug_flag(): config={}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), ) @@ -141,7 +153,9 @@ def test_transfer_archives_with_archive_calls_borg_with_match_archives_flag(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - 'archive', 'bar-{now}', '2.3.4' # noqa: FS003 + 'archive', + 'bar-{now}', + '2.3.4', ).and_return(('--match-archives', 'archive')) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -160,10 +174,13 @@ def test_transfer_archives_with_archive_calls_borg_with_match_archives_flag(): module.transfer_archives( dry_run=False, repository_path='repo', - config={'archive_name_format': 'bar-{now}'}, # noqa: FS003 + config={'archive_name_format': 'bar-{now}'}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive='archive', progress=None, match_archives=None, source_repository=None + archive='archive', + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), ) @@ -174,7 +191,9 @@ def test_transfer_archives_with_match_archives_calls_borg_with_match_archives_fl flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - 'sh:foo*', 'bar-{now}', '2.3.4' # noqa: FS003 + 'sh:foo*', + 'bar-{now}', + '2.3.4', ).and_return(('--match-archives', 'sh:foo*')) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -193,10 +212,13 @@ def test_transfer_archives_with_match_archives_calls_borg_with_match_archives_fl module.transfer_archives( dry_run=False, repository_path='repo', - config={'archive_name_format': 'bar-{now}', 'match_archives': 'sh:foo*'}, # noqa: FS003 + config={'archive_name_format': 'bar-{now}', 'match_archives': 'sh:foo*'}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives='sh:foo*', source_repository=None + archive=None, + progress=None, + match_archives='sh:foo*', + source_repository=None, ), global_arguments=flexmock(), ) @@ -207,7 +229,9 @@ def test_transfer_archives_with_archive_name_format_calls_borg_with_match_archiv flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').with_args( - None, 'bar-{now}', '2.3.4' # noqa: FS003 + None, + 'bar-{now}', + '2.3.4', ).and_return(('--match-archives', 'sh:bar-*')) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) @@ -226,10 +250,13 @@ def test_transfer_archives_with_archive_name_format_calls_borg_with_match_archiv module.transfer_archives( dry_run=False, repository_path='repo', - config={'archive_name_format': 'bar-{now}'}, # noqa: FS003 + config={'archive_name_format': 'bar-{now}'}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), ) @@ -260,7 +287,10 @@ def test_transfer_archives_with_local_path_calls_borg_via_local_path(): config={}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), local_path='borg2', @@ -293,7 +323,10 @@ def test_transfer_archives_with_exit_codes_calls_borg_using_them(): config={'borg_exit_codes': borg_exit_codes}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), ) @@ -304,7 +337,8 @@ def test_transfer_archives_with_remote_path_calls_borg_with_remote_path_flags(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').with_args( - 'remote-path', 'borg2' + 'remote-path', + 'borg2', ).and_return(('--remote-path', 'borg2')) flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) @@ -327,7 +361,10 @@ def test_transfer_archives_with_remote_path_calls_borg_with_remote_path_flags(): config={}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), remote_path='borg2', @@ -338,7 +375,7 @@ def test_transfer_archives_with_umask_calls_borg_with_umask_flags(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_flags').replace_with( - lambda name, value: (f'--{name}', value) if value else () + lambda name, value: (f'--{name}', value) if value else (), ) flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) @@ -361,7 +398,10 @@ def test_transfer_archives_with_umask_calls_borg_with_umask_flags(): config={'umask': '077'}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), ) @@ -372,7 +412,7 @@ def test_transfer_archives_with_log_json_calls_borg_with_log_json_flags(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').with_args('log-json', True).and_return( - ('--log-json',) + ('--log-json',), ) flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) @@ -395,7 +435,10 @@ def test_transfer_archives_with_log_json_calls_borg_with_log_json_flags(): config={'log_json': True}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), ) @@ -406,7 +449,7 @@ def test_transfer_archives_with_lock_wait_calls_borg_with_lock_wait_flags(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').with_args('lock-wait', 5).and_return( - ('--lock-wait', '5') + ('--lock-wait', '5'), ) flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) @@ -430,7 +473,10 @@ def test_transfer_archives_with_lock_wait_calls_borg_with_lock_wait_flags(): config=config, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), ) @@ -441,7 +487,7 @@ def test_transfer_archives_with_progress_calls_borg_with_progress_flags(): flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').with_args('progress', True).and_return( - ('--progress',) + ('--progress',), ) flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) @@ -464,7 +510,10 @@ def test_transfer_archives_with_progress_calls_borg_with_progress_flags(): config={'progress': True}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), ) @@ -478,7 +527,7 @@ def test_transfer_archives_passes_through_arguments_to_borg(argument_name): flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return( - (flag_name, 'value') + (flag_name, 'value'), ) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.environment).should_receive('make_environment') @@ -513,7 +562,7 @@ def test_transfer_archives_with_source_repository_calls_borg_with_other_repo_fla flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').with_args('other-repo', 'other').and_return( - ('--other-repo', 'other') + ('--other-repo', 'other'), ) flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) @@ -536,7 +585,10 @@ def test_transfer_archives_with_source_repository_calls_borg_with_other_repo_fla config={}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository='other' + archive=None, + progress=None, + match_archives=None, + source_repository='other', ), global_arguments=flexmock(), ) @@ -547,7 +599,7 @@ def test_transfer_archives_with_date_based_matching_calls_borg_with_date_based_f flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_match_archives_flags').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return( - ('--newer', '1d', '--newest', '1y', '--older', '1m', '--oldest', '1w') + ('--newer', '1d', '--newest', '1y', '--older', '1m', '--oldest', '1w'), ) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.environment).should_receive('make_environment') @@ -620,7 +672,10 @@ def test_transfer_archives_calls_borg_with_working_directory(): config={'working_directory': '/working/dir'}, local_borg_version='2.3.4', transfer_arguments=flexmock( - archive=None, progress=None, match_archives=None, source_repository=None + archive=None, + progress=None, + match_archives=None, + source_repository=None, ), global_arguments=flexmock(), ) diff --git a/tests/unit/borg/test_umount.py b/tests/unit/borg/test_umount.py index 69f67664..2f73c970 100644 --- a/tests/unit/borg/test_umount.py +++ b/tests/unit/borg/test_umount.py @@ -8,7 +8,10 @@ from ..test_verbosity import insert_logging_mock def insert_execute_command_mock( - command, borg_local_path='borg', working_directory=None, borg_exit_codes=None + command, + borg_local_path='borg', + working_directory=None, + borg_exit_codes=None, ): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( working_directory, diff --git a/tests/unit/borg/test_version.py b/tests/unit/borg/test_version.py index 17fc1861..3ba2261b 100644 --- a/tests/unit/borg/test_version.py +++ b/tests/unit/borg/test_version.py @@ -63,7 +63,8 @@ def test_local_borg_version_with_local_borg_path_calls_borg_with_it(): def test_local_borg_version_with_borg_exit_codes_calls_using_with_them(): borg_exit_codes = flexmock() insert_execute_command_and_capture_output_mock( - ('borg', '--version'), borg_exit_codes=borg_exit_codes + ('borg', '--version'), + borg_exit_codes=borg_exit_codes, ) flexmock(module.environment).should_receive('make_environment') @@ -80,7 +81,8 @@ def test_local_borg_version_with_invalid_version_raises(): def test_local_borg_version_calls_borg_with_working_directory(): insert_execute_command_and_capture_output_mock( - ('borg', '--version'), working_directory='/working/dir' + ('borg', '--version'), + working_directory='/working/dir', ) flexmock(module.environment).should_receive('make_environment') diff --git a/tests/unit/commands/completion/test_actions.py b/tests/unit/commands/completion/test_actions.py index 75f3dead..45c48f97 100644 --- a/tests/unit/commands/completion/test_actions.py +++ b/tests/unit/commands/completion/test_actions.py @@ -3,5 +3,7 @@ from borgmatic.commands.completion import actions as module def test_upgrade_message_does_not_raise(): module.upgrade_message( - language='English', upgrade_command='read a lot', completion_file='your brain' + language='English', + upgrade_command='read a lot', + completion_file='your brain', ) diff --git a/tests/unit/commands/completion/test_bash.py b/tests/unit/commands/completion/test_bash.py index 3f4265bd..e244b268 100644 --- a/tests/unit/commands/completion/test_bash.py +++ b/tests/unit/commands/completion/test_bash.py @@ -10,8 +10,8 @@ def test_parser_flags_flattens_and_joins_flags(): _actions=[ flexmock(option_strings=['--foo', '--bar']), flexmock(option_strings=['--baz']), - ] - ) + ], + ), ) == '--foo --bar --baz' ) diff --git a/tests/unit/commands/completion/test_fish.py b/tests/unit/commands/completion/test_fish.py index 35d53ed8..7ac1832e 100644 --- a/tests/unit/commands/completion/test_fish.py +++ b/tests/unit/commands/completion/test_fish.py @@ -1,6 +1,5 @@ from argparse import Action from collections import namedtuple -from typing import Tuple import pytest from flexmock import flexmock @@ -8,7 +7,7 @@ from flexmock import flexmock from borgmatic.commands.completion import fish as module OptionType = namedtuple('OptionType', ['file', 'choice', 'unknown_required']) -TestCase = Tuple[Action, OptionType] +TestCase = tuple[Action, OptionType] test_data = [ (Action('--flag', 'flag'), OptionType(file=False, choice=False, unknown_required=False)), @@ -59,10 +58,10 @@ test_data = [ ), *( ( - Action('--flag', 'flag', type=type, default=None), + Action('--flag', 'flag', type=flag_type, default=None), OptionType(file=False, choice=False, unknown_required=True), ) - for type in (int, str) + for flag_type in (int, str) ), ( Action('--flag', 'flag', type=int, default=1), @@ -95,7 +94,8 @@ def test_has_choice_options_detects_choice_options(action: Action, option_type: @pytest.mark.parametrize('action, option_type', test_data) def test_has_unknown_required_param_options_detects_unknown_required_param_options( - action: Action, option_type: OptionType + action: Action, + option_type: OptionType, ): assert module.has_unknown_required_param_options(action) == option_type.unknown_required @@ -107,7 +107,8 @@ def test_has_exact_options_detects_exact_options(action: Action, option_type: Op @pytest.mark.parametrize('action, option_type', test_data) def test_exact_options_completion_produces_reasonable_completions( - action: Action, option_type: OptionType + action: Action, + option_type: OptionType, ): completion = module.exact_options_completion(action) if True in option_type: @@ -131,5 +132,5 @@ def test_dedent_strip_as_tuple_does_not_raise(): ''' a b - ''' + ''', ) diff --git a/tests/unit/commands/test_arguments.py b/tests/unit/commands/test_arguments.py index f3094277..0fad32e7 100644 --- a/tests/unit/commands/test_arguments.py +++ b/tests/unit/commands/test_arguments.py @@ -21,9 +21,9 @@ def test_get_subaction_parsers_with_subactions_returns_one_entry_per_subaction() _group_actions=( flexmock(choices={'foo': foo_parser, 'bar': bar_parser}), flexmock(choices={'baz': baz_parser}), - ) - ) - ) + ), + ), + ), ) == {'foo': foo_parser, 'bar': bar_parser, 'baz': baz_parser} @@ -39,13 +39,13 @@ def test_get_subactions_for_actions_with_subactions_returns_one_entry_per_action _group_actions=( flexmock(choices={'foo': flexmock(), 'bar': flexmock()}), flexmock(choices={'baz': flexmock()}), - ) - ) + ), + ), ), 'other': flexmock( - _subparsers=flexmock(_group_actions=(flexmock(choices={'quux': flexmock()}),)) + _subparsers=flexmock(_group_actions=(flexmock(choices={'quux': flexmock()}),)), ), - } + }, ) == {'action': ('foo', 'bar', 'baz'), 'other': ('quux',)} @@ -66,12 +66,15 @@ def test_omit_values_colliding_twice_with_action_names_drops_action_names_that_h def test_parse_and_record_action_arguments_without_action_name_leaves_arguments_untouched(): unparsed_arguments = ('--foo', '--bar') flexmock(module).should_receive('omit_values_colliding_with_action_names').and_return( - unparsed_arguments + unparsed_arguments, ) assert ( module.parse_and_record_action_arguments( - unparsed_arguments, flexmock(), flexmock(), 'action' + unparsed_arguments, + flexmock(), + flexmock(), + 'action', ) == unparsed_arguments ) @@ -83,15 +86,19 @@ def test_parse_and_record_action_arguments_updates_parsed_arguments_and_returns_ parsed_arguments = {'other': other_parsed_arguments} action_parsed_arguments = flexmock() flexmock(module).should_receive('omit_values_colliding_with_action_names').and_return( - unparsed_arguments + unparsed_arguments, ) action_parser = flexmock() flexmock(action_parser).should_receive('parse_known_args').and_return( - action_parsed_arguments, ('action', '--verbosity', '1') + action_parsed_arguments, + ('action', '--verbosity', '1'), ) assert module.parse_and_record_action_arguments( - unparsed_arguments, parsed_arguments, action_parser, 'action' + unparsed_arguments, + parsed_arguments, + action_parser, + 'action', ) == ('--verbosity', '1') assert parsed_arguments == {'other': other_parsed_arguments, 'action': action_parsed_arguments} @@ -102,15 +109,20 @@ def test_parse_and_record_action_arguments_with_alias_updates_canonical_parsed_a parsed_arguments = {'other': other_parsed_arguments} action_parsed_arguments = flexmock() flexmock(module).should_receive('omit_values_colliding_with_action_names').and_return( - unparsed_arguments + unparsed_arguments, ) action_parser = flexmock() flexmock(action_parser).should_receive('parse_known_args').and_return( - action_parsed_arguments, ('action', '--verbosity', '1') + action_parsed_arguments, + ('action', '--verbosity', '1'), ) assert module.parse_and_record_action_arguments( - unparsed_arguments, parsed_arguments, action_parser, 'action', canonical_name='doit' + unparsed_arguments, + parsed_arguments, + action_parser, + 'action', + canonical_name='doit', ) == ('--verbosity', '1') assert parsed_arguments == {'other': other_parsed_arguments, 'doit': action_parsed_arguments} @@ -120,11 +132,12 @@ def test_parse_and_record_action_arguments_with_borg_action_consumes_arguments_a parsed_arguments = {} borg_parsed_arguments = flexmock(options=flexmock()) flexmock(module).should_receive('omit_values_colliding_with_action_names').and_return( - unparsed_arguments + unparsed_arguments, ) borg_parser = flexmock() flexmock(borg_parser).should_receive('parse_known_args').and_return( - borg_parsed_arguments, ('--verbosity', '1', 'borg', 'list') + borg_parsed_arguments, + ('--verbosity', '1', 'borg', 'list'), ) assert module.parse_and_record_action_arguments( @@ -299,11 +312,13 @@ def test_group_arguments_with_values_returns_flags_with_corresponding_values(arg ], ) def test_get_unparsable_arguments_returns_remaining_arguments_that_no_action_can_parse( - arguments, grouped_arguments, expected + arguments, + grouped_arguments, + expected, ): for action_arguments, grouped_action_arguments in zip(arguments, grouped_arguments): flexmock(module).should_receive('group_arguments_with_values').with_args( - action_arguments + action_arguments, ).and_return(grouped_action_arguments) assert module.get_unparsable_arguments(arguments) == expected @@ -315,9 +330,9 @@ def test_parse_arguments_for_actions_consumes_action_arguments_after_action_name flexmock(module).should_receive('get_subaction_parsers').and_return({}) flexmock(module).should_receive('parse_and_record_action_arguments').replace_with( lambda unparsed, parsed, parser, action, canonical=None: parsed.update( - {action: action_namespace} + {action: action_namespace}, ) - or remaining + or remaining, ) flexmock(module).should_receive('get_subactions_for_actions').and_return({}) action_parsers = {'action': flexmock(), 'other': flexmock()} @@ -326,7 +341,9 @@ def test_parse_arguments_for_actions_consumes_action_arguments_after_action_name global_parser.should_receive('parse_known_args').and_return((global_namespace, ())) arguments, remaining_action_arguments = module.parse_arguments_for_actions( - ('action', '--foo', 'true'), action_parsers, global_parser + ('action', '--foo', 'true'), + action_parsers, + global_parser, ) assert arguments == {'global': global_namespace, 'action': action_namespace} @@ -339,9 +356,9 @@ def test_parse_arguments_for_actions_consumes_action_arguments_with_alias(): flexmock(module).should_receive('get_subaction_parsers').and_return({}) flexmock(module).should_receive('parse_and_record_action_arguments').replace_with( lambda unparsed, parsed, parser, action, canonical=None: parsed.update( - {canonical or action: action_namespace} + {canonical or action: action_namespace}, ) - or remaining + or remaining, ) flexmock(module).should_receive('get_subactions_for_actions').and_return({}) action_parsers = { @@ -356,7 +373,9 @@ def test_parse_arguments_for_actions_consumes_action_arguments_with_alias(): flexmock(module).ACTION_ALIASES = {'action': ['-a'], 'other': ['-o']} arguments, remaining_action_arguments = module.parse_arguments_for_actions( - ('-a', '--foo', 'true'), action_parsers, global_parser + ('-a', '--foo', 'true'), + action_parsers, + global_parser, ) assert arguments == {'global': global_namespace, 'action': action_namespace} @@ -369,9 +388,9 @@ def test_parse_arguments_for_actions_consumes_multiple_action_arguments(): flexmock(module).should_receive('get_subaction_parsers').and_return({}) flexmock(module).should_receive('parse_and_record_action_arguments').replace_with( lambda unparsed, parsed, parser, action, canonical=None: parsed.update( - {action: action_namespace if action == 'action' else other_namespace} + {action: action_namespace if action == 'action' else other_namespace}, ) - or () + or (), ).and_return(('other', '--bar', '3')).and_return('action', '--foo', 'true') flexmock(module).should_receive('get_subactions_for_actions').and_return({}) action_parsers = { @@ -383,7 +402,9 @@ def test_parse_arguments_for_actions_consumes_multiple_action_arguments(): global_parser.should_receive('parse_known_args').and_return((global_namespace, ())) arguments, remaining_action_arguments = module.parse_arguments_for_actions( - ('action', '--foo', 'true', 'other', '--bar', '3'), action_parsers, global_parser + ('action', '--foo', 'true', 'other', '--bar', '3'), + action_parsers, + global_parser, ) assert arguments == { @@ -400,9 +421,9 @@ def test_parse_arguments_for_actions_respects_command_line_action_ordering(): flexmock(module).should_receive('get_subaction_parsers').and_return({}) flexmock(module).should_receive('parse_and_record_action_arguments').replace_with( lambda unparsed, parsed, parser, action, canonical=None: parsed.update( - {action: other_namespace if action == 'other' else action_namespace} + {action: other_namespace if action == 'other' else action_namespace}, ) - or () + or (), ).and_return(('action',)).and_return(('other', '--foo', 'true')) flexmock(module).should_receive('get_subactions_for_actions').and_return({}) action_parsers = { @@ -414,11 +435,13 @@ def test_parse_arguments_for_actions_respects_command_line_action_ordering(): global_parser.should_receive('parse_known_args').and_return((global_namespace, ())) arguments, remaining_action_arguments = module.parse_arguments_for_actions( - ('other', '--foo', 'true', 'action'), action_parsers, global_parser + ('other', '--foo', 'true', 'action'), + action_parsers, + global_parser, ) assert arguments == collections.OrderedDict( - [('other', other_namespace), ('action', action_namespace), ('global', global_namespace)] + [('other', other_namespace), ('action', action_namespace), ('global', global_namespace)], ) assert remaining_action_arguments == ((), (), ()) @@ -436,9 +459,9 @@ def test_parse_arguments_for_actions_applies_default_action_parsers(): flexmock(module).should_receive('get_subaction_parsers').and_return({}) flexmock(module).should_receive('parse_and_record_action_arguments').replace_with( lambda unparsed, parsed, parser, action, canonical=None: parsed.update( - {action: namespaces.get(action)} + {action: namespaces.get(action)}, ) - or () + or (), ).and_return(()) flexmock(module).should_receive('get_subactions_for_actions').and_return({}) action_parsers = { @@ -452,7 +475,9 @@ def test_parse_arguments_for_actions_applies_default_action_parsers(): global_parser.should_receive('parse_known_args').and_return((global_namespace, ())) arguments, remaining_action_arguments = module.parse_arguments_for_actions( - ('--progress'), action_parsers, global_parser + ('--progress'), + action_parsers, + global_parser, ) assert arguments == namespaces @@ -464,9 +489,9 @@ def test_parse_arguments_for_actions_consumes_global_arguments(): flexmock(module).should_receive('get_subaction_parsers').and_return({}) flexmock(module).should_receive('parse_and_record_action_arguments').replace_with( lambda unparsed, parsed, parser, action, canonical=None: parsed.update( - {action: action_namespace} + {action: action_namespace}, ) - or ('--verbosity', 'lots') + or ('--verbosity', 'lots'), ) flexmock(module).should_receive('get_subactions_for_actions').and_return({}) action_parsers = { @@ -478,7 +503,9 @@ def test_parse_arguments_for_actions_consumes_global_arguments(): global_parser.should_receive('parse_known_args').and_return((global_namespace, ())) arguments, remaining_action_arguments = module.parse_arguments_for_actions( - ('action', '--verbosity', 'lots'), action_parsers, global_parser + ('action', '--verbosity', 'lots'), + action_parsers, + global_parser, ) assert arguments == {'global': global_namespace, 'action': action_namespace} @@ -490,9 +517,9 @@ def test_parse_arguments_for_actions_passes_through_unknown_arguments_before_act flexmock(module).should_receive('get_subaction_parsers').and_return({}) flexmock(module).should_receive('parse_and_record_action_arguments').replace_with( lambda unparsed, parsed, parser, action, canonical=None: parsed.update( - {action: action_namespace} + {action: action_namespace}, ) - or ('--wtf', 'yes') + or ('--wtf', 'yes'), ) flexmock(module).should_receive('get_subactions_for_actions').and_return({}) action_parsers = { @@ -504,7 +531,9 @@ def test_parse_arguments_for_actions_passes_through_unknown_arguments_before_act global_parser.should_receive('parse_known_args').and_return((global_namespace, ())) arguments, remaining_action_arguments = module.parse_arguments_for_actions( - ('--wtf', 'yes', 'action'), action_parsers, global_parser + ('--wtf', 'yes', 'action'), + action_parsers, + global_parser, ) assert arguments == {'global': global_namespace, 'action': action_namespace} @@ -516,9 +545,9 @@ def test_parse_arguments_for_actions_passes_through_unknown_arguments_after_acti flexmock(module).should_receive('get_subaction_parsers').and_return({}) flexmock(module).should_receive('parse_and_record_action_arguments').replace_with( lambda unparsed, parsed, parser, action, canonical=None: parsed.update( - {action: action_namespace} + {action: action_namespace}, ) - or ('--wtf', 'yes') + or ('--wtf', 'yes'), ) flexmock(module).should_receive('get_subactions_for_actions').and_return({}) action_parsers = { @@ -530,7 +559,9 @@ def test_parse_arguments_for_actions_passes_through_unknown_arguments_after_acti global_parser.should_receive('parse_known_args').and_return((global_namespace, ())) arguments, remaining_action_arguments = module.parse_arguments_for_actions( - ('action', '--wtf', 'yes'), action_parsers, global_parser + ('action', '--wtf', 'yes'), + action_parsers, + global_parser, ) assert arguments == {'global': global_namespace, 'action': action_namespace} @@ -542,9 +573,9 @@ def test_parse_arguments_for_actions_with_borg_action_skips_other_action_parsers flexmock(module).should_receive('get_subaction_parsers').and_return({}) flexmock(module).should_receive('parse_and_record_action_arguments').replace_with( lambda unparsed, parsed, parser, action, canonical=None: parsed.update( - {action: action_namespace} + {action: action_namespace}, ) - or () + or (), ).and_return(()) flexmock(module).should_receive('get_subactions_for_actions').and_return({}) action_parsers = { @@ -556,7 +587,9 @@ def test_parse_arguments_for_actions_with_borg_action_skips_other_action_parsers global_parser.should_receive('parse_known_args').and_return((global_namespace, ())) arguments, remaining_action_arguments = module.parse_arguments_for_actions( - ('borg', 'list'), action_parsers, global_parser + ('borg', 'list'), + action_parsers, + global_parser, ) assert arguments == {'global': global_namespace, 'borg': action_namespace} @@ -567,7 +600,7 @@ def test_parse_arguments_for_actions_raises_error_when_no_action_is_specified(): flexmock(module).should_receive('get_subaction_parsers').and_return({'bootstrap': [flexmock()]}) flexmock(module).should_receive('parse_and_record_action_arguments').and_return(flexmock()) flexmock(module).should_receive('get_subactions_for_actions').and_return( - {'config': ['bootstrap']} + {'config': ['bootstrap']}, ) action_parsers = {'config': flexmock()} global_parser = flexmock() @@ -955,17 +988,19 @@ def test_add_arguments_from_schema_with_non_dict_schema_bails(): arguments_group.should_receive('add_argument').never() module.add_arguments_from_schema( - arguments_group=arguments_group, schema='foo', unparsed_arguments=() + arguments_group=arguments_group, + schema='foo', + unparsed_arguments=(), ) def test_add_arguments_from_schema_with_nested_object_adds_flag_for_each_option(): arguments_group = flexmock() flexmock(module).should_receive('make_argument_description').and_return('help 1').and_return( - 'help 2' + 'help 2', ) flexmock(module.borgmatic.config.schema).should_receive('parse_type').and_return( - int + int, ).and_return(str) arguments_group.should_receive('add_argument').with_args( '--foo.bar', @@ -992,7 +1027,7 @@ def test_add_arguments_from_schema_with_nested_object_adds_flag_for_each_option( 'bar': {'type': 'integer'}, 'baz': {'type': 'str'}, }, - } + }, }, }, unparsed_arguments=(), @@ -1021,7 +1056,7 @@ def test_add_arguments_from_schema_uses_first_non_null_type_from_multi_type_obje 'properties': { 'bar': {'type': 'integer'}, }, - } + }, }, }, unparsed_arguments=(), @@ -1046,7 +1081,7 @@ def test_add_arguments_from_schema_with_empty_multi_type_raises(): 'properties': { 'bar': {'type': 'integer'}, }, - } + }, }, }, unparsed_arguments=(), @@ -1072,7 +1107,7 @@ def test_add_arguments_from_schema_with_propertyless_option_adds_flag(): 'properties': { 'foo': { 'type': 'object', - } + }, }, }, unparsed_arguments=(), @@ -1083,10 +1118,14 @@ def test_add_arguments_from_schema_with_array_of_scalars_adds_multiple_flags(): arguments_group = flexmock() flexmock(module).should_receive('make_argument_description').and_return('help') flexmock(module.borgmatic.config.schema).should_receive('parse_type').with_args( - 'integer', object=str, array=str + 'integer', + object=str, + array=str, ).and_return(int) flexmock(module.borgmatic.config.schema).should_receive('parse_type').with_args( - 'array', object=str, array=str + 'array', + object=str, + array=str, ).and_return(str) arguments_group.should_receive('add_argument').with_args( '--foo[0]', @@ -1112,7 +1151,7 @@ def test_add_arguments_from_schema_with_array_of_scalars_adds_multiple_flags(): 'items': { 'type': 'integer', }, - } + }, }, }, unparsed_arguments=(), @@ -1122,10 +1161,10 @@ def test_add_arguments_from_schema_with_array_of_scalars_adds_multiple_flags(): def test_add_arguments_from_schema_with_array_of_objects_adds_multiple_flags(): arguments_group = flexmock() flexmock(module).should_receive('make_argument_description').and_return('help 1').and_return( - 'help 2' + 'help 2', ) flexmock(module.borgmatic.config.schema).should_receive('parse_type').and_return( - int + int, ).and_return(str) arguments_group.should_receive('add_argument').with_args( '--foo[0].bar', @@ -1158,10 +1197,10 @@ def test_add_arguments_from_schema_with_array_of_objects_adds_multiple_flags(): 'properties': { 'bar': { 'type': 'integer', - } + }, }, }, - } + }, }, }, unparsed_arguments=(), @@ -1194,7 +1233,7 @@ def test_add_arguments_from_schema_with_boolean_adds_two_valueless_flags(): 'properties': { 'foo': { 'type': 'boolean', - } + }, }, }, unparsed_arguments=(), @@ -1227,7 +1266,7 @@ def test_add_arguments_from_schema_with_nested_boolean_adds_two_valueless_flags( 'properties': { 'baz_quux': { 'type': 'boolean', - } + }, }, }, unparsed_arguments=(), @@ -1261,7 +1300,7 @@ def test_add_arguments_from_schema_with_boolean_with_name_prefixed_with_no_adds_ 'properties': { 'no_foo': { 'type': 'boolean', - } + }, }, }, unparsed_arguments=(), diff --git a/tests/unit/commands/test_borgmatic.py b/tests/unit/commands/test_borgmatic.py index b196cfe6..542f2586 100644 --- a/tests/unit/commands/test_borgmatic.py +++ b/tests/unit/commands/test_borgmatic.py @@ -165,14 +165,16 @@ def test_monitoring_hooks_with_start_ping_error_raises(): object, ).never() - with pytest.raises(ValueError): - with module.Monitoring_hooks( + with ( + pytest.raises(ValueError), + module.Monitoring_hooks( config_filename='test.yaml', config={}, arguments={'create': flexmock()}, global_arguments=flexmock(monitoring_verbosity=99, dry_run=False), - ): - assert False # This should never get called. + ), + ): + raise AssertionError() # This should never get called. def test_monitoring_hooks_with_log_ping_error_raises(): @@ -221,14 +223,16 @@ def test_monitoring_hooks_with_log_ping_error_raises(): object, ).never() - with pytest.raises(ValueError): - with module.Monitoring_hooks( + with ( + pytest.raises(ValueError), + module.Monitoring_hooks( config_filename='test.yaml', config={}, arguments={'create': flexmock()}, global_arguments=flexmock(monitoring_verbosity=99, dry_run=False), - ): - pass + ), + ): + pass def test_monitoring_hooks_with_finish_ping_error_raises(): @@ -277,14 +281,16 @@ def test_monitoring_hooks_with_finish_ping_error_raises(): object, ).never() - with pytest.raises(ValueError): - with module.Monitoring_hooks( + with ( + pytest.raises(ValueError), + module.Monitoring_hooks( config_filename='test.yaml', config={}, arguments={'create': flexmock()}, global_arguments=flexmock(monitoring_verbosity=99, dry_run=False), - ): - pass + ), + ): + pass def test_monitoring_hooks_with_wrapped_code_error_pings_fail(): @@ -342,14 +348,16 @@ def test_monitoring_hooks_with_wrapped_code_error_pings_fail(): object, ).once() - with pytest.raises(OSError): - with module.Monitoring_hooks( + with ( + pytest.raises(OSError), + module.Monitoring_hooks( config_filename='test.yaml', config={}, arguments={'create': flexmock()}, global_arguments=flexmock(monitoring_verbosity=99, dry_run=False), - ): - raise OSError() + ), + ): + raise OSError() def test_monitoring_hooks_with_fail_ping_error_raise_original_error(): @@ -407,14 +415,16 @@ def test_monitoring_hooks_with_fail_ping_error_raise_original_error(): object, ).never() - with pytest.raises(OSError): - with module.Monitoring_hooks( + with ( + pytest.raises(OSError), + module.Monitoring_hooks( config_filename='test.yaml', config={}, arguments={'create': flexmock()}, global_arguments=flexmock(monitoring_verbosity=99, dry_run=False), - ): - raise OSError() + ), + ): + raise OSError() def test_run_configuration_runs_actions_for_each_repository(): @@ -426,7 +436,7 @@ def test_run_configuration_runs_actions_for_each_repository(): expected_results = [flexmock(), flexmock()] flexmock(module).should_receive('Log_prefix').and_return(flexmock()) flexmock(module).should_receive('run_actions').and_return(expected_results[:1]).and_return( - expected_results[1:] + expected_results[1:], ) config = {'repositories': [{'path': 'foo'}, {'path': 'bar'}]} arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False)} @@ -475,7 +485,7 @@ def test_run_configuration_logs_actions_error(): flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) expected_results = [flexmock(), flexmock()] flexmock(module).should_receive('log_error_records').and_return( - expected_results[:1] + expected_results[:1], ).and_return(expected_results[1:]) flexmock(module).should_receive('Log_prefix').and_return(flexmock()) flexmock(module).should_receive('run_actions').and_raise(OSError) @@ -541,7 +551,7 @@ def test_run_configuration_logs_on_error_hook_error(): flexmock(module.command).should_receive('execute_hooks').and_raise(OSError) expected_results = [flexmock(), flexmock()] flexmock(module).should_receive('log_error_records').and_return( - expected_results[:1] + expected_results[:1], ).and_return(expected_results[1:2]).and_return(expected_results[2:]) flexmock(module).should_receive('Log_prefix').and_return(flexmock()) flexmock(module).should_receive('run_actions').and_raise(OSError) @@ -613,7 +623,7 @@ def test_run_configuration_bails_for_on_error_hook_soft_failure(): flexmock(module.command).should_receive('execute_hooks').and_raise(error) expected_results = [flexmock(), flexmock()] flexmock(module).should_receive('log_error_records').and_return( - expected_results[:1] + expected_results[:1], ).and_return(expected_results[1:]) flexmock(module).should_receive('Log_prefix').and_return(flexmock()) flexmock(module).should_receive('run_actions').and_raise(OSError) @@ -697,10 +707,12 @@ def test_run_configuration_retries_repositories_in_order(): flexmock(module).should_receive('run_actions').and_raise(OSError).times(2) expected_results = [flexmock(), flexmock(), flexmock()] flexmock(module).should_receive('log_error_records').with_args( - 'Error running actions for repository', OSError + 'Error running actions for repository', + OSError, ).and_return(expected_results[:1]).ordered() flexmock(module).should_receive('log_error_records').with_args( - 'Error running actions for repository', OSError + 'Error running actions for repository', + OSError, ).and_return(expected_results[1:2]).ordered() flexmock(module).should_receive('log_error_records').with_args( 'Error running configuration', @@ -740,11 +752,13 @@ def test_run_configuration_retries_round_robin(): ).and_return([flexmock()]).ordered() foo_error_logs = [flexmock()] flexmock(module).should_receive('log_error_records').with_args( - 'Error running actions for repository', OSError + 'Error running actions for repository', + OSError, ).and_return(foo_error_logs).ordered() bar_error_logs = [flexmock()] flexmock(module).should_receive('log_error_records').with_args( - 'Error running actions for repository', OSError + 'Error running actions for repository', + OSError, ).and_return(bar_error_logs).ordered() config_error_logs = [flexmock()] flexmock(module).should_receive('log_error_records').with_args( @@ -774,7 +788,7 @@ def test_run_configuration_with_one_retry(): flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module).should_receive('Log_prefix').and_return(flexmock()) flexmock(module).should_receive('run_actions').and_raise(OSError).and_raise(OSError).and_return( - [] + [], ).and_raise(OSError).times(4) flexmock(module).should_receive('log_error_records').with_args( 'Error running actions for repository', @@ -790,7 +804,8 @@ def test_run_configuration_with_one_retry(): ).and_return(flexmock()).ordered() error_logs = [flexmock(), flexmock()] flexmock(module).should_receive('log_error_records').with_args( - 'Error running actions for repository', OSError + 'Error running actions for repository', + OSError, ).and_return(error_logs[:1]).ordered() flexmock(module).should_receive('log_error_records').with_args( 'Error running configuration', @@ -845,7 +860,8 @@ def test_run_configuration_with_retry_wait_does_backoff_after_each_retry(): flexmock(time).should_receive('sleep').with_args(30).and_return().ordered() error_logs = [flexmock(), flexmock()] flexmock(module).should_receive('log_error_records').with_args( - 'Error running actions for repository', OSError + 'Error running actions for repository', + OSError, ).and_return(error_logs[:1]).ordered() flexmock(module).should_receive('log_error_records').with_args( 'Error running configuration', @@ -875,7 +891,7 @@ def test_run_configuration_with_multiple_repositories_retries_with_timeout(): flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module).should_receive('Log_prefix').and_return(flexmock()) flexmock(module).should_receive('run_actions').and_raise(OSError).and_raise(OSError).and_return( - [] + [], ).and_raise(OSError).times(4) flexmock(module).should_receive('log_error_records').with_args( 'Error running actions for repository', @@ -897,7 +913,8 @@ def test_run_configuration_with_multiple_repositories_retries_with_timeout(): flexmock(time).should_receive('sleep').with_args(10).and_return().ordered() error_logs = [flexmock(), flexmock()] flexmock(module).should_receive('log_error_records').with_args( - 'Error running actions for repository', OSError + 'Error running actions for repository', + OSError, ).and_return(error_logs[:1]).ordered() flexmock(module).should_receive('log_error_records').with_args( 'Error running configuration', @@ -923,7 +940,7 @@ def test_run_actions_runs_repo_create(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.repo_create).should_receive('run_repo_create').once() @@ -941,7 +958,7 @@ def test_run_actions_runs_repo_create(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -949,7 +966,7 @@ def test_run_actions_adds_label_file_to_hook_context(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) expected = flexmock() @@ -976,7 +993,7 @@ def test_run_actions_adds_label_file_to_hook_context(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo', 'label': 'my repo'}, - ) + ), ) assert result == (expected,) @@ -985,7 +1002,7 @@ def test_run_actions_adds_log_file_to_hook_context(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) expected = flexmock() @@ -1012,7 +1029,7 @@ def test_run_actions_adds_log_file_to_hook_context(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) assert result == (expected,) @@ -1021,7 +1038,7 @@ def test_run_actions_runs_transfer(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.transfer).should_receive('run_transfer').once() @@ -1036,7 +1053,7 @@ def test_run_actions_runs_transfer(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1044,7 +1061,7 @@ def test_run_actions_runs_create(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) expected = flexmock() @@ -1060,7 +1077,7 @@ def test_run_actions_runs_create(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) assert result == (expected,) @@ -1069,7 +1086,7 @@ def test_run_actions_with_skip_actions_does_not_run_action_or_action_command_hoo flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return(['create']) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(module.command).should_receive('Before_after_hooks').with_args( @@ -1097,7 +1114,7 @@ def test_run_actions_with_skip_actions_does_not_run_action_or_action_command_hoo remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1105,7 +1122,7 @@ def test_run_actions_runs_recreate(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) @@ -1121,7 +1138,7 @@ def test_run_actions_runs_recreate(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1129,7 +1146,7 @@ def test_run_actions_runs_prune(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.prune).should_receive('run_prune').once() @@ -1144,7 +1161,7 @@ def test_run_actions_runs_prune(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1152,7 +1169,7 @@ def test_run_actions_runs_compact(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.compact).should_receive('run_compact').once() @@ -1167,7 +1184,7 @@ def test_run_actions_runs_compact(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1175,7 +1192,7 @@ def test_run_actions_runs_check_when_repository_enabled_for_checks(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(module.checks).should_receive('repository_enabled_for_checks').and_return(True) @@ -1191,7 +1208,7 @@ def test_run_actions_runs_check_when_repository_enabled_for_checks(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1199,7 +1216,7 @@ def test_run_actions_skips_check_when_repository_not_enabled_for_checks(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(module.checks).should_receive('repository_enabled_for_checks').and_return(False) @@ -1215,7 +1232,7 @@ def test_run_actions_skips_check_when_repository_not_enabled_for_checks(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1223,7 +1240,7 @@ def test_run_actions_runs_extract(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.extract).should_receive('run_extract').once() @@ -1238,7 +1255,7 @@ def test_run_actions_runs_extract(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1246,7 +1263,7 @@ def test_run_actions_runs_export_tar(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.export_tar).should_receive('run_export_tar').once() @@ -1261,7 +1278,7 @@ def test_run_actions_runs_export_tar(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1269,7 +1286,7 @@ def test_run_actions_runs_mount(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.mount).should_receive('run_mount').once() @@ -1284,7 +1301,7 @@ def test_run_actions_runs_mount(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1292,7 +1309,7 @@ def test_run_actions_runs_restore(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.restore).should_receive('run_restore').once() @@ -1307,7 +1324,7 @@ def test_run_actions_runs_restore(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1315,7 +1332,7 @@ def test_run_actions_runs_repo_list(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) expected = flexmock() @@ -1331,7 +1348,7 @@ def test_run_actions_runs_repo_list(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) assert result == (expected,) @@ -1340,7 +1357,7 @@ def test_run_actions_runs_list(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) expected = flexmock() @@ -1356,7 +1373,7 @@ def test_run_actions_runs_list(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) assert result == (expected,) @@ -1365,7 +1382,7 @@ def test_run_actions_runs_repo_info(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) expected = flexmock() @@ -1381,7 +1398,7 @@ def test_run_actions_runs_repo_info(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) assert result == (expected,) @@ -1390,7 +1407,7 @@ def test_run_actions_runs_info(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) expected = flexmock() @@ -1406,7 +1423,7 @@ def test_run_actions_runs_info(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) assert result == (expected,) @@ -1415,7 +1432,7 @@ def test_run_actions_runs_break_lock(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.break_lock).should_receive('run_break_lock').once() @@ -1430,7 +1447,7 @@ def test_run_actions_runs_break_lock(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1438,7 +1455,7 @@ def test_run_actions_runs_export_key(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.export_key).should_receive('run_export_key').once() @@ -1453,7 +1470,7 @@ def test_run_actions_runs_export_key(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1461,7 +1478,7 @@ def test_run_actions_runs_import_key(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.import_key).should_receive('run_import_key').once() @@ -1476,7 +1493,7 @@ def test_run_actions_runs_import_key(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1484,7 +1501,7 @@ def test_run_actions_runs_change_passphrase(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.change_passphrase).should_receive('run_change_passphrase').once() @@ -1502,7 +1519,7 @@ def test_run_actions_runs_change_passphrase(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1510,7 +1527,7 @@ def test_run_actions_runs_delete(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.delete).should_receive('run_delete').once() @@ -1525,7 +1542,7 @@ def test_run_actions_runs_delete(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1533,7 +1550,7 @@ def test_run_actions_runs_repo_delete(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.repo_delete).should_receive('run_repo_delete').once() @@ -1551,7 +1568,7 @@ def test_run_actions_runs_repo_delete(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1559,7 +1576,7 @@ def test_run_actions_runs_borg(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.borg).should_receive('run_borg').once() @@ -1574,7 +1591,7 @@ def test_run_actions_runs_borg(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1582,7 +1599,7 @@ def test_run_actions_runs_multiple_actions_in_argument_order(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) flexmock(borgmatic.actions.borg).should_receive('run_borg').once().ordered() @@ -1602,7 +1619,7 @@ def test_run_actions_runs_multiple_actions_in_argument_order(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1610,7 +1627,7 @@ def test_run_actions_runs_action_hooks_for_one_action_at_a_time(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module).should_receive('get_skip_actions').and_return([]) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - flexmock() + flexmock(), ) flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock()) @@ -1646,7 +1663,7 @@ def test_run_actions_runs_action_hooks_for_one_action_at_a_time(): remote_path=flexmock(), local_borg_version=flexmock(), repository={'path': 'repo'}, - ) + ), ) @@ -1660,7 +1677,9 @@ def test_load_configurations_collects_parsed_configurations_and_logs(resolve_env test_expected_logs = [flexmock(), flexmock()] other_expected_logs = [flexmock(), flexmock()] flexmock(module.validate).should_receive('parse_configuration').and_return( - configuration, ['/tmp/test.yaml'], test_expected_logs + configuration, + ['/tmp/test.yaml'], + test_expected_logs, ).and_return(other_configuration, ['/tmp/other.yaml'], other_expected_logs) configs, config_paths, logs = tuple( @@ -1668,7 +1687,7 @@ def test_load_configurations_collects_parsed_configurations_and_logs(resolve_env ('test.yaml', 'other.yaml'), arguments=flexmock(), resolve_env=resolve_env, - ) + ), ) assert configs == {'test.yaml': configuration, 'other.yaml': other_configuration} @@ -1680,7 +1699,7 @@ def test_load_configurations_logs_warning_for_permission_error(): flexmock(module.validate).should_receive('parse_configuration').and_raise(PermissionError) configs, config_paths, logs = tuple( - module.load_configurations(('test.yaml',), arguments=flexmock()) + module.load_configurations(('test.yaml',), arguments=flexmock()), ) assert configs == {} @@ -1692,7 +1711,7 @@ def test_load_configurations_logs_critical_for_parse_error(): flexmock(module.validate).should_receive('parse_configuration').and_raise(ValueError) configs, config_paths, logs = tuple( - module.load_configurations(('test.yaml',), arguments=flexmock()) + module.load_configurations(('test.yaml',), arguments=flexmock()), ) assert configs == {} @@ -1721,7 +1740,7 @@ def test_log_error_records_generates_output_logs_for_called_process_error_with_b flexmock(module.logger).should_receive('getEffectiveLevel').and_return(logging.WARNING) logs = tuple( - module.log_error_records('Error', subprocess.CalledProcessError(1, 'ls', b'error output')) + module.log_error_records('Error', subprocess.CalledProcessError(1, 'ls', b'error output')), ) assert {log['levelno'] for log in logs} == {logging.CRITICAL} @@ -1733,7 +1752,7 @@ def test_log_error_records_generates_output_logs_for_called_process_error_with_s flexmock(module.logger).should_receive('getEffectiveLevel').and_return(logging.WARNING) logs = tuple( - module.log_error_records('Error', subprocess.CalledProcessError(1, 'ls', 'error output')) + module.log_error_records('Error', subprocess.CalledProcessError(1, 'ls', 'error output')), ) assert {log['levelno'] for log in logs} == {logging.CRITICAL} @@ -1748,9 +1767,11 @@ def test_log_error_records_generates_work_around_output_logs_for_called_process_ module.log_error_records( 'Error', subprocess.CalledProcessError( - module.BORG_REPOSITORY_ACCESS_ABORTED_EXIT_CODE, 'ls', 'error output' + module.BORG_REPOSITORY_ACCESS_ABORTED_EXIT_CODE, + 'ls', + 'error output', ), - ) + ), ) assert {log['levelno'] for log in logs} == {logging.CRITICAL} @@ -1764,8 +1785,9 @@ def test_log_error_records_splits_called_process_error_with_multiline_ouput_into logs = tuple( module.log_error_records( - 'Error', subprocess.CalledProcessError(1, 'ls', 'error output\nanother line') - ) + 'Error', + subprocess.CalledProcessError(1, 'ls', 'error output\nanother line'), + ), ) assert {log['levelno'] for log in logs} == {logging.CRITICAL} @@ -1814,8 +1836,10 @@ def test_collect_highlander_action_summary_logs_info_for_success_with_bootstrap( logs = tuple( module.collect_highlander_action_summary_logs( - {'test.yaml': {}}, arguments=arguments, configuration_parse_errors=False - ) + {'test.yaml': {}}, + arguments=arguments, + configuration_parse_errors=False, + ), ) assert {log.levelno for log in logs} == {logging.ANSWER} @@ -1823,7 +1847,7 @@ def test_collect_highlander_action_summary_logs_info_for_success_with_bootstrap( def test_collect_highlander_action_summary_logs_error_on_bootstrap_failure(): flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.borgmatic.actions.config.bootstrap).should_receive('run_bootstrap').and_raise( - ValueError + ValueError, ) arguments = { 'bootstrap': flexmock(repository='repo', local_path='borg7'), @@ -1832,8 +1856,10 @@ def test_collect_highlander_action_summary_logs_error_on_bootstrap_failure(): logs = tuple( module.collect_highlander_action_summary_logs( - {'test.yaml': {}}, arguments=arguments, configuration_parse_errors=False - ) + {'test.yaml': {}}, + arguments=arguments, + configuration_parse_errors=False, + ), ) assert {log.levelno for log in logs} == {logging.CRITICAL} @@ -1849,8 +1875,10 @@ def test_collect_highlander_action_summary_logs_error_on_bootstrap_local_borg_ve logs = tuple( module.collect_highlander_action_summary_logs( - {'test.yaml': {}}, arguments=arguments, configuration_parse_errors=False - ) + {'test.yaml': {}}, + arguments=arguments, + configuration_parse_errors=False, + ), ) assert {log.levelno for log in logs} == {logging.CRITICAL} @@ -1865,15 +1893,17 @@ def test_collect_highlander_action_summary_logs_info_for_success_with_generate() logs = tuple( module.collect_highlander_action_summary_logs( - {'test.yaml': {}}, arguments=arguments, configuration_parse_errors=False - ) + {'test.yaml': {}}, + arguments=arguments, + configuration_parse_errors=False, + ), ) assert {log.levelno for log in logs} == {logging.ANSWER} def test_collect_highlander_action_summary_logs_error_on_generate_failure(): flexmock(module.borgmatic.actions.config.generate).should_receive('run_generate').and_raise( - ValueError + ValueError, ) arguments = { 'generate': flexmock(destination='test.yaml'), @@ -1882,8 +1912,10 @@ def test_collect_highlander_action_summary_logs_error_on_generate_failure(): logs = tuple( module.collect_highlander_action_summary_logs( - {'test.yaml': {}}, arguments=arguments, configuration_parse_errors=False - ) + {'test.yaml': {}}, + arguments=arguments, + configuration_parse_errors=False, + ), ) assert {log.levelno for log in logs} == {logging.CRITICAL} @@ -1898,8 +1930,10 @@ def test_collect_highlander_action_summary_logs_info_for_success_with_validate() logs = tuple( module.collect_highlander_action_summary_logs( - {'test.yaml': {}}, arguments=arguments, configuration_parse_errors=False - ) + {'test.yaml': {}}, + arguments=arguments, + configuration_parse_errors=False, + ), ) assert {log.levelno for log in logs} == {logging.ANSWER} @@ -1913,8 +1947,10 @@ def test_collect_highlander_action_summary_logs_error_on_validate_parse_failure( logs = tuple( module.collect_highlander_action_summary_logs( - {'test.yaml': {}}, arguments=arguments, configuration_parse_errors=True - ) + {'test.yaml': {}}, + arguments=arguments, + configuration_parse_errors=True, + ), ) assert {log.levelno for log in logs} == {logging.CRITICAL} @@ -1922,7 +1958,7 @@ def test_collect_highlander_action_summary_logs_error_on_validate_parse_failure( def test_collect_highlander_action_summary_logs_error_on_run_validate_failure(): flexmock(module.borgmatic.actions.config.validate).should_receive('run_validate').and_raise( - ValueError + ValueError, ) arguments = { 'validate': flexmock(), @@ -1931,8 +1967,10 @@ def test_collect_highlander_action_summary_logs_error_on_run_validate_failure(): logs = tuple( module.collect_highlander_action_summary_logs( - {'test.yaml': {}}, arguments=arguments, configuration_parse_errors=False - ) + {'test.yaml': {}}, + arguments=arguments, + configuration_parse_errors=False, + ), ) assert {log.levelno for log in logs} == {logging.CRITICAL} @@ -1941,10 +1979,15 @@ def test_collect_highlander_action_summary_logs_error_on_run_validate_failure(): def test_collect_configuration_run_summary_logs_info_for_success(): flexmock(module.validate).should_receive('guard_configuration_contains_repository') flexmock(module.command).should_receive('filter_hooks').with_args( - object, before='everything', action_names=object + object, + before='everything', + action_names=object, ) flexmock(module.command).should_receive('filter_hooks').with_args( - object, after='everything', action_names=object, state_names=['finish'] + object, + after='everything', + action_names=object, + state_names=['finish'], ) flexmock(module.command).should_receive('execute_hooks') flexmock(module).should_receive('Log_prefix').and_return(flexmock()) @@ -1957,7 +2000,7 @@ def test_collect_configuration_run_summary_logs_info_for_success(): config_paths=['/tmp/test.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert {log.levelno for log in logs} == {logging.INFO} @@ -1969,10 +2012,15 @@ def test_collect_configuration_run_summary_executes_hooks_for_create(): command_hooks = (before_everything_hook, after_everything_hook) flexmock(module.validate).should_receive('guard_configuration_contains_repository') flexmock(module.command).should_receive('filter_hooks').with_args( - command_hooks, before='everything', action_names=object + command_hooks, + before='everything', + action_names=object, ).and_return([before_everything_hook]) flexmock(module.command).should_receive('filter_hooks').with_args( - command_hooks, after='everything', action_names=object, state_names=['finish'] + command_hooks, + after='everything', + action_names=object, + state_names=['finish'], ).and_return([after_everything_hook]) flexmock(module.command).should_receive('execute_hooks').twice() flexmock(module).should_receive('Log_prefix').and_return(flexmock()) @@ -1988,7 +2036,7 @@ def test_collect_configuration_run_summary_executes_hooks_for_create(): config_paths=['/tmp/test.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert {log.levelno for log in logs} == {logging.INFO} @@ -2000,16 +2048,26 @@ def test_collect_configuration_run_summary_deduplicates_everything_hooks_across_ command_hooks = (before_everything_hook, after_everything_hook) flexmock(module.validate).should_receive('guard_configuration_contains_repository') flexmock(module.command).should_receive('filter_hooks').with_args( - command_hooks, before='everything', action_names=object + command_hooks, + before='everything', + action_names=object, ).and_return([before_everything_hook]).once() flexmock(module.command).should_receive('filter_hooks').with_args( - (after_everything_hook,), before='everything', action_names=object + (after_everything_hook,), + before='everything', + action_names=object, ).and_return([]).once() flexmock(module.command).should_receive('filter_hooks').with_args( - command_hooks, after='everything', action_names=object, state_names=['finish'] + command_hooks, + after='everything', + action_names=object, + state_names=['finish'], ).and_return([after_everything_hook]).once() flexmock(module.command).should_receive('filter_hooks').with_args( - (before_everything_hook,), after='everything', action_names=object, state_names=['finish'] + (before_everything_hook,), + after='everything', + action_names=object, + state_names=['finish'], ).and_return([]).once() flexmock(module.command).should_receive('execute_hooks').twice() flexmock(module).should_receive('Log_prefix').and_return(flexmock()) @@ -2025,7 +2083,7 @@ def test_collect_configuration_run_summary_deduplicates_everything_hooks_across_ config_paths=['/tmp/test.yaml', '/tmp/other.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert {log.levelno for log in logs} == {logging.INFO} @@ -2034,10 +2092,15 @@ def test_collect_configuration_run_summary_deduplicates_everything_hooks_across_ def test_collect_configuration_run_summary_logs_info_for_success_with_extract(): flexmock(module.validate).should_receive('guard_configuration_contains_repository') flexmock(module.command).should_receive('filter_hooks').with_args( - object, before='everything', action_names=object + object, + before='everything', + action_names=object, ) flexmock(module.command).should_receive('filter_hooks').with_args( - object, after='everything', action_names=object, state_names=['finish'] + object, + after='everything', + action_names=object, + state_names=['finish'], ) flexmock(module.command).should_receive('execute_hooks') flexmock(module).should_receive('Log_prefix').and_return(flexmock()) @@ -2053,7 +2116,7 @@ def test_collect_configuration_run_summary_logs_info_for_success_with_extract(): config_paths=['/tmp/test.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert {log.levelno for log in logs} == {logging.INFO} @@ -2061,7 +2124,7 @@ def test_collect_configuration_run_summary_logs_info_for_success_with_extract(): def test_collect_configuration_run_summary_logs_extract_with_repository_error(): flexmock(module.validate).should_receive('guard_configuration_contains_repository').and_raise( - ValueError + ValueError, ) expected_logs = (flexmock(),) flexmock(module).should_receive('log_error_records').and_return(expected_logs) @@ -2073,7 +2136,7 @@ def test_collect_configuration_run_summary_logs_extract_with_repository_error(): config_paths=['/tmp/test.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert logs == expected_logs @@ -2082,10 +2145,15 @@ def test_collect_configuration_run_summary_logs_extract_with_repository_error(): def test_collect_configuration_run_summary_logs_info_for_success_with_mount(): flexmock(module.validate).should_receive('guard_configuration_contains_repository') flexmock(module.command).should_receive('filter_hooks').with_args( - object, before='everything', action_names=object + object, + before='everything', + action_names=object, ) flexmock(module.command).should_receive('filter_hooks').with_args( - object, after='everything', action_names=object, state_names=['finish'] + object, + after='everything', + action_names=object, + state_names=['finish'], ) flexmock(module.command).should_receive('execute_hooks') flexmock(module).should_receive('Log_prefix').and_return(flexmock()) @@ -2101,7 +2169,7 @@ def test_collect_configuration_run_summary_logs_info_for_success_with_mount(): config_paths=['/tmp/test.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert {log.levelno for log in logs} == {logging.INFO} @@ -2109,7 +2177,7 @@ def test_collect_configuration_run_summary_logs_info_for_success_with_mount(): def test_collect_configuration_run_summary_logs_mount_with_repository_error(): flexmock(module.validate).should_receive('guard_configuration_contains_repository').and_raise( - ValueError + ValueError, ) expected_logs = (flexmock(),) flexmock(module).should_receive('log_error_records').and_return(expected_logs) @@ -2124,7 +2192,7 @@ def test_collect_configuration_run_summary_logs_mount_with_repository_error(): config_paths=['/tmp/test.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert logs == expected_logs @@ -2133,10 +2201,15 @@ def test_collect_configuration_run_summary_logs_mount_with_repository_error(): def test_collect_configuration_run_summary_logs_missing_configs_error(): flexmock(module.validate).should_receive('guard_configuration_contains_repository') flexmock(module.command).should_receive('filter_hooks').with_args( - object, before='everything', action_names=object + object, + before='everything', + action_names=object, ) flexmock(module.command).should_receive('filter_hooks').with_args( - object, after='everything', action_names=object, state_names=['fail'] + object, + after='everything', + action_names=object, + state_names=['fail'], ) flexmock(module.command).should_receive('execute_hooks') arguments = {'global': flexmock(config_paths=[])} @@ -2145,8 +2218,11 @@ def test_collect_configuration_run_summary_logs_missing_configs_error(): logs = tuple( module.collect_configuration_run_summary_logs( - {}, config_paths=[], arguments=arguments, log_file_path=None - ) + {}, + config_paths=[], + arguments=arguments, + log_file_path=None, + ), ) assert logs == expected_logs @@ -2158,10 +2234,15 @@ def test_collect_configuration_run_summary_logs_before_hook_error(): command_hooks = (before_everything_hook, after_everything_hook) flexmock(module.validate).should_receive('guard_configuration_contains_repository') flexmock(module.command).should_receive('filter_hooks').with_args( - object, before='everything', action_names=object + object, + before='everything', + action_names=object, ).and_return([before_everything_hook]) flexmock(module.command).should_receive('filter_hooks').with_args( - object, after='everything', action_names=object, state_names=['fail'] + object, + after='everything', + action_names=object, + state_names=['fail'], ).and_return([after_everything_hook]) flexmock(module.command).should_receive('execute_hooks').and_raise(ValueError) expected_logs = (flexmock(),) @@ -2177,7 +2258,7 @@ def test_collect_configuration_run_summary_logs_before_hook_error(): config_paths=['/tmp/test.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert logs == expected_logs @@ -2189,10 +2270,15 @@ def test_collect_configuration_run_summary_logs_after_hook_error(): command_hooks = (before_everything_hook, after_everything_hook) flexmock(module.validate).should_receive('guard_configuration_contains_repository') flexmock(module.command).should_receive('filter_hooks').with_args( - object, before='everything', action_names=object + object, + before='everything', + action_names=object, ).and_return([before_everything_hook]) flexmock(module.command).should_receive('filter_hooks').with_args( - object, after='everything', action_names=object, state_names=['finish'] + object, + after='everything', + action_names=object, + state_names=['finish'], ).and_return([after_everything_hook]) flexmock(module.command).should_receive('execute_hooks').and_return(None).and_raise(ValueError) flexmock(module).should_receive('Log_prefix').and_return(flexmock()) @@ -2210,7 +2296,7 @@ def test_collect_configuration_run_summary_logs_after_hook_error(): config_paths=['/tmp/test.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert expected_logs[0] in logs @@ -2218,7 +2304,7 @@ def test_collect_configuration_run_summary_logs_after_hook_error(): def test_collect_configuration_run_summary_logs_for_list_with_archive_and_repository_error(): flexmock(module.validate).should_receive('guard_configuration_contains_repository').and_raise( - ValueError + ValueError, ) expected_logs = (flexmock(),) flexmock(module).should_receive('log_error_records').and_return(expected_logs) @@ -2233,7 +2319,7 @@ def test_collect_configuration_run_summary_logs_for_list_with_archive_and_reposi config_paths=['/tmp/test.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert logs == expected_logs @@ -2242,10 +2328,15 @@ def test_collect_configuration_run_summary_logs_for_list_with_archive_and_reposi def test_collect_configuration_run_summary_logs_info_for_success_with_list(): flexmock(module.validate).should_receive('guard_configuration_contains_repository') flexmock(module.command).should_receive('filter_hooks').with_args( - object, before='everything', action_names=object + object, + before='everything', + action_names=object, ) flexmock(module.command).should_receive('filter_hooks').with_args( - object, after='everything', action_names=object, state_names=['finish'] + object, + after='everything', + action_names=object, + state_names=['finish'], ) flexmock(module.command).should_receive('execute_hooks') flexmock(module).should_receive('Log_prefix').and_return(flexmock()) @@ -2261,7 +2352,7 @@ def test_collect_configuration_run_summary_logs_info_for_success_with_list(): config_paths=['/tmp/test.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert {log.levelno for log in logs} == {logging.INFO} @@ -2270,15 +2361,20 @@ def test_collect_configuration_run_summary_logs_info_for_success_with_list(): def test_collect_configuration_run_summary_logs_run_configuration_error_logs(): flexmock(module.validate).should_receive('guard_configuration_contains_repository') flexmock(module.command).should_receive('filter_hooks').with_args( - object, before='everything', action_names=object + object, + before='everything', + action_names=object, ) flexmock(module.command).should_receive('filter_hooks').with_args( - object, after='everything', action_names=object, state_names=['fail'] + object, + after='everything', + action_names=object, + state_names=['fail'], ) flexmock(module.command).should_receive('execute_hooks') flexmock(module).should_receive('Log_prefix').and_return(flexmock()) flexmock(module).should_receive('run_configuration').and_return( - [logging.makeLogRecord(dict(levelno=logging.CRITICAL, levelname='CRITICAL', msg='Error'))] + [logging.makeLogRecord(dict(levelno=logging.CRITICAL, levelname='CRITICAL', msg='Error'))], ) flexmock(module).should_receive('log_error_records').and_return([]) arguments = {'global': flexmock(dry_run=False)} @@ -2289,7 +2385,7 @@ def test_collect_configuration_run_summary_logs_run_configuration_error_logs(): config_paths=['/tmp/test.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert {log.levelno for log in logs} == {logging.CRITICAL} @@ -2298,17 +2394,22 @@ def test_collect_configuration_run_summary_logs_run_configuration_error_logs(): def test_collect_configuration_run_summary_logs_run_umount_error(): flexmock(module.validate).should_receive('guard_configuration_contains_repository') flexmock(module.command).should_receive('filter_hooks').with_args( - object, before='everything', action_names=object + object, + before='everything', + action_names=object, ) flexmock(module.command).should_receive('filter_hooks').with_args( - object, after='everything', action_names=object, state_names=['fail'] + object, + after='everything', + action_names=object, + state_names=['fail'], ) flexmock(module.command).should_receive('execute_hooks') flexmock(module).should_receive('Log_prefix').and_return(flexmock()) flexmock(module).should_receive('run_configuration').and_return([]) flexmock(module.borg_umount).should_receive('unmount_archive').and_raise(OSError) flexmock(module).should_receive('log_error_records').and_return( - [logging.makeLogRecord(dict(levelno=logging.CRITICAL, levelname='CRITICAL', msg='Error'))] + [logging.makeLogRecord(dict(levelno=logging.CRITICAL, levelname='CRITICAL', msg='Error'))], ) arguments = { 'umount': flexmock(mount_point='/mnt'), @@ -2321,7 +2422,7 @@ def test_collect_configuration_run_summary_logs_run_umount_error(): config_paths=['/tmp/test.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) assert {log.levelno for log in logs} == {logging.INFO, logging.CRITICAL} @@ -2330,15 +2431,20 @@ def test_collect_configuration_run_summary_logs_run_umount_error(): def test_collect_configuration_run_summary_logs_outputs_merged_json_results(): flexmock(module.validate).should_receive('guard_configuration_contains_repository') flexmock(module.command).should_receive('filter_hooks').with_args( - object, before='everything', action_names=object + object, + before='everything', + action_names=object, ) flexmock(module.command).should_receive('filter_hooks').with_args( - object, after='everything', action_names=object, state_names=['finish'] + object, + after='everything', + action_names=object, + state_names=['finish'], ) flexmock(module.command).should_receive('execute_hooks') flexmock(module).should_receive('Log_prefix').and_return(flexmock()) flexmock(module).should_receive('run_configuration').and_return(['foo', 'bar']).and_return( - ['baz'] + ['baz'], ) stdout = flexmock() stdout.should_receive('write').with_args('["foo", "bar", "baz"]').once() @@ -2351,7 +2457,7 @@ def test_collect_configuration_run_summary_logs_outputs_merged_json_results(): config_paths=['/tmp/test.yaml', '/tmp/test2.yaml'], arguments=arguments, log_file_path=None, - ) + ), ) diff --git a/tests/unit/config/test_arguments.py b/tests/unit/config/test_arguments.py index fdf5f0f5..92907206 100644 --- a/tests/unit/config/test_arguments.py +++ b/tests/unit/config/test_arguments.py @@ -74,7 +74,7 @@ def test_set_values_with_final_list_index_key_adds_it_to_config(): def test_type_for_option_with_option_finds_type(): flexmock(module.borgmatic.config.schema).should_receive('get_properties').replace_with( - lambda sub_schema: sub_schema['properties'] + lambda sub_schema: sub_schema['properties'], ) assert ( @@ -88,7 +88,7 @@ def test_type_for_option_with_option_finds_type(): def test_type_for_option_with_nested_option_finds_type(): flexmock(module.borgmatic.config.schema).should_receive('get_properties').replace_with( - lambda sub_schema: sub_schema['properties'] + lambda sub_schema: sub_schema['properties'], ) assert ( @@ -96,7 +96,7 @@ def test_type_for_option_with_nested_option_finds_type(): schema={ 'type': 'object', 'properties': { - 'foo': {'type': 'object', 'properties': {'bar': {'type': 'boolean'}}} + 'foo': {'type': 'object', 'properties': {'bar': {'type': 'boolean'}}}, }, }, option_keys=('foo', 'bar'), @@ -107,7 +107,7 @@ def test_type_for_option_with_nested_option_finds_type(): def test_type_for_option_with_missing_nested_option_finds_nothing(): flexmock(module.borgmatic.config.schema).should_receive('get_properties').replace_with( - lambda sub_schema: sub_schema['properties'] + lambda sub_schema: sub_schema['properties'], ) assert ( @@ -115,7 +115,7 @@ def test_type_for_option_with_missing_nested_option_finds_nothing(): schema={ 'type': 'object', 'properties': { - 'foo': {'type': 'object', 'properties': {'other': {'type': 'integer'}}} + 'foo': {'type': 'object', 'properties': {'other': {'type': 'integer'}}}, }, }, option_keys=('foo', 'bar'), @@ -126,7 +126,7 @@ def test_type_for_option_with_missing_nested_option_finds_nothing(): def test_type_for_option_with_typeless_nested_option_finds_nothing(): flexmock(module.borgmatic.config.schema).should_receive('get_properties').replace_with( - lambda sub_schema: sub_schema['properties'] + lambda sub_schema: sub_schema['properties'], ) assert ( @@ -143,7 +143,7 @@ def test_type_for_option_with_typeless_nested_option_finds_nothing(): def test_type_for_option_with_list_index_option_finds_type(): flexmock(module.borgmatic.config.schema).should_receive('get_properties').replace_with( - lambda sub_schema: sub_schema['properties'] + lambda sub_schema: sub_schema['properties'], ) assert ( @@ -160,7 +160,7 @@ def test_type_for_option_with_list_index_option_finds_type(): def test_type_for_option_with_nested_list_index_option_finds_type(): flexmock(module.borgmatic.config.schema).should_receive('get_properties').replace_with( - lambda sub_schema: sub_schema['properties'] + lambda sub_schema: sub_schema['properties'], ) assert ( @@ -171,7 +171,7 @@ def test_type_for_option_with_nested_list_index_option_finds_type(): 'foo': { 'type': 'array', 'items': {'type': 'object', 'properties': {'bar': {'type': 'integer'}}}, - } + }, }, }, option_keys=('foo[0]', 'bar'), @@ -227,7 +227,7 @@ def test_apply_arguments_to_config_does_not_raise(): ( (('foo', 'bar'), 'baz'), (('one', 'two'), 'three'), - ) + ), ) flexmock(module).should_receive('set_values') diff --git a/tests/unit/config/test_checks.py b/tests/unit/config/test_checks.py index 6de42b4b..29f04adb 100644 --- a/tests/unit/config/test_checks.py +++ b/tests/unit/config/test_checks.py @@ -9,7 +9,8 @@ def test_repository_enabled_for_checks_defaults_to_enabled_for_all_repositories( def test_repository_enabled_for_checks_is_enabled_for_specified_repositories(): enabled = module.repository_enabled_for_checks( - 'repo.borg', config={'check_repositories': ['repo.borg', 'other.borg']} + 'repo.borg', + config={'check_repositories': ['repo.borg', 'other.borg']}, ) assert enabled @@ -17,7 +18,8 @@ def test_repository_enabled_for_checks_is_enabled_for_specified_repositories(): def test_repository_enabled_for_checks_is_disabled_for_other_repositories(): enabled = module.repository_enabled_for_checks( - 'repo.borg', config={'check_repositories': ['other.borg']} + 'repo.borg', + config={'check_repositories': ['other.borg']}, ) assert not enabled diff --git a/tests/unit/config/test_collect.py b/tests/unit/config/test_collect.py index d20c006f..63881371 100644 --- a/tests/unit/config/test_collect.py +++ b/tests/unit/config/test_collect.py @@ -59,7 +59,7 @@ def test_collect_config_filenames_collects_files_from_given_directories_and_igno flexmock(module.os).should_receive('access').and_return(True) flexmock(module.os).should_receive('listdir') flexmock(sys.modules['builtins']).should_receive('sorted').and_return( - ['foo.yaml', 'bar', 'baz.yaml'] + ['foo.yaml', 'bar', 'baz.yaml'], ) config_filenames = tuple(module.collect_config_filenames(config_paths)) @@ -83,7 +83,7 @@ def test_collect_config_filenames_collects_files_from_given_directories_and_igno flexmock(module.os).should_receive('access').and_return(True) flexmock(module.os).should_receive('listdir') flexmock(sys.modules['builtins']).should_receive('sorted').and_return( - ['foo.yaml', 'bar.yaml~', 'baz.txt'] + ['foo.yaml', 'bar.yaml~', 'baz.txt'], ) config_filenames = tuple(module.collect_config_filenames(config_paths)) diff --git a/tests/unit/config/test_environment.py b/tests/unit/config/test_environment.py index 3e342fa0..b7b56dd8 100644 --- a/tests/unit/config/test_environment.py +++ b/tests/unit/config/test_environment.py @@ -12,7 +12,7 @@ def test_env(monkeypatch): def test_env_braces(monkeypatch): monkeypatch.setenv('MY_CUSTOM_VALUE', 'foo') - config = {'key': 'Hello ${MY_CUSTOM_VALUE}'} # noqa: FS003 + config = {'key': 'Hello ${MY_CUSTOM_VALUE}'} module.resolve_env_variables(config) assert config == {'key': 'Hello foo'} @@ -20,7 +20,7 @@ def test_env_braces(monkeypatch): def test_env_multi(monkeypatch): monkeypatch.setenv('MY_CUSTOM_VALUE', 'foo') monkeypatch.setenv('MY_CUSTOM_VALUE2', 'bar') - config = {'key': 'Hello ${MY_CUSTOM_VALUE}${MY_CUSTOM_VALUE2}'} # noqa: FS003 + config = {'key': 'Hello ${MY_CUSTOM_VALUE}${MY_CUSTOM_VALUE2}'} module.resolve_env_variables(config) assert config == {'key': 'Hello foobar'} @@ -28,21 +28,21 @@ def test_env_multi(monkeypatch): def test_env_escape(monkeypatch): monkeypatch.setenv('MY_CUSTOM_VALUE', 'foo') monkeypatch.setenv('MY_CUSTOM_VALUE2', 'bar') - config = {'key': r'Hello ${MY_CUSTOM_VALUE} \${MY_CUSTOM_VALUE}'} # noqa: FS003 + config = {'key': r'Hello ${MY_CUSTOM_VALUE} \${MY_CUSTOM_VALUE}'} module.resolve_env_variables(config) - assert config == {'key': r'Hello foo ${MY_CUSTOM_VALUE}'} # noqa: FS003 + assert config == {'key': r'Hello foo ${MY_CUSTOM_VALUE}'} def test_env_default_value(monkeypatch): monkeypatch.delenv('MY_CUSTOM_VALUE', raising=False) - config = {'key': 'Hello ${MY_CUSTOM_VALUE:-bar}'} # noqa: FS003 + config = {'key': 'Hello ${MY_CUSTOM_VALUE:-bar}'} module.resolve_env_variables(config) assert config == {'key': 'Hello bar'} def test_env_unknown(monkeypatch): monkeypatch.delenv('MY_CUSTOM_VALUE', raising=False) - config = {'key': 'Hello ${MY_CUSTOM_VALUE}'} # noqa: FS003 + config = {'key': 'Hello ${MY_CUSTOM_VALUE}'} with pytest.raises(ValueError): module.resolve_env_variables(config) @@ -55,20 +55,20 @@ def test_env_full(monkeypatch): 'dict': { 'key': 'value', 'anotherdict': { - 'key': 'My ${MY_CUSTOM_VALUE} here', # noqa: FS003 - 'other': '${MY_CUSTOM_VALUE}', # noqa: FS003 - 'escaped': r'\${MY_CUSTOM_VALUE}', # noqa: FS003 + 'key': 'My ${MY_CUSTOM_VALUE} here', + 'other': '${MY_CUSTOM_VALUE}', + 'escaped': r'\${MY_CUSTOM_VALUE}', 'list': [ - '/home/${MY_CUSTOM_VALUE}/.local', # noqa: FS003 + '/home/${MY_CUSTOM_VALUE}/.local', '/var/log/', - '/home/${MY_CUSTOM_VALUE2:-bar}/.config', # noqa: FS003 + '/home/${MY_CUSTOM_VALUE2:-bar}/.config', ], }, }, 'list': [ - '/home/${MY_CUSTOM_VALUE}/.local', # noqa: FS003 + '/home/${MY_CUSTOM_VALUE}/.local', '/var/log/', - '/home/${MY_CUSTOM_VALUE2-bar}/.config', # noqa: FS003 + '/home/${MY_CUSTOM_VALUE2-bar}/.config', ], } module.resolve_env_variables(config) @@ -79,7 +79,7 @@ def test_env_full(monkeypatch): 'anotherdict': { 'key': 'My foo here', 'other': 'foo', - 'escaped': '${MY_CUSTOM_VALUE}', # noqa: FS003 + 'escaped': '${MY_CUSTOM_VALUE}', 'list': ['/home/foo/.local', '/var/log/', '/home/bar/.config'], }, }, diff --git a/tests/unit/config/test_generate.py b/tests/unit/config/test_generate.py index ff71b9fb..5e1a2b93 100644 --- a/tests/unit/config/test_generate.py +++ b/tests/unit/config/test_generate.py @@ -12,18 +12,21 @@ def test_schema_to_sample_configuration_generates_config_map_with_examples(): ('field1', {'type': 'string', 'example': 'Example 1'}), ('field2', {'type': 'string', 'example': 'Example 2'}), ('field3', {'type': 'string', 'example': 'Example 3'}), - ] + ], ), } flexmock(module.borgmatic.config.schema).should_receive('compare_types').and_return(False) flexmock(module.borgmatic.config.schema).should_receive('compare_types').with_args( - 'object', {'object'} + 'object', + {'object'}, ).and_return(True) flexmock(module.borgmatic.config.schema).should_receive('compare_types').with_args( - 'string', module.SCALAR_SCHEMA_TYPES, match=all + 'string', + module.SCALAR_SCHEMA_TYPES, + match=all, ).and_return(True) flexmock(module.borgmatic.config.schema).should_receive('get_properties').and_return( - schema['properties'] + schema['properties'], ) flexmock(module.ruamel.yaml.comments).should_receive('CommentedMap').replace_with(dict) flexmock(module).should_receive('add_comments_to_configuration_object') @@ -35,7 +38,7 @@ def test_schema_to_sample_configuration_generates_config_map_with_examples(): ('field1', 'Example 1'), ('field2', 'Example 2'), ('field3', 'Example 3'), - ] + ], ) @@ -49,10 +52,13 @@ def test_schema_to_sample_configuration_with_empty_object_generates_config_map_w } flexmock(module.borgmatic.config.schema).should_receive('compare_types').and_return(False) flexmock(module.borgmatic.config.schema).should_receive('compare_types').with_args( - 'object', {'object'} + 'object', + {'object'}, ).and_return(True) flexmock(module.borgmatic.config.schema).should_receive('compare_types').with_args( - 'string', module.SCALAR_SCHEMA_TYPES, match=all + 'string', + module.SCALAR_SCHEMA_TYPES, + match=all, ).and_return(True) flexmock(module.borgmatic.config.schema).should_receive('get_properties').and_return({}) flexmock(module.ruamel.yaml.comments).should_receive('CommentedMap').replace_with(dict) @@ -64,7 +70,7 @@ def test_schema_to_sample_configuration_with_empty_object_generates_config_map_w [ ('foo', 'Example 1'), ('baz', 'Example 2'), - ] + ], ) @@ -87,22 +93,26 @@ def test_schema_to_sample_configuration_generates_config_sequence_of_maps_with_e [ ('field1', {'type': 'string', 'example': 'Example 1'}), ('field2', {'type': 'string', 'example': 'Example 2'}), - ] + ], ), }, } flexmock(module.borgmatic.config.schema).should_receive('compare_types').and_return(False) flexmock(module.borgmatic.config.schema).should_receive('compare_types').with_args( - 'array', {'array'} + 'array', + {'array'}, ).and_return(True) flexmock(module.borgmatic.config.schema).should_receive('compare_types').with_args( - 'object', {'object'} + 'object', + {'object'}, ).and_return(True) flexmock(module.borgmatic.config.schema).should_receive('compare_types').with_args( - 'string', module.SCALAR_SCHEMA_TYPES, match=all + 'string', + module.SCALAR_SCHEMA_TYPES, + match=all, ).and_return(True) flexmock(module.borgmatic.config.schema).should_receive('get_properties').and_return( - schema['items']['properties'] + schema['items']['properties'], ) flexmock(module.ruamel.yaml.comments).should_receive('CommentedSeq').replace_with(list) flexmock(module).should_receive('add_comments_to_configuration_sequence') @@ -122,22 +132,26 @@ def test_schema_to_sample_configuration_generates_config_sequence_of_maps_with_m [ ('field1', {'type': 'string', 'example': 'Example 1'}), ('field2', {'type': 'string', 'example': 'Example 2'}), - ] + ], ), }, } flexmock(module.borgmatic.config.schema).should_receive('compare_types').and_return(False) flexmock(module.borgmatic.config.schema).should_receive('compare_types').with_args( - 'array', {'array'} + 'array', + {'array'}, ).and_return(True) flexmock(module.borgmatic.config.schema).should_receive('compare_types').with_args( - ['object', 'null'], {'object'} + ['object', 'null'], + {'object'}, ).and_return(True) flexmock(module.borgmatic.config.schema).should_receive('compare_types').with_args( - 'string', module.SCALAR_SCHEMA_TYPES, match=all + 'string', + module.SCALAR_SCHEMA_TYPES, + match=all, ).and_return(True) flexmock(module.borgmatic.config.schema).should_receive('get_properties').and_return( - schema['items']['properties'] + schema['items']['properties'], ) flexmock(module.ruamel.yaml.comments).should_receive('CommentedSeq').replace_with(list) flexmock(module).should_receive('add_comments_to_configuration_sequence') diff --git a/tests/unit/config/test_load.py b/tests/unit/config/test_load.py index 4c1d221c..56f095e3 100644 --- a/tests/unit/config/test_load.py +++ b/tests/unit/config/test_load.py @@ -8,7 +8,8 @@ def test_probe_and_include_file_with_absolute_path_skips_probing(): config = flexmock() config_paths = set() flexmock(module).should_receive('load_configuration').with_args( - '/etc/include.yaml', config_paths + '/etc/include.yaml', + config_paths, ).and_return(config).once() assert ( @@ -20,16 +21,18 @@ def test_probe_and_include_file_with_relative_path_probes_include_directories(): config = {'foo': 'bar'} config_paths = set() flexmock(module.os.path).should_receive('exists').with_args('/etc/include.yaml').and_return( - False + False, ) flexmock(module.os.path).should_receive('exists').with_args('/var/include.yaml').and_return( - True + True, ) flexmock(module).should_receive('load_configuration').with_args( - '/etc/include.yaml', config_paths + '/etc/include.yaml', + config_paths, ).never() flexmock(module).should_receive('load_configuration').with_args( - '/var/include.yaml', config_paths + '/var/include.yaml', + config_paths, ).and_return(config).once() assert module.probe_and_include_file('include.yaml', ['/etc', '/var'], config_paths) == { diff --git a/tests/unit/config/test_normalize.py b/tests/unit/config/test_normalize.py index 24012fdd..58525811 100644 --- a/tests/unit/config/test_normalize.py +++ b/tests/unit/config/test_normalize.py @@ -90,7 +90,9 @@ from borgmatic.config import normalize as module ), ) def test_normalize_sections_moves_section_options_to_global_scope( - config, expected_config, produces_logs + config, + expected_config, + produces_logs, ): logs = module.normalize_sections('test.yaml', config) @@ -132,7 +134,7 @@ def test_normalize_sections_with_only_scalar_raises(): 'commands': [ {'before': 'repository', 'run': ['foo', 'bar']}, {'after': 'repository', 'run': ['baz']}, - ] + ], }, True, ), @@ -142,7 +144,7 @@ def test_normalize_sections_with_only_scalar_raises(): 'commands': [ {'before': 'action', 'when': ['create'], 'run': ['foo', 'bar']}, {'after': 'action', 'when': ['create'], 'run': ['baz']}, - ] + ], }, True, ), @@ -152,7 +154,7 @@ def test_normalize_sections_with_only_scalar_raises(): 'commands': [ {'before': 'action', 'when': ['prune'], 'run': ['foo', 'bar']}, {'after': 'action', 'when': ['prune'], 'run': ['baz']}, - ] + ], }, True, ), @@ -162,7 +164,7 @@ def test_normalize_sections_with_only_scalar_raises(): 'commands': [ {'before': 'action', 'when': ['compact'], 'run': ['foo', 'bar']}, {'after': 'action', 'when': ['compact'], 'run': ['baz']}, - ] + ], }, True, ), @@ -172,7 +174,7 @@ def test_normalize_sections_with_only_scalar_raises(): 'commands': [ {'before': 'action', 'when': ['check'], 'run': ['foo', 'bar']}, {'after': 'action', 'when': ['check'], 'run': ['baz']}, - ] + ], }, True, ), @@ -182,7 +184,7 @@ def test_normalize_sections_with_only_scalar_raises(): 'commands': [ {'before': 'action', 'when': ['extract'], 'run': ['foo', 'bar']}, {'after': 'action', 'when': ['extract'], 'run': ['baz']}, - ] + ], }, True, ), @@ -195,7 +197,7 @@ def test_normalize_sections_with_only_scalar_raises(): 'when': ['create', 'prune', 'compact', 'check'], 'run': ['foo', 'bar'], }, - ] + ], }, True, ), @@ -205,7 +207,7 @@ def test_normalize_sections_with_only_scalar_raises(): 'commands': [ {'before': 'everything', 'when': ['create'], 'run': ['foo', 'bar']}, {'after': 'everything', 'when': ['create'], 'run': ['baz']}, - ] + ], }, True, ), @@ -217,7 +219,9 @@ def test_normalize_sections_with_only_scalar_raises(): ), ) def test_normalize_commands_moves_individual_command_hooks_to_unified_commands( - config, expected_config, produces_logs + config, + expected_config, + produces_logs, ): flexmock(module).should_receive('make_command_hook_deprecation_log').and_return(flexmock()) @@ -382,7 +386,9 @@ def test_normalize_commands_moves_individual_command_hooks_to_unified_commands( ), ) def test_normalize_applies_hard_coded_normalization_to_config( - config, expected_config, produces_logs + config, + expected_config, + produces_logs, ): flexmock(module).should_receive('normalize_sections').and_return([]) flexmock(module).should_receive('normalize_commands').and_return([]) diff --git a/tests/unit/config/test_override.py b/tests/unit/config/test_override.py index ef6d0f64..9e1f3ed8 100644 --- a/tests/unit/config/test_override.py +++ b/tests/unit/config/test_override.py @@ -87,37 +87,34 @@ def test_strip_section_names_passes_through_key_without_section_name(key, expect def test_parse_overrides_splits_keys_and_values(): - flexmock(module).should_receive('strip_section_names').replace_with(lambda value: value) flexmock(module).should_receive('type_for_option').and_return('string') flexmock(module).should_receive('convert_value_type').replace_with( - lambda value, option_type: value + lambda value, option_type: value, ) raw_overrides = ['option.my_option=value1', 'other_option=value2'] expected_result = ( (('option', 'my_option'), 'value1'), - (('other_option'), 'value2'), + (('other_option',), 'value2'), ) - module.parse_overrides(raw_overrides, schema={}) == expected_result + assert module.parse_overrides(raw_overrides, schema={}) == expected_result def test_parse_overrides_allows_value_with_equal_sign(): - flexmock(module).should_receive('strip_section_names').replace_with(lambda value: value) flexmock(module).should_receive('type_for_option').and_return('string') flexmock(module).should_receive('convert_value_type').replace_with( - lambda value, option_type: value + lambda value, option_type: value, ) raw_overrides = ['option=this===value'] expected_result = ((('option',), 'this===value'),) - module.parse_overrides(raw_overrides, schema={}) == expected_result + assert module.parse_overrides(raw_overrides, schema={}) == expected_result def test_parse_overrides_raises_on_missing_equal_sign(): - flexmock(module).should_receive('strip_section_names').replace_with(lambda value: value) flexmock(module).should_receive('type_for_option').and_return('string') flexmock(module).should_receive('convert_value_type').replace_with( - lambda value, option_type: value + lambda value, option_type: value, ) raw_overrides = ['option'] @@ -126,7 +123,6 @@ def test_parse_overrides_raises_on_missing_equal_sign(): def test_parse_overrides_raises_on_invalid_override_value(): - flexmock(module).should_receive('strip_section_names').replace_with(lambda value: value) flexmock(module).should_receive('type_for_option').and_return('string') flexmock(module).should_receive('convert_value_type').and_raise(ruamel.yaml.parser.ParserError) raw_overrides = ['option=[in valid]'] @@ -136,16 +132,15 @@ def test_parse_overrides_raises_on_invalid_override_value(): def test_parse_overrides_allows_value_with_single_key(): - flexmock(module).should_receive('strip_section_names').replace_with(lambda value: value) flexmock(module).should_receive('type_for_option').and_return('string') flexmock(module).should_receive('convert_value_type').replace_with( - lambda value, option_type: value + lambda value, option_type: value, ) raw_overrides = ['option=value'] expected_result = ((('option',), 'value'),) - module.parse_overrides(raw_overrides, schema={}) == expected_result + assert module.parse_overrides(raw_overrides, schema={}) == expected_result def test_parse_overrides_handles_empty_overrides(): - module.parse_overrides(raw_overrides=None, schema={}) == () + assert module.parse_overrides(raw_overrides=None, schema={}) == () diff --git a/tests/unit/config/test_paths.py b/tests/unit/config/test_paths.py index 65e3e477..76cf7248 100644 --- a/tests/unit/config/test_paths.py +++ b/tests/unit/config/test_paths.py @@ -55,7 +55,8 @@ def test_replace_temporary_subdirectory_with_glob_passes_through_non_matching_pa def test_replace_temporary_subdirectory_with_glob_uses_custom_temporary_directory_prefix(): assert ( module.replace_temporary_subdirectory_with_glob( - '/tmp/.borgmatic-aet8kn93/borgmatic', temporary_directory_prefix='.borgmatic-' + '/tmp/.borgmatic-aet8kn93/borgmatic', + temporary_directory_prefix='.borgmatic-', ) == '/tmp/.borgmatic-*/borgmatic' ) @@ -83,15 +84,14 @@ def test_runtime_directory_with_relative_config_option_errors(): flexmock(module.os).should_receive('makedirs').never() config = {'user_runtime_directory': 'run', 'borgmatic_source_directory': '/nope'} - with pytest.raises(ValueError): - with module.Runtime_directory(config) as borgmatic_runtime_directory: # noqa: F841 - pass + with pytest.raises(ValueError), module.Runtime_directory(config): + pass def test_runtime_directory_falls_back_to_xdg_runtime_dir(): flexmock(module).should_receive('expand_user_in_path').replace_with(lambda path: path) flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return( - '/run' + '/run', ) flexmock(module.os).should_receive('makedirs') @@ -102,7 +102,7 @@ def test_runtime_directory_falls_back_to_xdg_runtime_dir(): def test_runtime_directory_falls_back_to_xdg_runtime_dir_without_adding_duplicate_borgmatic_subdirectory(): flexmock(module).should_receive('expand_user_in_path').replace_with(lambda path: path) flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return( - '/run/borgmatic' + '/run/borgmatic', ) flexmock(module.os).should_receive('makedirs') @@ -114,16 +114,15 @@ def test_runtime_directory_with_relative_xdg_runtime_dir_errors(): flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return('run') flexmock(module.os).should_receive('makedirs').never() - with pytest.raises(ValueError): - with module.Runtime_directory({}) as borgmatic_runtime_directory: # noqa: F841 - pass + with pytest.raises(ValueError), module.Runtime_directory({}): + pass def test_runtime_directory_falls_back_to_runtime_directory(): flexmock(module).should_receive('expand_user_in_path').replace_with(lambda path: path) flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('RUNTIME_DIRECTORY').and_return( - '/run' + '/run', ) flexmock(module.os).should_receive('makedirs') @@ -135,7 +134,7 @@ def test_runtime_directory_falls_back_to_runtime_directory_without_adding_duplic flexmock(module).should_receive('expand_user_in_path').replace_with(lambda path: path) flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('RUNTIME_DIRECTORY').and_return( - '/run/borgmatic' + '/run/borgmatic', ) flexmock(module.os).should_receive('makedirs') @@ -146,26 +145,26 @@ def test_runtime_directory_falls_back_to_runtime_directory_without_adding_duplic def test_runtime_directory_with_relative_runtime_directory_errors(): flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('RUNTIME_DIRECTORY').and_return( - 'run' + 'run', ) flexmock(module.os).should_receive('makedirs').never() - with pytest.raises(ValueError): - with module.Runtime_directory({}) as borgmatic_runtime_directory: # noqa: F841 - pass + with pytest.raises(ValueError), module.Runtime_directory({}): + pass def test_runtime_directory_falls_back_to_tmpdir_and_adds_temporary_subdirectory_that_get_cleaned_up(): flexmock(module).should_receive('expand_user_in_path').replace_with(lambda path: path) flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('RUNTIME_DIRECTORY').and_return( - None + None, ) flexmock(module.os.environ).should_receive('get').with_args('TMPDIR').and_return('/run') temporary_directory = flexmock(name='/run/borgmatic-1234') temporary_directory.should_receive('cleanup').once() flexmock(module.tempfile).should_receive('TemporaryDirectory').with_args( - prefix='borgmatic-', dir='/run' + prefix='borgmatic-', + dir='/run', ).and_return(temporary_directory) flexmock(module.os).should_receive('makedirs') @@ -176,29 +175,29 @@ def test_runtime_directory_falls_back_to_tmpdir_and_adds_temporary_subdirectory_ def test_runtime_directory_with_relative_tmpdir_errors(): flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('RUNTIME_DIRECTORY').and_return( - None + None, ) flexmock(module.os.environ).should_receive('get').with_args('TMPDIR').and_return('run') flexmock(module.tempfile).should_receive('TemporaryDirectory').never() flexmock(module.os).should_receive('makedirs').never() - with pytest.raises(ValueError): - with module.Runtime_directory({}) as borgmatic_runtime_directory: # noqa: F841 - pass + with pytest.raises(ValueError), module.Runtime_directory({}): + pass def test_runtime_directory_falls_back_to_temp_and_adds_temporary_subdirectory_that_get_cleaned_up(): flexmock(module).should_receive('expand_user_in_path').replace_with(lambda path: path) flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('RUNTIME_DIRECTORY').and_return( - None + None, ) flexmock(module.os.environ).should_receive('get').with_args('TMPDIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('TEMP').and_return('/run') temporary_directory = flexmock(name='/run/borgmatic-1234') temporary_directory.should_receive('cleanup').once() flexmock(module.tempfile).should_receive('TemporaryDirectory').with_args( - prefix='borgmatic-', dir='/run' + prefix='borgmatic-', + dir='/run', ).and_return(temporary_directory) flexmock(module.os).should_receive('makedirs') @@ -209,30 +208,30 @@ def test_runtime_directory_falls_back_to_temp_and_adds_temporary_subdirectory_th def test_runtime_directory_with_relative_temp_errors(): flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('RUNTIME_DIRECTORY').and_return( - None + None, ) flexmock(module.os.environ).should_receive('get').with_args('TMPDIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('TEMP').and_return('run') flexmock(module.tempfile).should_receive('TemporaryDirectory').never() flexmock(module.os).should_receive('makedirs') - with pytest.raises(ValueError): - with module.Runtime_directory({}) as borgmatic_runtime_directory: # noqa: F841 - pass + with pytest.raises(ValueError), module.Runtime_directory({}): + pass def test_runtime_directory_falls_back_to_hard_coded_tmp_path_and_adds_temporary_subdirectory_that_get_cleaned_up(): flexmock(module).should_receive('expand_user_in_path').replace_with(lambda path: path) flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('RUNTIME_DIRECTORY').and_return( - None + None, ) flexmock(module.os.environ).should_receive('get').with_args('TMPDIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('TEMP').and_return(None) temporary_directory = flexmock(name='/tmp/borgmatic-1234') temporary_directory.should_receive('cleanup').once() flexmock(module.tempfile).should_receive('TemporaryDirectory').with_args( - prefix='borgmatic-', dir='/tmp' + prefix='borgmatic-', + dir='/tmp', ).and_return(temporary_directory) flexmock(module.os).should_receive('makedirs') @@ -244,14 +243,15 @@ def test_runtime_directory_with_erroring_cleanup_does_not_raise(): flexmock(module).should_receive('expand_user_in_path').replace_with(lambda path: path) flexmock(module.os.environ).should_receive('get').with_args('XDG_RUNTIME_DIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('RUNTIME_DIRECTORY').and_return( - None + None, ) flexmock(module.os.environ).should_receive('get').with_args('TMPDIR').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('TEMP').and_return(None) temporary_directory = flexmock(name='/tmp/borgmatic-1234') temporary_directory.should_receive('cleanup').and_raise(OSError).once() flexmock(module.tempfile).should_receive('TemporaryDirectory').with_args( - prefix='borgmatic-', dir='/tmp' + prefix='borgmatic-', + dir='/tmp', ).and_return(temporary_directory) flexmock(module.os).should_receive('makedirs') @@ -277,7 +277,7 @@ def test_get_borgmatic_state_directory_uses_config_option(): assert ( module.get_borgmatic_state_directory( - {'user_state_directory': '/tmp', 'borgmatic_source_directory': '/nope'} + {'user_state_directory': '/tmp', 'borgmatic_source_directory': '/nope'}, ) == '/tmp/borgmatic' ) @@ -294,7 +294,7 @@ def test_get_borgmatic_state_directory_falls_back_to_state_directory(): flexmock(module).should_receive('expand_user_in_path').replace_with(lambda path: path) flexmock(module.os.environ).should_receive('get').with_args('XDG_STATE_HOME').and_return(None) flexmock(module.os.environ).should_receive('get').with_args('STATE_DIRECTORY').and_return( - '/tmp' + '/tmp', ) assert module.get_borgmatic_state_directory({}) == '/tmp/borgmatic' diff --git a/tests/unit/config/test_schema.py b/tests/unit/config/test_schema.py index 8af890fb..381c5bdf 100644 --- a/tests/unit/config/test_schema.py +++ b/tests/unit/config/test_schema.py @@ -9,7 +9,7 @@ def test_get_properties_with_simple_object(): 'properties': dict( [ ('field1', {'example': 'Example'}), - ] + ], ), } @@ -25,7 +25,7 @@ def test_get_properties_merges_oneof_list_properties(): [ ('field1', {'example': 'Example 1'}), ('field2', {'example': 'Example 2'}), - ] + ], ), }, { @@ -33,14 +33,15 @@ def test_get_properties_merges_oneof_list_properties(): [ ('field2', {'example': 'Example 2'}), ('field3', {'example': 'Example 3'}), - ] + ], ), }, ], } assert module.get_properties(schema) == dict( - schema['oneOf'][0]['properties'], **schema['oneOf'][1]['properties'] + schema['oneOf'][0]['properties'], + **schema['oneOf'][1]['properties'], ) @@ -54,7 +55,7 @@ def test_get_properties_interleaves_oneof_list_properties(): ('field1', {'example': 'Example 1'}), ('field2', {'example': 'Example 2'}), ('field3', {'example': 'Example 3'}), - ] + ], ), }, { @@ -62,7 +63,7 @@ def test_get_properties_interleaves_oneof_list_properties(): [ ('field4', {'example': 'Example 4'}), ('field5', {'example': 'Example 5'}), - ] + ], ), }, ], @@ -75,12 +76,12 @@ def test_get_properties_interleaves_oneof_list_properties(): ('field2', {'example': 'Example 2'}), ('field5', {'example': 'Example 5'}), ('field3', {'example': 'Example 3'}), - ] + ], ) def test_parse_type_maps_schema_type_to_python_type(): - module.parse_type('boolean') == bool + assert module.parse_type('boolean') is bool def test_parse_type_with_unknown_schema_type_raises(): @@ -89,7 +90,7 @@ def test_parse_type_with_unknown_schema_type_raises(): def test_parse_type_respect_overrides_when_mapping_types(): - module.parse_type('boolean', boolean=int) == int + assert module.parse_type('boolean', boolean=int) is int @pytest.mark.parametrize( @@ -152,7 +153,10 @@ def test_parse_type_respect_overrides_when_mapping_types(): ), ) def test_compare_types_returns_whether_schema_type_matches_target_types( - schema_type, target_types, match, expected_result + schema_type, + target_types, + match, + expected_result, ): if match: assert module.compare_types(schema_type, target_types, match) == expected_result diff --git a/tests/unit/config/test_validate.py b/tests/unit/config/test_validate.py index 04b5bb40..2f418903 100644 --- a/tests/unit/config/test_validate.py +++ b/tests/unit/config/test_validate.py @@ -13,7 +13,7 @@ def test_schema_filename_finds_schema_path(): flexmock(os.path).should_receive('dirname').and_return('/var/borgmatic/config') builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args(schema_path).and_return(StringIO()) + builtins.should_receive('open').with_args(schema_path, encoding='utf-8').and_return(StringIO()) assert module.schema_filename() == schema_path @@ -22,18 +22,20 @@ def test_schema_filename_raises_filenotfounderror(): flexmock(os.path).should_receive('dirname').and_return('/var/borgmatic/config') builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args(schema_path).and_raise(FileNotFoundError) + builtins.should_receive('open').with_args(schema_path, encoding='utf-8').and_raise( + FileNotFoundError + ) with pytest.raises(FileNotFoundError): module.schema_filename() def test_format_json_error_path_element_formats_array_index(): - module.format_json_error_path_element(3) == '[3]' + assert module.format_json_error_path_element(3) == '[3]' def test_format_json_error_path_element_formats_property(): - module.format_json_error_path_element('foo') == '.foo' + assert module.format_json_error_path_element('foo') == '.foo' def test_format_json_error_formats_error_including_path(): @@ -91,55 +93,56 @@ def test_apply_logical_validation_does_not_raise_if_known_repository_in_check_re def test_normalize_repository_path_passes_through_remote_repository(): repository = 'example.org:test.borg' - module.normalize_repository_path(repository) == repository + assert module.normalize_repository_path(repository) == repository def test_normalize_repository_path_passes_through_remote_repository_with_base_dir(): repository = 'example.org:test.borg' flexmock(module.os.path).should_receive('abspath').never() - module.normalize_repository_path(repository, '/working') == repository + + assert module.normalize_repository_path(repository, '/working') == repository def test_normalize_repository_path_passes_through_file_repository(): repository = 'file:///foo/bar/test.borg' flexmock(module.os.path).should_receive('abspath').with_args('/foo/bar/test.borg').and_return( - '/foo/bar/test.borg' + '/foo/bar/test.borg', ) - module.normalize_repository_path(repository) == '/foo/bar/test.borg' + assert module.normalize_repository_path(repository) == '/foo/bar/test.borg' def test_normalize_repository_path_passes_through_absolute_file_repository_with_base_dir(): repository = 'file:///foo/bar/test.borg' flexmock(module.os.path).should_receive('abspath').with_args('/foo/bar/test.borg').and_return( - '/foo/bar/test.borg' + '/foo/bar/test.borg', ) - module.normalize_repository_path(repository, '/working') == '/foo/bar/test.borg' + assert module.normalize_repository_path(repository, '/working') == '/foo/bar/test.borg' def test_normalize_repository_path_resolves_relative_file_repository_with_base_dir(): repository = 'file://foo/bar/test.borg' flexmock(module.os.path).should_receive('abspath').with_args( - '/working/foo/bar/test.borg' + '/working/foo/bar/test.borg', ).and_return('/working/foo/bar/test.borg') - module.normalize_repository_path(repository, '/working') == '/working/foo/bar/test.borg' + assert module.normalize_repository_path(repository, '/working') == '/working/foo/bar/test.borg' def test_normalize_repository_path_passes_through_absolute_repository(): repository = '/foo/bar/test.borg' flexmock(module.os.path).should_receive('abspath').and_return(repository) - module.normalize_repository_path(repository) == repository + assert module.normalize_repository_path(repository) == repository def test_normalize_repository_path_passes_through_absolute_repository_with_base_dir(): repository = '/foo/bar/test.borg' flexmock(module.os.path).should_receive('abspath').and_return(repository) - module.normalize_repository_path(repository, '/working') == repository + assert module.normalize_repository_path(repository, '/working') == repository def test_normalize_repository_path_resolves_relative_repository(): @@ -147,7 +150,7 @@ def test_normalize_repository_path_resolves_relative_repository(): absolute = '/foo/bar/test.borg' flexmock(module.os.path).should_receive('abspath').with_args(repository).and_return(absolute) - module.normalize_repository_path(repository) == absolute + assert module.normalize_repository_path(repository) == absolute def test_normalize_repository_path_resolves_relative_repository_with_base_dir(): @@ -155,10 +158,10 @@ def test_normalize_repository_path_resolves_relative_repository_with_base_dir(): base = '/working' absolute = '/working/test.borg' flexmock(module.os.path).should_receive('abspath').with_args('/working/test.borg').and_return( - absolute + absolute, ) - module.normalize_repository_path(repository, base) == absolute + assert module.normalize_repository_path(repository, base) == absolute @pytest.mark.parametrize( @@ -179,63 +182,75 @@ def test_glob_match_matches_globs(first, second, expected_result): def test_repositories_match_matches_on_path(): - flexmock(module).should_receive('normalize_repository_path') + flexmock(module).should_receive('normalize_repository_path').replace_with(lambda path: path) flexmock(module).should_receive('glob_match').replace_with( - lambda first, second: first == second + lambda first, second: first == second, ) - module.repositories_match( - {'path': 'foo', 'label': 'my repo'}, {'path': 'foo', 'label': 'other repo'} - ) is True + assert ( + module.repositories_match( + {'path': 'foo', 'label': 'my repo'}, + {'path': 'foo', 'label': 'other repo'}, + ) + is True + ) def test_repositories_match_matches_on_label(): - flexmock(module).should_receive('normalize_repository_path') + flexmock(module).should_receive('normalize_repository_path').replace_with(lambda path: path) flexmock(module).should_receive('glob_match').replace_with( - lambda first, second: first == second + lambda first, second: first == second, ) - module.repositories_match( - {'path': 'foo', 'label': 'my repo'}, {'path': 'bar', 'label': 'my repo'} - ) is True + assert ( + module.repositories_match( + {'path': 'foo', 'label': 'my repo'}, + {'path': 'bar', 'label': 'my repo'}, + ) + is True + ) def test_repositories_match_with_different_paths_and_labels_does_not_match(): - flexmock(module).should_receive('normalize_repository_path') + flexmock(module).should_receive('normalize_repository_path').replace_with(lambda path: path) flexmock(module).should_receive('glob_match').replace_with( - lambda first, second: first == second + lambda first, second: first == second, ) - module.repositories_match( - {'path': 'foo', 'label': 'my repo'}, {'path': 'bar', 'label': 'other repo'} - ) is False + assert ( + module.repositories_match( + {'path': 'foo', 'label': 'my repo'}, + {'path': 'bar', 'label': 'other repo'}, + ) + is False + ) def test_repositories_match_matches_on_string_repository(): - flexmock(module).should_receive('normalize_repository_path') + flexmock(module).should_receive('normalize_repository_path').replace_with(lambda path: path) flexmock(module).should_receive('glob_match').replace_with( - lambda first, second: first == second + lambda first, second: first == second, ) - module.repositories_match('foo', 'foo') is True + assert module.repositories_match('foo', 'foo') is True def test_repositories_match_with_different_string_repositories_does_not_match(): - flexmock(module).should_receive('normalize_repository_path') + flexmock(module).should_receive('normalize_repository_path').replace_with(lambda path: path) flexmock(module).should_receive('glob_match').replace_with( - lambda first, second: first == second + lambda first, second: first == second, ) - module.repositories_match('foo', 'bar') is False + assert module.repositories_match('foo', 'bar') is False def test_repositories_match_supports_mixed_repositories(): - flexmock(module).should_receive('normalize_repository_path') + flexmock(module).should_receive('normalize_repository_path').replace_with(lambda path: path) flexmock(module).should_receive('glob_match').replace_with( - lambda first, second: first == second + lambda first, second: first == second, ) - module.repositories_match({'path': 'foo', 'label': 'my foo'}, 'bar') is False + assert module.repositories_match({'path': 'foo', 'label': 'my foo'}, 'bar') is False def test_guard_configuration_contains_repository_does_not_raise_when_repository_matches(): diff --git a/tests/unit/hooks/credential/test_container.py b/tests/unit/hooks/credential/test_container.py index 5f03c871..7d5dc9d4 100644 --- a/tests/unit/hooks/credential/test_container.py +++ b/tests/unit/hooks/credential/test_container.py @@ -11,14 +11,18 @@ from borgmatic.hooks.credential import container as module def test_load_credential_with_invalid_credential_parameters_raises(credential_parameters): with pytest.raises(ValueError): module.load_credential( - hook_config={}, config={}, credential_parameters=credential_parameters + hook_config={}, + config={}, + credential_parameters=credential_parameters, ) def test_load_credential_with_invalid_secret_name_raises(): with pytest.raises(ValueError): module.load_credential( - hook_config={}, config={}, credential_parameters=('this is invalid',) + hook_config={}, + config={}, + credential_parameters=('this is invalid',), ) @@ -26,7 +30,9 @@ def test_load_credential_reads_named_secret_from_file(): credential_stream = io.StringIO('password') credential_stream.name = '/run/secrets/mysecret' builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('/run/secrets/mysecret').and_return(credential_stream) + builtins.should_receive('open').with_args('/run/secrets/mysecret', encoding='utf-8').and_return( + credential_stream + ) assert ( module.load_credential(hook_config={}, config={}, credential_parameters=('mysecret',)) @@ -39,11 +45,15 @@ def test_load_credential_with_custom_secrets_directory_looks_there_for_secret_fi credential_stream = io.StringIO('password') credential_stream.name = '/secrets/mysecret' builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('/secrets/mysecret').and_return(credential_stream) + builtins.should_receive('open').with_args('/secrets/mysecret', encoding='utf-8').and_return( + credential_stream + ) assert ( module.load_credential( - hook_config=config['container'], config=config, credential_parameters=('mysecret',) + hook_config=config['container'], + config=config, + credential_parameters=('mysecret',), ) == 'password' ) @@ -54,13 +64,17 @@ def test_load_credential_with_custom_secrets_directory_prefixes_it_with_working_ credential_stream = io.StringIO('password') credential_stream.name = '/working/secrets/mysecret' builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('/working/secrets/mysecret').and_return( - credential_stream + builtins.should_receive('open').with_args( + '/working/secrets/mysecret', encoding='utf-8' + ).and_return( + credential_stream, ) assert ( module.load_credential( - hook_config=config['container'], config=config, credential_parameters=('mysecret',) + hook_config=config['container'], + config=config, + credential_parameters=('mysecret',), ) == 'password' ) @@ -68,7 +82,9 @@ def test_load_credential_with_custom_secrets_directory_prefixes_it_with_working_ def test_load_credential_with_file_not_found_error_raises(): builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('/run/secrets/mysecret').and_raise(FileNotFoundError) + builtins.should_receive('open').with_args('/run/secrets/mysecret', encoding='utf-8').and_raise( + FileNotFoundError + ) with pytest.raises(ValueError): module.load_credential(hook_config={}, config={}, credential_parameters=('mysecret',)) diff --git a/tests/unit/hooks/credential/test_file.py b/tests/unit/hooks/credential/test_file.py index 42827a85..85354b88 100644 --- a/tests/unit/hooks/credential/test_file.py +++ b/tests/unit/hooks/credential/test_file.py @@ -11,14 +11,18 @@ from borgmatic.hooks.credential import file as module def test_load_credential_with_invalid_credential_parameters_raises(credential_parameters): with pytest.raises(ValueError): module.load_credential( - hook_config={}, config={}, credential_parameters=credential_parameters + hook_config={}, + config={}, + credential_parameters=credential_parameters, ) def test_load_credential_with_invalid_credential_name_raises(): with pytest.raises(ValueError): module.load_credential( - hook_config={}, config={}, credential_parameters=('this is invalid',) + hook_config={}, + config={}, + credential_parameters=('this is invalid',), ) @@ -27,15 +31,19 @@ def test_load_credential_reads_named_credential_from_file(): credential_stream.name = '/credentials/mycredential' builtins = flexmock(sys.modules['builtins']) flexmock(module.os.path).should_receive('expanduser').with_args( - '/credentials/mycredential' + '/credentials/mycredential', ).and_return('/credentials/mycredential') - builtins.should_receive('open').with_args('/credentials/mycredential').and_return( - credential_stream + builtins.should_receive('open').with_args( + '/credentials/mycredential', encoding='utf-8' + ).and_return( + credential_stream, ) assert ( module.load_credential( - hook_config={}, config={}, credential_parameters=('/credentials/mycredential',) + hook_config={}, + config={}, + credential_parameters=('/credentials/mycredential',), ) == 'password' ) @@ -46,10 +54,12 @@ def test_load_credential_reads_named_credential_from_file_using_working_director credential_stream.name = '/working/credentials/mycredential' builtins = flexmock(sys.modules['builtins']) flexmock(module.os.path).should_receive('expanduser').with_args( - 'credentials/mycredential' + 'credentials/mycredential', ).and_return('credentials/mycredential') - builtins.should_receive('open').with_args('/working/credentials/mycredential').and_return( - credential_stream + builtins.should_receive('open').with_args( + '/working/credentials/mycredential', encoding='utf-8' + ).and_return( + credential_stream, ) assert ( @@ -65,15 +75,19 @@ def test_load_credential_reads_named_credential_from_file_using_working_director def test_load_credential_with_file_not_found_error_raises(): builtins = flexmock(sys.modules['builtins']) flexmock(module.os.path).should_receive('expanduser').with_args( - '/credentials/mycredential' + '/credentials/mycredential', ).and_return('/credentials/mycredential') - builtins.should_receive('open').with_args('/credentials/mycredential').and_raise( - FileNotFoundError + builtins.should_receive('open').with_args( + '/credentials/mycredential', encoding='utf-8' + ).and_raise( + FileNotFoundError, ) with pytest.raises(ValueError): module.load_credential( - hook_config={}, config={}, credential_parameters=('/credentials/mycredential',) + hook_config={}, + config={}, + credential_parameters=('/credentials/mycredential',), ) @@ -82,15 +96,19 @@ def test_load_credential_reads_named_credential_from_expanded_directory(): credential_stream.name = '/root/credentials/mycredential' builtins = flexmock(sys.modules['builtins']) flexmock(module.os.path).should_receive('expanduser').with_args( - '~/credentials/mycredential' + '~/credentials/mycredential', ).and_return('/root/credentials/mycredential') - builtins.should_receive('open').with_args('/root/credentials/mycredential').and_return( - credential_stream + builtins.should_receive('open').with_args( + '/root/credentials/mycredential', encoding='utf-8' + ).and_return( + credential_stream, ) assert ( module.load_credential( - hook_config={}, config={}, credential_parameters=('~/credentials/mycredential',) + hook_config={}, + config={}, + credential_parameters=('~/credentials/mycredential',), ) == 'password' ) diff --git a/tests/unit/hooks/credential/test_keepassxc.py b/tests/unit/hooks/credential/test_keepassxc.py index ccb9173b..a9275019 100644 --- a/tests/unit/hooks/credential/test_keepassxc.py +++ b/tests/unit/hooks/credential/test_keepassxc.py @@ -10,30 +10,34 @@ def test_load_credential_with_invalid_credential_parameters_raises(credential_pa with pytest.raises(ValueError): module.load_credential( - hook_config={}, config={}, credential_parameters=credential_parameters + hook_config={}, + config={}, + credential_parameters=credential_parameters, ) def test_load_credential_with_missing_database_raises(): flexmock(module.os.path).should_receive('expanduser').with_args('database.kdbx').and_return( - 'database.kdbx' + 'database.kdbx', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.execute).should_receive('execute_command_and_capture_output').never() with pytest.raises(ValueError): module.load_credential( - hook_config={}, config={}, credential_parameters=('database.kdbx', 'mypassword') + hook_config={}, + config={}, + credential_parameters=('database.kdbx', 'mypassword'), ) def test_load_credential_with_present_database_fetches_password_from_keepassxc(): flexmock(module.os.path).should_receive('expanduser').with_args('database.kdbx').and_return( - 'database.kdbx' + 'database.kdbx', ) flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args( ( 'keepassxc-cli', @@ -43,14 +47,14 @@ def test_load_credential_with_present_database_fetches_password_from_keepassxc() 'Password', 'database.kdbx', 'mypassword', - ) - ).and_return( - 'password' - ).once() + ), + ).and_return('password').once() assert ( module.load_credential( - hook_config={}, config={}, credential_parameters=('database.kdbx', 'mypassword') + hook_config={}, + config={}, + credential_parameters=('database.kdbx', 'mypassword'), ) == 'password' ) @@ -58,12 +62,12 @@ def test_load_credential_with_present_database_fetches_password_from_keepassxc() def test_load_credential_with_custom_keepassxc_cli_command_calls_it(): flexmock(module.os.path).should_receive('expanduser').with_args('database.kdbx').and_return( - 'database.kdbx' + 'database.kdbx', ) config = {'keepassxc': {'keepassxc_cli_command': '/usr/local/bin/keepassxc-cli --some-option'}} flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args( ( '/usr/local/bin/keepassxc-cli', @@ -74,10 +78,8 @@ def test_load_credential_with_custom_keepassxc_cli_command_calls_it(): 'Password', 'database.kdbx', 'mypassword', - ) - ).and_return( - 'password' - ).once() + ), + ).and_return('password').once() assert ( module.load_credential( @@ -91,11 +93,11 @@ def test_load_credential_with_custom_keepassxc_cli_command_calls_it(): def test_load_credential_with_expanded_directory_with_present_database_fetches_password_from_keepassxc(): flexmock(module.os.path).should_receive('expanduser').with_args('~/database.kdbx').and_return( - '/root/database.kdbx' + '/root/database.kdbx', ) flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args( ( 'keepassxc-cli', @@ -105,14 +107,14 @@ def test_load_credential_with_expanded_directory_with_present_database_fetches_p 'Password', '/root/database.kdbx', 'mypassword', - ) - ).and_return( - 'password' - ).once() + ), + ).and_return('password').once() assert ( module.load_credential( - hook_config={}, config={}, credential_parameters=('~/database.kdbx', 'mypassword') + hook_config={}, + config={}, + credential_parameters=('~/database.kdbx', 'mypassword'), ) == 'password' ) @@ -120,11 +122,11 @@ def test_load_credential_with_expanded_directory_with_present_database_fetches_p def test_load_credential_with_key_file(): flexmock(module.os.path).should_receive('expanduser').with_args('database.kdbx').and_return( - 'database.kdbx' + 'database.kdbx', ) flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args( ( 'keepassxc-cli', @@ -136,10 +138,8 @@ def test_load_credential_with_key_file(): '/path/to/keyfile', 'database.kdbx', 'mypassword', - ) - ).and_return( - 'password' - ).once() + ), + ).and_return('password').once() assert ( module.load_credential( @@ -153,11 +153,11 @@ def test_load_credential_with_key_file(): def test_load_credential_with_yubikey(): flexmock(module.os.path).should_receive('expanduser').with_args('database.kdbx').and_return( - 'database.kdbx' + 'database.kdbx', ) flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args( ( 'keepassxc-cli', @@ -169,10 +169,8 @@ def test_load_credential_with_yubikey(): '1:7370001', 'database.kdbx', 'mypassword', - ) - ).and_return( - 'password' - ).once() + ), + ).and_return('password').once() assert ( module.load_credential( @@ -186,11 +184,11 @@ def test_load_credential_with_yubikey(): def test_load_credential_with_key_file_and_yubikey(): flexmock(module.os.path).should_receive('expanduser').with_args('database.kdbx').and_return( - 'database.kdbx' + 'database.kdbx', ) flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args( ( 'keepassxc-cli', @@ -204,10 +202,8 @@ def test_load_credential_with_key_file_and_yubikey(): '2', 'database.kdbx', 'mypassword', - ) - ).and_return( - 'password' - ).once() + ), + ).and_return('password').once() assert ( module.load_credential( diff --git a/tests/unit/hooks/credential/test_systemd.py b/tests/unit/hooks/credential/test_systemd.py index 32133883..80cb3a33 100644 --- a/tests/unit/hooks/credential/test_systemd.py +++ b/tests/unit/hooks/credential/test_systemd.py @@ -13,13 +13,15 @@ def test_load_credential_with_invalid_credential_parameters_raises(credential_pa with pytest.raises(ValueError): module.load_credential( - hook_config={}, config={}, credential_parameters=credential_parameters + hook_config={}, + config={}, + credential_parameters=credential_parameters, ) def test_load_credential_without_credentials_directory_raises(): flexmock(module.os.environ).should_receive('get').with_args('CREDENTIALS_DIRECTORY').and_return( - None + None, ) with pytest.raises(ValueError): @@ -28,23 +30,27 @@ def test_load_credential_without_credentials_directory_raises(): def test_load_credential_with_invalid_credential_name_raises(): flexmock(module.os.environ).should_receive('get').with_args('CREDENTIALS_DIRECTORY').and_return( - '/var' + '/var', ) with pytest.raises(ValueError): module.load_credential( - hook_config={}, config={}, credential_parameters=('../../my!@#$credential',) + hook_config={}, + config={}, + credential_parameters=('../../my!@#$credential',), ) def test_load_credential_reads_named_credential_from_file(): flexmock(module.os.environ).should_receive('get').with_args('CREDENTIALS_DIRECTORY').and_return( - '/var' + '/var', ) credential_stream = io.StringIO('password') credential_stream.name = '/var/borgmatic.pw' builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('/var/borgmatic.pw').and_return(credential_stream) + builtins.should_receive('open').with_args('/var/borgmatic.pw', encoding='utf-8').and_return( + credential_stream + ) assert ( module.load_credential(hook_config={}, config={}, credential_parameters=('borgmatic.pw',)) @@ -54,10 +60,12 @@ def test_load_credential_reads_named_credential_from_file(): def test_load_credential_with_file_not_found_error_raises(): flexmock(module.os.environ).should_receive('get').with_args('CREDENTIALS_DIRECTORY').and_return( - '/var' + '/var', ) builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('/var/mycredential').and_raise(FileNotFoundError) + builtins.should_receive('open').with_args('/var/mycredential', encoding='utf-8').and_raise( + FileNotFoundError + ) with pytest.raises(ValueError): module.load_credential(hook_config={}, config={}, credential_parameters=('mycredential',)) diff --git a/tests/unit/hooks/data_source/test_bootstrap.py b/tests/unit/hooks/data_source/test_bootstrap.py index 1623dfb7..847bd28e 100644 --- a/tests/unit/hooks/data_source/test_bootstrap.py +++ b/tests/unit/hooks/data_source/test_bootstrap.py @@ -14,7 +14,9 @@ def test_dump_data_sources_creates_manifest_file(): __exit__=lambda *args: None, ) flexmock(sys.modules['builtins']).should_receive('open').with_args( - '/run/borgmatic/bootstrap/manifest.json', 'w' + '/run/borgmatic/bootstrap/manifest.json', + 'w', + encoding='utf-8', ).and_return(manifest_file) flexmock(module.json).should_receive('dump').with_args( {'borgmatic_version': '1.0.0', 'config_paths': ('test.yaml',)}, @@ -62,11 +64,11 @@ def test_dump_data_sources_with_dry_run_does_not_create_manifest_file(): def test_remove_data_source_dumps_deletes_manifest_and_parent_directory(): flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with(lambda path: [path]) flexmock(module.os).should_receive('remove').with_args( - '/run/borgmatic/bootstrap/manifest.json' + '/run/borgmatic/bootstrap/manifest.json', ).once() flexmock(module.os).should_receive('rmdir').with_args('/run/borgmatic/bootstrap').once() @@ -80,7 +82,7 @@ def test_remove_data_source_dumps_deletes_manifest_and_parent_directory(): def test_remove_data_source_dumps_with_dry_run_bails(): flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with(lambda path: [path]) flexmock(module.os).should_receive('remove').never() @@ -96,11 +98,11 @@ def test_remove_data_source_dumps_with_dry_run_bails(): def test_remove_data_source_dumps_swallows_manifest_file_not_found_error(): flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with(lambda path: [path]) flexmock(module.os).should_receive('remove').with_args( - '/run/borgmatic/bootstrap/manifest.json' + '/run/borgmatic/bootstrap/manifest.json', ).and_raise(FileNotFoundError).once() flexmock(module.os).should_receive('rmdir').with_args('/run/borgmatic/bootstrap').once() @@ -114,14 +116,14 @@ def test_remove_data_source_dumps_swallows_manifest_file_not_found_error(): def test_remove_data_source_dumps_swallows_manifest_parent_directory_not_found_error(): flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with(lambda path: [path]) flexmock(module.os).should_receive('remove').with_args( - '/run/borgmatic/bootstrap/manifest.json' + '/run/borgmatic/bootstrap/manifest.json', ).once() flexmock(module.os).should_receive('rmdir').with_args('/run/borgmatic/bootstrap').and_raise( - FileNotFoundError + FileNotFoundError, ).once() module.remove_data_source_dumps( diff --git a/tests/unit/hooks/data_source/test_btrfs.py b/tests/unit/hooks/data_source/test_btrfs.py index 7493a004..0ad67d0f 100644 --- a/tests/unit/hooks/data_source/test_btrfs.py +++ b/tests/unit/hooks/data_source/test_btrfs.py @@ -7,9 +7,9 @@ from borgmatic.hooks.data_source import btrfs as module def test_get_contained_subvolume_paths_parses_btrfs_output(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args(('btrfs', 'subvolume', 'list', '/mnt0'), close_fds=True).and_return( - 'ID 256 gen 28 top level 5 path @sub\nID 258 gen 17 top level 5 path snap\n\n' + 'ID 256 gen 28 top level 5 path @sub\nID 258 gen 17 top level 5 path snap\n\n', ) assert module.get_contained_subvolume_paths('btrfs', '/mnt0') == ( @@ -21,9 +21,9 @@ def test_get_contained_subvolume_paths_parses_btrfs_output(): def test_get_contained_subvolume_paths_swallows_called_process_error(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).with_args(('btrfs', 'subvolume', 'list', '/mnt0'), close_fds=True).and_raise( - module.subprocess.CalledProcessError(1, 'btrfs') + module.subprocess.CalledProcessError(1, 'btrfs'), ) assert module.get_contained_subvolume_paths('btrfs', '/mnt0') == () @@ -31,7 +31,7 @@ def test_get_contained_subvolume_paths_swallows_called_process_error(): def test_get_all_subvolume_paths_parses_findmnt_output(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( '''{ "filesystems": [ @@ -55,16 +55,19 @@ def test_get_all_subvolume_paths_parses_findmnt_output(): } ] } - ''' + ''', ) flexmock(module).should_receive('get_contained_subvolume_paths').with_args( - 'btrfs', '/mnt0' + 'btrfs', + '/mnt0', ).and_return(('/mnt0',)) flexmock(module).should_receive('get_contained_subvolume_paths').with_args( - 'btrfs', '/mnt1' + 'btrfs', + '/mnt1', ).and_return(('/mnt1', '/mnt1/sub')) flexmock(module).should_receive('get_contained_subvolume_paths').with_args( - 'btrfs', '/mnt2' + 'btrfs', + '/mnt2', ).never() assert module.get_all_subvolume_paths('btrfs', 'findmnt') == ( @@ -77,7 +80,7 @@ def test_get_all_subvolume_paths_parses_findmnt_output(): def test_get_all_subvolume_paths_with_invalid_findmnt_json_errors(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return('{') flexmock(module).should_receive('get_contained_subvolume_paths').never() @@ -87,7 +90,7 @@ def test_get_all_subvolume_paths_with_invalid_findmnt_json_errors(): def test_get_all_subvolume_paths_with_findmnt_json_missing_filesystems_errors(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return('{"wtf": "something is wrong here"}') flexmock(module).should_receive('get_contained_subvolume_paths').never() @@ -97,7 +100,7 @@ def test_get_all_subvolume_paths_with_findmnt_json_missing_filesystems_errors(): def test_get_subvolume_property_with_invalid_btrfs_output_errors(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return('invalid') with pytest.raises(ValueError): @@ -106,7 +109,7 @@ def test_get_subvolume_property_with_invalid_btrfs_output_errors(): def test_get_subvolume_property_with_true_output_returns_true_bool(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return('ro=true') assert module.get_subvolume_property('btrfs', '/foo', 'ro') is True @@ -114,7 +117,7 @@ def test_get_subvolume_property_with_true_output_returns_true_bool(): def test_get_subvolume_property_with_false_output_returns_false_bool(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return('ro=false') assert module.get_subvolume_property('btrfs', '/foo', 'ro') is False @@ -122,7 +125,7 @@ def test_get_subvolume_property_with_false_output_returns_false_bool(): def test_get_subvolume_property_passes_through_general_value(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return('thing=value') assert module.get_subvolume_property('btrfs', '/foo', 'thing') == 'value' @@ -130,13 +133,19 @@ def test_get_subvolume_property_passes_through_general_value(): def test_omit_read_only_subvolume_paths_filters_out_read_only_subvolumes(): flexmock(module).should_receive('get_subvolume_property').with_args( - 'btrfs', '/foo', 'ro' + 'btrfs', + '/foo', + 'ro', ).and_return(False) flexmock(module).should_receive('get_subvolume_property').with_args( - 'btrfs', '/bar', 'ro' + 'btrfs', + '/bar', + 'ro', ).and_return(True) flexmock(module).should_receive('get_subvolume_property').with_args( - 'btrfs', '/baz', 'ro' + 'btrfs', + '/baz', + 'ro', ).and_return(False) assert module.omit_read_only_subvolume_paths('btrfs', ('/foo', '/bar', '/baz')) == ( @@ -147,13 +156,19 @@ def test_omit_read_only_subvolume_paths_filters_out_read_only_subvolumes(): def test_omit_read_only_subvolume_paths_filters_out_erroring_subvolumes(): flexmock(module).should_receive('get_subvolume_property').with_args( - 'btrfs', '/foo', 'ro' + 'btrfs', + '/foo', + 'ro', ).and_raise(module.subprocess.CalledProcessError(1, 'btrfs')) flexmock(module).should_receive('get_subvolume_property').with_args( - 'btrfs', '/bar', 'ro' + 'btrfs', + '/bar', + 'ro', ).and_return(True) flexmock(module).should_receive('get_subvolume_property').with_args( - 'btrfs', '/baz', 'ro' + 'btrfs', + '/baz', + 'ro', ).and_return(False) assert module.omit_read_only_subvolume_paths('btrfs', ('/foo', '/bar', '/baz')) == ('/baz',) @@ -169,10 +184,10 @@ def test_get_subvolumes_collects_subvolumes_matching_patterns(): source=Pattern_source.CONFIG, ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt1', object).and_return((contained_pattern,)) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt2', object).and_return(()) assert module.get_subvolumes( @@ -190,7 +205,7 @@ def test_get_subvolumes_skips_non_root_patterns(): flexmock(module).should_receive('omit_read_only_subvolume_paths').and_return(('/mnt1', '/mnt2')) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt1', object).and_return( ( Pattern( @@ -198,10 +213,10 @@ def test_get_subvolumes_skips_non_root_patterns(): type=Pattern_type.EXCLUDE, source=Pattern_source.CONFIG, ), - ) + ), ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt2', object).and_return(()) assert ( @@ -222,7 +237,7 @@ def test_get_subvolumes_skips_non_config_patterns(): flexmock(module).should_receive('omit_read_only_subvolume_paths').and_return(('/mnt1', '/mnt2')) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt1', object).and_return( ( Pattern( @@ -230,10 +245,10 @@ def test_get_subvolumes_skips_non_config_patterns(): type=Pattern_type.ROOT, source=Pattern_source.HOOK, ), - ) + ), ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt2', object).and_return(()) assert ( @@ -254,10 +269,10 @@ def test_get_subvolumes_without_patterns_collects_all_subvolumes(): flexmock(module).should_receive('omit_read_only_subvolume_paths').and_return(('/mnt1', '/mnt2')) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt1', object).and_return((Pattern('/mnt1'),)) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt2', object).and_return((Pattern('/mnt2'),)) assert module.get_subvolumes('btrfs', 'findmnt') == ( @@ -274,7 +289,8 @@ def test_get_subvolumes_without_patterns_collects_all_subvolumes(): ), ) def test_make_snapshot_path_includes_stripped_subvolume_path( - subvolume_path, expected_snapshot_path + subvolume_path, + expected_snapshot_path, ): flexmock(module.os).should_receive('getpid').and_return(1234) @@ -313,7 +329,9 @@ def test_make_snapshot_path_includes_stripped_subvolume_path( ), ) def test_make_borg_snapshot_pattern_includes_slashdot_hack_and_stripped_pattern_path( - subvolume_path, pattern, expected_pattern + subvolume_path, + pattern, + expected_pattern, ): flexmock(module.os).should_receive('getpid').and_return(1234) @@ -327,43 +345,49 @@ def test_dump_data_sources_snapshots_each_subvolume_and_updates_patterns(): ( module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)), module.Subvolume('/mnt/subvol2', contained_patterns=(Pattern('/mnt/subvol2'),)), - ) + ), ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol1').and_return( - '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol2').and_return( - '/mnt/subvol2/.borgmatic-1234/mnt/subvol2' + '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', ) flexmock(module).should_receive('snapshot_subvolume').with_args( - 'btrfs', '/mnt/subvol1', '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + 'btrfs', + '/mnt/subvol1', + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ).once() flexmock(module).should_receive('snapshot_subvolume').with_args( - 'btrfs', '/mnt/subvol2', '/mnt/subvol2/.borgmatic-1234/mnt/subvol2' + 'btrfs', + '/mnt/subvol2', + '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', ).once() flexmock(module).should_receive('make_snapshot_exclude_pattern').with_args( - '/mnt/subvol1' + '/mnt/subvol1', ).and_return( Pattern( '/mnt/subvol1/.borgmatic-1234/mnt/subvol1/.borgmatic-1234', Pattern_type.NO_RECURSE, Pattern_style.FNMATCH, - ) + ), ) flexmock(module).should_receive('make_snapshot_exclude_pattern').with_args( - '/mnt/subvol2' + '/mnt/subvol2', ).and_return( Pattern( '/mnt/subvol2/.borgmatic-1234/mnt/subvol2/.borgmatic-1234', Pattern_type.NO_RECURSE, Pattern_style.FNMATCH, - ) + ), ) flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - '/mnt/subvol1', object + '/mnt/subvol1', + object, ).and_return(Pattern('/mnt/subvol1/.borgmatic-1234/mnt/subvol1')) flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - '/mnt/subvol2', object + '/mnt/subvol2', + object, ).and_return(Pattern('/mnt/subvol2/.borgmatic-1234/mnt/subvol2')) assert ( @@ -402,25 +426,28 @@ def test_dump_data_sources_uses_custom_btrfs_command_in_commands(): patterns = [Pattern('/foo'), Pattern('/mnt/subvol1')] config = {'btrfs': {'btrfs_command': '/usr/local/bin/btrfs'}} flexmock(module).should_receive('get_subvolumes').and_return( - (module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)),) + (module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)),), ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol1').and_return( - '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ) flexmock(module).should_receive('snapshot_subvolume').with_args( - '/usr/local/bin/btrfs', '/mnt/subvol1', '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + '/usr/local/bin/btrfs', + '/mnt/subvol1', + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ).once() flexmock(module).should_receive('make_snapshot_exclude_pattern').with_args( - '/mnt/subvol1' + '/mnt/subvol1', ).and_return( Pattern( '/mnt/subvol1/.borgmatic-1234/mnt/subvol1/.borgmatic-1234', Pattern_type.NO_RECURSE, Pattern_style.FNMATCH, - ) + ), ) flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - '/mnt/subvol1', object + '/mnt/subvol1', + object, ).and_return(Pattern('/mnt/subvol1/.borgmatic-1234/mnt/subvol1')) assert ( @@ -455,27 +482,32 @@ def test_dump_data_sources_uses_custom_findmnt_command_in_commands(): patterns = [Pattern('/foo'), Pattern('/mnt/subvol1')] config = {'btrfs': {'findmnt_command': '/usr/local/bin/findmnt'}} flexmock(module).should_receive('get_subvolumes').with_args( - 'btrfs', '/usr/local/bin/findmnt', patterns + 'btrfs', + '/usr/local/bin/findmnt', + patterns, ).and_return( - (module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)),) + (module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)),), ).once() flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol1').and_return( - '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ) flexmock(module).should_receive('snapshot_subvolume').with_args( - 'btrfs', '/mnt/subvol1', '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + 'btrfs', + '/mnt/subvol1', + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ).once() flexmock(module).should_receive('make_snapshot_exclude_pattern').with_args( - '/mnt/subvol1' + '/mnt/subvol1', ).and_return( Pattern( '/mnt/subvol1/.borgmatic-1234/mnt/subvol1/.borgmatic-1234', Pattern_type.NO_RECURSE, Pattern_style.FNMATCH, - ) + ), ) flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - '/mnt/subvol1', object + '/mnt/subvol1', + object, ).and_return(Pattern('/mnt/subvol1/.borgmatic-1234/mnt/subvol1')) assert ( @@ -510,10 +542,10 @@ def test_dump_data_sources_with_dry_run_skips_snapshot_and_patterns_update(): patterns = [Pattern('/foo'), Pattern('/mnt/subvol1')] config = {'btrfs': {}} flexmock(module).should_receive('get_subvolumes').and_return( - (module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)),) + (module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)),), ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol1').and_return( - '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ) flexmock(module).should_receive('snapshot_subvolume').never() flexmock(module).should_receive('make_snapshot_exclude_pattern').never() @@ -565,43 +597,49 @@ def test_dump_data_sources_snapshots_adds_to_existing_exclude_patterns(): ( module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)), module.Subvolume('/mnt/subvol2', contained_patterns=(Pattern('/mnt/subvol2'),)), - ) + ), ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol1').and_return( - '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol2').and_return( - '/mnt/subvol2/.borgmatic-1234/mnt/subvol2' + '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', ) flexmock(module).should_receive('snapshot_subvolume').with_args( - 'btrfs', '/mnt/subvol1', '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + 'btrfs', + '/mnt/subvol1', + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ).once() flexmock(module).should_receive('snapshot_subvolume').with_args( - 'btrfs', '/mnt/subvol2', '/mnt/subvol2/.borgmatic-1234/mnt/subvol2' + 'btrfs', + '/mnt/subvol2', + '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', ).once() flexmock(module).should_receive('make_snapshot_exclude_pattern').with_args( - '/mnt/subvol1' + '/mnt/subvol1', ).and_return( Pattern( '/mnt/subvol1/.borgmatic-1234/mnt/subvol1/.borgmatic-1234', Pattern_type.NO_RECURSE, Pattern_style.FNMATCH, - ) + ), ) flexmock(module).should_receive('make_snapshot_exclude_pattern').with_args( - '/mnt/subvol2' + '/mnt/subvol2', ).and_return( Pattern( '/mnt/subvol2/.borgmatic-1234/mnt/subvol2/.borgmatic-1234', Pattern_type.NO_RECURSE, Pattern_style.FNMATCH, - ) + ), ) flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - '/mnt/subvol1', object + '/mnt/subvol1', + object, ).and_return(Pattern('/mnt/subvol1/.borgmatic-1234/mnt/subvol1')) flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - '/mnt/subvol2', object + '/mnt/subvol2', + object, ).and_return(Pattern('/mnt/subvol2/.borgmatic-1234/mnt/subvol2')) assert ( @@ -643,87 +681,87 @@ def test_remove_data_source_dumps_deletes_snapshots(): ( module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)), module.Subvolume('/mnt/subvol2', contained_patterns=(Pattern('/mnt/subvol2'),)), - ) + ), ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol1').and_return( - '/mnt/subvol1/.borgmatic-1234/./mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/./mnt/subvol1', ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol2').and_return( - '/mnt/subvol2/.borgmatic-1234/./mnt/subvol2' + '/mnt/subvol2/.borgmatic-1234/./mnt/subvol2', ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).with_args( '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', temporary_directory_prefix=module.BORGMATIC_SNAPSHOT_PREFIX, - ).and_return( - '/mnt/subvol1/.borgmatic-*/mnt/subvol1' - ) + ).and_return('/mnt/subvol1/.borgmatic-*/mnt/subvol1') flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).with_args( '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', temporary_directory_prefix=module.BORGMATIC_SNAPSHOT_PREFIX, + ).and_return('/mnt/subvol2/.borgmatic-*/mnt/subvol2') + flexmock(module.glob).should_receive('glob').with_args( + '/mnt/subvol1/.borgmatic-*/mnt/subvol1', ).and_return( - '/mnt/subvol2/.borgmatic-*/mnt/subvol2' + ('/mnt/subvol1/.borgmatic-1234/mnt/subvol1', '/mnt/subvol1/.borgmatic-5678/mnt/subvol1'), ) flexmock(module.glob).should_receive('glob').with_args( - '/mnt/subvol1/.borgmatic-*/mnt/subvol1' + '/mnt/subvol2/.borgmatic-*/mnt/subvol2', ).and_return( - ('/mnt/subvol1/.borgmatic-1234/mnt/subvol1', '/mnt/subvol1/.borgmatic-5678/mnt/subvol1') - ) - flexmock(module.glob).should_receive('glob').with_args( - '/mnt/subvol2/.borgmatic-*/mnt/subvol2' - ).and_return( - ('/mnt/subvol2/.borgmatic-1234/mnt/subvol2', '/mnt/subvol2/.borgmatic-5678/mnt/subvol2') + ('/mnt/subvol2/.borgmatic-1234/mnt/subvol2', '/mnt/subvol2/.borgmatic-5678/mnt/subvol2'), ) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol1/.borgmatic-5678/mnt/subvol1' + '/mnt/subvol1/.borgmatic-5678/mnt/subvol1', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol2/.borgmatic-1234/mnt/subvol2' + '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol2/.borgmatic-5678/mnt/subvol2' + '/mnt/subvol2/.borgmatic-5678/mnt/subvol2', ).and_return(False) flexmock(module).should_receive('delete_snapshot').with_args( - 'btrfs', '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + 'btrfs', + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ).once() flexmock(module).should_receive('delete_snapshot').with_args( - 'btrfs', '/mnt/subvol1/.borgmatic-5678/mnt/subvol1' + 'btrfs', + '/mnt/subvol1/.borgmatic-5678/mnt/subvol1', ).once() flexmock(module).should_receive('delete_snapshot').with_args( - 'btrfs', '/mnt/subvol2/.borgmatic-1234/mnt/subvol2' + 'btrfs', + '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', ).once() flexmock(module).should_receive('delete_snapshot').with_args( - 'btrfs', '/mnt/subvol2/.borgmatic-5678/mnt/subvol2' + 'btrfs', + '/mnt/subvol2/.borgmatic-5678/mnt/subvol2', ).never() flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol1/.borgmatic-1234' + '/mnt/subvol1/.borgmatic-1234', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol1/.borgmatic-5678' + '/mnt/subvol1/.borgmatic-5678', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol2/.borgmatic-1234' + '/mnt/subvol2/.borgmatic-1234', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol2/.borgmatic-5678' + '/mnt/subvol2/.borgmatic-5678', ).and_return(True) flexmock(module.shutil).should_receive('rmtree').with_args( - '/mnt/subvol1/.borgmatic-1234' + '/mnt/subvol1/.borgmatic-1234', ).once() flexmock(module.shutil).should_receive('rmtree').with_args( - '/mnt/subvol1/.borgmatic-5678' + '/mnt/subvol1/.borgmatic-5678', ).once() flexmock(module.shutil).should_receive('rmtree').with_args( - '/mnt/subvol2/.borgmatic-1234' + '/mnt/subvol2/.borgmatic-1234', ).once() flexmock(module.shutil).should_receive('rmtree').with_args( - '/mnt/subvol2/.borgmatic-5678' + '/mnt/subvol2/.borgmatic-5678', ).never() module.remove_data_source_dumps( @@ -738,7 +776,7 @@ def test_remove_data_source_dumps_without_hook_configuration_bails(): flexmock(module).should_receive('get_subvolumes').never() flexmock(module).should_receive('make_snapshot_path').never() flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).never() flexmock(module).should_receive('delete_snapshot').never() flexmock(module.shutil).should_receive('rmtree').never() @@ -756,7 +794,7 @@ def test_remove_data_source_dumps_with_get_subvolumes_file_not_found_error_bails flexmock(module).should_receive('get_subvolumes').and_raise(FileNotFoundError) flexmock(module).should_receive('make_snapshot_path').never() flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).never() flexmock(module).should_receive('delete_snapshot').never() flexmock(module.shutil).should_receive('rmtree').never() @@ -772,11 +810,11 @@ def test_remove_data_source_dumps_with_get_subvolumes_file_not_found_error_bails def test_remove_data_source_dumps_with_get_subvolumes_called_process_error_bails(): config = {'btrfs': {}} flexmock(module).should_receive('get_subvolumes').and_raise( - module.subprocess.CalledProcessError(1, 'command', 'error') + module.subprocess.CalledProcessError(1, 'command', 'error'), ) flexmock(module).should_receive('make_snapshot_path').never() flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).never() flexmock(module).should_receive('delete_snapshot').never() flexmock(module.shutil).should_receive('rmtree').never() @@ -795,51 +833,47 @@ def test_remove_data_source_dumps_with_dry_run_skips_deletes(): ( module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)), module.Subvolume('/mnt/subvol2', contained_patterns=(Pattern('/mnt/subvol2'),)), - ) + ), ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol1').and_return( - '/mnt/subvol1/.borgmatic-1234/./mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/./mnt/subvol1', ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol2').and_return( - '/mnt/subvol2/.borgmatic-1234/./mnt/subvol2' + '/mnt/subvol2/.borgmatic-1234/./mnt/subvol2', ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).with_args( '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', temporary_directory_prefix=module.BORGMATIC_SNAPSHOT_PREFIX, - ).and_return( - '/mnt/subvol1/.borgmatic-*/mnt/subvol1' - ) + ).and_return('/mnt/subvol1/.borgmatic-*/mnt/subvol1') flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).with_args( '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', temporary_directory_prefix=module.BORGMATIC_SNAPSHOT_PREFIX, + ).and_return('/mnt/subvol2/.borgmatic-*/mnt/subvol2') + flexmock(module.glob).should_receive('glob').with_args( + '/mnt/subvol1/.borgmatic-*/mnt/subvol1', ).and_return( - '/mnt/subvol2/.borgmatic-*/mnt/subvol2' + ('/mnt/subvol1/.borgmatic-1234/mnt/subvol1', '/mnt/subvol1/.borgmatic-5678/mnt/subvol1'), ) flexmock(module.glob).should_receive('glob').with_args( - '/mnt/subvol1/.borgmatic-*/mnt/subvol1' + '/mnt/subvol2/.borgmatic-*/mnt/subvol2', ).and_return( - ('/mnt/subvol1/.borgmatic-1234/mnt/subvol1', '/mnt/subvol1/.borgmatic-5678/mnt/subvol1') - ) - flexmock(module.glob).should_receive('glob').with_args( - '/mnt/subvol2/.borgmatic-*/mnt/subvol2' - ).and_return( - ('/mnt/subvol2/.borgmatic-1234/mnt/subvol2', '/mnt/subvol2/.borgmatic-5678/mnt/subvol2') + ('/mnt/subvol2/.borgmatic-1234/mnt/subvol2', '/mnt/subvol2/.borgmatic-5678/mnt/subvol2'), ) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol1/.borgmatic-5678/mnt/subvol1' + '/mnt/subvol1/.borgmatic-5678/mnt/subvol1', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol2/.borgmatic-1234/mnt/subvol2' + '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol2/.borgmatic-5678/mnt/subvol2' + '/mnt/subvol2/.borgmatic-5678/mnt/subvol2', ).and_return(False) flexmock(module).should_receive('delete_snapshot').never() flexmock(module.shutil).should_receive('rmtree').never() @@ -857,7 +891,7 @@ def test_remove_data_source_dumps_without_subvolumes_skips_deletes(): flexmock(module).should_receive('get_subvolumes').and_return(()) flexmock(module).should_receive('make_snapshot_path').never() flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).never() flexmock(module).should_receive('delete_snapshot').never() flexmock(module.shutil).should_receive('rmtree').never() @@ -876,30 +910,26 @@ def test_remove_data_source_without_snapshots_skips_deletes(): ( module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)), module.Subvolume('/mnt/subvol2', contained_patterns=(Pattern('/mnt/subvol2'),)), - ) + ), ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol1').and_return( - '/mnt/subvol1/.borgmatic-1234/./mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/./mnt/subvol1', ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol2').and_return( - '/mnt/subvol2/.borgmatic-1234/./mnt/subvol2' + '/mnt/subvol2/.borgmatic-1234/./mnt/subvol2', ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).with_args( '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', temporary_directory_prefix=module.BORGMATIC_SNAPSHOT_PREFIX, - ).and_return( - '/mnt/subvol1/.borgmatic-*/mnt/subvol1' - ) + ).and_return('/mnt/subvol1/.borgmatic-*/mnt/subvol1') flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).with_args( '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', temporary_directory_prefix=module.BORGMATIC_SNAPSHOT_PREFIX, - ).and_return( - '/mnt/subvol2/.borgmatic-*/mnt/subvol2' - ) + ).and_return('/mnt/subvol2/.borgmatic-*/mnt/subvol2') flexmock(module.glob).should_receive('glob').and_return(()) flexmock(module.os.path).should_receive('isdir').never() flexmock(module).should_receive('delete_snapshot').never() @@ -919,51 +949,47 @@ def test_remove_data_source_dumps_with_delete_snapshot_file_not_found_error_bail ( module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)), module.Subvolume('/mnt/subvol2', contained_patterns=(Pattern('/mnt/subvol2'),)), - ) + ), ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol1').and_return( - '/mnt/subvol1/.borgmatic-1234/./mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/./mnt/subvol1', ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol2').and_return( - '/mnt/subvol2/.borgmatic-1234/./mnt/subvol2' + '/mnt/subvol2/.borgmatic-1234/./mnt/subvol2', ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).with_args( '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', temporary_directory_prefix=module.BORGMATIC_SNAPSHOT_PREFIX, - ).and_return( - '/mnt/subvol1/.borgmatic-*/mnt/subvol1' - ) + ).and_return('/mnt/subvol1/.borgmatic-*/mnt/subvol1') flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).with_args( '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', temporary_directory_prefix=module.BORGMATIC_SNAPSHOT_PREFIX, + ).and_return('/mnt/subvol2/.borgmatic-*/mnt/subvol2') + flexmock(module.glob).should_receive('glob').with_args( + '/mnt/subvol1/.borgmatic-*/mnt/subvol1', ).and_return( - '/mnt/subvol2/.borgmatic-*/mnt/subvol2' + ('/mnt/subvol1/.borgmatic-1234/mnt/subvol1', '/mnt/subvol1/.borgmatic-5678/mnt/subvol1'), ) flexmock(module.glob).should_receive('glob').with_args( - '/mnt/subvol1/.borgmatic-*/mnt/subvol1' + '/mnt/subvol2/.borgmatic-*/mnt/subvol2', ).and_return( - ('/mnt/subvol1/.borgmatic-1234/mnt/subvol1', '/mnt/subvol1/.borgmatic-5678/mnt/subvol1') - ) - flexmock(module.glob).should_receive('glob').with_args( - '/mnt/subvol2/.borgmatic-*/mnt/subvol2' - ).and_return( - ('/mnt/subvol2/.borgmatic-1234/mnt/subvol2', '/mnt/subvol2/.borgmatic-5678/mnt/subvol2') + ('/mnt/subvol2/.borgmatic-1234/mnt/subvol2', '/mnt/subvol2/.borgmatic-5678/mnt/subvol2'), ) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol1/.borgmatic-5678/mnt/subvol1' + '/mnt/subvol1/.borgmatic-5678/mnt/subvol1', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol2/.borgmatic-1234/mnt/subvol2' + '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol2/.borgmatic-5678/mnt/subvol2' + '/mnt/subvol2/.borgmatic-5678/mnt/subvol2', ).and_return(False) flexmock(module).should_receive('delete_snapshot').and_raise(FileNotFoundError) flexmock(module.shutil).should_receive('rmtree').never() @@ -982,54 +1008,50 @@ def test_remove_data_source_dumps_with_delete_snapshot_called_process_error_bail ( module.Subvolume('/mnt/subvol1', contained_patterns=(Pattern('/mnt/subvol1'),)), module.Subvolume('/mnt/subvol2', contained_patterns=(Pattern('/mnt/subvol2'),)), - ) + ), ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol1').and_return( - '/mnt/subvol1/.borgmatic-1234/./mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/./mnt/subvol1', ) flexmock(module).should_receive('make_snapshot_path').with_args('/mnt/subvol2').and_return( - '/mnt/subvol2/.borgmatic-1234/./mnt/subvol2' + '/mnt/subvol2/.borgmatic-1234/./mnt/subvol2', ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).with_args( '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', temporary_directory_prefix=module.BORGMATIC_SNAPSHOT_PREFIX, - ).and_return( - '/mnt/subvol1/.borgmatic-*/mnt/subvol1' - ) + ).and_return('/mnt/subvol1/.borgmatic-*/mnt/subvol1') flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).with_args( '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', temporary_directory_prefix=module.BORGMATIC_SNAPSHOT_PREFIX, + ).and_return('/mnt/subvol2/.borgmatic-*/mnt/subvol2') + flexmock(module.glob).should_receive('glob').with_args( + '/mnt/subvol1/.borgmatic-*/mnt/subvol1', ).and_return( - '/mnt/subvol2/.borgmatic-*/mnt/subvol2' + ('/mnt/subvol1/.borgmatic-1234/mnt/subvol1', '/mnt/subvol1/.borgmatic-5678/mnt/subvol1'), ) flexmock(module.glob).should_receive('glob').with_args( - '/mnt/subvol1/.borgmatic-*/mnt/subvol1' + '/mnt/subvol2/.borgmatic-*/mnt/subvol2', ).and_return( - ('/mnt/subvol1/.borgmatic-1234/mnt/subvol1', '/mnt/subvol1/.borgmatic-5678/mnt/subvol1') - ) - flexmock(module.glob).should_receive('glob').with_args( - '/mnt/subvol2/.borgmatic-*/mnt/subvol2' - ).and_return( - ('/mnt/subvol2/.borgmatic-1234/mnt/subvol2', '/mnt/subvol2/.borgmatic-5678/mnt/subvol2') + ('/mnt/subvol2/.borgmatic-1234/mnt/subvol2', '/mnt/subvol2/.borgmatic-5678/mnt/subvol2'), ) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol1/.borgmatic-1234/mnt/subvol1' + '/mnt/subvol1/.borgmatic-1234/mnt/subvol1', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol1/.borgmatic-5678/mnt/subvol1' + '/mnt/subvol1/.borgmatic-5678/mnt/subvol1', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol2/.borgmatic-1234/mnt/subvol2' + '/mnt/subvol2/.borgmatic-1234/mnt/subvol2', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/mnt/subvol2/.borgmatic-5678/mnt/subvol2' + '/mnt/subvol2/.borgmatic-5678/mnt/subvol2', ).and_return(False) flexmock(module).should_receive('delete_snapshot').and_raise( - module.subprocess.CalledProcessError(1, 'command', 'error') + module.subprocess.CalledProcessError(1, 'command', 'error'), ) flexmock(module.shutil).should_receive('rmtree').never() @@ -1044,31 +1066,29 @@ def test_remove_data_source_dumps_with_delete_snapshot_called_process_error_bail def test_remove_data_source_dumps_with_root_subvolume_skips_duplicate_removal(): config = {'btrfs': {}} flexmock(module).should_receive('get_subvolumes').and_return( - (module.Subvolume('/', contained_patterns=(Pattern('/etc'),)),) + (module.Subvolume('/', contained_patterns=(Pattern('/etc'),)),), ) flexmock(module).should_receive('make_snapshot_path').with_args('/').and_return( - '/.borgmatic-1234' + '/.borgmatic-1234', ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).with_args( '/.borgmatic-1234', temporary_directory_prefix=module.BORGMATIC_SNAPSHOT_PREFIX, - ).and_return( - '/.borgmatic-*' - ) + ).and_return('/.borgmatic-*') flexmock(module.glob).should_receive('glob').with_args('/.borgmatic-*').and_return( - ('/.borgmatic-1234', '/.borgmatic-5678') + ('/.borgmatic-1234', '/.borgmatic-5678'), ) flexmock(module.os.path).should_receive('isdir').with_args('/.borgmatic-1234').and_return( - True + True, ).and_return(False) flexmock(module.os.path).should_receive('isdir').with_args('/.borgmatic-5678').and_return( - True + True, ).and_return(False) flexmock(module).should_receive('delete_snapshot').with_args('btrfs', '/.borgmatic-1234').once() diff --git a/tests/unit/hooks/data_source/test_lvm.py b/tests/unit/hooks/data_source/test_lvm.py index 430dfa68..a6e6eb6d 100644 --- a/tests/unit/hooks/data_source/test_lvm.py +++ b/tests/unit/hooks/data_source/test_lvm.py @@ -7,7 +7,7 @@ from borgmatic.hooks.data_source import lvm as module def test_get_logical_volumes_filters_by_patterns(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( ''' { @@ -35,28 +35,28 @@ def test_get_logical_volumes_filters_by_patterns(): } ] } - ''' + ''', ) contained = { Pattern('/mnt/lvolume', source=Pattern_source.CONFIG), Pattern('/mnt/lvolume/subdir', source=Pattern_source.CONFIG), } flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args(None, contained).never() flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt/lvolume', contained).and_return( ( Pattern('/mnt/lvolume', source=Pattern_source.CONFIG), Pattern('/mnt/lvolume/subdir', source=Pattern_source.CONFIG), - ) + ), ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt/other', contained).and_return(()) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt/notlvm', contained).never() assert module.get_logical_volumes( @@ -80,7 +80,7 @@ def test_get_logical_volumes_filters_by_patterns(): def test_get_logical_volumes_skips_non_root_patterns(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( ''' { @@ -93,22 +93,22 @@ def test_get_logical_volumes_skips_non_root_patterns(): } ] } - ''' + ''', ) contained = { Pattern('/mnt/lvolume', type=Pattern_type.EXCLUDE, source=Pattern_source.CONFIG), Pattern('/mnt/lvolume/subdir', type=Pattern_type.EXCLUDE, source=Pattern_source.CONFIG), } flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args(None, contained).never() flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt/lvolume', contained).and_return( ( Pattern('/mnt/lvolume', type=Pattern_type.EXCLUDE, source=Pattern_source.CONFIG), Pattern('/mnt/lvolume/subdir', type=Pattern_type.EXCLUDE, source=Pattern_source.CONFIG), - ) + ), ) assert ( @@ -117,7 +117,9 @@ def test_get_logical_volumes_skips_non_root_patterns(): patterns=( Pattern('/mnt/lvolume', type=Pattern_type.EXCLUDE, source=Pattern_source.CONFIG), Pattern( - '/mnt/lvolume/subdir', type=Pattern_type.EXCLUDE, source=Pattern_source.CONFIG + '/mnt/lvolume/subdir', + type=Pattern_type.EXCLUDE, + source=Pattern_source.CONFIG, ), ), ) @@ -127,7 +129,7 @@ def test_get_logical_volumes_skips_non_root_patterns(): def test_get_logical_volumes_skips_non_config_patterns(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( ''' { @@ -140,22 +142,22 @@ def test_get_logical_volumes_skips_non_config_patterns(): } ] } - ''' + ''', ) contained = { Pattern('/mnt/lvolume', source=Pattern_source.HOOK), Pattern('/mnt/lvolume/subdir', source=Pattern_source.HOOK), } flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args(None, contained).never() flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/mnt/lvolume', contained).and_return( ( Pattern('/mnt/lvolume', source=Pattern_source.HOOK), Pattern('/mnt/lvolume/subdir', source=Pattern_source.HOOK), - ) + ), ) assert ( @@ -172,31 +174,33 @@ def test_get_logical_volumes_skips_non_config_patterns(): def test_get_logical_volumes_with_invalid_lsblk_json_errors(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return('{') flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).never() with pytest.raises(ValueError): module.get_logical_volumes( - 'lsblk', patterns=(Pattern('/mnt/lvolume'), Pattern('/mnt/lvolume/subdir')) + 'lsblk', + patterns=(Pattern('/mnt/lvolume'), Pattern('/mnt/lvolume/subdir')), ) def test_get_logical_volumes_with_lsblk_json_missing_keys_errors(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return('{"block_devices": [{}]}') flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).never() with pytest.raises(ValueError): module.get_logical_volumes( - 'lsblk', patterns=(Pattern('/mnt/lvolume'), Pattern('/mnt/lvolume/subdir')) + 'lsblk', + patterns=(Pattern('/mnt/lvolume'), Pattern('/mnt/lvolume/subdir')), ) @@ -269,15 +273,18 @@ def test_snapshot_logical_volume_with_non_percentage_snapshot_name_uses_lvcreate ), ) def test_make_borg_snapshot_pattern_includes_slashdot_hack_and_stripped_pattern_path( - pattern, expected_pattern + pattern, + expected_pattern, ): flexmock(module.hashlib).should_receive('shake_256').and_return( - flexmock(hexdigest=lambda length: 'b33f') + flexmock(hexdigest=lambda length: 'b33f'), ) assert ( module.make_borg_snapshot_pattern( - pattern, flexmock(mount_point='/something'), '/run/borgmatic' + pattern, + flexmock(mount_point='/something'), + '/run/borgmatic', ) == expected_pattern ) @@ -303,35 +310,51 @@ def test_dump_data_sources_snapshots_and_mounts_and_updates_patterns(): flexmock(module).should_receive('get_logical_volumes').and_return(logical_volumes) flexmock(module.os).should_receive('getpid').and_return(1234) flexmock(module).should_receive('snapshot_logical_volume').with_args( - 'lvcreate', 'lvolume1_borgmatic-1234', '/dev/lvolume1', module.DEFAULT_SNAPSHOT_SIZE + 'lvcreate', + 'lvolume1_borgmatic-1234', + '/dev/lvolume1', + module.DEFAULT_SNAPSHOT_SIZE, ).once() flexmock(module).should_receive('snapshot_logical_volume').with_args( - 'lvcreate', 'lvolume2_borgmatic-1234', '/dev/lvolume2', module.DEFAULT_SNAPSHOT_SIZE + 'lvcreate', + 'lvolume2_borgmatic-1234', + '/dev/lvolume2', + module.DEFAULT_SNAPSHOT_SIZE, ).once() flexmock(module).should_receive('get_snapshots').with_args( - 'lvs', snapshot_name='lvolume1_borgmatic-1234' + 'lvs', + snapshot_name='lvolume1_borgmatic-1234', ).and_return( - (module.Snapshot(name='lvolume1_borgmatic-1234', device_path='/dev/lvolume1_snap'),) + (module.Snapshot(name='lvolume1_borgmatic-1234', device_path='/dev/lvolume1_snap'),), ) flexmock(module).should_receive('get_snapshots').with_args( - 'lvs', snapshot_name='lvolume2_borgmatic-1234' + 'lvs', + snapshot_name='lvolume2_borgmatic-1234', ).and_return( - (module.Snapshot(name='lvolume2_borgmatic-1234', device_path='/dev/lvolume2_snap'),) + (module.Snapshot(name='lvolume2_borgmatic-1234', device_path='/dev/lvolume2_snap'),), ) flexmock(module.hashlib).should_receive('shake_256').and_return( - flexmock(hexdigest=lambda length: 'b33f') + flexmock(hexdigest=lambda length: 'b33f'), ) flexmock(module).should_receive('mount_snapshot').with_args( - 'mount', '/dev/lvolume1_snap', '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1' + 'mount', + '/dev/lvolume1_snap', + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1', ).once() flexmock(module).should_receive('mount_snapshot').with_args( - 'mount', '/dev/lvolume2_snap', '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2' + 'mount', + '/dev/lvolume2_snap', + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2', ).once() flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - Pattern('/mnt/lvolume1/subdir'), logical_volumes[0], '/run/borgmatic' + Pattern('/mnt/lvolume1/subdir'), + logical_volumes[0], + '/run/borgmatic', ).and_return(Pattern('/run/borgmatic/lvm_snapshots/b33f/./mnt/lvolume1/subdir')) flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - Pattern('/mnt/lvolume2'), logical_volumes[1], '/run/borgmatic' + Pattern('/mnt/lvolume2'), + logical_volumes[1], + '/run/borgmatic', ).and_return(Pattern('/run/borgmatic/lvm_snapshots/b33f/./mnt/lvolume2')) assert ( @@ -406,29 +429,39 @@ def test_dump_data_sources_uses_snapshot_size_for_snapshot(): '1000PB', ).once() flexmock(module).should_receive('get_snapshots').with_args( - 'lvs', snapshot_name='lvolume1_borgmatic-1234' + 'lvs', + snapshot_name='lvolume1_borgmatic-1234', ).and_return( - (module.Snapshot(name='lvolume1_borgmatic-1234', device_path='/dev/lvolume1_snap'),) + (module.Snapshot(name='lvolume1_borgmatic-1234', device_path='/dev/lvolume1_snap'),), ) flexmock(module).should_receive('get_snapshots').with_args( - 'lvs', snapshot_name='lvolume2_borgmatic-1234' + 'lvs', + snapshot_name='lvolume2_borgmatic-1234', ).and_return( - (module.Snapshot(name='lvolume2_borgmatic-1234', device_path='/dev/lvolume2_snap'),) + (module.Snapshot(name='lvolume2_borgmatic-1234', device_path='/dev/lvolume2_snap'),), ) flexmock(module.hashlib).should_receive('shake_256').and_return( - flexmock(hexdigest=lambda length: 'b33f') + flexmock(hexdigest=lambda length: 'b33f'), ) flexmock(module).should_receive('mount_snapshot').with_args( - 'mount', '/dev/lvolume1_snap', '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1' + 'mount', + '/dev/lvolume1_snap', + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1', ).once() flexmock(module).should_receive('mount_snapshot').with_args( - 'mount', '/dev/lvolume2_snap', '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2' + 'mount', + '/dev/lvolume2_snap', + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2', ).once() flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - Pattern('/mnt/lvolume1/subdir'), logical_volumes[0], '/run/borgmatic' + Pattern('/mnt/lvolume1/subdir'), + logical_volumes[0], + '/run/borgmatic', ).and_return(Pattern('/run/borgmatic/lvm_snapshots/b33f/./mnt/lvolume1/subdir')) flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - Pattern('/mnt/lvolume2'), logical_volumes[1], '/run/borgmatic' + Pattern('/mnt/lvolume2'), + logical_volumes[1], + '/run/borgmatic', ).and_return(Pattern('/run/borgmatic/lvm_snapshots/b33f/./mnt/lvolume2')) assert ( @@ -488,17 +521,19 @@ def test_dump_data_sources_uses_custom_commands(): module.DEFAULT_SNAPSHOT_SIZE, ).once() flexmock(module).should_receive('get_snapshots').with_args( - '/usr/local/bin/lvs', snapshot_name='lvolume1_borgmatic-1234' + '/usr/local/bin/lvs', + snapshot_name='lvolume1_borgmatic-1234', ).and_return( - (module.Snapshot(name='lvolume1_borgmatic-1234', device_path='/dev/lvolume1_snap'),) + (module.Snapshot(name='lvolume1_borgmatic-1234', device_path='/dev/lvolume1_snap'),), ) flexmock(module).should_receive('get_snapshots').with_args( - '/usr/local/bin/lvs', snapshot_name='lvolume2_borgmatic-1234' + '/usr/local/bin/lvs', + snapshot_name='lvolume2_borgmatic-1234', ).and_return( - (module.Snapshot(name='lvolume2_borgmatic-1234', device_path='/dev/lvolume2_snap'),) + (module.Snapshot(name='lvolume2_borgmatic-1234', device_path='/dev/lvolume2_snap'),), ) flexmock(module.hashlib).should_receive('shake_256').and_return( - flexmock(hexdigest=lambda length: 'b33f') + flexmock(hexdigest=lambda length: 'b33f'), ) flexmock(module).should_receive('mount_snapshot').with_args( '/usr/local/bin/mount', @@ -511,10 +546,14 @@ def test_dump_data_sources_uses_custom_commands(): '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2', ).once() flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - Pattern('/mnt/lvolume1/subdir'), logical_volumes[0], '/run/borgmatic' + Pattern('/mnt/lvolume1/subdir'), + logical_volumes[0], + '/run/borgmatic', ).and_return(Pattern('/run/borgmatic/lvm_snapshots/b33f/./mnt/lvolume1/subdir')) flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - Pattern('/mnt/lvolume2'), logical_volumes[1], '/run/borgmatic' + Pattern('/mnt/lvolume2'), + logical_volumes[1], + '/run/borgmatic', ).and_return(Pattern('/run/borgmatic/lvm_snapshots/b33f/./mnt/lvolume2')) assert ( @@ -552,7 +591,7 @@ def test_dump_data_sources_with_dry_run_skips_snapshots_and_does_not_touch_patte mount_point='/mnt/lvolume2', contained_patterns=(Pattern('/mnt/lvolume2'),), ), - ) + ), ) flexmock(module.os).should_receive('getpid').and_return(1234) flexmock(module).should_receive('snapshot_logical_volume').never() @@ -597,35 +636,51 @@ def test_dump_data_sources_ignores_mismatch_between_given_patterns_and_contained flexmock(module).should_receive('get_logical_volumes').and_return(logical_volumes) flexmock(module.os).should_receive('getpid').and_return(1234) flexmock(module).should_receive('snapshot_logical_volume').with_args( - 'lvcreate', 'lvolume1_borgmatic-1234', '/dev/lvolume1', module.DEFAULT_SNAPSHOT_SIZE + 'lvcreate', + 'lvolume1_borgmatic-1234', + '/dev/lvolume1', + module.DEFAULT_SNAPSHOT_SIZE, ).once() flexmock(module).should_receive('snapshot_logical_volume').with_args( - 'lvcreate', 'lvolume2_borgmatic-1234', '/dev/lvolume2', module.DEFAULT_SNAPSHOT_SIZE + 'lvcreate', + 'lvolume2_borgmatic-1234', + '/dev/lvolume2', + module.DEFAULT_SNAPSHOT_SIZE, ).once() flexmock(module).should_receive('get_snapshots').with_args( - 'lvs', snapshot_name='lvolume1_borgmatic-1234' + 'lvs', + snapshot_name='lvolume1_borgmatic-1234', ).and_return( - (module.Snapshot(name='lvolume1_borgmatic-1234', device_path='/dev/lvolume1_snap'),) + (module.Snapshot(name='lvolume1_borgmatic-1234', device_path='/dev/lvolume1_snap'),), ) flexmock(module).should_receive('get_snapshots').with_args( - 'lvs', snapshot_name='lvolume2_borgmatic-1234' + 'lvs', + snapshot_name='lvolume2_borgmatic-1234', ).and_return( - (module.Snapshot(name='lvolume2_borgmatic-1234', device_path='/dev/lvolume2_snap'),) + (module.Snapshot(name='lvolume2_borgmatic-1234', device_path='/dev/lvolume2_snap'),), ) flexmock(module.hashlib).should_receive('shake_256').and_return( - flexmock(hexdigest=lambda length: 'b33f') + flexmock(hexdigest=lambda length: 'b33f'), ) flexmock(module).should_receive('mount_snapshot').with_args( - 'mount', '/dev/lvolume1_snap', '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1' + 'mount', + '/dev/lvolume1_snap', + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1', ).once() flexmock(module).should_receive('mount_snapshot').with_args( - 'mount', '/dev/lvolume2_snap', '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2' + 'mount', + '/dev/lvolume2_snap', + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2', ).once() flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - Pattern('/mnt/lvolume1/subdir'), logical_volumes[0], '/run/borgmatic' + Pattern('/mnt/lvolume1/subdir'), + logical_volumes[0], + '/run/borgmatic', ).and_return(Pattern('/run/borgmatic/lvm_snapshots/b33f/./mnt/lvolume1/subdir')) flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - Pattern('/mnt/lvolume2'), logical_volumes[1], '/run/borgmatic' + Pattern('/mnt/lvolume2'), + logical_volumes[1], + '/run/borgmatic', ).and_return(Pattern('/run/borgmatic/lvm_snapshots/b33f/./mnt/lvolume2')) assert ( @@ -664,20 +719,28 @@ def test_dump_data_sources_with_missing_snapshot_errors(): mount_point='/mnt/lvolume2', contained_patterns=(Pattern('/mnt/lvolume2'),), ), - ) + ), ) flexmock(module.os).should_receive('getpid').and_return(1234) flexmock(module).should_receive('snapshot_logical_volume').with_args( - 'lvcreate', 'lvolume1_borgmatic-1234', '/dev/lvolume1', module.DEFAULT_SNAPSHOT_SIZE + 'lvcreate', + 'lvolume1_borgmatic-1234', + '/dev/lvolume1', + module.DEFAULT_SNAPSHOT_SIZE, ).once() flexmock(module).should_receive('snapshot_logical_volume').with_args( - 'lvcreate', 'lvolume2_borgmatic-1234', '/dev/lvolume2', module.DEFAULT_SNAPSHOT_SIZE + 'lvcreate', + 'lvolume2_borgmatic-1234', + '/dev/lvolume2', + module.DEFAULT_SNAPSHOT_SIZE, ).never() flexmock(module).should_receive('get_snapshots').with_args( - 'lvs', snapshot_name='lvolume1_borgmatic-1234' + 'lvs', + snapshot_name='lvolume1_borgmatic-1234', ).and_return(()) flexmock(module).should_receive('get_snapshots').with_args( - 'lvs', snapshot_name='lvolume2_borgmatic-1234' + 'lvs', + snapshot_name='lvolume2_borgmatic-1234', ).never() flexmock(module).should_receive('mount_snapshot').never() @@ -694,7 +757,7 @@ def test_dump_data_sources_with_missing_snapshot_errors(): def test_get_snapshots_lists_all_snapshots(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( ''' { @@ -709,7 +772,7 @@ def test_get_snapshots_lists_all_snapshots(): "log": [ ] } - ''' + ''', ) assert module.get_snapshots('lvs') == ( @@ -720,7 +783,7 @@ def test_get_snapshots_lists_all_snapshots(): def test_get_snapshots_with_snapshot_name_lists_just_that_snapshot(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( ''' { @@ -735,7 +798,7 @@ def test_get_snapshots_with_snapshot_name_lists_just_that_snapshot(): "log": [ ] } - ''' + ''', ) assert module.get_snapshots('lvs', snapshot_name='snap2') == ( @@ -745,7 +808,7 @@ def test_get_snapshots_with_snapshot_name_lists_just_that_snapshot(): def test_get_snapshots_with_invalid_lvs_json_errors(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return('{') with pytest.raises(ValueError): @@ -754,7 +817,7 @@ def test_get_snapshots_with_invalid_lvs_json_errors(): def test_get_snapshots_with_lvs_json_missing_report_errors(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( ''' { @@ -762,7 +825,7 @@ def test_get_snapshots_with_lvs_json_missing_report_errors(): "log": [ ] } - ''' + ''', ) with pytest.raises(ValueError): @@ -771,7 +834,7 @@ def test_get_snapshots_with_lvs_json_missing_report_errors(): def test_get_snapshots_with_lvs_json_missing_keys_errors(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( ''' { @@ -785,7 +848,7 @@ def test_get_snapshots_with_lvs_json_missing_keys_errors(): "log": [ ] } - ''' + ''', ) with pytest.raises(ValueError): @@ -808,13 +871,13 @@ def test_remove_data_source_dumps_unmounts_and_remove_snapshots(): mount_point='/mnt/lvolume2', contained_patterns=(Pattern('/mnt/lvolume2'),), ), - ) + ), ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').and_return(True) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) @@ -837,7 +900,8 @@ def test_remove_data_source_dumps_unmounts_and_remove_snapshots(): flexmock(module).should_receive('remove_snapshot').with_args('lvremove', '/dev/lvolume1').once() flexmock(module).should_receive('remove_snapshot').with_args('lvremove', '/dev/lvolume2').once() flexmock(module).should_receive('remove_snapshot').with_args( - 'nonborgmatic', '/dev/nonborgmatic' + 'nonborgmatic', + '/dev/nonborgmatic', ).never() module.remove_data_source_dumps( @@ -851,7 +915,7 @@ def test_remove_data_source_dumps_unmounts_and_remove_snapshots(): def test_remove_data_source_dumps_bails_for_missing_lvm_configuration(): flexmock(module).should_receive('get_logical_volumes').never() flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).never() flexmock(module).should_receive('unmount_snapshot').never() flexmock(module).should_receive('remove_snapshot').never() @@ -868,7 +932,7 @@ def test_remove_data_source_dumps_bails_for_missing_lsblk_command(): config = {'lvm': {}} flexmock(module).should_receive('get_logical_volumes').and_raise(FileNotFoundError) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).never() flexmock(module).should_receive('unmount_snapshot').never() flexmock(module).should_receive('remove_snapshot').never() @@ -884,10 +948,10 @@ def test_remove_data_source_dumps_bails_for_missing_lsblk_command(): def test_remove_data_source_dumps_bails_for_lsblk_command_error(): config = {'lvm': {}} flexmock(module).should_receive('get_logical_volumes').and_raise( - module.subprocess.CalledProcessError(1, 'wtf') + module.subprocess.CalledProcessError(1, 'wtf'), ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).never() flexmock(module).should_receive('unmount_snapshot').never() flexmock(module).should_receive('remove_snapshot').never() @@ -916,16 +980,16 @@ def test_remove_data_source_dumps_with_missing_snapshot_directory_skips_unmount( mount_point='/mnt/lvolume2', contained_patterns=(Pattern('/mnt/lvolume2'),), ), - ) + ), ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/lvm_snapshots/b33f' + '/run/borgmatic/lvm_snapshots/b33f', ).and_return(False) flexmock(module.shutil).should_receive('rmtree').never() flexmock(module).should_receive('unmount_snapshot').never() @@ -962,22 +1026,22 @@ def test_remove_data_source_dumps_with_missing_snapshot_mount_path_skips_unmount mount_point='/mnt/lvolume2', contained_patterns=(Pattern('/mnt/lvolume2'),), ), - ) + ), ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/lvm_snapshots/b33f' + '/run/borgmatic/lvm_snapshots/b33f', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1' + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1', ).and_return(False) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2' + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2', ).and_return(True) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) flexmock(module.shutil).should_receive('rmtree') @@ -1022,28 +1086,28 @@ def test_remove_data_source_dumps_with_empty_snapshot_mount_path_skips_unmount() mount_point='/mnt/lvolume2', contained_patterns=(Pattern('/mnt/lvolume2'),), ), - ) + ), ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/lvm_snapshots/b33f' + '/run/borgmatic/lvm_snapshots/b33f', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1' + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1', ).and_return(True) flexmock(module.os).should_receive('listdir').with_args( - '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1' + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1', ).and_return([]) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2' + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2', ).and_return(True) flexmock(module.os).should_receive('listdir').with_args( - '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2' + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2', ).and_return(['file.txt']) flexmock(module.shutil).should_receive('rmtree') flexmock(module).should_receive('unmount_snapshot').with_args( @@ -1087,22 +1151,22 @@ def test_remove_data_source_dumps_with_successful_mount_point_removal_skips_unmo mount_point='/mnt/lvolume2', contained_patterns=(Pattern('/mnt/lvolume2'),), ), - ) + ), ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/lvm_snapshots/b33f' + '/run/borgmatic/lvm_snapshots/b33f', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1' + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume1', ).and_return(True).and_return(False) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2' + '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2', ).and_return(True).and_return(True) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) flexmock(module.shutil).should_receive('rmtree') @@ -1147,13 +1211,13 @@ def test_remove_data_source_dumps_bails_for_missing_umount_command(): mount_point='/mnt/lvolume2', contained_patterns=(Pattern('/mnt/lvolume2'),), ), - ) + ), ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').and_return(True) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) @@ -1193,13 +1257,13 @@ def test_remove_data_source_dumps_swallows_umount_command_error(): mount_point='/mnt/lvolume2', contained_patterns=(Pattern('/mnt/lvolume2'),), ), - ) + ), ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').and_return(True) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) @@ -1245,13 +1309,13 @@ def test_remove_data_source_dumps_bails_for_missing_lvs_command(): mount_point='/mnt/lvolume2', contained_patterns=(Pattern('/mnt/lvolume2'),), ), - ) + ), ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').and_return(True) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) @@ -1291,13 +1355,13 @@ def test_remove_data_source_dumps_bails_for_lvs_command_error(): mount_point='/mnt/lvolume2', contained_patterns=(Pattern('/mnt/lvolume2'),), ), - ) + ), ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').and_return(True) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) @@ -1311,7 +1375,7 @@ def test_remove_data_source_dumps_bails_for_lvs_command_error(): '/run/borgmatic/lvm_snapshots/b33f/mnt/lvolume2', ).once() flexmock(module).should_receive('get_snapshots').and_raise( - module.subprocess.CalledProcessError(1, 'wtf') + module.subprocess.CalledProcessError(1, 'wtf'), ) flexmock(module).should_receive('remove_snapshot').never() @@ -1339,10 +1403,10 @@ def test_remove_data_source_with_dry_run_skips_snapshot_unmount_and_delete(): mount_point='/mnt/lvolume2', contained_patterns=(Pattern('/mnt/lvolume2'),), ), - ) + ), ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with(lambda path: [path]) flexmock(module.os.path).should_receive('isdir').and_return(True) diff --git a/tests/unit/hooks/data_source/test_mariadb.py b/tests/unit/hooks/data_source/test_mariadb.py index 21a1ff7e..f2ece606 100644 --- a/tests/unit/hooks/data_source/test_mariadb.py +++ b/tests/unit/hooks/data_source/test_mariadb.py @@ -36,7 +36,8 @@ def test_make_defaults_file_option_with_username_and_password_writes_them_to_fil flexmock(module.os).should_receive('pipe').and_return(read_descriptor, write_descriptor) flexmock(module.os).should_receive('write').with_args( - write_descriptor, b'[client]\nuser=root\npassword="trustsome1"' + write_descriptor, + b'[client]\nuser=root\npassword="trustsome1"', ).once() flexmock(module.os).should_receive('close') flexmock(module.os).should_receive('set_inheritable') @@ -52,7 +53,8 @@ def test_make_defaults_file_escapes_password_containing_backslash(): flexmock(module.os).should_receive('pipe').and_return(read_descriptor, write_descriptor) flexmock(module.os).should_receive('write').with_args( - write_descriptor, b'[client]\nuser=root\n' + br'password="trust\\nsome1"' + write_descriptor, + b'[client]\nuser=root\n' + rb'password="trust\\nsome1"', ).once() flexmock(module.os).should_receive('close') flexmock(module.os).should_receive('set_inheritable') @@ -68,7 +70,8 @@ def test_make_defaults_file_pipe_with_only_username_writes_it_to_file_descriptor flexmock(module.os).should_receive('pipe').and_return(read_descriptor, write_descriptor) flexmock(module.os).should_receive('write').with_args( - write_descriptor, b'[client]\nuser=root' + write_descriptor, + b'[client]\nuser=root', ).once() flexmock(module.os).should_receive('close') flexmock(module.os).should_receive('set_inheritable') @@ -84,7 +87,8 @@ def test_make_defaults_file_pipe_with_only_password_writes_it_to_file_descriptor flexmock(module.os).should_receive('pipe').and_return(read_descriptor, write_descriptor) flexmock(module.os).should_receive('write').with_args( - write_descriptor, b'[client]\npassword="trustsome1"' + write_descriptor, + b'[client]\npassword="trustsome1"', ).once() flexmock(module.os).should_receive('close') flexmock(module.os).should_receive('set_inheritable') @@ -100,13 +104,16 @@ def test_make_defaults_file_option_with_defaults_extra_filename_includes_it_in_f flexmock(module.os).should_receive('pipe').and_return(read_descriptor, write_descriptor) flexmock(module.os).should_receive('write').with_args( - write_descriptor, b'!include extra.cnf\n[client]\nuser=root\npassword="trustsome1"' + write_descriptor, + b'!include extra.cnf\n[client]\nuser=root\npassword="trustsome1"', ).once() flexmock(module.os).should_receive('close') flexmock(module.os).should_receive('set_inheritable') assert module.make_defaults_file_options( - username='root', password='trustsome1', defaults_extra_filename='extra.cnf' + username='root', + password='trustsome1', + defaults_extra_filename='extra.cnf', ) == ('--defaults-extra-file=/dev/fd/99',) @@ -114,7 +121,9 @@ def test_make_defaults_file_option_with_only_defaults_extra_filename_uses_it_ins flexmock(module.os).should_receive('pipe').never() assert module.make_defaults_file_options( - username=None, password=None, defaults_extra_filename='extra.cnf' + username=None, + password=None, + defaults_extra_filename='extra.cnf', ) == ('--defaults-extra-file=extra.cnf',) @@ -122,7 +131,12 @@ def test_database_names_to_dump_passes_through_name(): environment = flexmock() names = module.database_names_to_dump( - {'name': 'foo'}, {}, 'root', 'trustsome1', environment, dry_run=False + {'name': 'foo'}, + {}, + 'root', + 'trustsome1', + environment, + dry_run=False, ) assert names == ('foo',) @@ -133,7 +147,12 @@ def test_database_names_to_dump_bails_for_dry_run(): flexmock(module).should_receive('execute_command_and_capture_output').never() names = module.database_names_to_dump( - {'name': 'all'}, {}, 'root', 'trustsome1', environment, dry_run=True + {'name': 'all'}, + {}, + 'root', + 'trustsome1', + environment, + dry_run=True, ) assert names == () @@ -142,11 +161,13 @@ def test_database_names_to_dump_bails_for_dry_run(): def test_database_names_to_dump_queries_mariadb_for_database_names(): environment = flexmock() flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( @@ -161,7 +182,12 @@ def test_database_names_to_dump_queries_mariadb_for_database_names(): ).and_return('foo\nbar\nmysql\n').once() names = module.database_names_to_dump( - {'name': 'all'}, {}, 'root', 'trustsome1', environment, dry_run=False + {'name': 'all'}, + {}, + 'root', + 'trustsome1', + environment, + dry_run=False, ) assert names == ('foo', 'bar') @@ -170,7 +196,7 @@ def test_database_names_to_dump_queries_mariadb_for_database_names(): def test_database_names_to_dump_with_environment_password_transport_skips_defaults_file_and_passes_user_flag(): environment = flexmock() flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').never() @@ -202,11 +228,13 @@ def test_database_names_to_dump_with_environment_password_transport_skips_defaul def test_database_names_to_dump_runs_mariadb_with_tls(): environment = flexmock() flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( @@ -222,7 +250,12 @@ def test_database_names_to_dump_runs_mariadb_with_tls(): ).and_return('foo\nbar\nmysql\n').once() names = module.database_names_to_dump( - {'name': 'all', 'tls': True}, {}, 'root', 'trustsome1', environment, dry_run=False + {'name': 'all', 'tls': True}, + {}, + 'root', + 'trustsome1', + environment, + dry_run=False, ) assert names == ('foo', 'bar') @@ -231,11 +264,13 @@ def test_database_names_to_dump_runs_mariadb_with_tls(): def test_database_names_to_dump_runs_mariadb_without_tls(): environment = flexmock() flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( @@ -251,7 +286,12 @@ def test_database_names_to_dump_runs_mariadb_without_tls(): ).and_return('foo\nbar\nmysql\n').once() names = module.database_names_to_dump( - {'name': 'all', 'tls': False}, {}, 'root', 'trustsome1', environment, dry_run=False + {'name': 'all', 'tls': False}, + {}, + 'root', + 'trustsome1', + environment, + dry_run=False, ) assert names == ('foo', 'bar') @@ -273,11 +313,11 @@ def test_dump_data_sources_dumps_each_database(): processes = [flexmock(), flexmock()] flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('database_names_to_dump').with_args( database=databases[0], @@ -327,7 +367,7 @@ def test_dump_data_sources_dumps_with_password(): process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('database_names_to_dump').with_args( @@ -371,7 +411,7 @@ def test_dump_data_sources_dumps_with_environment_password_transport_passes_pass process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('database_names_to_dump').with_args( @@ -410,7 +450,7 @@ def test_dump_data_sources_dumps_all_databases_at_once(): process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('database_names_to_dump').and_return(('foo', 'bar')) @@ -441,7 +481,7 @@ def test_dump_data_sources_dumps_all_databases_separately_when_format_configured processes = [flexmock(), flexmock()] flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('database_names_to_dump').and_return(('foo', 'bar')) @@ -477,10 +517,10 @@ def test_dump_data_sources_errors_for_missing_all_databases(): flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/all' + 'databases/localhost/all', ) flexmock(module).should_receive('database_names_to_dump').and_return(()) @@ -500,10 +540,10 @@ def test_dump_data_sources_does_not_error_for_missing_all_databases_with_dry_run flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/all' + 'databases/localhost/all', ) flexmock(module).should_receive('database_names_to_dump').and_return(()) @@ -523,10 +563,13 @@ def test_dump_data_sources_does_not_error_for_missing_all_databases_with_dry_run def test_database_names_to_dump_runs_mariadb_with_list_options(): database = {'name': 'all', 'list_options': '--defaults-extra-file=mariadb.cnf --skip-ssl'} flexmock(module).should_receive('parse_extra_options').and_return( - ('--skip-ssl',), 'mariadb.cnf' + ('--skip-ssl',), + 'mariadb.cnf', ) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', 'mariadb.cnf' + 'root', + 'trustsome1', + 'mariadb.cnf', ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( @@ -539,7 +582,7 @@ def test_database_names_to_dump_runs_mariadb_with_list_options(): 'show schemas', ), environment=None, - ).and_return(('foo\nbar')).once() + ).and_return('foo\nbar').once() assert module.database_names_to_dump(database, {}, 'root', 'trustsome1', None, '') == ( 'foo', @@ -554,10 +597,13 @@ def test_database_names_to_dump_runs_non_default_mariadb_with_list_options(): 'mariadb_command': 'custom_mariadb', } flexmock(module).should_receive('parse_extra_options').and_return( - ('--skip-ssl',), 'mariadb.cnf' + ('--skip-ssl',), + 'mariadb.cnf', ) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', 'mariadb.cnf' + 'root', + 'trustsome1', + 'mariadb.cnf', ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module).should_receive('execute_command_and_capture_output').with_args( environment=None, @@ -570,7 +616,7 @@ def test_database_names_to_dump_runs_non_default_mariadb_with_list_options(): '--execute', 'show schemas', ), - ).and_return(('foo\nbar')).once() + ).and_return('foo\nbar').once() assert module.database_names_to_dump(database, {}, 'root', 'trustsome1', None, '') == ( 'foo', @@ -583,11 +629,13 @@ def test_execute_dump_command_runs_mariadb_dump(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -626,7 +674,7 @@ def test_execute_dump_command_with_environment_password_transport_skips_defaults flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').never() @@ -668,11 +716,13 @@ def test_execute_dump_command_runs_mariadb_dump_without_add_drop_database(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -710,11 +760,13 @@ def test_execute_dump_command_runs_mariadb_dump_with_hostname_and_port(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -759,11 +811,13 @@ def test_execute_dump_command_runs_mariadb_dump_with_tls(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -803,11 +857,13 @@ def test_execute_dump_command_runs_mariadb_dump_without_tls(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -847,11 +903,13 @@ def test_execute_dump_command_runs_mariadb_dump_with_username_and_password(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -890,11 +948,13 @@ def test_execute_dump_command_runs_mariadb_dump_with_options(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return(('--stuff=such',), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -934,11 +994,13 @@ def test_execute_dump_command_runs_non_default_mariadb_dump_with_options(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return(('--stuff=such',), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -982,7 +1044,9 @@ def test_execute_dump_command_with_duplicate_dump_skips_mariadb_dump(): flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump').never() flexmock(module).should_receive('execute_command').never() @@ -1007,11 +1071,13 @@ def test_execute_dump_command_with_dry_run_skips_mariadb_dump(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -1038,11 +1104,13 @@ def test_restore_data_source_dump_runs_mariadb_to_restore(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - None, None, None + None, + None, + None, ).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1074,11 +1142,13 @@ def test_restore_data_source_dump_runs_mariadb_with_options(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return(('--harder',), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - None, None, None + None, + None, + None, ).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1107,16 +1177,18 @@ def test_restore_data_source_dump_runs_mariadb_with_options(): def test_restore_data_source_dump_runs_non_default_mariadb_with_options(): hook_config = [ - {'name': 'foo', 'restore_options': '--harder', 'mariadb_command': 'custom_mariadb'} + {'name': 'foo', 'restore_options': '--harder', 'mariadb_command': 'custom_mariadb'}, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return(('--harder',), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - None, None, None + None, + None, + None, ).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1148,11 +1220,13 @@ def test_restore_data_source_dump_runs_mariadb_with_hostname_and_port(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - None, None, None + None, + None, + None, ).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1193,11 +1267,13 @@ def test_restore_data_source_dump_runs_mariadb_with_tls(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - None, None, None + None, + None, + None, ).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1233,11 +1309,13 @@ def test_restore_data_source_dump_runs_mariadb_without_tls(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - None, None, None + None, + None, + None, ).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1273,11 +1351,13 @@ def test_restore_data_source_dump_runs_mariadb_with_username_and_password(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'root', 'trustsome1', None + 'root', + 'trustsome1', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1311,17 +1391,17 @@ def test_restore_data_source_with_environment_password_transport_skips_defaults_ 'username': 'root', 'password': 'trustsome1', 'password_transport': 'environment', - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').never() flexmock(module.os).should_receive('environ').and_return( - {'USER': 'root', 'MYSQL_PWD': 'trustsome1'} + {'USER': 'root', 'MYSQL_PWD': 'trustsome1'}, ) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mariadb', '--batch', '--user', 'root'), @@ -1357,16 +1437,18 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ 'restore_port': 'restoreport', 'restore_username': 'restoreusername', 'restore_password': 'restorepassword', - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'cliusername', 'clipassword', None + 'cliusername', + 'clipassword', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1417,16 +1499,18 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ 'restore_hostname': 'restorehost', 'restore_port': 'restoreport', 'restore_tls': False, - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - 'restoreuser', 'restorepass', None + 'restoreuser', + 'restorepass', + None, ).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1468,11 +1552,13 @@ def test_restore_data_source_dump_with_dry_run_skips_restore(): hook_config = [{'name': 'foo'}] flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('parse_extra_options').and_return((), None) flexmock(module).should_receive('make_defaults_file_options').with_args( - None, None, None + None, + None, + None, ).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').never() diff --git a/tests/unit/hooks/data_source/test_mongodb.py b/tests/unit/hooks/data_source/test_mongodb.py index 8f4c7f7b..d09dff60 100644 --- a/tests/unit/hooks/data_source/test_mongodb.py +++ b/tests/unit/hooks/data_source/test_mongodb.py @@ -28,7 +28,7 @@ def test_dump_data_sources_runs_mongodump_for_each_database(): processes = [flexmock(), flexmock()] flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ).and_return('databases/localhost/bar') flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -56,7 +56,7 @@ def test_dump_data_sources_with_dry_run_skips_mongodump(): databases = [{'name': 'foo'}, {'name': 'bar'}] flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ).and_return('databases/localhost/bar') flexmock(module.dump).should_receive('create_named_pipe_for_dump').never() flexmock(module).should_receive('execute_command').never() @@ -79,7 +79,7 @@ def test_dump_data_sources_runs_mongodump_with_hostname_and_port(): process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/database.example.org/foo' + 'databases/database.example.org/foo', ) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -117,18 +117,18 @@ def test_dump_data_sources_runs_mongodump_with_username_and_password(): 'username': 'mongo', 'password': 'trustsome1', 'authentication_database': 'admin', - } + }, ] process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_password_config_file').with_args('trustsome1').and_return( - '/dev/fd/99' + '/dev/fd/99', ) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -165,7 +165,7 @@ def test_dump_data_sources_runs_mongodump_with_directory_format(): databases = [{'name': 'foo', 'format': 'directory'}] flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ) flexmock(module.dump).should_receive('create_parent_directory_for_dump') flexmock(module.dump).should_receive('create_named_pipe_for_dump').never() @@ -193,7 +193,7 @@ def test_dump_data_sources_runs_mongodump_with_options(): process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -226,7 +226,7 @@ def test_dump_data_sources_runs_mongodumpall_for_all_databases(): process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/all' + 'databases/localhost/all', ) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -251,10 +251,11 @@ def test_make_password_config_file_writes_password_to_pipe(): write_file_descriptor = flexmock() flexmock(module.os).should_receive('pipe').and_return( - (read_file_descriptor, write_file_descriptor) + (read_file_descriptor, write_file_descriptor), ) flexmock(module.os).should_receive('write').with_args( - write_file_descriptor, b'password: trustsome1' + write_file_descriptor, + b'password: trustsome1', ).once() flexmock(module.os).should_receive('close') flexmock(module.os).should_receive('set_inheritable') @@ -265,7 +266,7 @@ def test_make_password_config_file_writes_password_to_pipe(): def test_build_dump_command_with_username_injection_attack_gets_escaped(): database = {'name': 'test', 'username': 'bob; naughty-command'} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) command = module.build_dump_command(database, {}, dump_filename='test', dump_format='archive') @@ -280,7 +281,7 @@ def test_restore_data_source_dump_runs_mongorestore(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ['mongorestore', '--archive', '--drop'], @@ -307,14 +308,14 @@ def test_restore_data_source_dump_runs_mongorestore(): def test_restore_data_source_dump_runs_mongorestore_with_hostname_and_port(): hook_config = [ - {'name': 'foo', 'hostname': 'database.example.org', 'port': 5433, 'schemas': None} + {'name': 'foo', 'hostname': 'database.example.org', 'port': 5433, 'schemas': None}, ] extract_process = flexmock(stdout=flexmock()) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_with_processes').with_args( [ @@ -355,17 +356,17 @@ def test_restore_data_source_dump_runs_mongorestore_with_username_and_password() 'password': 'trustsome1', 'authentication_database': 'admin', 'schemas': None, - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_password_config_file').with_args('trustsome1').and_return( - '/dev/fd/99' + '/dev/fd/99', ) flexmock(module).should_receive('execute_command_with_processes').with_args( [ @@ -412,17 +413,17 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ 'restore_username': 'restoreusername', 'restore_password': 'restorepassword', 'schemas': None, - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_password_config_file').with_args( - 'clipassword' + 'clipassword', ).and_return('/dev/fd/99') flexmock(module).should_receive('execute_command_with_processes').with_args( [ @@ -473,17 +474,17 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ 'restore_port': 'restoreport', 'restore_username': 'restoreuser', 'restore_password': 'restorepass', - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_password_config_file').with_args( - 'restorepass' + 'restorepass', ).and_return('/dev/fd/99') flexmock(module).should_receive('execute_command_with_processes').with_args( [ @@ -529,7 +530,7 @@ def test_restore_data_source_dump_runs_mongorestore_with_options(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ['mongorestore', '--archive', '--drop', '--harder'], @@ -561,7 +562,7 @@ def test_restore_databases_dump_runs_mongorestore_with_schemas(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_with_processes').with_args( [ @@ -601,7 +602,7 @@ def test_restore_data_source_dump_runs_psql_for_all_database_dump(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ['mongorestore', '--archive'], @@ -632,7 +633,7 @@ def test_restore_data_source_dump_with_dry_run_skips_restore(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_with_processes').never() @@ -658,7 +659,7 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('/dump/path') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ['mongorestore', '--dir', '/dump/path', '--drop'], @@ -685,13 +686,13 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk(): def test_dump_data_sources_uses_custom_mongodump_command(): flexmock(module.borgmatic.hooks.command).should_receive('Before_after_hooks').and_return( - flexmock() + flexmock(), ) databases = [{'name': 'foo', 'mongodump_command': 'custom_mongodump'}] process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -748,14 +749,14 @@ def test_restore_data_source_dump_uses_custom_mongorestore_command(): 'mongorestore_command': 'custom_mongorestore', 'schemas': None, 'restore_options': '--gzip', - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_with_processes').with_args( [ @@ -806,7 +807,11 @@ def test_build_restore_command_prevents_shell_injection(): extract_process = None command = module.build_restore_command( - extract_process, database, config, dump_filename, connection_params + extract_process, + database, + config, + dump_filename, + connection_params, ) # Ensure the malicious input is properly escaped and does not execute diff --git a/tests/unit/hooks/data_source/test_mysql.py b/tests/unit/hooks/data_source/test_mysql.py index 4eac5cb7..262d9c44 100644 --- a/tests/unit/hooks/data_source/test_mysql.py +++ b/tests/unit/hooks/data_source/test_mysql.py @@ -10,7 +10,12 @@ def test_database_names_to_dump_passes_through_name(): environment = flexmock() names = module.database_names_to_dump( - {'name': 'foo'}, {}, 'root', 'trustsome1', environment, dry_run=False + {'name': 'foo'}, + {}, + 'root', + 'trustsome1', + environment, + dry_run=False, ) assert names == ('foo',) @@ -19,12 +24,17 @@ def test_database_names_to_dump_passes_through_name(): def test_database_names_to_dump_bails_for_dry_run(): environment = flexmock() flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_and_capture_output').never() names = module.database_names_to_dump( - {'name': 'all'}, {}, 'root', 'trustsome1', environment, dry_run=True + {'name': 'all'}, + {}, + 'root', + 'trustsome1', + environment, + dry_run=True, ) assert names == () @@ -33,13 +43,13 @@ def test_database_names_to_dump_bails_for_dry_run(): def test_database_names_to_dump_queries_mysql_for_database_names(): environment = flexmock() flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( @@ -54,7 +64,12 @@ def test_database_names_to_dump_queries_mysql_for_database_names(): ).and_return('foo\nbar\nmysql\n').once() names = module.database_names_to_dump( - {'name': 'all'}, {}, 'root', 'trustsome1', environment, dry_run=False + {'name': 'all'}, + {}, + 'root', + 'trustsome1', + environment, + dry_run=False, ) assert names == ('foo', 'bar') @@ -63,13 +78,13 @@ def test_database_names_to_dump_queries_mysql_for_database_names(): def test_database_names_to_dump_with_environment_password_transport_skips_defaults_file_and_passes_user_flag(): environment = flexmock() flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).never() flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( @@ -99,13 +114,13 @@ def test_database_names_to_dump_with_environment_password_transport_skips_defaul def test_database_names_to_dump_runs_mysql_with_tls(): environment = flexmock() flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( @@ -121,7 +136,12 @@ def test_database_names_to_dump_runs_mysql_with_tls(): ).and_return('foo\nbar\nmysql\n').once() names = module.database_names_to_dump( - {'name': 'all', 'tls': True}, {}, 'root', 'trustsome1', environment, dry_run=False + {'name': 'all', 'tls': True}, + {}, + 'root', + 'trustsome1', + environment, + dry_run=False, ) assert names == ('foo', 'bar') @@ -130,13 +150,13 @@ def test_database_names_to_dump_runs_mysql_with_tls(): def test_database_names_to_dump_runs_mysql_without_tls(): environment = flexmock() flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( @@ -152,7 +172,12 @@ def test_database_names_to_dump_runs_mysql_without_tls(): ).and_return('foo\nbar\nmysql\n').once() names = module.database_names_to_dump( - {'name': 'all', 'tls': False}, {}, 'root', 'trustsome1', environment, dry_run=False + {'name': 'all', 'tls': False}, + {}, + 'root', + 'trustsome1', + environment, + dry_run=False, ) assert names == ('foo', 'bar') @@ -174,7 +199,7 @@ def test_dump_data_sources_dumps_each_database(): processes = [flexmock(), flexmock()] flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('database_names_to_dump').with_args( @@ -225,7 +250,7 @@ def test_dump_data_sources_dumps_with_password(): process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('database_names_to_dump').with_args( @@ -269,7 +294,7 @@ def test_dump_data_sources_dumps_with_environment_password_transport_passes_pass process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('database_names_to_dump').with_args( @@ -308,7 +333,7 @@ def test_dump_data_sources_dumps_all_databases_at_once(): process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('database_names_to_dump').and_return(('foo', 'bar')) @@ -339,7 +364,7 @@ def test_dump_data_sources_dumps_all_databases_separately_when_format_configured processes = [flexmock(), flexmock()] flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_return(None) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('database_names_to_dump').and_return(('foo', 'bar')) @@ -375,10 +400,10 @@ def test_dump_data_sources_errors_for_missing_all_databases(): flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/all' + 'databases/localhost/all', ) flexmock(module).should_receive('database_names_to_dump').and_return(()) @@ -398,10 +423,10 @@ def test_dump_data_sources_does_not_error_for_missing_all_databases_with_dry_run flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/all' + 'databases/localhost/all', ) flexmock(module).should_receive('database_names_to_dump').and_return(()) @@ -421,10 +446,10 @@ def test_dump_data_sources_does_not_error_for_missing_all_databases_with_dry_run def test_database_names_to_dump_runs_mysql_with_list_options(): database = {'name': 'all', 'list_options': '--defaults-extra-file=my.cnf --skip-ssl'} flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return(('--skip-ssl',), 'my.cnf') flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', 'my.cnf').and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( @@ -437,7 +462,7 @@ def test_database_names_to_dump_runs_mysql_with_list_options(): 'show schemas', ), environment=None, - ).and_return(('foo\nbar')).once() + ).and_return('foo\nbar').once() assert module.database_names_to_dump(database, {}, 'root', 'trustsome1', None, '') == ( 'foo', @@ -452,10 +477,10 @@ def test_database_names_to_dump_runs_non_default_mysql_with_list_options(): 'mysql_command': 'custom_mysql', } flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return(('--skip-ssl',), 'my.cnf') flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', 'my.cnf').and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module).should_receive('execute_command_and_capture_output').with_args( environment=None, @@ -468,7 +493,7 @@ def test_database_names_to_dump_runs_non_default_mysql_with_list_options(): '--execute', 'show schemas', ), - ).and_return(('foo\nbar')).once() + ).and_return('foo\nbar').once() assert module.database_names_to_dump(database, {}, 'root', 'trustsome1', None, '') == ( 'foo', @@ -481,13 +506,13 @@ def test_execute_dump_command_runs_mysqldump(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -526,13 +551,13 @@ def test_execute_dump_command_with_environment_password_transport_skips_defaults flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).never() flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -572,13 +597,13 @@ def test_execute_dump_command_runs_mysqldump_without_add_drop_database(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -616,13 +641,13 @@ def test_execute_dump_command_runs_mysqldump_with_hostname_and_port(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -667,13 +692,13 @@ def test_execute_dump_command_runs_mysqldump_with_tls(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -713,13 +738,13 @@ def test_execute_dump_command_runs_mysqldump_without_tls(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -759,13 +784,13 @@ def test_execute_dump_command_runs_mysqldump_with_username_and_password(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -804,13 +829,13 @@ def test_execute_dump_command_runs_mysqldump_with_options(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return(('--stuff=such',), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -850,13 +875,13 @@ def test_execute_dump_command_runs_non_default_mysqldump(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -897,10 +922,10 @@ def test_execute_dump_command_with_duplicate_dump_skips_mysqldump(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump').never() flexmock(module).should_receive('execute_command').never() @@ -925,13 +950,13 @@ def test_execute_dump_command_with_dry_run_skips_mysqldump(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -958,13 +983,13 @@ def test_restore_data_source_dump_runs_mysql_to_restore(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args(None, None, None).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -996,13 +1021,13 @@ def test_restore_data_source_dump_runs_mysql_with_options(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return(('--harder',), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args(None, None, None).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1034,13 +1059,13 @@ def test_restore_data_source_dump_runs_non_default_mysql_with_options(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return(('--harder',), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args(None, None, None).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1072,13 +1097,13 @@ def test_restore_data_source_dump_runs_mysql_with_hostname_and_port(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args(None, None, None).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1119,13 +1144,13 @@ def test_restore_data_source_dump_runs_mysql_with_tls(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args(None, None, None).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1161,13 +1186,13 @@ def test_restore_data_source_dump_runs_mysql_without_tls(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args(None, None, None).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1203,13 +1228,13 @@ def test_restore_data_source_dump_runs_mysql_with_username_and_password(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',)) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1243,21 +1268,21 @@ def test_restore_data_source_with_environment_password_transport_skips_defaults_ 'username': 'root', 'password': 'trustsome1', 'password_transport': 'environment', - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).never() flexmock(module.os).should_receive('environ').and_return( - {'USER': 'root', 'MYSQL_PWD': 'trustsome1'} + {'USER': 'root', 'MYSQL_PWD': 'trustsome1'}, ) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mysql', '--batch', '--user', 'root'), @@ -1293,20 +1318,20 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ 'restore_port': 'restoreport', 'restore_username': 'restoreusername', 'restore_password': 'restorepassword', - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('cliusername', 'clipassword', None).and_return( - ('--defaults-extra-file=/dev/fd/99',) + ('--defaults-extra-file=/dev/fd/99',), ) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1357,20 +1382,20 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ 'restore_hostname': 'restorehost', 'restore_port': 'restoreport', 'restore_tls': False, - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args('restoreuser', 'restorepass', None).and_return( - ('--defaults-extra-file=/dev/fd/99',) + ('--defaults-extra-file=/dev/fd/99',), ) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1412,13 +1437,13 @@ def test_restore_data_source_dump_with_dry_run_skips_restore(): hook_config = [{'name': 'foo'}] flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'parse_extra_options' + 'parse_extra_options', ).and_return((), None) flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive( - 'make_defaults_file_options' + 'make_defaults_file_options', ).with_args(None, None, None).and_return(()) flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').never() diff --git a/tests/unit/hooks/data_source/test_postgresql.py b/tests/unit/hooks/data_source/test_postgresql.py index f1589a6e..15c65d48 100644 --- a/tests/unit/hooks/data_source/test_postgresql.py +++ b/tests/unit/hooks/data_source/test_postgresql.py @@ -27,7 +27,7 @@ def test_make_environment_maps_options_to_environment(): } flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) assert module.make_environment(database, {}) == expected @@ -37,11 +37,13 @@ def test_make_environment_with_cli_password_sets_correct_password(): database = {'name': 'foo', 'restore_password': 'trustsome1', 'password': 'anotherpassword'} flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) environment = module.make_environment( - database, {}, restore_connection_params={'password': 'clipassword'} + database, + {}, + restore_connection_params={'password': 'clipassword'}, ) assert environment['PGPASSWORD'] == 'clipassword' @@ -51,7 +53,9 @@ def test_make_environment_without_cli_password_or_configured_password_does_not_s database = {'name': 'foo'} environment = module.make_environment( - database, {}, restore_connection_params={'username': 'someone'} + database, + {}, + restore_connection_params={'username': 'someone'}, ) assert 'PGPASSWORD' not in environment @@ -86,7 +90,7 @@ def test_database_names_to_dump_passes_through_all_without_format(): def test_database_names_to_dump_with_all_and_format_and_dry_run_bails(): database = {'name': 'all', 'format': 'custom'} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_and_capture_output').never() @@ -96,10 +100,10 @@ def test_database_names_to_dump_with_all_and_format_and_dry_run_bails(): def test_database_names_to_dump_with_all_and_format_lists_databases(): database = {'name': 'all', 'format': 'custom'} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_and_capture_output').and_return( - 'foo,test,\nbar,test,"stuff and such"' + 'foo,test,\nbar,test,"stuff and such"', ) assert module.database_names_to_dump(database, {}, flexmock(), dry_run=False) == ( @@ -111,7 +115,7 @@ def test_database_names_to_dump_with_all_and_format_lists_databases(): def test_database_names_to_dump_with_all_and_format_lists_databases_with_hostname_and_port(): database = {'name': 'all', 'format': 'custom', 'hostname': 'localhost', 'port': 1234} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( @@ -138,7 +142,7 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_hostnam def test_database_names_to_dump_with_all_and_format_lists_databases_with_username(): database = {'name': 'all', 'format': 'custom', 'username': 'postgres'} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( @@ -163,7 +167,7 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_usernam def test_database_names_to_dump_with_all_and_format_lists_databases_with_options(): database = {'name': 'all', 'format': 'custom', 'list_options': '--harder'} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('psql', '--list', '--no-password', '--no-psqlrc', '--csv', '--tuples-only', '--harder'), @@ -179,10 +183,10 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_options def test_database_names_to_dump_with_all_and_format_excludes_particular_databases(): database = {'name': 'all', 'format': 'custom'} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_and_capture_output').and_return( - 'foo,test,\ntemplate0,test,blah' + 'foo,test,\ntemplate0,test,blah', ) assert module.database_names_to_dump(database, {}, flexmock(), dry_run=False) == ('foo',) @@ -195,7 +199,7 @@ def test_database_names_to_dump_with_all_and_psql_command_uses_custom_command(): 'psql_command': 'docker exec --workdir * mycontainer psql', } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( @@ -241,14 +245,14 @@ def test_dump_data_sources_runs_pg_dump_for_each_database(): flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return( - ('bar',) + ('bar',), ) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ).and_return('databases/localhost/bar') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -306,14 +310,17 @@ def test_dump_data_sources_does_not_raise_when_no_database_names_to_dump(): flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(()) - module.dump_data_sources( - databases, - {}, - config_paths=('test.yaml',), - borgmatic_runtime_directory='/run/borgmatic', - patterns=[], - dry_run=True, - ) == [] + assert ( + module.dump_data_sources( + databases, + {}, + config_paths=('test.yaml',), + borgmatic_runtime_directory='/run/borgmatic', + patterns=[], + dry_run=True, + ) + == [] + ) def test_dump_data_sources_with_duplicate_dump_skips_pg_dump(): @@ -321,10 +328,10 @@ def test_dump_data_sources_with_duplicate_dump_skips_pg_dump(): flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return( - ('bar',) + ('bar',), ) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ).and_return('databases/localhost/bar') flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.dump).should_receive('create_named_pipe_for_dump').never() @@ -348,14 +355,14 @@ def test_dump_data_sources_with_dry_run_skips_pg_dump(): flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return( - ('bar',) + ('bar',), ) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ).and_return('databases/localhost/bar') flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump').never() flexmock(module).should_receive('execute_command').never() @@ -380,11 +387,11 @@ def test_dump_data_sources_runs_pg_dump_with_hostname_and_port(): flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/database.example.org/foo' + 'databases/database.example.org/foo', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -423,16 +430,16 @@ def test_dump_data_sources_runs_pg_dump_with_username_and_password(): databases = [{'name': 'foo', 'username': 'postgres', 'password': 'trustsome1'}] process = flexmock() flexmock(module).should_receive('make_environment').and_return( - {'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'} + {'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}, ) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -469,16 +476,16 @@ def test_dump_data_sources_with_username_injection_attack_gets_escaped(): databases = [{'name': 'foo', 'username': 'postgres; naughty-command', 'password': 'trustsome1'}] process = flexmock() flexmock(module).should_receive('make_environment').and_return( - {'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'} + {'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}, ) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -517,11 +524,11 @@ def test_dump_data_sources_runs_pg_dump_with_directory_format(): flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('create_parent_directory_for_dump') flexmock(module.dump).should_receive('create_named_pipe_for_dump').never() @@ -562,11 +569,11 @@ def test_dump_data_sources_runs_pg_dump_with_string_compression(): flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -609,11 +616,11 @@ def test_dump_data_sources_runs_pg_dump_with_integer_compression(): flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -656,11 +663,11 @@ def test_dump_data_sources_runs_pg_dump_with_options(): flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -699,11 +706,11 @@ def test_dump_data_sources_runs_pg_dumpall_for_all_databases(): flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('all',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/all' + 'databases/localhost/all', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -731,11 +738,11 @@ def test_dump_data_sources_runs_non_default_pg_dump(): flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - 'databases/localhost/foo' + 'databases/localhost/foo', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -773,7 +780,7 @@ def test_restore_data_source_dump_runs_pg_restore(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') @@ -825,12 +832,12 @@ def test_restore_data_source_dump_runs_pg_restore(): def test_restore_data_source_dump_runs_pg_restore_with_hostname_and_port(): hook_config = [ - {'name': 'foo', 'hostname': 'database.example.org', 'port': 5433, 'schemas': None} + {'name': 'foo', 'hostname': 'database.example.org', 'port': 5433, 'schemas': None}, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') @@ -890,15 +897,15 @@ def test_restore_data_source_dump_runs_pg_restore_with_hostname_and_port(): def test_restore_data_source_dump_runs_pg_restore_with_username_and_password(): hook_config = [ - {'name': 'foo', 'username': 'postgres', 'password': 'trustsome1', 'schemas': None} + {'name': 'foo', 'username': 'postgres', 'password': 'trustsome1', 'schemas': None}, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_environment').and_return( - {'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'} + {'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}, ) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') @@ -964,15 +971,15 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ 'restore_username': 'restoreusername', 'restore_password': 'restorepassword', 'schemas': None, - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_environment').and_return( - {'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'} + {'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'}, ) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') @@ -1046,15 +1053,15 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ 'restore_port': 'restoreport', 'restore_username': 'restoreusername', 'restore_password': 'restorepassword', - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_environment').and_return( - {'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'} + {'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'}, ) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') @@ -1122,12 +1129,12 @@ def test_restore_data_source_dump_runs_pg_restore_with_options(): 'restore_options': '--harder', 'analyze_options': '--smarter', 'schemas': None, - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') @@ -1184,7 +1191,7 @@ def test_restore_data_source_dump_runs_psql_for_all_database_dump(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') @@ -1226,7 +1233,7 @@ def test_restore_data_source_dump_runs_psql_for_plain_database_dump(): extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') @@ -1275,12 +1282,12 @@ def test_restore_data_source_dump_runs_non_default_pg_restore_and_psql(): 'pg_restore_command': 'docker exec --workdir * mycontainer pg_restore', 'psql_command': 'docker exec --workdir * mycontainer psql', 'schemas': None, - } + }, ] extract_process = flexmock(stdout=flexmock()) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') @@ -1344,7 +1351,7 @@ def test_restore_data_source_dump_with_dry_run_skips_restore(): hook_config = [{'name': 'foo', 'schemas': None}] flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') @@ -1371,7 +1378,7 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk(): hook_config = [{'name': 'foo', 'schemas': None}] flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') @@ -1426,7 +1433,7 @@ def test_restore_data_source_dump_with_schemas_restores_schemas(): hook_config = [{'name': 'foo', 'schemas': ['bar', 'baz']}] flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') diff --git a/tests/unit/hooks/data_source/test_sqlite.py b/tests/unit/hooks/data_source/test_sqlite.py index 16a4e8f9..4c532266 100644 --- a/tests/unit/hooks/data_source/test_sqlite.py +++ b/tests/unit/hooks/data_source/test_sqlite.py @@ -21,7 +21,7 @@ def test_dump_data_sources_logs_and_skips_if_dump_already_exists(): flexmock(module).should_receive('make_dump_path').and_return('/run/borgmatic') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - '/run/borgmatic/database' + '/run/borgmatic/database', ) flexmock(module.os.path).should_receive('exists').and_return(True) flexmock(module.dump).should_receive('create_named_pipe_for_dump').never() @@ -49,12 +49,12 @@ def test_dump_data_sources_dumps_each_database(): flexmock(module).should_receive('make_dump_path').and_return('/run/borgmatic') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - '/run/borgmatic/database' + '/run/borgmatic/database', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').and_return(processes[0]).and_return( - processes[1] + processes[1], ) assert ( @@ -78,7 +78,7 @@ def test_dump_data_sources_with_path_injection_attack_gets_escaped(): flexmock(module).should_receive('make_dump_path').and_return('/run/borgmatic') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - '/run/borgmatic/database' + '/run/borgmatic/database', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -119,7 +119,7 @@ def test_dump_data_sources_runs_non_default_sqlite_with_path_injection_attack_ge flexmock(module).should_receive('make_dump_path').and_return('/run/borgmatic') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - '/run/borgmatic/database' + '/run/borgmatic/database', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -158,7 +158,7 @@ def test_dump_data_sources_with_non_existent_path_warns_and_dumps_database(): flexmock(module).should_receive('make_dump_path').and_return('/run/borgmatic') flexmock(module.logger).should_receive('warning').once() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - '/run/borgmatic' + '/run/borgmatic', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -185,10 +185,10 @@ def test_dump_data_sources_with_name_all_warns_and_dumps_all_databases(): flexmock(module).should_receive('make_dump_path').and_return('/run/borgmatic') flexmock(module.logger).should_receive( - 'warning' + 'warning', ).twice() # once for the name=all, once for the non-existent path flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - '/run/borgmatic/database' + '/run/borgmatic/database', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.dump).should_receive('create_named_pipe_for_dump') @@ -212,7 +212,7 @@ def test_dump_data_sources_does_not_dump_if_dry_run(): flexmock(module).should_receive('make_dump_path').and_return('/run/borgmatic') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( - '/run/borgmatic' + '/run/borgmatic', ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.dump).should_receive('create_named_pipe_for_dump').never() @@ -295,7 +295,11 @@ def test_restore_data_source_dump_runs_non_default_sqlite_restores_database(): def test_restore_data_source_dump_with_connection_params_uses_connection_params_for_restore(): hook_config = [ - {'path': '/path/to/database', 'name': 'database', 'restore_path': 'config/path/to/database'} + { + 'path': '/path/to/database', + 'name': 'database', + 'restore_path': 'config/path/to/database', + }, ] extract_process = flexmock(stdout=flexmock()) @@ -324,7 +328,11 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ def test_restore_data_source_dump_runs_non_default_sqlite_with_connection_params_uses_connection_params_for_restore(): hook_config = [ - {'path': '/path/to/database', 'name': 'database', 'restore_path': 'config/path/to/database'} + { + 'path': '/path/to/database', + 'name': 'database', + 'restore_path': 'config/path/to/database', + }, ] extract_process = flexmock(stdout=flexmock()) @@ -356,7 +364,11 @@ def test_restore_data_source_dump_runs_non_default_sqlite_with_connection_params def test_restore_data_source_dump_without_connection_params_uses_restore_params_in_config_for_restore(): hook_config = [ - {'path': '/path/to/database', 'name': 'database', 'restore_path': 'config/path/to/database'} + { + 'path': '/path/to/database', + 'name': 'database', + 'restore_path': 'config/path/to/database', + }, ] extract_process = flexmock(stdout=flexmock()) @@ -390,7 +402,7 @@ def test_restore_data_source_dump_runs_non_default_sqlite_without_connection_par 'name': 'database', 'sqlite_restore_command': 'custom_sqlite', 'restore_path': 'config/path/to/database', - } + }, ] extract_process = flexmock(stdout=flexmock()) diff --git a/tests/unit/hooks/data_source/test_zfs.py b/tests/unit/hooks/data_source/test_zfs.py index 74ca87b3..5d51213a 100644 --- a/tests/unit/hooks/data_source/test_zfs.py +++ b/tests/unit/hooks/data_source/test_zfs.py @@ -9,12 +9,12 @@ from borgmatic.hooks.data_source import zfs as module def test_get_datasets_to_backup_filters_datasets_by_patterns(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'dataset\t/dataset\ton\t-\nother\t/other\ton\t-', ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/dataset', object).and_return( ( Pattern( @@ -22,10 +22,10 @@ def test_get_datasets_to_backup_filters_datasets_by_patterns(): Pattern_type.ROOT, source=Pattern_source.CONFIG, ), - ) + ), ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/other', object).and_return(()) assert module.get_datasets_to_backup( @@ -64,12 +64,12 @@ def test_get_datasets_to_backup_filters_datasets_by_patterns(): def test_get_datasets_to_backup_skips_non_root_patterns(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'dataset\t/dataset\ton\t-\nother\t/other\ton\t-', ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/dataset', object).and_return( ( Pattern( @@ -77,10 +77,10 @@ def test_get_datasets_to_backup_skips_non_root_patterns(): Pattern_type.EXCLUDE, source=Pattern_source.CONFIG, ), - ) + ), ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/other', object).and_return(()) assert ( @@ -110,12 +110,12 @@ def test_get_datasets_to_backup_skips_non_root_patterns(): def test_get_datasets_to_backup_skips_non_config_patterns(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'dataset\t/dataset\ton\t-\nother\t/other\ton\t-', ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/dataset', object).and_return( ( Pattern( @@ -123,10 +123,10 @@ def test_get_datasets_to_backup_skips_non_config_patterns(): Pattern_type.ROOT, source=Pattern_source.HOOK, ), - ) + ), ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/other', object).and_return(()) assert ( @@ -156,15 +156,15 @@ def test_get_datasets_to_backup_skips_non_config_patterns(): def test_get_datasets_to_backup_filters_datasets_by_user_property(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'dataset\t/dataset\ton\tauto\nother\t/other\ton\t-', ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/dataset', object).and_return(()) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/other', object).and_return(()) assert module.get_datasets_to_backup( @@ -182,15 +182,15 @@ def test_get_datasets_to_backup_filters_datasets_by_user_property(): def test_get_datasets_to_backup_filters_datasets_by_canmount_property(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'dataset\t/dataset\toff\t-\nother\t/other\ton\t-', ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/dataset', object).and_return((Pattern('/dataset'),)) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).with_args('/other', object).and_return(()) assert ( @@ -208,12 +208,12 @@ def test_get_datasets_to_backup_filters_datasets_by_canmount_property(): def test_get_datasets_to_backup_with_invalid_list_output_raises(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'dataset', ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).never() with pytest.raises(ValueError, match='zfs'): @@ -222,12 +222,12 @@ def test_get_datasets_to_backup_with_invalid_list_output_raises(): def test_get_all_dataset_mount_points_omits_none(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( '/dataset\nnone\n/other', ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).and_return((Pattern('/dataset'),)) assert module.get_all_dataset_mount_points('zfs') == ( @@ -238,12 +238,12 @@ def test_get_all_dataset_mount_points_omits_none(): def test_get_all_dataset_mount_points_omits_duplicates(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( '/dataset\n/other\n/dataset\n/other', ) flexmock(module.borgmatic.hooks.data_source.snapshot).should_receive( - 'get_contained_patterns' + 'get_contained_patterns', ).and_return((Pattern('/dataset'),)) assert module.get_all_dataset_mount_points('zfs') == ( @@ -281,15 +281,18 @@ def test_get_all_dataset_mount_points_omits_duplicates(): ), ) def test_make_borg_snapshot_pattern_includes_slashdot_hack_and_stripped_pattern_path( - pattern, expected_pattern + pattern, + expected_pattern, ): flexmock(module.hashlib).should_receive('shake_256').and_return( - flexmock(hexdigest=lambda length: 'b33f') + flexmock(hexdigest=lambda length: 'b33f'), ) assert ( module.make_borg_snapshot_pattern( - pattern, flexmock(mount_point='/something'), '/run/borgmatic' + pattern, + flexmock(mount_point='/something'), + '/run/borgmatic', ) == expected_pattern ) @@ -309,7 +312,7 @@ def test_dump_data_sources_snapshots_and_mounts_and_updates_patterns(): full_snapshot_name, ).once() flexmock(module.hashlib).should_receive('shake_256').and_return( - flexmock(hexdigest=lambda length: 'b33f') + flexmock(hexdigest=lambda length: 'b33f'), ) snapshot_mount_path = '/run/borgmatic/zfs_snapshots/b33f/./mnt/dataset' flexmock(module).should_receive('mount_snapshot').with_args( @@ -318,7 +321,9 @@ def test_dump_data_sources_snapshots_and_mounts_and_updates_patterns(): module.os.path.normpath(snapshot_mount_path), ).once() flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - Pattern('/mnt/dataset/subdir'), dataset, '/run/borgmatic' + Pattern('/mnt/dataset/subdir'), + dataset, + '/run/borgmatic', ).and_return(Pattern('/run/borgmatic/zfs_snapshots/b33f/./mnt/dataset/subdir')) patterns = [Pattern('/mnt/dataset/subdir')] @@ -373,7 +378,7 @@ def test_dump_data_sources_uses_custom_commands(): full_snapshot_name, ).once() flexmock(module.hashlib).should_receive('shake_256').and_return( - flexmock(hexdigest=lambda length: 'b33f') + flexmock(hexdigest=lambda length: 'b33f'), ) snapshot_mount_path = '/run/borgmatic/zfs_snapshots/b33f/./mnt/dataset' flexmock(module).should_receive('mount_snapshot').with_args( @@ -382,7 +387,9 @@ def test_dump_data_sources_uses_custom_commands(): module.os.path.normpath(snapshot_mount_path), ).once() flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - Pattern('/mnt/dataset/subdir'), dataset, '/run/borgmatic' + Pattern('/mnt/dataset/subdir'), + dataset, + '/run/borgmatic', ).and_return(Pattern('/run/borgmatic/zfs_snapshots/b33f/./mnt/dataset/subdir')) patterns = [Pattern('/mnt/dataset/subdir')] hook_config = { @@ -410,7 +417,7 @@ def test_dump_data_sources_uses_custom_commands(): def test_dump_data_sources_with_dry_run_skips_commands_and_does_not_touch_patterns(): flexmock(module).should_receive('get_datasets_to_backup').and_return( - (flexmock(name='dataset', mount_point='/mnt/dataset'),) + (flexmock(name='dataset', mount_point='/mnt/dataset'),), ) flexmock(module.os).should_receive('getpid').and_return(1234) flexmock(module).should_receive('snapshot_dataset').never() @@ -446,7 +453,7 @@ def test_dump_data_sources_ignores_mismatch_between_given_patterns_and_contained full_snapshot_name, ).once() flexmock(module.hashlib).should_receive('shake_256').and_return( - flexmock(hexdigest=lambda length: 'b33f') + flexmock(hexdigest=lambda length: 'b33f'), ) snapshot_mount_path = '/run/borgmatic/zfs_snapshots/b33f/./mnt/dataset' flexmock(module).should_receive('mount_snapshot').with_args( @@ -455,7 +462,9 @@ def test_dump_data_sources_ignores_mismatch_between_given_patterns_and_contained module.os.path.normpath(snapshot_mount_path), ).once() flexmock(module).should_receive('make_borg_snapshot_pattern').with_args( - Pattern('/mnt/dataset/subdir'), dataset, '/run/borgmatic' + Pattern('/mnt/dataset/subdir'), + dataset, + '/run/borgmatic', ).and_return(Pattern('/run/borgmatic/zfs_snapshots/b33f/./mnt/dataset/subdir')) patterns = [Pattern('/hmm')] @@ -476,7 +485,7 @@ def test_dump_data_sources_ignores_mismatch_between_given_patterns_and_contained def test_get_all_snapshots_parses_list_output(): flexmock(module.borgmatic.execute).should_receive( - 'execute_command_and_capture_output' + 'execute_command_and_capture_output', ).and_return( 'dataset1@borgmatic-1234\ndataset2@borgmatic-4567', ) @@ -487,22 +496,24 @@ def test_get_all_snapshots_parses_list_output(): def test_remove_data_source_dumps_unmounts_and_destroys_snapshots(): flexmock(module).should_receive('get_all_dataset_mount_points').and_return(('/mnt/dataset',)) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').and_return(True) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) flexmock(module.shutil).should_receive('rmtree') flexmock(module).should_receive('unmount_snapshot').with_args( - 'umount', '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset' + 'umount', + '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset', ).once() flexmock(module).should_receive('get_all_snapshots').and_return( - ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid') + ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid'), ) flexmock(module).should_receive('destroy_snapshot').with_args( - 'zfs', 'dataset@borgmatic-1234' + 'zfs', + 'dataset@borgmatic-1234', ).once() module.remove_data_source_dumps( @@ -516,22 +527,24 @@ def test_remove_data_source_dumps_unmounts_and_destroys_snapshots(): def test_remove_data_source_dumps_use_custom_commands(): flexmock(module).should_receive('get_all_dataset_mount_points').and_return(('/mnt/dataset',)) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').and_return(True) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) flexmock(module.shutil).should_receive('rmtree') flexmock(module).should_receive('unmount_snapshot').with_args( - '/usr/local/bin/umount', '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset' + '/usr/local/bin/umount', + '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset', ).once() flexmock(module).should_receive('get_all_snapshots').and_return( - ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid') + ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid'), ) flexmock(module).should_receive('destroy_snapshot').with_args( - '/usr/local/bin/zfs', 'dataset@borgmatic-1234' + '/usr/local/bin/zfs', + 'dataset@borgmatic-1234', ).once() hook_config = {'zfs_command': '/usr/local/bin/zfs', 'umount_command': '/usr/local/bin/umount'} @@ -546,7 +559,7 @@ def test_remove_data_source_dumps_use_custom_commands(): def test_remove_data_source_dumps_bails_for_missing_hook_configuration(): flexmock(module).should_receive('get_all_dataset_mount_points').never() flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).never() module.remove_data_source_dumps( @@ -560,7 +573,7 @@ def test_remove_data_source_dumps_bails_for_missing_hook_configuration(): def test_remove_data_source_dumps_bails_for_missing_zfs_command(): flexmock(module).should_receive('get_all_dataset_mount_points').and_raise(FileNotFoundError) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).never() hook_config = {'zfs_command': 'wtf'} @@ -574,10 +587,10 @@ def test_remove_data_source_dumps_bails_for_missing_zfs_command(): def test_remove_data_source_dumps_bails_for_zfs_command_error(): flexmock(module).should_receive('get_all_dataset_mount_points').and_raise( - module.subprocess.CalledProcessError(1, 'wtf') + module.subprocess.CalledProcessError(1, 'wtf'), ) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).never() hook_config = {'zfs_command': 'wtf'} @@ -592,16 +605,17 @@ def test_remove_data_source_dumps_bails_for_zfs_command_error(): def test_remove_data_source_dumps_bails_for_missing_umount_command(): flexmock(module).should_receive('get_all_dataset_mount_points').and_return(('/mnt/dataset',)) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').and_return(True) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) flexmock(module.shutil).should_receive('rmtree') flexmock(module).should_receive('unmount_snapshot').with_args( - '/usr/local/bin/umount', '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset' + '/usr/local/bin/umount', + '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset', ).and_raise(FileNotFoundError) flexmock(module).should_receive('get_all_snapshots').never() flexmock(module).should_receive('destroy_snapshot').never() @@ -618,22 +632,24 @@ def test_remove_data_source_dumps_bails_for_missing_umount_command(): def test_remove_data_source_dumps_swallows_umount_command_error(): flexmock(module).should_receive('get_all_dataset_mount_points').and_return(('/mnt/dataset',)) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').and_return(True) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) flexmock(module.shutil).should_receive('rmtree') flexmock(module).should_receive('unmount_snapshot').with_args( - '/usr/local/bin/umount', '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset' + '/usr/local/bin/umount', + '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset', ).and_raise(module.subprocess.CalledProcessError(1, 'wtf')) flexmock(module).should_receive('get_all_snapshots').and_return( - ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid') + ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid'), ) flexmock(module).should_receive('destroy_snapshot').with_args( - '/usr/local/bin/zfs', 'dataset@borgmatic-1234' + '/usr/local/bin/zfs', + 'dataset@borgmatic-1234', ).once() hook_config = {'zfs_command': '/usr/local/bin/zfs', 'umount_command': '/usr/local/bin/umount'} @@ -648,19 +664,20 @@ def test_remove_data_source_dumps_swallows_umount_command_error(): def test_remove_data_source_dumps_skips_unmount_snapshot_directories_that_are_not_actually_directories(): flexmock(module).should_receive('get_all_dataset_mount_points').and_return(('/mnt/dataset',)) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').and_return(False) flexmock(module.shutil).should_receive('rmtree').never() flexmock(module).should_receive('unmount_snapshot').never() flexmock(module).should_receive('get_all_snapshots').and_return( - ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid') + ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid'), ) flexmock(module).should_receive('destroy_snapshot').with_args( - 'zfs', 'dataset@borgmatic-1234' + 'zfs', + 'dataset@borgmatic-1234', ).once() module.remove_data_source_dumps( @@ -674,25 +691,26 @@ def test_remove_data_source_dumps_skips_unmount_snapshot_directories_that_are_no def test_remove_data_source_dumps_skips_unmount_snapshot_mount_paths_that_are_not_actually_directories(): flexmock(module).should_receive('get_all_dataset_mount_points').and_return(('/mnt/dataset',)) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/zfs_snapshots/b33f' + '/run/borgmatic/zfs_snapshots/b33f', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset' + '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset', ).and_return(False) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) flexmock(module.shutil).should_receive('rmtree') flexmock(module).should_receive('unmount_snapshot').never() flexmock(module).should_receive('get_all_snapshots').and_return( - ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid') + ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid'), ) flexmock(module).should_receive('destroy_snapshot').with_args( - 'zfs', 'dataset@borgmatic-1234' + 'zfs', + 'dataset@borgmatic-1234', ).once() module.remove_data_source_dumps( @@ -706,27 +724,28 @@ def test_remove_data_source_dumps_skips_unmount_snapshot_mount_paths_that_are_no def test_remove_data_source_dumps_skips_unmount_snapshot_mount_paths_that_are_empty(): flexmock(module).should_receive('get_all_dataset_mount_points').and_return(('/mnt/dataset',)) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/zfs_snapshots/b33f' + '/run/borgmatic/zfs_snapshots/b33f', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset' + '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset', ).and_return(True) flexmock(module.os).should_receive('listdir').with_args( - '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset' + '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset', ).and_return([]) flexmock(module.shutil).should_receive('rmtree') flexmock(module).should_receive('unmount_snapshot').never() flexmock(module).should_receive('get_all_snapshots').and_return( - ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid') + ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid'), ) flexmock(module).should_receive('destroy_snapshot').with_args( - 'zfs', 'dataset@borgmatic-1234' + 'zfs', + 'dataset@borgmatic-1234', ).once() module.remove_data_source_dumps( @@ -740,25 +759,26 @@ def test_remove_data_source_dumps_skips_unmount_snapshot_mount_paths_that_are_em def test_remove_data_source_dumps_skips_unmount_snapshot_mount_paths_after_rmtree_succeeds(): flexmock(module).should_receive('get_all_dataset_mount_points').and_return(('/mnt/dataset',)) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/zfs_snapshots/b33f' + '/run/borgmatic/zfs_snapshots/b33f', ).and_return(True) flexmock(module.os.path).should_receive('isdir').with_args( - '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset' + '/run/borgmatic/zfs_snapshots/b33f/mnt/dataset', ).and_return(True).and_return(False) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) flexmock(module.shutil).should_receive('rmtree') flexmock(module).should_receive('unmount_snapshot').never() flexmock(module).should_receive('get_all_snapshots').and_return( - ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid') + ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid'), ) flexmock(module).should_receive('destroy_snapshot').with_args( - 'zfs', 'dataset@borgmatic-1234' + 'zfs', + 'dataset@borgmatic-1234', ).once() module.remove_data_source_dumps( @@ -772,17 +792,17 @@ def test_remove_data_source_dumps_skips_unmount_snapshot_mount_paths_after_rmtre def test_remove_data_source_dumps_with_dry_run_skips_unmount_and_destroy(): flexmock(module).should_receive('get_all_dataset_mount_points').and_return(('/mnt/dataset',)) flexmock(module.borgmatic.config.paths).should_receive( - 'replace_temporary_subdirectory_with_glob' + 'replace_temporary_subdirectory_with_glob', ).and_return('/run/borgmatic') flexmock(module.glob).should_receive('glob').replace_with( - lambda path: [path.replace('*', 'b33f')] + lambda path: [path.replace('*', 'b33f')], ) flexmock(module.os.path).should_receive('isdir').and_return(True) flexmock(module.os).should_receive('listdir').and_return(['file.txt']) flexmock(module.shutil).should_receive('rmtree').never() flexmock(module).should_receive('unmount_snapshot').never() flexmock(module).should_receive('get_all_snapshots').and_return( - ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid') + ('dataset@borgmatic-1234', 'dataset@other', 'other@other', 'invalid'), ) flexmock(module).should_receive('destroy_snapshot').never() diff --git a/tests/unit/hooks/monitoring/test_apprise.py b/tests/unit/hooks/monitoring/test_apprise.py index fd0e9615..86b532d2 100644 --- a/tests/unit/hooks/monitoring/test_apprise.py +++ b/tests/unit/hooks/monitoring/test_apprise.py @@ -10,7 +10,8 @@ TOPIC = 'borgmatic-unit-testing' def mock_apprise(): apprise_mock = flexmock( - add=lambda servers: None, notify=lambda title, body, body_format, notify_type: None + add=lambda servers: None, + notify=lambda title, body, body_format, notify_type: None, ) flexmock(apprise.Apprise).new_instances(apprise_mock) @@ -32,7 +33,7 @@ def test_initialize_monitor_with_send_logs_false_does_not_add_handler(): def test_initialize_monitor_with_send_logs_true_adds_handler_with_default_log_size_limit(): truncation_indicator_length = 4 flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).with_args( module.HANDLER_IDENTIFIER, module.DEFAULT_LOGS_SIZE_LIMIT_BYTES - truncation_indicator_length, @@ -52,7 +53,7 @@ def test_initialize_monitor_with_send_logs_true_adds_handler_with_default_log_si def test_initialize_monitor_without_send_logs_adds_handler_with_default_log_size_limit(): truncation_indicator_length = 4 flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).with_args( module.HANDLER_IDENTIFIER, module.DEFAULT_LOGS_SIZE_LIMIT_BYTES - truncation_indicator_length, @@ -72,7 +73,7 @@ def test_initialize_monitor_without_send_logs_adds_handler_with_default_log_size def test_ping_monitor_respects_dry_run(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('loggy log') mock_apprise().should_receive('notify').never() @@ -89,7 +90,7 @@ def test_ping_monitor_respects_dry_run(): def test_ping_monitor_with_no_states_does_not_notify(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler').never() flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).never() mock_apprise().should_receive('notify').never() @@ -106,7 +107,7 @@ def test_ping_monitor_with_no_states_does_not_notify(): def test_ping_monitor_notifies_fail_by_default(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('') mock_apprise().should_receive('notify').with_args( title='A borgmatic FAIL event happened', @@ -129,7 +130,7 @@ def test_ping_monitor_notifies_fail_by_default(): def test_ping_monitor_with_logs_appends_logs_to_body(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('loggy log') mock_apprise().should_receive('notify').with_args( title='A borgmatic FAIL event happened', @@ -152,7 +153,7 @@ def test_ping_monitor_with_logs_appends_logs_to_body(): def test_ping_monitor_with_finish_default_config_notifies(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('') mock_apprise().should_receive('notify').with_args( title='A borgmatic FINISH event happened', @@ -174,7 +175,7 @@ def test_ping_monitor_with_finish_default_config_notifies(): def test_ping_monitor_with_start_default_config_notifies(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler').never() flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).never() mock_apprise().should_receive('notify').with_args( title='A borgmatic START event happened', @@ -196,7 +197,7 @@ def test_ping_monitor_with_start_default_config_notifies(): def test_ping_monitor_with_fail_default_config_notifies(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('') mock_apprise().should_receive('notify').with_args( title='A borgmatic FAIL event happened', @@ -218,7 +219,7 @@ def test_ping_monitor_with_fail_default_config_notifies(): def test_ping_monitor_with_log_default_config_notifies(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('') mock_apprise().should_receive('notify').with_args( title='A borgmatic LOG event happened', @@ -240,7 +241,7 @@ def test_ping_monitor_with_log_default_config_notifies(): def test_ping_monitor_passes_through_custom_message_title(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('') mock_apprise().should_receive('notify').with_args( title='foo', @@ -266,7 +267,7 @@ def test_ping_monitor_passes_through_custom_message_title(): def test_ping_monitor_passes_through_custom_message_body(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('') mock_apprise().should_receive('notify').with_args( title='', @@ -292,7 +293,7 @@ def test_ping_monitor_passes_through_custom_message_body(): def test_ping_monitor_passes_through_custom_message_body_and_appends_logs(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('loggy log') mock_apprise().should_receive('notify').with_args( title='', @@ -318,7 +319,7 @@ def test_ping_monitor_passes_through_custom_message_body_and_appends_logs(): def test_ping_monitor_pings_multiple_services(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('') mock_apprise().should_receive('add').with_args([f'ntfys://{TOPIC}', f'ntfy://{TOPIC}']).once() @@ -327,7 +328,7 @@ def test_ping_monitor_pings_multiple_services(): 'services': [ {'url': f'ntfys://{TOPIC}', 'label': 'ntfys'}, {'url': f'ntfy://{TOPIC}', 'label': 'ntfy'}, - ] + ], }, {}, 'config.yaml', @@ -340,7 +341,7 @@ def test_ping_monitor_pings_multiple_services(): def test_ping_monitor_logs_info_for_no_services(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler').never() flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).never() flexmock(module.logger).should_receive('info').once() @@ -357,7 +358,7 @@ def test_ping_monitor_logs_info_for_no_services(): def test_ping_monitor_logs_warning_when_notify_fails(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('') mock_apprise().should_receive('notify').and_return(False) flexmock(module.logger).should_receive('warning').once() diff --git a/tests/unit/hooks/monitoring/test_cronhub.py b/tests/unit/hooks/monitoring/test_cronhub.py index 95edb021..3b5e1480 100644 --- a/tests/unit/hooks/monitoring/test_cronhub.py +++ b/tests/unit/hooks/monitoring/test_cronhub.py @@ -6,7 +6,8 @@ from borgmatic.hooks.monitoring import cronhub as module def test_ping_monitor_rewrites_ping_url_for_start_state(): hook_config = {'ping_url': 'https://example.com/start/abcdef'} flexmock(module.requests).should_receive('get').with_args( - 'https://example.com/start/abcdef', timeout=int + 'https://example.com/start/abcdef', + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -22,7 +23,8 @@ def test_ping_monitor_rewrites_ping_url_for_start_state(): def test_ping_monitor_rewrites_ping_url_and_state_for_start_state(): hook_config = {'ping_url': 'https://example.com/ping/abcdef'} flexmock(module.requests).should_receive('get').with_args( - 'https://example.com/start/abcdef', timeout=int + 'https://example.com/start/abcdef', + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -38,7 +40,8 @@ def test_ping_monitor_rewrites_ping_url_and_state_for_start_state(): def test_ping_monitor_rewrites_ping_url_for_finish_state(): hook_config = {'ping_url': 'https://example.com/start/abcdef'} flexmock(module.requests).should_receive('get').with_args( - 'https://example.com/finish/abcdef', timeout=int + 'https://example.com/finish/abcdef', + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -54,7 +57,8 @@ def test_ping_monitor_rewrites_ping_url_for_finish_state(): def test_ping_monitor_rewrites_ping_url_for_fail_state(): hook_config = {'ping_url': 'https://example.com/start/abcdef'} flexmock(module.requests).should_receive('get').with_args( - 'https://example.com/fail/abcdef', timeout=int + 'https://example.com/fail/abcdef', + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -84,7 +88,7 @@ def test_ping_monitor_dry_run_does_not_hit_ping_url(): def test_ping_monitor_with_connection_error_logs_warning(): hook_config = {'ping_url': 'https://example.com/start/abcdef'} flexmock(module.requests).should_receive('get').and_raise( - module.requests.exceptions.ConnectionError + module.requests.exceptions.ConnectionError, ) flexmock(module.logger).should_receive('warning').once() @@ -102,10 +106,11 @@ def test_ping_monitor_with_other_error_logs_warning(): hook_config = {'ping_url': 'https://example.com/start/abcdef'} response = flexmock(ok=False) response.should_receive('raise_for_status').and_raise( - module.requests.exceptions.RequestException + module.requests.exceptions.RequestException, ) flexmock(module.requests).should_receive('get').with_args( - 'https://example.com/start/abcdef', timeout=int + 'https://example.com/start/abcdef', + timeout=int, ).and_return(response) flexmock(module.logger).should_receive('warning').once() diff --git a/tests/unit/hooks/monitoring/test_cronitor.py b/tests/unit/hooks/monitoring/test_cronitor.py index 0fd81740..eac86f92 100644 --- a/tests/unit/hooks/monitoring/test_cronitor.py +++ b/tests/unit/hooks/monitoring/test_cronitor.py @@ -6,7 +6,8 @@ from borgmatic.hooks.monitoring import cronitor as module def test_ping_monitor_hits_ping_url_for_start_state(): hook_config = {'ping_url': 'https://example.com'} flexmock(module.requests).should_receive('get').with_args( - 'https://example.com/run', timeout=int + 'https://example.com/run', + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -22,7 +23,8 @@ def test_ping_monitor_hits_ping_url_for_start_state(): def test_ping_monitor_hits_ping_url_for_finish_state(): hook_config = {'ping_url': 'https://example.com'} flexmock(module.requests).should_receive('get').with_args( - 'https://example.com/complete', timeout=int + 'https://example.com/complete', + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -38,7 +40,8 @@ def test_ping_monitor_hits_ping_url_for_finish_state(): def test_ping_monitor_hits_ping_url_for_fail_state(): hook_config = {'ping_url': 'https://example.com'} flexmock(module.requests).should_receive('get').with_args( - 'https://example.com/fail', timeout=int + 'https://example.com/fail', + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -68,7 +71,7 @@ def test_ping_monitor_dry_run_does_not_hit_ping_url(): def test_ping_monitor_with_connection_error_logs_warning(): hook_config = {'ping_url': 'https://example.com'} flexmock(module.requests).should_receive('get').and_raise( - module.requests.exceptions.ConnectionError + module.requests.exceptions.ConnectionError, ) flexmock(module.logger).should_receive('warning').once() @@ -86,10 +89,11 @@ def test_ping_monitor_with_other_error_logs_warning(): hook_config = {'ping_url': 'https://example.com'} response = flexmock(ok=False) response.should_receive('raise_for_status').and_raise( - module.requests.exceptions.RequestException + module.requests.exceptions.RequestException, ) flexmock(module.requests).should_receive('get').with_args( - 'https://example.com/run', timeout=int + 'https://example.com/run', + timeout=int, ).and_return(response) flexmock(module.logger).should_receive('warning').once() diff --git a/tests/unit/hooks/monitoring/test_healthchecks.py b/tests/unit/hooks/monitoring/test_healthchecks.py index 2031a661..1cb54532 100644 --- a/tests/unit/hooks/monitoring/test_healthchecks.py +++ b/tests/unit/hooks/monitoring/test_healthchecks.py @@ -8,7 +8,7 @@ def test_initialize_monitor_creates_log_handler_with_ping_body_limit(): monitoring_log_level = 1 flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).with_args( module.HANDLER_IDENTIFIER, ping_body_limit - len(module.borgmatic.hooks.monitoring.logs.PAYLOAD_TRUNCATION_INDICATOR), @@ -17,7 +17,11 @@ def test_initialize_monitor_creates_log_handler_with_ping_body_limit(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('add_handler') module.initialize_monitor( - {'ping_body_limit': ping_body_limit}, {}, 'test.yaml', monitoring_log_level, dry_run=False + {'ping_body_limit': ping_body_limit}, + {}, + 'test.yaml', + monitoring_log_level, + dry_run=False, ) @@ -25,7 +29,7 @@ def test_initialize_monitor_creates_log_handler_with_default_ping_body_limit(): monitoring_log_level = 1 flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).with_args( module.HANDLER_IDENTIFIER, module.DEFAULT_PING_BODY_LIMIT_BYTES @@ -42,44 +46,59 @@ def test_initialize_monitor_creates_log_handler_with_zero_ping_body_limit(): monitoring_log_level = 1 flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).with_args(module.HANDLER_IDENTIFIER, ping_body_limit, monitoring_log_level).once() flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('add_handler') module.initialize_monitor( - {'ping_body_limit': ping_body_limit}, {}, 'test.yaml', monitoring_log_level, dry_run=False + {'ping_body_limit': ping_body_limit}, + {}, + 'test.yaml', + monitoring_log_level, + dry_run=False, ) def test_initialize_monitor_creates_log_handler_when_send_logs_true(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).once() flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('add_handler') module.initialize_monitor( - {'send_logs': True}, {}, 'test.yaml', monitoring_log_level=1, dry_run=False + {'send_logs': True}, + {}, + 'test.yaml', + monitoring_log_level=1, + dry_run=False, ) def test_initialize_monitor_bails_when_send_logs_false(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).never() flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('add_handler') module.initialize_monitor( - {'send_logs': False}, {}, 'test.yaml', monitoring_log_level=1, dry_run=False + {'send_logs': False}, + {}, + 'test.yaml', + monitoring_log_level=1, + dry_run=False, ) def test_ping_monitor_hits_ping_url_for_start_state(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).never() hook_config = {'ping_url': 'https://example.com'} flexmock(module.requests).should_receive('post').with_args( - 'https://example.com/start', data=''.encode('utf-8'), verify=True, timeout=int + 'https://example.com/start', + data=b'', + verify=True, + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -97,10 +116,13 @@ def test_ping_monitor_hits_ping_url_for_finish_state(): payload = 'data' flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return(payload) flexmock(module.requests).should_receive('post').with_args( - 'https://example.com', data=payload.encode('utf-8'), verify=True, timeout=int + 'https://example.com', + data=payload.encode('utf-8'), + verify=True, + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -118,10 +140,13 @@ def test_ping_monitor_hits_ping_url_for_fail_state(): payload = 'data' flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return(payload) flexmock(module.requests).should_receive('post').with_args( - 'https://example.com/fail', data=payload.encode('utf'), verify=True, timeout=int + 'https://example.com/fail', + data=payload.encode('utf'), + verify=True, + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -139,10 +164,13 @@ def test_ping_monitor_hits_ping_url_for_log_state(): payload = 'data' flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return(payload) flexmock(module.requests).should_receive('post').with_args( - 'https://example.com/log', data=payload.encode('utf'), verify=True, timeout=int + 'https://example.com/log', + data=payload.encode('utf'), + verify=True, + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -160,7 +188,7 @@ def test_ping_monitor_with_ping_uuid_hits_corresponding_url(): payload = 'data' flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return(payload) flexmock(module.requests).should_receive('post').with_args( f"https://hc-ping.com/{hook_config['ping_url']}", @@ -184,10 +212,13 @@ def test_ping_monitor_skips_ssl_verification_when_verify_tls_false(): payload = 'data' flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return(payload) flexmock(module.requests).should_receive('post').with_args( - 'https://example.com', data=payload.encode('utf-8'), verify=False, timeout=int + 'https://example.com', + data=payload.encode('utf-8'), + verify=False, + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -205,10 +236,13 @@ def test_ping_monitor_executes_ssl_verification_when_verify_tls_true(): payload = 'data' flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler') flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return(payload) flexmock(module.requests).should_receive('post').with_args( - 'https://example.com', data=payload.encode('utf-8'), verify=True, timeout=int + 'https://example.com', + data=payload.encode('utf-8'), + verify=True, + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -223,7 +257,7 @@ def test_ping_monitor_executes_ssl_verification_when_verify_tls_true(): def test_ping_monitor_dry_run_does_not_hit_ping_url(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).never() hook_config = {'ping_url': 'https://example.com'} flexmock(module.requests).should_receive('post').never() @@ -240,7 +274,7 @@ def test_ping_monitor_dry_run_does_not_hit_ping_url(): def test_ping_monitor_does_not_hit_ping_url_when_states_not_matching(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).never() hook_config = {'ping_url': 'https://example.com', 'states': ['finish']} flexmock(module.requests).should_receive('post').never() @@ -257,11 +291,14 @@ def test_ping_monitor_does_not_hit_ping_url_when_states_not_matching(): def test_ping_monitor_hits_ping_url_when_states_matching(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).never() hook_config = {'ping_url': 'https://example.com', 'states': ['start', 'finish']} flexmock(module.requests).should_receive('post').with_args( - 'https://example.com/start', data=''.encode('utf-8'), verify=True, timeout=int + 'https://example.com/start', + data=b'', + verify=True, + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -276,11 +313,14 @@ def test_ping_monitor_hits_ping_url_when_states_matching(): def test_ping_monitor_adds_create_query_parameter_when_create_slug_true(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).never() hook_config = {'ping_url': 'https://example.com', 'create_slug': True} flexmock(module.requests).should_receive('post').with_args( - 'https://example.com/start?create=1', data=''.encode('utf-8'), verify=True, timeout=int + 'https://example.com/start?create=1', + data=b'', + verify=True, + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -295,11 +335,14 @@ def test_ping_monitor_adds_create_query_parameter_when_create_slug_true(): def test_ping_monitor_does_not_add_create_query_parameter_when_create_slug_false(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).never() hook_config = {'ping_url': 'https://example.com', 'create_slug': False} flexmock(module.requests).should_receive('post').with_args( - 'https://example.com/start', data=''.encode('utf-8'), verify=True, timeout=int + 'https://example.com/start', + data=b'', + verify=True, + timeout=int, ).and_return(flexmock(ok=True)) module.ping_monitor( @@ -316,7 +359,7 @@ def test_ping_monitor_does_not_add_create_query_parameter_when_ping_url_is_uuid( hook_config = {'ping_url': 'b3611b24-df9c-4d36-9203-fa292820bf2a', 'create_slug': True} flexmock(module.requests).should_receive('post').with_args( f"https://hc-ping.com/{hook_config['ping_url']}", - data=''.encode('utf-8'), + data=b'', verify=True, timeout=int, ).and_return(flexmock(ok=True)) @@ -350,11 +393,14 @@ def test_ping_monitor_issues_warning_when_ping_url_is_uuid_and_create_slug_true( def test_ping_monitor_with_connection_error_logs_warning(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).never() hook_config = {'ping_url': 'https://example.com'} flexmock(module.requests).should_receive('post').with_args( - 'https://example.com/start', data=''.encode('utf-8'), verify=True, timeout=int + 'https://example.com/start', + data=b'', + verify=True, + timeout=int, ).and_raise(module.requests.exceptions.ConnectionError) flexmock(module.logger).should_receive('warning').once() @@ -370,15 +416,18 @@ def test_ping_monitor_with_connection_error_logs_warning(): def test_ping_monitor_with_other_error_logs_warning(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).never() hook_config = {'ping_url': 'https://example.com'} response = flexmock(ok=False) response.should_receive('raise_for_status').and_raise( - module.requests.exceptions.RequestException + module.requests.exceptions.RequestException, ) flexmock(module.requests).should_receive('post').with_args( - 'https://example.com/start', data=''.encode('utf-8'), verify=True, timeout=int + 'https://example.com/start', + data=b'', + verify=True, + timeout=int, ).and_return(response) flexmock(module.logger).should_receive('warning').once() diff --git a/tests/unit/hooks/monitoring/test_logs.py b/tests/unit/hooks/monitoring/test_logs.py index 085c781c..649f74b1 100644 --- a/tests/unit/hooks/monitoring/test_logs.py +++ b/tests/unit/hooks/monitoring/test_logs.py @@ -24,7 +24,9 @@ def test_forgetful_buffering_handler_emit_collects_log_records_with_zero_byte_ca def test_forgetful_buffering_handler_emit_forgets_log_records_when_capacity_reached(): handler = module.Forgetful_buffering_handler( - identifier='test', byte_capacity=len('foo\nbar\n'), log_level=1 + identifier='test', + byte_capacity=len('foo\nbar\n'), + log_level=1, ) handler.emit(flexmock(getMessage=lambda: 'foo')) assert handler.buffer == ['foo\n'] diff --git a/tests/unit/hooks/monitoring/test_loki.py b/tests/unit/hooks/monitoring/test_loki.py index b00ac3a2..ca448ce2 100644 --- a/tests/unit/hooks/monitoring/test_loki.py +++ b/tests/unit/hooks/monitoring/test_loki.py @@ -37,7 +37,7 @@ def test_loki_log_buffer_json_serializes_labels(): buffer.add_label('test', 'label') assert json.loads(buffer.to_request()) == json.loads( - '{"streams":[{"stream":{"test": "label"},"values":[]}]}' + '{"streams":[{"stream":{"test": "label"},"values":[]}]}', ) @@ -80,7 +80,7 @@ def test_loki_log_handler_raw_posts_to_server(): ''' handler = module.Loki_log_handler(flexmock(), False) flexmock(module.requests).should_receive('post').and_return( - flexmock(raise_for_status=lambda: '') + flexmock(raise_for_status=lambda: ''), ).once() for num in range(int(module.MAX_BUFFER_LINES * 1.5)): @@ -93,7 +93,7 @@ def test_loki_log_handler_raw_post_failure_does_not_raise(): ''' handler = module.Loki_log_handler(flexmock(), False) flexmock(module.requests).should_receive('post').and_return( - flexmock(raise_for_status=lambda: (_ for _ in ()).throw(requests.RequestException())) + flexmock(raise_for_status=lambda: (_ for _ in ()).throw(requests.RequestException())), ).once() for num in range(int(module.MAX_BUFFER_LINES * 1.5)): diff --git a/tests/unit/hooks/monitoring/test_ntfy.py b/tests/unit/hooks/monitoring/test_ntfy.py index 3e749e4b..fd140d63 100644 --- a/tests/unit/hooks/monitoring/test_ntfy.py +++ b/tests/unit/hooks/monitoring/test_ntfy.py @@ -25,19 +25,18 @@ custom_message_headers = { def return_default_message_headers(state=Enum): - headers = { + return { 'X-Title': f'A borgmatic {state.name} event happened', 'X-Message': f'A borgmatic {state.name} event happened', 'X-Priority': 'default', 'X-Tags': 'borgmatic', } - return headers def test_ping_monitor_minimal_config_hits_hosted_ntfy_on_fail(): hook_config = {'topic': topic} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', @@ -62,7 +61,7 @@ def test_ping_monitor_with_access_token_hits_hosted_ntfy_on_fail(): 'access_token': 'abc123', } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', @@ -89,7 +88,7 @@ def test_ping_monitor_with_username_password_and_access_token_ignores_username_p 'access_token': 'abc123', } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', @@ -116,7 +115,7 @@ def test_ping_monitor_with_username_password_hits_hosted_ntfy_on_fail(): 'password': 'fakepassword', } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', @@ -138,7 +137,7 @@ def test_ping_monitor_with_username_password_hits_hosted_ntfy_on_fail(): def test_ping_monitor_with_password_but_no_username_warns(): hook_config = {'topic': topic, 'password': 'fakepassword'} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', @@ -161,7 +160,7 @@ def test_ping_monitor_with_password_but_no_username_warns(): def test_ping_monitor_with_username_but_no_password_warns(): hook_config = {'topic': topic, 'username': 'testuser'} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', @@ -184,7 +183,7 @@ def test_ping_monitor_with_username_but_no_password_warns(): def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_start(): hook_config = {'topic': topic} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').never() @@ -201,7 +200,7 @@ def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_start(): def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_finish(): hook_config = {'topic': topic} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').never() @@ -218,7 +217,7 @@ def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_finish(): def test_ping_monitor_minimal_config_hits_selfhosted_ntfy_on_fail(): hook_config = {'topic': topic, 'server': custom_base_url} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').with_args( f'{custom_base_url}/{topic}', @@ -240,7 +239,7 @@ def test_ping_monitor_minimal_config_hits_selfhosted_ntfy_on_fail(): def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_fail_dry_run(): hook_config = {'topic': topic} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').never() @@ -257,10 +256,13 @@ def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_fail_dry_run(): def test_ping_monitor_custom_message_hits_hosted_ntfy_on_fail(): hook_config = {'topic': topic, 'fail': custom_message_config} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').with_args( - f'{default_base_url}/{topic}', headers=custom_message_headers, auth=None, timeout=int + f'{default_base_url}/{topic}', + headers=custom_message_headers, + auth=None, + timeout=int, ).and_return(flexmock(ok=True)).once() module.ping_monitor( @@ -276,7 +278,7 @@ def test_ping_monitor_custom_message_hits_hosted_ntfy_on_fail(): def test_ping_monitor_custom_state_hits_hosted_ntfy_on_start(): hook_config = {'topic': topic, 'states': ['start', 'fail']} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', @@ -298,7 +300,7 @@ def test_ping_monitor_custom_state_hits_hosted_ntfy_on_start(): def test_ping_monitor_with_connection_error_logs_warning(): hook_config = {'topic': topic} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', @@ -321,7 +323,7 @@ def test_ping_monitor_with_connection_error_logs_warning(): def test_ping_monitor_with_credential_error_logs_warning(): hook_config = {'topic': topic} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_raise(ValueError) flexmock(module.requests).should_receive('post').never() flexmock(module.logger).should_receive('warning').once() @@ -339,11 +341,11 @@ def test_ping_monitor_with_credential_error_logs_warning(): def test_ping_monitor_with_other_error_logs_warning(): hook_config = {'topic': topic} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) response = flexmock(ok=False) response.should_receive('raise_for_status').and_raise( - module.requests.exceptions.RequestException + module.requests.exceptions.RequestException, ) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', diff --git a/tests/unit/hooks/monitoring/test_pagerduty.py b/tests/unit/hooks/monitoring/test_pagerduty.py index 12266c32..91b0b4a4 100644 --- a/tests/unit/hooks/monitoring/test_pagerduty.py +++ b/tests/unit/hooks/monitoring/test_pagerduty.py @@ -7,7 +7,7 @@ def test_initialize_monitor_creates_log_handler(): monitoring_log_level = 1 flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).once() flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('add_handler') @@ -16,29 +16,37 @@ def test_initialize_monitor_creates_log_handler(): def test_initialize_monitor_creates_log_handler_when_send_logs_true(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).once() flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('add_handler') module.initialize_monitor( - {'send_logs': True}, {}, 'test.yaml', monitoring_log_level=1, dry_run=False + {'send_logs': True}, + {}, + 'test.yaml', + monitoring_log_level=1, + dry_run=False, ) def test_initialize_monitor_bails_when_send_logs_false(): flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'Forgetful_buffering_handler' + 'Forgetful_buffering_handler', ).never() flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('add_handler') module.initialize_monitor( - {'send_logs': False}, {}, 'test.yaml', monitoring_log_level=1, dry_run=False + {'send_logs': False}, + {}, + 'test.yaml', + monitoring_log_level=1, + dry_run=False, ) def test_ping_monitor_ignores_start_state(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').never() @@ -54,7 +62,7 @@ def test_ping_monitor_ignores_start_state(): def test_ping_monitor_ignores_finish_state(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.requests).should_receive('post').never() @@ -70,10 +78,10 @@ def test_ping_monitor_ignores_finish_state(): def test_ping_monitor_calls_api_for_fail_state(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('loggy\nlogs') flexmock(module.requests).should_receive('post').and_return(flexmock(ok=True)) @@ -89,10 +97,10 @@ def test_ping_monitor_calls_api_for_fail_state(): def test_ping_monitor_dry_run_does_not_call_api(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('loggy\nlogs') flexmock(module.requests).should_receive('post').never() @@ -108,13 +116,13 @@ def test_ping_monitor_dry_run_does_not_call_api(): def test_ping_monitor_with_connection_error_logs_warning(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('loggy\nlogs') flexmock(module.requests).should_receive('post').and_raise( - module.requests.exceptions.ConnectionError + module.requests.exceptions.ConnectionError, ) flexmock(module.logger).should_receive('warning').once() @@ -130,7 +138,7 @@ def test_ping_monitor_with_connection_error_logs_warning(): def test_ping_monitor_with_credential_error_logs_warning(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_raise(ValueError) flexmock(module.requests).should_receive('post').never() flexmock(module.logger).should_receive('warning') @@ -148,13 +156,13 @@ def test_ping_monitor_with_credential_error_logs_warning(): def test_ping_monitor_with_other_error_logs_warning(): response = flexmock(ok=False) flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.borgmatic.hooks.monitoring.logs).should_receive( - 'format_buffered_logs_for_payload' + 'format_buffered_logs_for_payload', ).and_return('loggy\nlogs') response.should_receive('raise_for_status').and_raise( - module.requests.exceptions.RequestException + module.requests.exceptions.RequestException, ) flexmock(module.requests).should_receive('post').and_return(response) flexmock(module.logger).should_receive('warning') diff --git a/tests/unit/hooks/monitoring/test_pushover.py b/tests/unit/hooks/monitoring/test_pushover.py index 139467b0..41cf9c2c 100644 --- a/tests/unit/hooks/monitoring/test_pushover.py +++ b/tests/unit/hooks/monitoring/test_pushover.py @@ -12,7 +12,7 @@ def test_ping_monitor_config_with_minimum_config_fail_state_backup_successfully_ ''' hook_config = {'token': 'ksdjfwoweijfvwoeifvjmwghagy92', 'user': '983hfe0of902lkjfa2amanfgui'} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( @@ -43,7 +43,7 @@ def test_ping_monitor_config_with_minimum_config_start_state_backup_not_send_to_ ''' hook_config = {'token': 'ksdjfwoweijfvwoeifvjmwghagy92', 'user': '983hfe0of902lkjfa2amanfgui'} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').never() @@ -71,7 +71,7 @@ def test_ping_monitor_start_state_backup_default_message_successfully_send_to_pu 'states': {'start', 'fail', 'finish'}, } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( @@ -108,7 +108,7 @@ def test_ping_monitor_start_state_backup_custom_message_successfully_send_to_pus 'start': {'message': 'custom start message'}, } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( @@ -144,7 +144,7 @@ def test_ping_monitor_start_state_backup_default_message_with_priority_emergency 'start': {'priority': 2}, } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( @@ -183,7 +183,7 @@ def test_ping_monitor_start_state_backup_default_message_with_priority_emergency 'start': {'priority': 2, 'expire': 600}, } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( @@ -222,7 +222,7 @@ def test_ping_monitor_start_state_backup_default_message_with_priority_emergency 'start': {'priority': 2, 'retry': 30}, } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( @@ -264,7 +264,7 @@ def test_ping_monitor_start_state_backup_default_message_with_priority_high_decl } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').never() @@ -319,7 +319,7 @@ def test_ping_monitor_start_state_backup_based_on_documentation_advanced_example }, } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( @@ -386,7 +386,7 @@ def test_ping_monitor_fail_state_backup_based_on_documentation_advanced_example_ }, } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( @@ -458,7 +458,7 @@ def test_ping_monitor_finish_state_backup_based_on_documentation_advanced_exampl }, } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( @@ -495,7 +495,7 @@ def test_ping_monitor_config_with_minimum_config_fail_state_backup_successfully_ ''' hook_config = {'token': 'ksdjfwoweijfvwoeifvjmwghagy92', 'user': '983hfe0of902lkjfa2amanfgui'} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').and_return(flexmock(ok=True)).never() @@ -519,7 +519,7 @@ def test_ping_monitor_config_incorrect_state_exit_early(): 'user': '983hfe0of902lkjfa2amanfgui', } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').and_return(flexmock(ok=True)).never() @@ -539,17 +539,17 @@ def test_ping_monitor_push_post_error_bails(): This test simulates the Pushover servers not responding with a 200 OK. We should raise for status and warn then exit. ''' - hook_config = hook_config = { + hook_config = { 'token': 'ksdjfwoweijfvwoeifvjmwghagy92', 'user': '983hfe0of902lkjfa2amanfgui', } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) push_response = flexmock(ok=False) push_response.should_receive('raise_for_status').and_raise( - module.requests.ConnectionError + module.requests.ConnectionError, ).once() flexmock(module.requests).should_receive('post').with_args( 'https://api.pushover.net/1/messages.json', @@ -575,13 +575,13 @@ def test_ping_monitor_push_post_error_bails(): def test_ping_monitor_credential_error_bails(): - hook_config = hook_config = { + hook_config = { 'token': 'ksdjfwoweijfvwoeifvjmwghagy92', 'user': '983hfe0of902lkjfa2amanfgui', } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_raise(ValueError) flexmock(module.requests).should_receive('post').never() flexmock(module.logger).should_receive('warning').once() diff --git a/tests/unit/hooks/monitoring/test_sentry.py b/tests/unit/hooks/monitoring/test_sentry.py index bd959de1..970549d5 100644 --- a/tests/unit/hooks/monitoring/test_sentry.py +++ b/tests/unit/hooks/monitoring/test_sentry.py @@ -132,7 +132,7 @@ def test_ping_monitor_with_network_error_does_not_raise(): response = flexmock(ok=False) response.should_receive('raise_for_status').and_raise( - module.requests.exceptions.ConnectionError + module.requests.exceptions.ConnectionError, ) flexmock(module.requests).should_receive('post').with_args( 'https://o294220.ingest.us.sentry.io/api/203069/cron/test/5f80ec/?status=in_progress', diff --git a/tests/unit/hooks/monitoring/test_uptimekuma.py b/tests/unit/hooks/monitoring/test_uptimekuma.py index adef5db7..da49d974 100644 --- a/tests/unit/hooks/monitoring/test_uptimekuma.py +++ b/tests/unit/hooks/monitoring/test_uptimekuma.py @@ -10,7 +10,9 @@ CUSTOM_PUSH_URL = 'https://uptime.example.com/api/push/efgh5678' def test_ping_monitor_hits_default_uptimekuma_on_fail(): hook_config = {} flexmock(module.requests).should_receive('get').with_args( - f'{DEFAULT_PUSH_URL}?status=down&msg=fail', verify=True, timeout=int + f'{DEFAULT_PUSH_URL}?status=down&msg=fail', + verify=True, + timeout=int, ).and_return(flexmock(ok=True)).once() module.ping_monitor( @@ -26,7 +28,9 @@ def test_ping_monitor_hits_default_uptimekuma_on_fail(): def test_ping_monitor_hits_custom_uptimekuma_on_fail(): hook_config = {'push_url': CUSTOM_PUSH_URL} flexmock(module.requests).should_receive('get').with_args( - f'{CUSTOM_PUSH_URL}?status=down&msg=fail', verify=True, timeout=int + f'{CUSTOM_PUSH_URL}?status=down&msg=fail', + verify=True, + timeout=int, ).and_return(flexmock(ok=True)).once() module.ping_monitor( @@ -42,7 +46,9 @@ def test_ping_monitor_hits_custom_uptimekuma_on_fail(): def test_ping_monitor_custom_uptimekuma_on_start(): hook_config = {'push_url': CUSTOM_PUSH_URL} flexmock(module.requests).should_receive('get').with_args( - f'{CUSTOM_PUSH_URL}?status=up&msg=start', verify=True, timeout=int + f'{CUSTOM_PUSH_URL}?status=up&msg=start', + verify=True, + timeout=int, ).and_return(flexmock(ok=True)).once() module.ping_monitor( @@ -58,7 +64,9 @@ def test_ping_monitor_custom_uptimekuma_on_start(): def test_ping_monitor_custom_uptimekuma_on_finish(): hook_config = {'push_url': CUSTOM_PUSH_URL} flexmock(module.requests).should_receive('get').with_args( - f'{CUSTOM_PUSH_URL}?status=up&msg=finish', verify=True, timeout=int + f'{CUSTOM_PUSH_URL}?status=up&msg=finish', + verify=True, + timeout=int, ).and_return(flexmock(ok=True)).once() module.ping_monitor( @@ -116,7 +124,9 @@ def test_ping_monitor_does_not_hit_custom_uptimekuma_on_finish_dry_run(): def test_ping_monitor_with_connection_error_logs_warning(): hook_config = {'push_url': CUSTOM_PUSH_URL} flexmock(module.requests).should_receive('get').with_args( - f'{CUSTOM_PUSH_URL}?status=down&msg=fail', verify=True, timeout=int + f'{CUSTOM_PUSH_URL}?status=down&msg=fail', + verify=True, + timeout=int, ).and_raise(module.requests.exceptions.ConnectionError) flexmock(module.logger).should_receive('warning').once() @@ -134,10 +144,12 @@ def test_ping_monitor_with_other_error_logs_warning(): hook_config = {'push_url': CUSTOM_PUSH_URL} response = flexmock(ok=False) response.should_receive('raise_for_status').and_raise( - module.requests.exceptions.RequestException + module.requests.exceptions.RequestException, ) flexmock(module.requests).should_receive('get').with_args( - f'{CUSTOM_PUSH_URL}?status=down&msg=fail', verify=True, timeout=int + f'{CUSTOM_PUSH_URL}?status=down&msg=fail', + verify=True, + timeout=int, ).and_return(response) flexmock(module.logger).should_receive('warning').once() @@ -168,7 +180,9 @@ def test_ping_monitor_with_invalid_run_state(): def test_ping_monitor_skips_ssl_verification_when_verify_tls_false(): hook_config = {'push_url': CUSTOM_PUSH_URL, 'verify_tls': False} flexmock(module.requests).should_receive('get').with_args( - f'{CUSTOM_PUSH_URL}?status=down&msg=fail', verify=False, timeout=int + f'{CUSTOM_PUSH_URL}?status=down&msg=fail', + verify=False, + timeout=int, ).and_return(flexmock(ok=True)).once() module.ping_monitor( @@ -184,7 +198,9 @@ def test_ping_monitor_skips_ssl_verification_when_verify_tls_false(): def test_ping_monitor_executes_ssl_verification_when_verify_tls_true(): hook_config = {'push_url': CUSTOM_PUSH_URL, 'verify_tls': True} flexmock(module.requests).should_receive('get').with_args( - f'{CUSTOM_PUSH_URL}?status=down&msg=fail', verify=True, timeout=int + f'{CUSTOM_PUSH_URL}?status=down&msg=fail', + verify=True, + timeout=int, ).and_return(flexmock(ok=True)).once() module.ping_monitor( diff --git a/tests/unit/hooks/monitoring/test_zabbix.py b/tests/unit/hooks/monitoring/test_zabbix.py index 90627191..d9777e5f 100644 --- a/tests/unit/hooks/monitoring/test_zabbix.py +++ b/tests/unit/hooks/monitoring/test_zabbix.py @@ -70,11 +70,14 @@ def test_send_zabbix_request_with_post_error_bails(): data = {'method': 'do.stuff'} response = flexmock(ok=False) response.should_receive('raise_for_status').and_raise( - module.requests.exceptions.RequestException + module.requests.exceptions.RequestException, ) flexmock(module.requests).should_receive('post').with_args( - server, headers=headers, json=data, timeout=int + server, + headers=headers, + json=data, + timeout=int, ).and_return(response) assert module.send_zabbix_request(server, headers, data) is None @@ -89,7 +92,10 @@ def test_send_zabbix_request_with_invalid_json_response_bails(): response.should_receive('json').and_raise(module.requests.exceptions.JSONDecodeError) flexmock(module.requests).should_receive('post').with_args( - server, headers=headers, json=data, timeout=int + server, + headers=headers, + json=data, + timeout=int, ).and_return(response) assert module.send_zabbix_request(server, headers, data) is None @@ -103,7 +109,10 @@ def test_send_zabbix_request_with_success_returns_response_result(): response.should_receive('json').and_return({'result': {'foo': 'bar'}}) flexmock(module.requests).should_receive('post').with_args( - server, headers=headers, json=data, timeout=int + server, + headers=headers, + json=data, + timeout=int, ).and_return(response) assert module.send_zabbix_request(server, headers, data) == {'foo': 'bar'} @@ -117,7 +126,10 @@ def test_send_zabbix_request_with_success_passes_through_missing_result(): response.should_receive('json').and_return({}) flexmock(module.requests).should_receive('post').with_args( - server, headers=headers, json=data, timeout=int + server, + headers=headers, + json=data, + timeout=int, ).and_return(response) assert module.send_zabbix_request(server, headers, data) is None @@ -131,7 +143,10 @@ def test_send_zabbix_request_with_error_bails(): response.should_receive('json').and_return({'result': {'data': [{'error': 'oops'}]}}) flexmock(module.requests).should_receive('post').with_args( - server, headers=headers, json=data, timeout=int + server, + headers=headers, + json=data, + timeout=int, ).and_return(response) assert module.send_zabbix_request(server, headers, data) is None @@ -156,7 +171,7 @@ def test_ping_monitor_config_with_api_key_only_bails(): # for the hook to work hook_config = {'api_key': API_KEY} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').once() flexmock(module).should_receive('send_zabbix_request').never() @@ -176,7 +191,7 @@ def test_ping_monitor_config_with_host_only_bails(): # for the hook to work hook_config = {'host': HOST} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').once() flexmock(module).should_receive('send_zabbix_request').never() @@ -196,7 +211,7 @@ def test_ping_monitor_config_with_key_only_bails(): # for the hook to work hook_config = {'key': KEY} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').once() flexmock(module).should_receive('send_zabbix_request').never() @@ -216,7 +231,7 @@ def test_ping_monitor_config_with_server_only_bails(): # for the hook to work hook_config = {'server': SERVER} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').once() flexmock(module).should_receive('send_zabbix_request').never() @@ -235,7 +250,7 @@ def test_ping_monitor_config_user_password_no_zabbix_data_bails(): # This test should exit early since there are HOST/KEY or ITEMID provided to publish data to hook_config = {'server': SERVER, 'username': USERNAME, 'password': PASSWORD} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').once() flexmock(module).should_receive('send_zabbix_request').never() @@ -254,7 +269,7 @@ def test_ping_monitor_config_api_key_no_zabbix_data_bails(): # This test should exit early since there are HOST/KEY or ITEMID provided to publish data to hook_config = {'server': SERVER, 'api_key': API_KEY} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').once() flexmock(module).should_receive('send_zabbix_request').never() @@ -274,7 +289,7 @@ def test_ping_monitor_config_itemid_no_auth_data_bails(): # and Zabbix requires authentication to use it's API hook_config = {'server': SERVER, 'itemid': ITEMID} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').once() flexmock(module).should_receive('send_zabbix_request').never() @@ -294,7 +309,7 @@ def test_ping_monitor_config_host_and_key_no_auth_data_bails(): # and Zabbix requires authentication to use it's API hook_config = {'server': SERVER, 'host': HOST, 'key': KEY} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').once() flexmock(module).should_receive('send_zabbix_request').never() @@ -314,7 +329,7 @@ def test_ping_monitor_config_host_and_key_with_api_key_auth_data_successful(): # to authenticate and HOST/KEY to know which item to populate in Zabbix. hook_config = {'server': SERVER, 'host': HOST, 'key': KEY, 'api_key': API_KEY} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('send_zabbix_request').with_args( f'{SERVER}', @@ -338,7 +353,7 @@ def test_ping_monitor_config_adds_missing_api_endpoint_to_server_url(): # to authenticate and HOST/KEY to know which item to populate in Zabbix. hook_config = {'server': SERVER, 'host': HOST, 'key': KEY, 'api_key': API_KEY} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('send_zabbix_request').with_args( f'{SERVER}', @@ -360,7 +375,7 @@ def test_ping_monitor_config_adds_missing_api_endpoint_to_server_url(): def test_ping_monitor_config_host_and_missing_key_bails(): hook_config = {'server': SERVER, 'host': HOST, 'api_key': API_KEY} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').once() flexmock(module).should_receive('send_zabbix_request').never() @@ -378,7 +393,7 @@ def test_ping_monitor_config_host_and_missing_key_bails(): def test_ping_monitor_config_key_and_missing_host_bails(): hook_config = {'server': SERVER, 'key': KEY, 'api_key': API_KEY} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').once() flexmock(module).should_receive('send_zabbix_request').never() @@ -405,7 +420,7 @@ def test_ping_monitor_config_host_and_key_with_username_password_auth_data_succe } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('send_zabbix_request').with_args( @@ -448,7 +463,7 @@ def test_ping_monitor_config_host_and_key_with_username_password_auth_data_and_a } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('send_zabbix_request').with_args( @@ -487,7 +502,7 @@ def test_ping_monitor_config_host_and_key_with_username_and_missing_password_bai } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').once() flexmock(module).should_receive('send_zabbix_request').never() @@ -511,7 +526,7 @@ def test_ping_monitor_config_host_and_key_with_password_and_missing_username_bai } flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module.logger).should_receive('warning').once() flexmock(module).should_receive('send_zabbix_request').never() @@ -531,7 +546,7 @@ def test_ping_monitor_config_itemid_with_api_key_auth_data_successful(): # to authenticate and HOST/KEY to know which item to populate in Zabbix. hook_config = {'server': SERVER, 'itemid': ITEMID, 'api_key': API_KEY} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('send_zabbix_request').with_args( f'{SERVER}', @@ -556,7 +571,7 @@ def test_ping_monitor_config_itemid_with_username_password_auth_data_successful( hook_config = {'server': SERVER, 'itemid': ITEMID, 'username': USERNAME, 'password': PASSWORD} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).replace_with(lambda value, config: value) flexmock(module).should_receive('send_zabbix_request').with_args( @@ -593,7 +608,7 @@ def test_ping_monitor_with_credential_error_bails(): hook_config = {'server': SERVER, 'itemid': ITEMID, 'username': USERNAME, 'password': PASSWORD} flexmock(module.borgmatic.hooks.credential.parse).should_receive( - 'resolve_credential' + 'resolve_credential', ).and_raise(ValueError) flexmock(module).should_receive('send_zabbix_request').never() flexmock(module.logger).should_receive('warning').once() diff --git a/tests/unit/hooks/test_command.py b/tests/unit/hooks/test_command.py index edf5dfa7..45666f6c 100644 --- a/tests/unit/hooks/test_command.py +++ b/tests/unit/hooks/test_command.py @@ -12,28 +12,28 @@ def test_interpolate_context_passes_through_command_without_variable(): def test_interpolate_context_warns_and_passes_through_command_with_unknown_variable(): - command = 'ls {baz}' # noqa: FS003 + command = 'ls {baz}' flexmock(module.logger).should_receive('warning').once() assert module.interpolate_context('pre-backup', command, {'foo': 'bar'}) == command def test_interpolate_context_does_not_warn_and_passes_through_command_with_unknown_variable_matching_borg_placeholder(): - command = 'ls {hostname}' # noqa: FS003 + command = 'ls {hostname}' flexmock(module.logger).should_receive('warning').never() assert module.interpolate_context('pre-backup', command, {'foo': 'bar'}) == command def test_interpolate_context_interpolates_variables(): - command = 'ls {foo}{baz} {baz}' # noqa: FS003 + command = 'ls {foo}{baz} {baz}' context = {'foo': 'bar', 'baz': 'quux'} assert module.interpolate_context('pre-backup', command, context) == 'ls barquux quux' def test_interpolate_context_escapes_interpolated_variables(): - command = 'ls {foo} {inject}' # noqa: FS003 + command = 'ls {foo} {inject}' context = {'foo': 'bar', 'inject': 'hi; naughty-command'} assert ( @@ -47,13 +47,14 @@ def test_make_environment_without_pyinstaller_does_not_touch_environment(): def test_make_environment_with_pyinstaller_clears_LD_LIBRARY_PATH(): assert module.make_environment({}, sys_module=flexmock(frozen=True, _MEIPASS='yup')) == { - 'LD_LIBRARY_PATH': '' + 'LD_LIBRARY_PATH': '', } def test_make_environment_with_pyinstaller_and_LD_LIBRARY_PATH_ORIG_copies_it_into_LD_LIBRARY_PATH(): assert module.make_environment( - {'LD_LIBRARY_PATH_ORIG': '/lib/lib/lib'}, sys_module=flexmock(frozen=True, _MEIPASS='yup') + {'LD_LIBRARY_PATH_ORIG': '/lib/lib/lib'}, + sys_module=flexmock(frozen=True, _MEIPASS='yup'), ) == {'LD_LIBRARY_PATH_ORIG': '/lib/lib/lib', 'LD_LIBRARY_PATH': '/lib/lib/lib'} @@ -226,7 +227,7 @@ def test_execute_hooks_invokes_each_hook_and_command(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = LOGGING_ANSWER flexmock(module).should_receive('interpolate_context').replace_with( - lambda hook_description, command, context: command + lambda hook_description, command, context: command, ) flexmock(module).should_receive('make_environment').and_return({}) @@ -251,7 +252,7 @@ def test_execute_hooks_with_umask_sets_that_umask(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = LOGGING_ANSWER flexmock(module).should_receive('interpolate_context').replace_with( - lambda hook_description, command, context: command + lambda hook_description, command, context: command, ) flexmock(module.os).should_receive('umask').with_args(0o77).and_return(0o22).once() flexmock(module.os).should_receive('umask').with_args(0o22).once() @@ -265,7 +266,10 @@ def test_execute_hooks_with_umask_sets_that_umask(): ) module.execute_hooks( - [{'before': 'create', 'run': ['foo']}], umask=77, working_directory=None, dry_run=False + [{'before': 'create', 'run': ['foo']}], + umask=77, + working_directory=None, + dry_run=False, ) @@ -273,7 +277,7 @@ def test_execute_hooks_with_working_directory_executes_command_with_it(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = LOGGING_ANSWER flexmock(module).should_receive('interpolate_context').replace_with( - lambda hook_description, command, context: command + lambda hook_description, command, context: command, ) flexmock(module).should_receive('make_environment').and_return({}) flexmock(module.borgmatic.execute).should_receive('execute_command').with_args( @@ -296,13 +300,16 @@ def test_execute_hooks_with_dry_run_skips_commands(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = LOGGING_ANSWER flexmock(module).should_receive('interpolate_context').replace_with( - lambda hook_description, command, context: command + lambda hook_description, command, context: command, ) flexmock(module).should_receive('make_environment').and_return({}) flexmock(module.borgmatic.execute).should_receive('execute_command').never() module.execute_hooks( - [{'before': 'create', 'run': ['foo']}], umask=None, working_directory=None, dry_run=True + [{'before': 'create', 'run': ['foo']}], + umask=None, + working_directory=None, + dry_run=True, ) @@ -314,7 +321,7 @@ def test_execute_hooks_with_error_logs_as_error(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = LOGGING_ANSWER flexmock(module).should_receive('interpolate_context').replace_with( - lambda hook_description, command, context: command + lambda hook_description, command, context: command, ) flexmock(module).should_receive('make_environment').and_return({}) flexmock(module.borgmatic.execute).should_receive('execute_command').with_args( @@ -326,7 +333,10 @@ def test_execute_hooks_with_error_logs_as_error(): ).once() module.execute_hooks( - [{'after': 'error', 'run': ['foo']}], umask=None, working_directory=None, dry_run=False + [{'after': 'error', 'run': ['foo']}], + umask=None, + working_directory=None, + dry_run=False, ) @@ -353,7 +363,7 @@ def test_execute_hooks_without_commands_to_run_does_not_raise(): flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = LOGGING_ANSWER flexmock(module).should_receive('interpolate_context').replace_with( - lambda hook_description, command, context: command + lambda hook_description, command, context: command, ) flexmock(module).should_receive('make_environment').and_return({}) @@ -424,8 +434,9 @@ def test_before_after_hooks_with_before_error_runs_after_hook_and_raises(): flexmock(module).should_receive('execute_hooks').and_raise(OSError).and_return(None) flexmock(module).should_receive('considered_soft_failure').and_return(False) - with pytest.raises(ValueError): - with module.Before_after_hooks( + with ( + pytest.raises(ValueError), + module.Before_after_hooks( command_hooks=commands, before_after='action', umask=1234, @@ -434,8 +445,9 @@ def test_before_after_hooks_with_before_error_runs_after_hook_and_raises(): action_names=['create'], context1='stuff', context2='such', - ): - assert False # This should never get called. + ), + ): + raise AssertionError() # This should never get called. def test_before_after_hooks_with_before_soft_failure_raises(): @@ -457,8 +469,9 @@ def test_before_after_hooks_with_before_soft_failure_raises(): flexmock(module).should_receive('execute_hooks').and_raise(OSError) flexmock(module).should_receive('considered_soft_failure').and_return(True) - with pytest.raises(OSError): - with module.Before_after_hooks( + with ( + pytest.raises(OSError), + module.Before_after_hooks( command_hooks=commands, before_after='action', umask=1234, @@ -467,8 +480,9 @@ def test_before_after_hooks_with_before_soft_failure_raises(): action_names=['create'], context1='stuff', context2='such', - ): - pass + ), + ): + pass def test_before_after_hooks_with_wrapped_code_error_runs_after_hook_and_raises(): @@ -489,8 +503,9 @@ def test_before_after_hooks_with_wrapped_code_error_runs_after_hook_and_raises() ).and_return(flexmock()).once() flexmock(module).should_receive('execute_hooks').twice() - with pytest.raises(ValueError): - with module.Before_after_hooks( + with ( + pytest.raises(ValueError), + module.Before_after_hooks( command_hooks=commands, before_after='action', umask=1234, @@ -499,8 +514,9 @@ def test_before_after_hooks_with_wrapped_code_error_runs_after_hook_and_raises() action_names=['create'], context1='stuff', context2='such', - ): - raise ValueError() + ), + ): + raise ValueError() def test_before_after_hooks_with_after_error_raises(): @@ -522,8 +538,9 @@ def test_before_after_hooks_with_after_error_raises(): flexmock(module).should_receive('execute_hooks').and_return(None).and_raise(OSError) flexmock(module).should_receive('considered_soft_failure').and_return(False) - with pytest.raises(ValueError): - with module.Before_after_hooks( + with ( + pytest.raises(ValueError), + module.Before_after_hooks( command_hooks=commands, before_after='action', umask=1234, @@ -532,8 +549,9 @@ def test_before_after_hooks_with_after_error_raises(): action_names=['create'], context1='stuff', context2='such', - ): - pass + ), + ): + pass def test_before_after_hooks_with_after_soft_failure_raises(): @@ -555,8 +573,9 @@ def test_before_after_hooks_with_after_soft_failure_raises(): flexmock(module).should_receive('execute_hooks').and_return(None).and_raise(OSError) flexmock(module).should_receive('considered_soft_failure').and_return(True) - with pytest.raises(OSError): - with module.Before_after_hooks( + with ( + pytest.raises(OSError), + module.Before_after_hooks( command_hooks=commands, before_after='action', umask=1234, @@ -565,8 +584,9 @@ def test_before_after_hooks_with_after_soft_failure_raises(): action_names=['create'], context1='stuff', context2='such', - ): - pass + ), + ): + pass def test_considered_soft_failure_treats_soft_fail_exit_code_as_soft_fail(): diff --git a/tests/unit/hooks/test_dispatch.py b/tests/unit/hooks/test_dispatch.py index 8f3f8ecf..ccbe5af5 100644 --- a/tests/unit/hooks/test_dispatch.py +++ b/tests/unit/hooks/test_dispatch.py @@ -10,7 +10,6 @@ def hook_function(hook_config, config, thing, value): ''' This test function gets mocked out below. ''' - pass def test_call_hook_invokes_module_function_with_arguments_and_returns_value(): @@ -18,19 +17,22 @@ def test_call_hook_invokes_module_function_with_arguments_and_returns_value(): expected_return_value = flexmock() test_module = sys.modules[__name__] flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.credential + module.borgmatic.hooks.credential, ).and_return(['other_hook']) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.data_source + module.borgmatic.hooks.data_source, ).and_return(['other_hook']) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.monitoring + module.borgmatic.hooks.monitoring, ).and_return(['super_hook', 'third_hook']) flexmock(module.importlib).should_receive('import_module').with_args( - 'borgmatic.hooks.monitoring.super_hook' + 'borgmatic.hooks.monitoring.super_hook', ).and_return(test_module) flexmock(test_module).should_receive('hook_function').with_args( - config['super_hook'], config, 55, value=66 + config['super_hook'], + config, + 55, + value=66, ).and_return(expected_return_value).once() return_value = module.call_hook('hook_function', config, 'super_hook', 55, value=66) @@ -43,19 +45,22 @@ def test_call_hook_probes_config_with_databases_suffix(): expected_return_value = flexmock() test_module = sys.modules[__name__] flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.credential + module.borgmatic.hooks.credential, ).and_return(['other_hook']) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.data_source + module.borgmatic.hooks.data_source, ).and_return(['other_hook']) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.monitoring + module.borgmatic.hooks.monitoring, ).and_return(['super_hook', 'third_hook']) flexmock(module.importlib).should_receive('import_module').with_args( - 'borgmatic.hooks.monitoring.super_hook' + 'borgmatic.hooks.monitoring.super_hook', ).and_return(test_module) flexmock(test_module).should_receive('hook_function').with_args( - config['super_hook_databases'], config, 55, value=66 + config['super_hook_databases'], + config, + 55, + value=66, ).and_return(expected_return_value).once() return_value = module.call_hook('hook_function', config, 'super_hook', 55, value=66) @@ -68,19 +73,22 @@ def test_call_hook_strips_databases_suffix_from_hook_name(): expected_return_value = flexmock() test_module = sys.modules[__name__] flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.credential + module.borgmatic.hooks.credential, ).and_return(['other_hook']) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.data_source + module.borgmatic.hooks.data_source, ).and_return(['other_hook']) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.monitoring + module.borgmatic.hooks.monitoring, ).and_return(['super_hook', 'third_hook']) flexmock(module.importlib).should_receive('import_module').with_args( - 'borgmatic.hooks.monitoring.super_hook' + 'borgmatic.hooks.monitoring.super_hook', ).and_return(test_module) flexmock(test_module).should_receive('hook_function').with_args( - config['super_hook_databases'], config, 55, value=66 + config['super_hook_databases'], + config, + 55, + value=66, ).and_return(expected_return_value).once() return_value = module.call_hook('hook_function', config, 'super_hook_databases', 55, value=66) @@ -93,19 +101,22 @@ def test_call_hook_without_hook_config_invokes_module_function_with_arguments_an expected_return_value = flexmock() test_module = sys.modules[__name__] flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.credential + module.borgmatic.hooks.credential, ).and_return(['other_hook']) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.data_source + module.borgmatic.hooks.data_source, ).and_return(['other_hook']) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.monitoring + module.borgmatic.hooks.monitoring, ).and_return(['super_hook', 'third_hook']) flexmock(module.importlib).should_receive('import_module').with_args( - 'borgmatic.hooks.monitoring.super_hook' + 'borgmatic.hooks.monitoring.super_hook', ).and_return(test_module) flexmock(test_module).should_receive('hook_function').with_args( - None, config, 55, value=66 + None, + config, + 55, + value=66, ).and_return(expected_return_value).once() return_value = module.call_hook('hook_function', config, 'super_hook', 55, value=66) @@ -117,16 +128,16 @@ def test_call_hook_without_corresponding_module_raises(): config = {'super_hook': flexmock(), 'other_hook': flexmock()} test_module = sys.modules[__name__] flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.credential + module.borgmatic.hooks.credential, ).and_return(['other_hook']) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.data_source + module.borgmatic.hooks.data_source, ).and_return(['other_hook']) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.monitoring + module.borgmatic.hooks.monitoring, ).and_return(['some_hook']) flexmock(module.importlib).should_receive('import_module').with_args( - 'borgmatic.hooks.monitoring.super_hook' + 'borgmatic.hooks.monitoring.super_hook', ).and_return(test_module) flexmock(test_module).should_receive('hook_function').never() @@ -137,17 +148,17 @@ def test_call_hook_without_corresponding_module_raises(): def test_call_hook_skips_non_hook_modules(): config = {'not_a_hook': flexmock(), 'other_hook': flexmock()} flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.credential + module.borgmatic.hooks.credential, ).and_return(['other_hook']) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.data_source + module.borgmatic.hooks.data_source, ).and_return(['other_hook']) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.monitoring + module.borgmatic.hooks.monitoring, ).and_return(['not_a_hook', 'third_hook']) not_a_hook_module = flexmock(IS_A_HOOK=False) flexmock(module.importlib).should_receive('import_module').with_args( - 'borgmatic.hooks.monitoring.not_a_hook' + 'borgmatic.hooks.monitoring.not_a_hook', ).and_return(not_a_hook_module) return_value = module.call_hook('hook_function', config, 'not_a_hook', 55, value=66) @@ -159,13 +170,13 @@ def test_call_hooks_calls_each_hook_and_collects_return_values(): config = {'super_hook': flexmock(), 'other_hook': flexmock()} expected_return_values = {'super_hook': flexmock(), 'other_hook': flexmock()} flexmock(module.importlib).should_receive('import_module').with_args( - 'borgmatic.hooks.monitoring' + 'borgmatic.hooks.monitoring', ).and_return(module.borgmatic.hooks.monitoring) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.monitoring + module.borgmatic.hooks.monitoring, ).and_return(['super_hook', 'other_hook']) flexmock(module).should_receive('call_hook').and_return( - expected_return_values['super_hook'] + expected_return_values['super_hook'], ).and_return(expected_return_values['other_hook']) return_values = module.call_hooks('do_stuff', config, module.Hook_type.MONITORING, 55) @@ -177,10 +188,10 @@ def test_call_hooks_calls_skips_return_values_for_unconfigured_hooks(): config = {'super_hook': flexmock()} expected_return_values = {'super_hook': flexmock()} flexmock(module.importlib).should_receive('import_module').with_args( - 'borgmatic.hooks.monitoring' + 'borgmatic.hooks.monitoring', ).and_return(module.borgmatic.hooks.monitoring) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.monitoring + module.borgmatic.hooks.monitoring, ).and_return(['super_hook', 'other_hook']) flexmock(module).should_receive('call_hook').and_return(expected_return_values['super_hook']) @@ -193,13 +204,13 @@ def test_call_hooks_calls_treats_null_hook_as_optionless(): config = {'super_hook': flexmock(), 'other_hook': None} expected_return_values = {'super_hook': flexmock(), 'other_hook': flexmock()} flexmock(module.importlib).should_receive('import_module').with_args( - 'borgmatic.hooks.monitoring' + 'borgmatic.hooks.monitoring', ).and_return(module.borgmatic.hooks.monitoring) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.monitoring + module.borgmatic.hooks.monitoring, ).and_return(['super_hook', 'other_hook']) flexmock(module).should_receive('call_hook').and_return( - expected_return_values['super_hook'] + expected_return_values['super_hook'], ).and_return(expected_return_values['other_hook']) return_values = module.call_hooks('do_stuff', config, module.Hook_type.MONITORING, 55) @@ -211,13 +222,13 @@ def test_call_hooks_calls_looks_up_databases_suffix_in_config(): config = {'super_hook_databases': flexmock(), 'other_hook': flexmock()} expected_return_values = {'super_hook': flexmock(), 'other_hook': flexmock()} flexmock(module.importlib).should_receive('import_module').with_args( - 'borgmatic.hooks.monitoring' + 'borgmatic.hooks.monitoring', ).and_return(module.borgmatic.hooks.monitoring) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.monitoring + module.borgmatic.hooks.monitoring, ).and_return(['super_hook', 'other_hook']) flexmock(module).should_receive('call_hook').and_return( - expected_return_values['super_hook'] + expected_return_values['super_hook'], ).and_return(expected_return_values['other_hook']) return_values = module.call_hooks('do_stuff', config, module.Hook_type.MONITORING, 55) @@ -229,17 +240,20 @@ def test_call_hooks_even_if_unconfigured_calls_each_hook_and_collects_return_val config = {'super_hook': flexmock(), 'other_hook': flexmock()} expected_return_values = {'super_hook': flexmock(), 'other_hook': flexmock()} flexmock(module.importlib).should_receive('import_module').with_args( - 'borgmatic.hooks.monitoring' + 'borgmatic.hooks.monitoring', ).and_return(module.borgmatic.hooks.monitoring) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.monitoring + module.borgmatic.hooks.monitoring, ).and_return(['super_hook', 'other_hook']) flexmock(module).should_receive('call_hook').and_return( - expected_return_values['super_hook'] + expected_return_values['super_hook'], ).and_return(expected_return_values['other_hook']) return_values = module.call_hooks_even_if_unconfigured( - 'do_stuff', config, module.Hook_type.MONITORING, 55 + 'do_stuff', + config, + module.Hook_type.MONITORING, + 55, ) assert return_values == expected_return_values @@ -249,17 +263,20 @@ def test_call_hooks_even_if_unconfigured_calls_each_hook_configured_or_not_and_c config = {'other_hook': flexmock()} expected_return_values = {'super_hook': flexmock(), 'other_hook': flexmock()} flexmock(module.importlib).should_receive('import_module').with_args( - 'borgmatic.hooks.monitoring' + 'borgmatic.hooks.monitoring', ).and_return(module.borgmatic.hooks.monitoring) flexmock(module).should_receive('get_submodule_names').with_args( - module.borgmatic.hooks.monitoring + module.borgmatic.hooks.monitoring, ).and_return(['super_hook', 'other_hook']) flexmock(module).should_receive('call_hook').and_return( - expected_return_values['super_hook'] + expected_return_values['super_hook'], ).and_return(expected_return_values['other_hook']) return_values = module.call_hooks_even_if_unconfigured( - 'do_stuff', config, module.Hook_type.MONITORING, 55 + 'do_stuff', + config, + module.Hook_type.MONITORING, + 55, ) assert return_values == expected_return_values diff --git a/tests/unit/test_execute.py b/tests/unit/test_execute.py index f3ef9413..f5ed955e 100644 --- a/tests/unit/test_execute.py +++ b/tests/unit/test_execute.py @@ -44,7 +44,11 @@ from borgmatic import execute as module ), ) def test_interpret_exit_code_respects_exit_code_and_borg_local_path( - command, exit_code, borg_local_path, borg_exit_codes, expected_result + command, + exit_code, + borg_local_path, + borg_exit_codes, + expected_result, ): assert ( module.interpret_exit_code(command, exit_code, borg_local_path, borg_exit_codes) @@ -87,22 +91,28 @@ def test_append_last_lines_under_max_line_count_appends(): flexmock(module.logger).should_receive('log').once() module.append_last_lines( - last_lines, captured_output=flexmock(), line='line', output_log_level=flexmock() + last_lines, + captured_output=flexmock(), + line='line', + output_log_level=flexmock(), ) assert last_lines == ['last', 'line'] def test_append_last_lines_over_max_line_count_trims_and_appends(): - original_last_lines = [str(number) for number in range(0, module.ERROR_OUTPUT_MAX_LINE_COUNT)] + original_last_lines = [str(number) for number in range(module.ERROR_OUTPUT_MAX_LINE_COUNT)] last_lines = list(original_last_lines) flexmock(module.logger).should_receive('log').once() module.append_last_lines( - last_lines, captured_output=flexmock(), line='line', output_log_level=flexmock() + last_lines, + captured_output=flexmock(), + line='line', + output_log_level=flexmock(), ) - assert last_lines == original_last_lines[1:] + ['line'] + assert last_lines == [*original_last_lines[1:], 'line'] def test_append_last_lines_with_output_log_level_none_appends_captured_output(): @@ -111,7 +121,10 @@ def test_append_last_lines_with_output_log_level_none_appends_captured_output(): flexmock(module.logger).should_receive('log').never() module.append_last_lines( - last_lines, captured_output=captured_output, line='line', output_log_level=None + last_lines, + captured_output=captured_output, + line='line', + output_log_level=None, ) assert captured_output == ['captured', 'line'] @@ -172,7 +185,11 @@ def test_mask_command_secrets_passes_through_other_commands(): ), ) def test_log_command_logs_command_constructed_from_arguments( - full_command, input_file, output_file, environment, expected_result + full_command, + input_file, + output_file, + environment, + expected_result, ): flexmock(module).should_receive('mask_command_secrets').replace_with(lambda command: command) flexmock(module.logger).should_receive('debug').with_args(expected_result).once() @@ -403,7 +420,7 @@ def test_execute_command_and_capture_output_returns_output_when_process_error_is close_fds=False, ).and_raise(subprocess.CalledProcessError(1, full_command, err_output)).once() flexmock(module).should_receive('interpret_exit_code').and_return( - module.Exit_status.SUCCESS + module.Exit_status.SUCCESS, ).once() output = module.execute_command_and_capture_output(full_command) @@ -425,7 +442,7 @@ def test_execute_command_and_capture_output_raises_when_command_errors(): close_fds=False, ).and_raise(subprocess.CalledProcessError(2, full_command, expected_output)).once() flexmock(module).should_receive('interpret_exit_code').and_return( - module.Exit_status.ERROR + module.Exit_status.ERROR, ).once() with pytest.raises(subprocess.CalledProcessError): @@ -466,7 +483,9 @@ def test_execute_command_and_capture_output_returns_output_with_environment(): ).and_return(flexmock(decode=lambda: expected_output)).once() output = module.execute_command_and_capture_output( - full_command, shell=False, environment={'a': 'b'} + full_command, + shell=False, + environment={'a': 'b'}, ) assert output == expected_output @@ -487,7 +506,9 @@ def test_execute_command_and_capture_output_returns_output_with_working_director ).and_return(flexmock(decode=lambda: expected_output)).once() output = module.execute_command_and_capture_output( - full_command, shell=False, working_directory='/working' + full_command, + shell=False, + working_directory='/working', ) assert output == expected_output @@ -580,7 +601,9 @@ def test_execute_command_with_processes_calls_full_command_without_capturing_out flexmock(module).should_receive('log_outputs') output = module.execute_command_with_processes( - full_command, processes, output_file=module.DO_NOT_CAPTURE + full_command, + processes, + output_file=module.DO_NOT_CAPTURE, ) assert output is None @@ -671,7 +694,9 @@ def test_execute_command_with_processes_calls_full_command_with_working_director flexmock(module).should_receive('log_outputs') output = module.execute_command_with_processes( - full_command, processes, working_directory='/working' + full_command, + processes, + working_directory='/working', ) assert output is None diff --git a/tests/unit/test_logger.py b/tests/unit/test_logger.py index d179735f..6b092e9d 100644 --- a/tests/unit/test_logger.py +++ b/tests/unit/test_logger.py @@ -81,7 +81,7 @@ def test_should_do_markup_prefers_any_false_config_value(): def test_should_do_markup_respects_PY_COLORS_environment_variable(): flexmock(module.os.environ).should_receive('get').with_args('PY_COLORS', None).and_return( - 'True' + 'True', ) flexmock(module.os.environ).should_receive('get').with_args('NO_COLOR', None).and_return(None) @@ -126,7 +126,7 @@ def test_should_do_markup_respects_interactive_console_value(): def test_should_do_markup_prefers_PY_COLORS_to_interactive_console_value(): flexmock(module.os.environ).should_receive('get').with_args('PY_COLORS', None).and_return( - 'True' + 'True', ) flexmock(module.os.environ).should_receive('get').with_args('NO_COLOR', None).and_return(None) flexmock(module).should_receive('to_bool').and_return(True) @@ -161,10 +161,10 @@ def test_should_do_markup_ignores_empty_NO_COLOR_environment_variable(): def test_should_do_markup_prefers_NO_COLOR_to_PY_COLORS(): flexmock(module.os.environ).should_receive('get').with_args('PY_COLORS', None).and_return( - 'True' + 'True', ) flexmock(module.os.environ).should_receive('get').with_args('NO_COLOR', None).and_return( - 'SomeValue' + 'SomeValue', ) flexmock(module).should_receive('interactive_console').never() @@ -177,7 +177,7 @@ def test_multi_stream_handler_logs_to_handler_for_log_level(): info_handler = flexmock() multi_handler = module.Multi_stream_handler( - {module.logging.ERROR: error_handler, module.logging.INFO: info_handler} + {module.logging.ERROR: error_handler, module.logging.INFO: info_handler}, ) multi_handler.emit(flexmock(levelno=module.logging.ERROR)) @@ -244,7 +244,7 @@ def test_get_log_prefix_gets_prefix_from_first_handler_formatter_with_prefix(): flexmock(formatter=flexmock(prefix='myprefix')), ], removeHandler=lambda handler: None, - ) + ), ) assert module.get_log_prefix() == 'myprefix' @@ -255,7 +255,7 @@ def test_get_log_prefix_with_no_handlers_does_not_raise(): flexmock( handlers=[], removeHandler=lambda handler: None, - ) + ), ) assert module.get_log_prefix() is None @@ -269,7 +269,7 @@ def test_get_log_prefix_with_no_formatters_does_not_raise(): flexmock(formatter=None), ], removeHandler=lambda handler: None, - ) + ), ) assert module.get_log_prefix() is None @@ -284,7 +284,7 @@ def test_get_log_prefix_with_no_prefix_does_not_raise(): ), ], removeHandler=lambda handler: None, - ) + ), ) assert module.get_log_prefix() is None @@ -307,7 +307,7 @@ def test_set_log_prefix_updates_all_handler_formatters(): ), ], removeHandler=lambda handler: None, - ) + ), ) module.set_log_prefix('myprefix') @@ -330,7 +330,7 @@ def test_set_log_prefix_skips_handlers_without_a_formatter(): ), ], removeHandler=lambda handler: None, - ) + ), ) module.set_log_prefix('myprefix') @@ -455,12 +455,13 @@ def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_linux( flexmock(module).should_receive('interactive_console').and_return(False) flexmock(module).should_receive('flush_delayed_logging') flexmock(module.logging).should_receive('basicConfig').with_args( - level=logging.DEBUG, handlers=list + level=logging.DEBUG, + handlers=list, ) flexmock(module.os.path).should_receive('exists').with_args('/dev/log').and_return(True) syslog_handler = logging.handlers.SysLogHandler() flexmock(module.logging.handlers).should_receive('SysLogHandler').with_args( - address='/dev/log' + address='/dev/log', ).and_return(syslog_handler).once() module.configure_logging(logging.INFO, syslog_log_level=logging.DEBUG) @@ -477,13 +478,14 @@ def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_macos( flexmock(module).should_receive('interactive_console').and_return(False) flexmock(module).should_receive('flush_delayed_logging') flexmock(module.logging).should_receive('basicConfig').with_args( - level=logging.DEBUG, handlers=list + level=logging.DEBUG, + handlers=list, ) flexmock(module.os.path).should_receive('exists').with_args('/dev/log').and_return(False) flexmock(module.os.path).should_receive('exists').with_args('/var/run/syslog').and_return(True) syslog_handler = logging.handlers.SysLogHandler() flexmock(module.logging.handlers).should_receive('SysLogHandler').with_args( - address='/var/run/syslog' + address='/var/run/syslog', ).and_return(syslog_handler).once() module.configure_logging(logging.INFO, syslog_log_level=logging.DEBUG) @@ -500,14 +502,15 @@ def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_freebs flexmock(module).should_receive('interactive_console').and_return(False) flexmock(module).should_receive('flush_delayed_logging') flexmock(module.logging).should_receive('basicConfig').with_args( - level=logging.DEBUG, handlers=list + level=logging.DEBUG, + handlers=list, ) flexmock(module.os.path).should_receive('exists').with_args('/dev/log').and_return(False) flexmock(module.os.path).should_receive('exists').with_args('/var/run/syslog').and_return(False) flexmock(module.os.path).should_receive('exists').with_args('/var/run/log').and_return(True) syslog_handler = logging.handlers.SysLogHandler() flexmock(module.logging.handlers).should_receive('SysLogHandler').with_args( - address='/var/run/log' + address='/var/run/log', ).and_return(syslog_handler).once() module.configure_logging(logging.INFO, syslog_log_level=logging.DEBUG) @@ -523,7 +526,8 @@ def test_configure_logging_without_syslog_log_level_skips_syslog(): flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler) flexmock(module).should_receive('flush_delayed_logging') flexmock(module.logging).should_receive('basicConfig').with_args( - level=logging.INFO, handlers=list + level=logging.INFO, + handlers=list, ) flexmock(module.os.path).should_receive('exists').never() flexmock(module.logging.handlers).should_receive('SysLogHandler').never() @@ -541,7 +545,8 @@ def test_configure_logging_skips_syslog_if_not_found(): flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler) flexmock(module).should_receive('flush_delayed_logging') flexmock(module.logging).should_receive('basicConfig').with_args( - level=logging.INFO, handlers=list + level=logging.INFO, + handlers=list, ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.logging.handlers).should_receive('SysLogHandler').never() @@ -560,14 +565,17 @@ def test_configure_logging_skips_log_file_if_log_file_logging_is_disabled(): flexmock(module).should_receive('flush_delayed_logging') flexmock(module.logging).should_receive('basicConfig').with_args( - level=logging.INFO, handlers=list + level=logging.INFO, + handlers=list, ) flexmock(module.os.path).should_receive('exists').never() flexmock(module.logging.handlers).should_receive('SysLogHandler').never() flexmock(module.logging.handlers).should_receive('WatchedFileHandler').never() module.configure_logging( - console_log_level=logging.INFO, log_file_log_level=logging.DISABLED, log_file='/tmp/logfile' + console_log_level=logging.INFO, + log_file_log_level=logging.DISABLED, + log_file='/tmp/logfile', ) @@ -582,13 +590,14 @@ def test_configure_logging_to_log_file_instead_of_syslog(): flexmock(module).should_receive('flush_delayed_logging') flexmock(module.logging).should_receive('basicConfig').with_args( - level=logging.DEBUG, handlers=list + level=logging.DEBUG, + handlers=list, ) flexmock(module.os.path).should_receive('exists').never() flexmock(module.logging.handlers).should_receive('SysLogHandler').never() file_handler = logging.handlers.WatchedFileHandler('/tmp/logfile') flexmock(module.logging.handlers).should_receive('WatchedFileHandler').with_args( - '/tmp/logfile' + '/tmp/logfile', ).and_return(file_handler).once() module.configure_logging( @@ -610,16 +619,17 @@ def test_configure_logging_to_both_log_file_and_syslog(): flexmock(module).should_receive('flush_delayed_logging') flexmock(module.logging).should_receive('basicConfig').with_args( - level=logging.DEBUG, handlers=list + level=logging.DEBUG, + handlers=list, ) flexmock(module.os.path).should_receive('exists').with_args('/dev/log').and_return(True) syslog_handler = logging.handlers.SysLogHandler() flexmock(module.logging.handlers).should_receive('SysLogHandler').with_args( - address='/dev/log' + address='/dev/log', ).and_return(syslog_handler).once() file_handler = logging.handlers.WatchedFileHandler('/tmp/logfile') flexmock(module.logging.handlers).should_receive('WatchedFileHandler').with_args( - '/tmp/logfile' + '/tmp/logfile', ).and_return(file_handler).once() module.configure_logging( @@ -634,7 +644,7 @@ def test_configure_logging_to_log_file_formats_with_custom_log_format(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.ANSWER flexmock(module).should_receive('Log_prefix_formatter').with_args( - '{message}', # noqa: FS003 + '{message}', ).once() fake_formatter = flexmock() flexmock(module).should_receive('Console_color_formatter').and_return(fake_formatter) @@ -645,20 +655,21 @@ def test_configure_logging_to_log_file_formats_with_custom_log_format(): flexmock(module).should_receive('interactive_console').and_return(False) flexmock(module).should_receive('flush_delayed_logging') flexmock(module.logging).should_receive('basicConfig').with_args( - level=logging.DEBUG, handlers=list + level=logging.DEBUG, + handlers=list, ) flexmock(module.os.path).should_receive('exists').with_args('/dev/log').and_return(True) flexmock(module.logging.handlers).should_receive('SysLogHandler').never() file_handler = logging.handlers.WatchedFileHandler('/tmp/logfile') flexmock(module.logging.handlers).should_receive('WatchedFileHandler').with_args( - '/tmp/logfile' + '/tmp/logfile', ).and_return(file_handler).once() module.configure_logging( console_log_level=logging.INFO, log_file_log_level=logging.DEBUG, log_file='/tmp/logfile', - log_file_format='{message}', # noqa: FS003 + log_file_format='{message}', ) @@ -673,7 +684,8 @@ def test_configure_logging_skips_log_file_if_argument_is_none(): flexmock(module).should_receive('flush_delayed_logging') flexmock(module.logging).should_receive('basicConfig').with_args( - level=logging.INFO, handlers=list + level=logging.INFO, + handlers=list, ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.logging.handlers).should_receive('WatchedFileHandler').never() @@ -693,7 +705,8 @@ def test_configure_logging_uses_console_no_color_formatter_if_color_disabled(): flexmock(module).should_receive('flush_delayed_logging') flexmock(module.logging).should_receive('basicConfig').with_args( - level=logging.INFO, handlers=list + level=logging.INFO, + handlers=list, ) flexmock(module.os.path).should_receive('exists').and_return(False) flexmock(module.logging.handlers).should_receive('WatchedFileHandler').never() diff --git a/tests/unit/test_signals.py b/tests/unit/test_signals.py index 57ee14ab..3beab77c 100644 --- a/tests/unit/test_signals.py +++ b/tests/unit/test_signals.py @@ -29,7 +29,7 @@ def test_handle_signal_exits_on_sigterm(): flexmock(module.os).should_receive('getpgrp').and_return(flexmock()) flexmock(module.os).should_receive('killpg') flexmock(module.sys).should_receive('exit').with_args( - module.EXIT_CODE_FROM_SIGNAL + signal_number + module.EXIT_CODE_FROM_SIGNAL + signal_number, ).once() module.handle_signal(signal_number, frame) diff --git a/tox.ini b/tox.ini index 6e3f4f05..65d24d64 100644 --- a/tox.ini +++ b/tox.ini @@ -1,34 +1,30 @@ [tox] env_list = py39,py310,py311,py312,py313 -skip_missing_interpreters = True +skip_missing_interpreters = true package = editable min_version = 4.0 [testenv] deps = -r test_requirements.txt -whitelist_externals = +allowlist_externals = find sh + ruff passenv = COVERAGE_FILE commands = pytest {posargs} - black --check . - isort --check-only . - flake8 borgmatic tests + ruff check + ruff format --check codespell -[testenv:black] -commands = - black {posargs} . - [testenv:test] commands = pytest {posargs} [testenv:end-to-end] package = editable -system_site_packages = True +system_site_packages = true deps = -r test_requirements.txt . @@ -36,19 +32,19 @@ pass_env = COVERAGE_FILE commands = pytest {posargs} --no-cov tests/end-to-end -[testenv:isort] -deps = {[testenv]deps} +[testenv:lint] +deps = [] +skip_install = true commands = - isort . + ruff check --diff {posargs} -[testenv:codespell] +[testenv:format] +deps = [] +skip_install = true +commands = + ruff format {posargs} + +[testenv:spell] deps = {[testenv]deps} commands = codespell --write-changes - -[flake8] -max-line-length = 100 -extend-ignore = E203,E501,W503 -exclude = *.*/* -multiline-quotes = ''' -docstring-quotes = '''