From 457ed807440106db1dbc8cde227648a055c28a58 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Thu, 30 Jun 2022 13:42:17 -0700 Subject: [PATCH] Fix environment variable plumbing so options in one configuration file aren't used for others (#555). --- NEWS | 2 + borgmatic/borg/borg.py | 6 +- borgmatic/borg/check.py | 14 ++- borgmatic/borg/compact.py | 8 +- borgmatic/borg/create.py | 6 +- borgmatic/borg/environment.py | 23 +++-- borgmatic/borg/export_tar.py | 2 + borgmatic/borg/extract.py | 29 ++++-- borgmatic/borg/info.py | 2 + borgmatic/borg/init.py | 9 +- borgmatic/borg/list.py | 12 ++- borgmatic/borg/mount.py | 12 ++- borgmatic/borg/prune.py | 8 +- borgmatic/borg/version.py | 12 ++- borgmatic/commands/borgmatic.py | 6 +- tests/integration/config/test_generate.py | 2 +- tests/unit/borg/test_borg.py | 49 +++++++-- tests/unit/borg/test_check.py | 15 ++- tests/unit/borg/test_compact.py | 6 +- tests/unit/borg/test_create.py | 120 ++++++++++++++++++++++ tests/unit/borg/test_environment.py | 86 ++++------------ tests/unit/borg/test_export_tar.py | 2 + tests/unit/borg/test_extract.py | 31 ++++-- tests/unit/borg/test_info.py | 50 +++++++-- tests/unit/borg/test_init.py | 7 +- tests/unit/borg/test_list.py | 55 ++++++++-- tests/unit/borg/test_mount.py | 5 +- tests/unit/borg/test_prune.py | 6 +- tests/unit/borg/test_version.py | 18 ++-- tests/unit/commands/test_borgmatic.py | 17 --- 30 files changed, 454 insertions(+), 166 deletions(-) diff --git a/NEWS b/NEWS index 58df9bb..a08df7c 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ the first few lines. * #554: Fix all monitoring hooks to warn if the server returns an HTTP 4xx error. This can happen with Healthchecks, for instance, when using an invalid ping URL. + * #555: Fix environment variable plumbing so options like "encryption_passphrase" and + "encryption_passcommand" in one configuration file aren't used for other configuration files. 1.6.4 * #546, #382: Keep your repository passphrases and database passwords outside of borgmatic's diff --git a/borgmatic/borg/borg.py b/borgmatic/borg/borg.py index d40bb92..24a8864 100644 --- a/borgmatic/borg/borg.py +++ b/borgmatic/borg/borg.py @@ -1,5 +1,6 @@ import logging +from borgmatic.borg import environment from borgmatic.borg.flags import make_flags from borgmatic.execute import execute_command @@ -51,5 +52,8 @@ def run_arbitrary_borg( ) return execute_command( - full_command, output_log_level=logging.WARNING, borg_local_path=local_path, + full_command, + output_log_level=logging.WARNING, + borg_local_path=local_path, + extra_environment=environment.make_environment(storage_config), ) diff --git a/borgmatic/borg/check.py b/borgmatic/borg/check.py index 0657b2a..83c3eea 100644 --- a/borgmatic/borg/check.py +++ b/borgmatic/borg/check.py @@ -5,7 +5,7 @@ import logging import os import pathlib -from borgmatic.borg import extract, info, state +from borgmatic.borg import environment, extract, info, state from borgmatic.execute import DO_NOT_CAPTURE, execute_command DEFAULT_CHECKS = ( @@ -304,16 +304,22 @@ def check_archives( + (repository,) ) + borg_environment = environment.make_environment(storage_config) + # The Borg repair option triggers an interactive prompt, which won't work when output is # captured. And progress messes with the terminal directly. if repair or progress: - execute_command(full_command, output_file=DO_NOT_CAPTURE) + execute_command( + full_command, output_file=DO_NOT_CAPTURE, extra_environment=borg_environment + ) else: - execute_command(full_command) + execute_command(full_command, extra_environment=borg_environment) for check in checks: write_check_time(make_check_time_path(location_config, borg_repository_id, check)) if 'extract' in checks: - extract.extract_last_archive_dry_run(repository, lock_wait, local_path, remote_path) + extract.extract_last_archive_dry_run( + storage_config, repository, lock_wait, local_path, remote_path + ) write_check_time(make_check_time_path(location_config, borg_repository_id, 'extract')) diff --git a/borgmatic/borg/compact.py b/borgmatic/borg/compact.py index 42871d3..17f0f1a 100644 --- a/borgmatic/borg/compact.py +++ b/borgmatic/borg/compact.py @@ -1,5 +1,6 @@ import logging +from borgmatic.borg import environment from borgmatic.execute import execute_command logger = logging.getLogger(__name__) @@ -38,4 +39,9 @@ def compact_segments( ) if not dry_run: - execute_command(full_command, output_log_level=logging.INFO, borg_local_path=local_path) + execute_command( + full_command, + output_log_level=logging.INFO, + borg_local_path=local_path, + extra_environment=environment.make_environment(storage_config), + ) diff --git a/borgmatic/borg/create.py b/borgmatic/borg/create.py index 196ff74..1a7ae40 100644 --- a/borgmatic/borg/create.py +++ b/borgmatic/borg/create.py @@ -5,7 +5,7 @@ import os import pathlib import tempfile -from borgmatic.borg import feature, state +from borgmatic.borg import environment, feature, state from borgmatic.execute import DO_NOT_CAPTURE, execute_command, execute_command_with_processes logger = logging.getLogger(__name__) @@ -317,6 +317,8 @@ def create_archive( # the terminal directly. output_file = DO_NOT_CAPTURE if progress else None + borg_environment = environment.make_environment(storage_config) + if stream_processes: return execute_command_with_processes( full_command, @@ -325,6 +327,7 @@ def create_archive( output_file, borg_local_path=local_path, working_directory=working_directory, + extra_environment=borg_environment, ) return execute_command( @@ -333,4 +336,5 @@ def create_archive( output_file, borg_local_path=local_path, working_directory=working_directory, + extra_environment=borg_environment, ) diff --git a/borgmatic/borg/environment.py b/borgmatic/borg/environment.py index 490c07a..235c674 100644 --- a/borgmatic/borg/environment.py +++ b/borgmatic/borg/environment.py @@ -1,5 +1,3 @@ -import os - OPTION_TO_ENVIRONMENT_VARIABLE = { 'borg_base_directory': 'BORG_BASE_DIR', 'borg_config_directory': 'BORG_CONFIG_DIR', @@ -18,21 +16,24 @@ DEFAULT_BOOL_OPTION_TO_ENVIRONMENT_VARIABLE = { } -def initialize(storage_config): - for option_name, environment_variable_name in OPTION_TO_ENVIRONMENT_VARIABLE.items(): +def make_environment(storage_config): + ''' + Given a borgmatic storage configuration dict, return its options converted to a Borg environment + variable dict. + ''' + environment = {} - # Options from borgmatic configuration take precedence over already set BORG_* environment - # variables. - value = storage_config.get(option_name) or os.environ.get(environment_variable_name) + for option_name, environment_variable_name in OPTION_TO_ENVIRONMENT_VARIABLE.items(): + value = storage_config.get(option_name) if value: - os.environ[environment_variable_name] = value - else: - os.environ.pop(environment_variable_name, None) + environment[environment_variable_name] = value for ( option_name, environment_variable_name, ) in DEFAULT_BOOL_OPTION_TO_ENVIRONMENT_VARIABLE.items(): value = storage_config.get(option_name, False) - os.environ[environment_variable_name] = 'yes' if value else 'no' + environment[environment_variable_name] = 'yes' if value else 'no' + + return environment diff --git a/borgmatic/borg/export_tar.py b/borgmatic/borg/export_tar.py index f0470a9..5420928 100644 --- a/borgmatic/borg/export_tar.py +++ b/borgmatic/borg/export_tar.py @@ -1,6 +1,7 @@ import logging import os +from borgmatic.borg import environment from borgmatic.execute import DO_NOT_CAPTURE, execute_command logger = logging.getLogger(__name__) @@ -61,4 +62,5 @@ def export_tar_archive( output_file=DO_NOT_CAPTURE if destination_path == '-' else None, output_log_level=output_log_level, borg_local_path=local_path, + extra_environment=environment.make_environment(storage_config), ) diff --git a/borgmatic/borg/extract.py b/borgmatic/borg/extract.py index 2621fb8..9bbc2d7 100644 --- a/borgmatic/borg/extract.py +++ b/borgmatic/borg/extract.py @@ -2,13 +2,15 @@ import logging import os import subprocess -from borgmatic.borg import feature +from borgmatic.borg import environment, feature from borgmatic.execute import DO_NOT_CAPTURE, execute_command logger = logging.getLogger(__name__) -def extract_last_archive_dry_run(repository, lock_wait=None, local_path='borg', remote_path=None): +def extract_last_archive_dry_run( + storage_config, repository, lock_wait=None, local_path='borg', remote_path=None +): ''' Perform an extraction dry-run of the most recent archive. If there are no archives, skip the dry-run. @@ -29,8 +31,13 @@ def extract_last_archive_dry_run(repository, lock_wait=None, local_path='borg', + (repository,) ) + borg_environment = environment.make_environment(storage_config) + list_output = execute_command( - full_list_command, output_log_level=None, borg_local_path=local_path + full_list_command, + output_log_level=None, + borg_local_path=local_path, + extra_environment=borg_environment, ) try: @@ -52,7 +59,9 @@ def extract_last_archive_dry_run(repository, lock_wait=None, local_path='borg', ) ) - execute_command(full_extract_command, working_directory=None) + execute_command( + full_extract_command, working_directory=None, extra_environment=borg_environment + ) def extract_archive( @@ -106,11 +115,16 @@ def extract_archive( + (tuple(paths) if paths else ()) ) + borg_environment = environment.make_environment(storage_config) + # The progress output isn't compatible with captured and logged output, as progress messes with # the terminal directly. if progress: return execute_command( - full_command, output_file=DO_NOT_CAPTURE, working_directory=destination_path + full_command, + output_file=DO_NOT_CAPTURE, + working_directory=destination_path, + extra_environment=borg_environment, ) return None @@ -120,8 +134,11 @@ def extract_archive( output_file=subprocess.PIPE, working_directory=destination_path, run_to_completion=False, + extra_environment=borg_environment, ) # Don't give Borg local path, so as to error on warnings, as Borg only gives a warning if the # restore paths don't exist in the archive! - execute_command(full_command, working_directory=destination_path) + execute_command( + full_command, working_directory=destination_path, extra_environment=borg_environment + ) diff --git a/borgmatic/borg/info.py b/borgmatic/borg/info.py index 62676a4..6e783e8 100644 --- a/borgmatic/borg/info.py +++ b/borgmatic/borg/info.py @@ -1,5 +1,6 @@ import logging +from borgmatic.borg import environment from borgmatic.borg.flags import make_flags, make_flags_from_arguments from borgmatic.execute import execute_command @@ -42,4 +43,5 @@ def display_archives_info( full_command, output_log_level=None if info_arguments.json else logging.WARNING, borg_local_path=local_path, + extra_environment=environment.make_environment(storage_config), ) diff --git a/borgmatic/borg/init.py b/borgmatic/borg/init.py index 861b95a..9329bc1 100644 --- a/borgmatic/borg/init.py +++ b/borgmatic/borg/init.py @@ -2,7 +2,7 @@ import argparse import logging import subprocess -from borgmatic.borg import info +from borgmatic.borg import environment, info from borgmatic.execute import DO_NOT_CAPTURE, execute_command logger = logging.getLogger(__name__) @@ -54,4 +54,9 @@ def initialize_repository( ) # Do not capture output here, so as to support interactive prompts. - execute_command(init_command, output_file=DO_NOT_CAPTURE, borg_local_path=local_path) + execute_command( + init_command, + output_file=DO_NOT_CAPTURE, + borg_local_path=local_path, + extra_environment=environment.make_environment(storage_config), + ) diff --git a/borgmatic/borg/list.py b/borgmatic/borg/list.py index c1061e3..1d897ec 100644 --- a/borgmatic/borg/list.py +++ b/borgmatic/borg/list.py @@ -2,6 +2,7 @@ import copy import logging import re +from borgmatic.borg import environment from borgmatic.borg.flags import make_flags, make_flags_from_arguments from borgmatic.execute import execute_command @@ -31,7 +32,12 @@ def resolve_archive_name(repository, archive, storage_config, local_path='borg', + ('--short', repository) ) - output = execute_command(full_command, output_log_level=None, borg_local_path=local_path) + output = execute_command( + full_command, + output_log_level=None, + borg_local_path=local_path, + extra_environment=environment.make_environment(storage_config), + ) try: latest_archive = output.strip().splitlines()[-1] except IndexError: @@ -111,6 +117,8 @@ def list_archives(repository, storage_config, list_arguments, local_path='borg', archive. Or, if list_arguments.find_paths are given, list the files by searching across multiple archives. ''' + borg_environment = environment.make_environment(storage_config) + # If there are any paths to find (and there's not a single archive already selected), start by # getting a list of archives to search. if list_arguments.find_paths and not list_arguments.archive: @@ -127,6 +135,7 @@ def list_archives(repository, storage_config, list_arguments, local_path='borg', ), output_log_level=None, borg_local_path=local_path, + extra_environment=borg_environment, ) .strip('\n') .split('\n') @@ -154,6 +163,7 @@ def list_archives(repository, storage_config, list_arguments, local_path='borg', main_command, output_log_level=None if list_arguments.json else logging.WARNING, borg_local_path=local_path, + extra_environment=borg_environment, ) if list_arguments.json: diff --git a/borgmatic/borg/mount.py b/borgmatic/borg/mount.py index e9419cc..4f5db81 100644 --- a/borgmatic/borg/mount.py +++ b/borgmatic/borg/mount.py @@ -1,5 +1,6 @@ import logging +from borgmatic.borg import environment from borgmatic.execute import DO_NOT_CAPTURE, execute_command logger = logging.getLogger(__name__) @@ -38,9 +39,16 @@ def mount_archive( + (tuple(paths) if paths else ()) ) + borg_environment = environment.make_environment(storage_config) + # Don't capture the output when foreground mode is used so that ctrl-C can work properly. if foreground: - execute_command(full_command, output_file=DO_NOT_CAPTURE, borg_local_path=local_path) + execute_command( + full_command, + output_file=DO_NOT_CAPTURE, + borg_local_path=local_path, + extra_environment=borg_environment, + ) return - execute_command(full_command, borg_local_path=local_path) + execute_command(full_command, borg_local_path=local_path, extra_environment=borg_environment) diff --git a/borgmatic/borg/prune.py b/borgmatic/borg/prune.py index 9770a1f..9b2f2b4 100644 --- a/borgmatic/borg/prune.py +++ b/borgmatic/borg/prune.py @@ -1,5 +1,6 @@ import logging +from borgmatic.borg import environment from borgmatic.execute import execute_command logger = logging.getLogger(__name__) @@ -72,4 +73,9 @@ def prune_archives( else: output_log_level = logging.INFO - execute_command(full_command, output_log_level=output_log_level, borg_local_path=local_path) + execute_command( + full_command, + output_log_level=output_log_level, + borg_local_path=local_path, + extra_environment=environment.make_environment(storage_config), + ) diff --git a/borgmatic/borg/version.py b/borgmatic/borg/version.py index 4ccab9b..61766e4 100644 --- a/borgmatic/borg/version.py +++ b/borgmatic/borg/version.py @@ -1,13 +1,14 @@ import logging +from borgmatic.borg import environment from borgmatic.execute import execute_command logger = logging.getLogger(__name__) -def local_borg_version(local_path='borg'): +def local_borg_version(storage_config, local_path='borg'): ''' - Given a local Borg binary path, return a version string for it. + Given a storage configuration dict and a local Borg binary path, return a version string for it. Raise OSError or CalledProcessError if there is a problem running Borg. Raise ValueError if the version cannot be parsed. @@ -17,7 +18,12 @@ def local_borg_version(local_path='borg'): + (('--info',) if logger.getEffectiveLevel() == logging.INFO else ()) + (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ()) ) - output = execute_command(full_command, output_log_level=None, borg_local_path=local_path) + output = execute_command( + full_command, + output_log_level=None, + borg_local_path=local_path, + extra_environment=environment.make_environment(storage_config), + ) try: return output.split(' ')[1].strip() diff --git a/borgmatic/commands/borgmatic.py b/borgmatic/commands/borgmatic.py index c3c7df6..1ec250f 100644 --- a/borgmatic/commands/borgmatic.py +++ b/borgmatic/commands/borgmatic.py @@ -16,7 +16,6 @@ from borgmatic.borg import borg as borg_borg from borgmatic.borg import check as borg_check from borgmatic.borg import compact as borg_compact from borgmatic.borg import create as borg_create -from borgmatic.borg import environment as borg_environment from borgmatic.borg import export_tar as borg_export_tar from borgmatic.borg import extract as borg_extract from borgmatic.borg import feature as borg_feature @@ -60,14 +59,13 @@ def run_configuration(config_filename, config, arguments): remote_path = location.get('remote_path') retries = storage.get('retries', 0) retry_wait = storage.get('retry_wait', 0) - borg_environment.initialize(storage) encountered_error = None error_repository = '' using_primary_action = {'prune', 'compact', 'create', 'check'}.intersection(arguments) monitoring_log_level = verbosity_to_log_level(global_arguments.monitoring_verbosity) try: - local_borg_version = borg_version.local_borg_version(local_path) + local_borg_version = borg_version.local_borg_version(storage, local_path) except (OSError, CalledProcessError, ValueError) as error: yield from log_error_records( '{}: Error getting local Borg version'.format(config_filename), error @@ -835,7 +833,7 @@ def collect_configuration_run_summary_logs(configs, arguments): logger.info('Unmounting mount point {}'.format(arguments['umount'].mount_point)) try: borg_umount.unmount_archive( - mount_point=arguments['umount'].mount_point, local_path=get_local_path(configs) + mount_point=arguments['umount'].mount_point, local_path=get_local_path(configs), ) except (CalledProcessError, OSError) as error: yield from log_error_records('Error unmounting mount point', error) diff --git a/tests/integration/config/test_generate.py b/tests/integration/config/test_generate.py index 1b030a5..637bb77 100644 --- a/tests/integration/config/test_generate.py +++ b/tests/integration/config/test_generate.py @@ -113,7 +113,7 @@ def test_write_configuration_with_already_existing_file_raises(): def test_write_configuration_with_already_existing_file_and_overwrite_does_not_raise(): flexmock(os.path).should_receive('exists').and_return(True) - module.write_configuration('config.yaml', 'config: yaml', overwrite=True) + module.write_configuration('/tmp/config.yaml', 'config: yaml', overwrite=True) def test_write_configuration_with_already_existing_directory_does_not_raise(): diff --git a/tests/unit/borg/test_borg.py b/tests/unit/borg/test_borg.py index 6cec02c..8282bd5 100644 --- a/tests/unit/borg/test_borg.py +++ b/tests/unit/borg/test_borg.py @@ -8,8 +8,12 @@ from ..test_verbosity import insert_logging_mock def test_run_arbitrary_borg_calls_borg_with_parameters(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'break-lock', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg' + ('borg', 'break-lock', 'repo'), + output_log_level=logging.WARNING, + borg_local_path='borg', + extra_environment=None, ) module.run_arbitrary_borg( @@ -18,10 +22,12 @@ def test_run_arbitrary_borg_calls_borg_with_parameters(): def test_run_arbitrary_borg_with_log_info_calls_borg_with_info_parameter(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'break-lock', 'repo', '--info'), output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ) insert_logging_mock(logging.INFO) @@ -31,10 +37,12 @@ def test_run_arbitrary_borg_with_log_info_calls_borg_with_info_parameter(): def test_run_arbitrary_borg_with_log_debug_calls_borg_with_debug_parameter(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'break-lock', 'repo', '--debug', '--show-rc'), output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ) insert_logging_mock(logging.DEBUG) @@ -45,10 +53,12 @@ def test_run_arbitrary_borg_with_log_debug_calls_borg_with_debug_parameter(): def test_run_arbitrary_borg_with_lock_wait_calls_borg_with_lock_wait_parameters(): storage_config = {'lock_wait': 5} + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'break-lock', 'repo', '--lock-wait', '5'), output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ) module.run_arbitrary_borg( @@ -58,10 +68,12 @@ def test_run_arbitrary_borg_with_lock_wait_calls_borg_with_lock_wait_parameters( def test_run_arbitrary_borg_with_archive_calls_borg_with_archive_parameter(): storage_config = {} + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'break-lock', 'repo::archive'), output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ) module.run_arbitrary_borg( @@ -70,8 +82,12 @@ def test_run_arbitrary_borg_with_archive_calls_borg_with_archive_parameter(): def test_run_arbitrary_borg_with_local_path_calls_borg_via_local_path(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg1', 'break-lock', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg1' + ('borg1', 'break-lock', 'repo'), + output_log_level=logging.WARNING, + borg_local_path='borg1', + extra_environment=None, ) module.run_arbitrary_borg( @@ -80,10 +96,12 @@ def test_run_arbitrary_borg_with_local_path_calls_borg_via_local_path(): def test_run_arbitrary_borg_with_remote_path_calls_borg_with_remote_path_parameters(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'break-lock', 'repo', '--remote-path', 'borg1'), output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ) module.run_arbitrary_borg( @@ -92,10 +110,12 @@ def test_run_arbitrary_borg_with_remote_path_calls_borg_with_remote_path_paramet def test_run_arbitrary_borg_passes_borg_specific_parameters_to_borg(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', 'repo', '--progress'), output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ) module.run_arbitrary_borg( @@ -104,8 +124,12 @@ def test_run_arbitrary_borg_passes_borg_specific_parameters_to_borg(): def test_run_arbitrary_borg_omits_dash_dash_in_parameters_passed_to_borg(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'break-lock', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg', + ('borg', 'break-lock', 'repo'), + output_log_level=logging.WARNING, + borg_local_path='borg', + extra_environment=None, ) module.run_arbitrary_borg( @@ -114,8 +138,9 @@ def test_run_arbitrary_borg_omits_dash_dash_in_parameters_passed_to_borg(): def test_run_arbitrary_borg_without_borg_specific_parameters_does_not_raise(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg',), output_log_level=logging.WARNING, borg_local_path='borg', + ('borg',), output_log_level=logging.WARNING, borg_local_path='borg', extra_environment=None, ) module.run_arbitrary_borg( @@ -124,8 +149,12 @@ def test_run_arbitrary_borg_without_borg_specific_parameters_does_not_raise(): def test_run_arbitrary_borg_passes_key_sub_command_to_borg_before_repository(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'key', 'export', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg', + ('borg', 'key', 'export', 'repo'), + output_log_level=logging.WARNING, + borg_local_path='borg', + extra_environment=None, ) module.run_arbitrary_borg( @@ -134,10 +163,12 @@ def test_run_arbitrary_borg_passes_key_sub_command_to_borg_before_repository(): def test_run_arbitrary_borg_passes_debug_sub_command_to_borg_before_repository(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'debug', 'dump-manifest', 'repo', 'path'), output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ) module.run_arbitrary_borg( @@ -146,8 +177,12 @@ def test_run_arbitrary_borg_passes_debug_sub_command_to_borg_before_repository() def test_run_arbitrary_borg_with_debug_info_command_does_not_pass_borg_repository(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'debug', 'info'), output_log_level=logging.WARNING, borg_local_path='borg', + ('borg', 'debug', 'info'), + output_log_level=logging.WARNING, + borg_local_path='borg', + extra_environment=None, ) module.run_arbitrary_borg( @@ -156,10 +191,12 @@ def test_run_arbitrary_borg_with_debug_info_command_does_not_pass_borg_repositor def test_run_arbitrary_borg_with_debug_convert_profile_command_does_not_pass_borg_repository(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'debug', 'convert-profile', 'in', 'out'), output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ) module.run_arbitrary_borg( diff --git a/tests/unit/borg/test_check.py b/tests/unit/borg/test_check.py index 6cd84b1..0b4c0ce 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): - flexmock(module).should_receive('execute_command').with_args(command).once() + flexmock(module.environment).should_receive('make_environment') + flexmock(module).should_receive('execute_command').with_args( + command, extra_environment=None + ).once() def insert_execute_command_never(): @@ -310,8 +313,11 @@ def test_check_archives_with_progress_calls_borg_with_progress_parameter(): ) flexmock(module).should_receive('make_check_flags').and_return(()) flexmock(module).should_receive('execute_command').never() + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'check', '--progress', 'repo'), output_file=module.DO_NOT_CAPTURE + ('borg', 'check', '--progress', 'repo'), + output_file=module.DO_NOT_CAPTURE, + extra_environment=None, ).once() flexmock(module).should_receive('make_check_time_path') flexmock(module).should_receive('write_check_time') @@ -335,8 +341,11 @@ def test_check_archives_with_repair_calls_borg_with_repair_parameter(): ) flexmock(module).should_receive('make_check_flags').and_return(()) flexmock(module).should_receive('execute_command').never() + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'check', '--repair', 'repo'), output_file=module.DO_NOT_CAPTURE + ('borg', 'check', '--repair', 'repo'), + output_file=module.DO_NOT_CAPTURE, + extra_environment=None, ).once() flexmock(module).should_receive('make_check_time_path') flexmock(module).should_receive('write_check_time') diff --git a/tests/unit/borg/test_compact.py b/tests/unit/borg/test_compact.py index 4ab0cfc..4c2abb7 100644 --- a/tests/unit/borg/test_compact.py +++ b/tests/unit/borg/test_compact.py @@ -8,8 +8,12 @@ from ..test_verbosity import insert_logging_mock def insert_execute_command_mock(compact_command, output_log_level): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - compact_command, output_log_level=output_log_level, borg_local_path=compact_command[0] + compact_command, + output_log_level=output_log_level, + borg_local_path=compact_command[0], + extra_environment=None, ).once() diff --git a/tests/unit/borg/test_create.py b/tests/unit/borg/test_create.py index 0f680f3..c51bd34 100644 --- a/tests/unit/borg/test_create.py +++ b/tests/unit/borg/test_create.py @@ -292,12 +292,50 @@ def test_create_archive_calls_borg_with_parameters(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, + ) + + module.create_archive( + dry_run=False, + repository='repo', + location_config={ + 'source_directories': ['foo', 'bar'], + 'repositories': ['repo'], + 'exclude_patterns': None, + }, + storage_config={}, + local_borg_version='1.2.3', + ) + + +def test_create_archive_calls_borg_with_environment(): + flexmock(module).should_receive('borgmatic_source_directories').and_return([]) + flexmock(module).should_receive('deduplicate_directories').and_return(('foo', 'bar')) + flexmock(module).should_receive('map_directories_to_devices').and_return({}) + flexmock(module).should_receive('expand_directories').and_return(()) + flexmock(module.os.path).should_receive('expanduser').and_raise(TypeError) + flexmock(module).should_receive('expand_home_directories').and_return(()) + flexmock(module).should_receive('write_pattern_file').and_return(None) + flexmock(module.feature).should_receive('available').and_return(True) + flexmock(module).should_receive('ensure_files_readable') + flexmock(module).should_receive('make_pattern_flags').and_return(()) + flexmock(module).should_receive('make_exclude_flags').and_return(()) + environment = {'BORG_THINGY': 'YUP'} + flexmock(module.environment).should_receive('make_environment').and_return(environment) + flexmock(module).should_receive('execute_command').with_args( + ('borg', 'create') + ARCHIVE_WITH_PATHS, + output_log_level=logging.INFO, + output_file=None, + borg_local_path='borg', + working_directory=None, + extra_environment=environment, ) module.create_archive( @@ -328,12 +366,14 @@ def test_create_archive_with_patterns_calls_borg_with_patterns(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(pattern_flags) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create') + pattern_flags + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -364,12 +404,14 @@ def test_create_archive_with_exclude_patterns_calls_borg_with_excludes(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(exclude_flags) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create') + exclude_flags + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -397,12 +439,14 @@ def test_create_archive_with_log_info_calls_borg_with_info_parameter(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--info') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) insert_logging_mock(logging.INFO) @@ -431,12 +475,14 @@ def test_create_archive_with_log_info_and_json_suppresses_most_borg_output(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--json') + ARCHIVE_WITH_PATHS, output_log_level=None, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) insert_logging_mock(logging.INFO) @@ -466,12 +512,14 @@ def test_create_archive_with_log_debug_calls_borg_with_debug_parameter(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--debug', '--show-rc') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) insert_logging_mock(logging.DEBUG) @@ -500,12 +548,14 @@ def test_create_archive_with_log_debug_and_json_suppresses_most_borg_output(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--json') + ARCHIVE_WITH_PATHS, output_log_level=None, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) insert_logging_mock(logging.DEBUG) @@ -535,12 +585,14 @@ def test_create_archive_with_dry_run_calls_borg_with_dry_run_parameter(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--dry-run') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -570,12 +622,14 @@ def test_create_archive_with_stats_and_dry_run_calls_borg_without_stats_paramete flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--info', '--dry-run') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) insert_logging_mock(logging.INFO) @@ -605,12 +659,14 @@ def test_create_archive_with_checkpoint_interval_calls_borg_with_checkpoint_inte flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--checkpoint-interval', '600') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -638,12 +694,14 @@ def test_create_archive_with_chunker_params_calls_borg_with_chunker_params_param flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--chunker-params', '1,2,3,4') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -671,12 +729,14 @@ def test_create_archive_with_compression_calls_borg_with_compression_parameters( flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--compression', 'rle') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -709,12 +769,14 @@ def test_create_archive_with_remote_rate_limit_calls_borg_with_upload_ratelimit_ flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', option_flag, '100') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -744,12 +806,14 @@ def test_create_archive_with_working_directory_calls_borg_with_working_directory flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory='/working/dir', + extra_environment=None, ) module.create_archive( @@ -778,12 +842,14 @@ def test_create_archive_with_one_file_system_calls_borg_with_one_file_system_par flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--one-file-system') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -817,12 +883,14 @@ def test_create_archive_with_numeric_owner_calls_borg_with_numeric_ids_parameter flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', option_flag) + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -851,12 +919,14 @@ def test_create_archive_with_read_special_calls_borg_with_read_special_parameter flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--read-special') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -892,12 +962,14 @@ def test_create_archive_with_basic_option_calls_borg_with_corresponding_paramete flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -937,12 +1009,14 @@ def test_create_archive_with_atime_option_calls_borg_with_corresponding_paramete flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -982,12 +1056,14 @@ def test_create_archive_with_bsd_flags_option_calls_borg_with_corresponding_para flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1016,12 +1092,14 @@ def test_create_archive_with_files_cache_calls_borg_with_files_cache_parameters( flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--files-cache', 'ctime,size') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1050,12 +1128,14 @@ def test_create_archive_with_local_path_calls_borg_via_local_path(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg1', 'create') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg1', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1084,12 +1164,14 @@ def test_create_archive_with_remote_path_calls_borg_with_remote_path_parameters( flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--remote-path', 'borg1') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1118,12 +1200,14 @@ def test_create_archive_with_umask_calls_borg_with_umask_parameters(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--umask', '740') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1151,12 +1235,14 @@ def test_create_archive_with_lock_wait_calls_borg_with_lock_wait_parameters(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--lock-wait', '5') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1184,12 +1270,14 @@ def test_create_archive_with_stats_calls_borg_with_stats_parameter_and_warning_o flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--stats') + ARCHIVE_WITH_PATHS, output_log_level=logging.WARNING, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1218,12 +1306,14 @@ def test_create_archive_with_stats_and_log_info_calls_borg_with_stats_parameter_ flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--info', '--stats') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) insert_logging_mock(logging.INFO) @@ -1253,12 +1343,14 @@ def test_create_archive_with_files_calls_borg_with_list_parameter_and_warning_ou flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--list', '--filter', 'AME-') + ARCHIVE_WITH_PATHS, output_log_level=logging.WARNING, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1287,12 +1379,14 @@ def test_create_archive_with_files_and_log_info_calls_borg_with_list_parameter_a flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--list', '--filter', 'AME-', '--info') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) insert_logging_mock(logging.INFO) @@ -1322,12 +1416,14 @@ def test_create_archive_with_progress_and_log_info_calls_borg_with_progress_para flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--info', '--progress') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=module.DO_NOT_CAPTURE, borg_local_path='borg', working_directory=None, + extra_environment=None, ) insert_logging_mock(logging.INFO) @@ -1357,12 +1453,14 @@ def test_create_archive_with_progress_calls_borg_with_progress_parameter(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--progress') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=module.DO_NOT_CAPTURE, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1392,6 +1490,7 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command_with_processes').with_args( ('borg', 'create', '--one-file-system', '--read-special', '--progress') + ARCHIVE_WITH_PATHS, @@ -1400,6 +1499,7 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr output_file=module.DO_NOT_CAPTURE, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1429,12 +1529,14 @@ def test_create_archive_with_json_calls_borg_with_json_parameter(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--json') + ARCHIVE_WITH_PATHS, output_log_level=None, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ).and_return('[]') json_output = module.create_archive( @@ -1465,12 +1567,14 @@ def test_create_archive_with_stats_and_json_calls_borg_without_stats_parameter() flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--json') + ARCHIVE_WITH_PATHS, output_log_level=None, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ).and_return('[]') json_output = module.create_archive( @@ -1502,12 +1606,14 @@ def test_create_archive_with_source_directories_glob_expands(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', 'repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo', 'food'), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) flexmock(module.glob).should_receive('glob').with_args('foo*').and_return(['foo', 'food']) @@ -1536,12 +1642,14 @@ def test_create_archive_with_non_matching_source_directories_glob_passes_through flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', 'repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo*'), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) flexmock(module.glob).should_receive('glob').with_args('foo*').and_return([]) @@ -1570,12 +1678,14 @@ def test_create_archive_with_glob_calls_borg_with_expanded_directories(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', 'repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo', 'food'), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1603,12 +1713,14 @@ def test_create_archive_with_archive_name_format_calls_borg_with_archive_name(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', 'repo::ARCHIVE_NAME', 'foo', 'bar'), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1636,12 +1748,14 @@ def test_create_archive_with_archive_name_format_accepts_borg_placeholders(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', 'repo::Documents_{hostname}-{now}', 'foo', 'bar'), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1669,12 +1783,14 @@ def test_create_archive_with_repository_accepts_borg_placeholders(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '{fqdn}::Documents_{hostname}-{now}', 'foo', 'bar'), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1702,12 +1818,14 @@ def test_create_archive_with_extra_borg_options_calls_borg_with_extra_options(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '--extra', '--options') + ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( @@ -1736,6 +1854,7 @@ def test_create_archive_with_stream_processes_calls_borg_with_processes(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command_with_processes').with_args( ('borg', 'create', '--one-file-system', '--read-special') + ARCHIVE_WITH_PATHS, processes=processes, @@ -1743,6 +1862,7 @@ def test_create_archive_with_stream_processes_calls_borg_with_processes(): output_file=None, borg_local_path='borg', working_directory=None, + extra_environment=None, ) module.create_archive( diff --git a/tests/unit/borg/test_environment.py b/tests/unit/borg/test_environment.py index 5a08e76..c5fce80 100644 --- a/tests/unit/borg/test_environment.py +++ b/tests/unit/borg/test_environment.py @@ -1,84 +1,34 @@ -import os - from borgmatic.borg import environment as module -def test_initialize_with_passcommand_should_set_environment(): - orig_environ = os.environ +def test_make_environment_with_passcommand_should_set_environment(): + environment = module.make_environment({'encryption_passcommand': 'command'}) - try: - os.environ = {} - module.initialize({'encryption_passcommand': 'command'}) - assert os.environ.get('BORG_PASSCOMMAND') == 'command' - finally: - os.environ = orig_environ + assert environment.get('BORG_PASSCOMMAND') == 'command' -def test_initialize_with_passphrase_should_set_environment(): - orig_environ = os.environ +def test_make_environment_with_passphrase_should_set_environment(): + environment = module.make_environment({'encryption_passphrase': 'pass'}) - try: - os.environ = {} - module.initialize({'encryption_passphrase': 'pass'}) - assert os.environ.get('BORG_PASSPHRASE') == 'pass' - finally: - os.environ = orig_environ + assert environment.get('BORG_PASSPHRASE') == 'pass' -def test_initialize_with_ssh_command_should_set_environment(): - orig_environ = os.environ +def test_make_environment_with_ssh_command_should_set_environment(): + environment = module.make_environment({'ssh_command': 'ssh -C'}) - try: - os.environ = {} - module.initialize({'ssh_command': 'ssh -C'}) - assert os.environ.get('BORG_RSH') == 'ssh -C' - finally: - os.environ = orig_environ + assert environment.get('BORG_RSH') == 'ssh -C' -def test_initialize_without_configuration_should_only_set_default_environment(): - orig_environ = os.environ +def test_make_environment_without_configuration_should_only_set_default_environment(): + environment = module.make_environment({}) - try: - os.environ = {} - module.initialize({}) - - assert {key: value for key, value in os.environ.items() if key.startswith('BORG_')} == { - 'BORG_RELOCATED_REPO_ACCESS_IS_OK': 'no', - 'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK': 'no', - } - finally: - os.environ = orig_environ + assert environment == { + 'BORG_RELOCATED_REPO_ACCESS_IS_OK': 'no', + 'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK': 'no', + } -def test_initialize_with_relocated_repo_access_should_override_default(): - orig_environ = os.environ +def test_make_environment_with_relocated_repo_access_should_override_default(): + environment = module.make_environment({'relocated_repo_access_is_ok': True}) - try: - os.environ = {} - module.initialize({'relocated_repo_access_is_ok': True}) - assert os.environ.get('BORG_RELOCATED_REPO_ACCESS_IS_OK') == 'yes' - finally: - os.environ = orig_environ - - -def test_initialize_prefers_configuration_option_over_borg_environment_variable(): - orig_environ = os.environ - - try: - os.environ = {'BORG_SSH': 'mosh'} - module.initialize({'ssh_command': 'ssh -C'}) - assert os.environ.get('BORG_RSH') == 'ssh -C' - finally: - os.environ = orig_environ - - -def test_initialize_passes_through_existing_borg_environment_variable(): - orig_environ = os.environ - - try: - os.environ = {'BORG_PASSPHRASE': 'pass'} - module.initialize({'ssh_command': 'ssh -C'}) - assert os.environ.get('BORG_PASSPHRASE') == 'pass' - finally: - os.environ = orig_environ + assert environment.get('BORG_RELOCATED_REPO_ACCESS_IS_OK') == 'yes' diff --git a/tests/unit/borg/test_export_tar.py b/tests/unit/borg/test_export_tar.py index 8a60b21..11b2b20 100644 --- a/tests/unit/borg/test_export_tar.py +++ b/tests/unit/borg/test_export_tar.py @@ -10,11 +10,13 @@ from ..test_verbosity import insert_logging_mock def insert_execute_command_mock( command, output_log_level=logging.INFO, borg_local_path='borg', capture=True ): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( command, output_file=None if capture else module.DO_NOT_CAPTURE, output_log_level=output_log_level, borg_local_path=borg_local_path, + extra_environment=None, ).once() diff --git a/tests/unit/borg/test_extract.py b/tests/unit/borg/test_extract.py index 7881fce..58503f7 100644 --- a/tests/unit/borg/test_extract.py +++ b/tests/unit/borg/test_extract.py @@ -9,14 +9,16 @@ from ..test_verbosity import insert_logging_mock def insert_execute_command_mock(command, working_directory=None): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - command, working_directory=working_directory + command, working_directory=working_directory, extra_environment=None, ).once() def insert_execute_command_output_mock(command, result): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - command, output_log_level=None, borg_local_path=command[0] + command, output_log_level=None, borg_local_path=command[0], extra_environment=None, ).and_return(result).once() @@ -27,14 +29,14 @@ def test_extract_last_archive_dry_run_calls_borg_with_last_archive(): insert_execute_command_mock(('borg', 'extract', '--dry-run', 'repo::archive2')) flexmock(module.feature).should_receive('available').and_return(True) - module.extract_last_archive_dry_run(repository='repo', lock_wait=None) + module.extract_last_archive_dry_run(storage_config={}, repository='repo', lock_wait=None) def test_extract_last_archive_dry_run_without_any_archives_should_not_raise(): insert_execute_command_output_mock(('borg', 'list', '--short', 'repo'), result='\n') flexmock(module.feature).should_receive('available').and_return(True) - module.extract_last_archive_dry_run(repository='repo', lock_wait=None) + module.extract_last_archive_dry_run(storage_config={}, repository='repo', lock_wait=None) def test_extract_last_archive_dry_run_with_log_info_calls_borg_with_info_parameter(): @@ -45,7 +47,7 @@ def test_extract_last_archive_dry_run_with_log_info_calls_borg_with_info_paramet insert_logging_mock(logging.INFO) flexmock(module.feature).should_receive('available').and_return(True) - module.extract_last_archive_dry_run(repository='repo', lock_wait=None) + module.extract_last_archive_dry_run(storage_config={}, repository='repo', lock_wait=None) def test_extract_last_archive_dry_run_with_log_debug_calls_borg_with_debug_parameter(): @@ -58,7 +60,7 @@ def test_extract_last_archive_dry_run_with_log_debug_calls_borg_with_debug_param insert_logging_mock(logging.DEBUG) flexmock(module.feature).should_receive('available').and_return(True) - module.extract_last_archive_dry_run(repository='repo', lock_wait=None) + module.extract_last_archive_dry_run(storage_config={}, repository='repo', lock_wait=None) def test_extract_last_archive_dry_run_calls_borg_via_local_path(): @@ -68,7 +70,9 @@ def test_extract_last_archive_dry_run_calls_borg_via_local_path(): insert_execute_command_mock(('borg1', 'extract', '--dry-run', 'repo::archive2')) flexmock(module.feature).should_receive('available').and_return(True) - module.extract_last_archive_dry_run(repository='repo', lock_wait=None, local_path='borg1') + module.extract_last_archive_dry_run( + storage_config={}, repository='repo', lock_wait=None, local_path='borg1' + ) def test_extract_last_archive_dry_run_calls_borg_with_remote_path_parameters(): @@ -80,7 +84,9 @@ def test_extract_last_archive_dry_run_calls_borg_with_remote_path_parameters(): ) flexmock(module.feature).should_receive('available').and_return(True) - module.extract_last_archive_dry_run(repository='repo', lock_wait=None, remote_path='borg1') + module.extract_last_archive_dry_run( + storage_config={}, repository='repo', lock_wait=None, remote_path='borg1' + ) def test_extract_last_archive_dry_run_calls_borg_with_lock_wait_parameters(): @@ -92,7 +98,7 @@ def test_extract_last_archive_dry_run_calls_borg_with_lock_wait_parameters(): ) flexmock(module.feature).should_receive('available').and_return(True) - module.extract_last_archive_dry_run(repository='repo', lock_wait=5) + module.extract_last_archive_dry_run(storage_config={}, repository='repo', lock_wait=5) def test_extract_archive_calls_borg_with_path_parameters(): @@ -267,10 +273,12 @@ def test_extract_archive_calls_borg_with_strip_components(): def test_extract_archive_calls_borg_with_progress_parameter(): flexmock(module.os.path).should_receive('abspath').and_return('repo') + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'extract', '--progress', 'repo::archive'), output_file=module.DO_NOT_CAPTURE, working_directory=None, + extra_environment=None, ).once() flexmock(module.feature).should_receive('available').and_return(True) @@ -306,11 +314,13 @@ def test_extract_archive_with_progress_and_extract_to_stdout_raises(): def test_extract_archive_calls_borg_with_stdout_parameter_and_returns_process(): flexmock(module.os.path).should_receive('abspath').and_return('repo') process = flexmock() + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'extract', '--stdout', 'repo::archive'), output_file=module.subprocess.PIPE, working_directory=None, run_to_completion=False, + extra_environment=None, ).and_return(process).once() flexmock(module.feature).should_receive('available').and_return(True) @@ -331,8 +341,9 @@ def test_extract_archive_calls_borg_with_stdout_parameter_and_returns_process(): def test_extract_archive_skips_abspath_for_remote_repository(): flexmock(module.os.path).should_receive('abspath').never() + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'extract', 'server:repo::archive'), working_directory=None + ('borg', 'extract', 'server:repo::archive'), working_directory=None, extra_environment=None, ).once() flexmock(module.feature).should_receive('available').and_return(True) diff --git a/tests/unit/borg/test_info.py b/tests/unit/borg/test_info.py index fffac76..b91f560 100644 --- a/tests/unit/borg/test_info.py +++ b/tests/unit/borg/test_info.py @@ -9,8 +9,12 @@ from ..test_verbosity import insert_logging_mock def test_display_archives_info_calls_borg_with_parameters(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'info', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg' + ('borg', 'info', 'repo'), + output_log_level=logging.WARNING, + borg_local_path='borg', + extra_environment=None, ) module.display_archives_info( @@ -19,8 +23,12 @@ def test_display_archives_info_calls_borg_with_parameters(): def test_display_archives_info_with_log_info_calls_borg_with_info_parameter(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'info', '--info', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg' + ('borg', 'info', '--info', 'repo'), + output_log_level=logging.WARNING, + borg_local_path='borg', + extra_environment=None, ) insert_logging_mock(logging.INFO) module.display_archives_info( @@ -29,8 +37,12 @@ def test_display_archives_info_with_log_info_calls_borg_with_info_parameter(): def test_display_archives_info_with_log_info_and_json_suppresses_most_borg_output(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'info', '--json', 'repo'), output_log_level=None, borg_local_path='borg' + ('borg', 'info', '--json', 'repo'), + output_log_level=None, + borg_local_path='borg', + extra_environment=None, ).and_return('[]') insert_logging_mock(logging.INFO) @@ -42,10 +54,12 @@ def test_display_archives_info_with_log_info_and_json_suppresses_most_borg_outpu def test_display_archives_info_with_log_debug_calls_borg_with_debug_parameter(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'info', '--debug', '--show-rc', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ) insert_logging_mock(logging.DEBUG) @@ -55,8 +69,12 @@ def test_display_archives_info_with_log_debug_calls_borg_with_debug_parameter(): def test_display_archives_info_with_log_debug_and_json_suppresses_most_borg_output(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'info', '--json', 'repo'), output_log_level=None, borg_local_path='borg' + ('borg', 'info', '--json', 'repo'), + output_log_level=None, + borg_local_path='borg', + extra_environment=None, ).and_return('[]') insert_logging_mock(logging.DEBUG) @@ -68,8 +86,12 @@ def test_display_archives_info_with_log_debug_and_json_suppresses_most_borg_outp def test_display_archives_info_with_json_calls_borg_with_json_parameter(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'info', '--json', 'repo'), output_log_level=None, borg_local_path='borg' + ('borg', 'info', '--json', 'repo'), + output_log_level=None, + borg_local_path='borg', + extra_environment=None, ).and_return('[]') json_output = module.display_archives_info( @@ -80,8 +102,12 @@ def test_display_archives_info_with_json_calls_borg_with_json_parameter(): def test_display_archives_info_with_archive_calls_borg_with_archive_parameter(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'info', 'repo::archive'), output_log_level=logging.WARNING, borg_local_path='borg' + ('borg', 'info', 'repo::archive'), + output_log_level=logging.WARNING, + borg_local_path='borg', + extra_environment=None, ) module.display_archives_info( @@ -90,8 +116,12 @@ def test_display_archives_info_with_archive_calls_borg_with_archive_parameter(): def test_display_archives_info_with_local_path_calls_borg_via_local_path(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg1', 'info', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg1' + ('borg1', 'info', 'repo'), + output_log_level=logging.WARNING, + borg_local_path='borg1', + extra_environment=None, ) module.display_archives_info( @@ -103,10 +133,12 @@ def test_display_archives_info_with_local_path_calls_borg_via_local_path(): def test_display_archives_info_with_remote_path_calls_borg_with_remote_path_parameters(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'info', '--remote-path', 'borg1', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ) module.display_archives_info( @@ -119,10 +151,12 @@ def test_display_archives_info_with_remote_path_calls_borg_with_remote_path_para def test_display_archives_info_with_lock_wait_calls_borg_with_lock_wait_parameters(): storage_config = {'lock_wait': 5} + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'info', '--lock-wait', '5', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ) module.display_archives_info( @@ -134,10 +168,12 @@ def test_display_archives_info_with_lock_wait_calls_borg_with_lock_wait_paramete @pytest.mark.parametrize('argument_name', ('prefix', 'glob_archives', 'sort_by', 'first', 'last')) def test_display_archives_info_passes_through_arguments_to_borg(argument_name): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'info', '--' + argument_name.replace('_', '-'), 'value', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ) module.display_archives_info( diff --git a/tests/unit/borg/test_init.py b/tests/unit/borg/test_init.py index 556b40d..fb81f34 100644 --- a/tests/unit/borg/test_init.py +++ b/tests/unit/borg/test_init.py @@ -23,8 +23,12 @@ def insert_info_command_not_found_mock(): def insert_init_command_mock(init_command, **kwargs): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - init_command, output_file=module.DO_NOT_CAPTURE, borg_local_path=init_command[0] + init_command, + output_file=module.DO_NOT_CAPTURE, + borg_local_path=init_command[0], + extra_environment=None, ).once() @@ -37,6 +41,7 @@ def test_initialize_repository_calls_borg_with_parameters(): def test_initialize_repository_raises_for_borg_init_error(): insert_info_command_not_found_mock() + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').and_raise( module.subprocess.CalledProcessError(2, 'borg init') ) diff --git a/tests/unit/borg/test_list.py b/tests/unit/borg/test_list.py index dd85f82..6123a07 100644 --- a/tests/unit/borg/test_list.py +++ b/tests/unit/borg/test_list.py @@ -24,8 +24,12 @@ def test_resolve_archive_name_passes_through_non_latest_archive_name(): def test_resolve_archive_name_calls_borg_with_parameters(): expected_archive = 'archive-name' + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, output_log_level=None, borg_local_path='borg' + ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, + output_log_level=None, + borg_local_path='borg', + extra_environment=None, ).and_return(expected_archive + '\n') assert module.resolve_archive_name('repo', 'latest', storage_config={}) == expected_archive @@ -33,10 +37,12 @@ def test_resolve_archive_name_calls_borg_with_parameters(): def test_resolve_archive_name_with_log_info_calls_borg_with_info_parameter(): expected_archive = 'archive-name' + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', '--info') + BORG_LIST_LATEST_ARGUMENTS, output_log_level=None, borg_local_path='borg', + extra_environment=None, ).and_return(expected_archive + '\n') insert_logging_mock(logging.INFO) @@ -45,10 +51,12 @@ def test_resolve_archive_name_with_log_info_calls_borg_with_info_parameter(): def test_resolve_archive_name_with_log_debug_calls_borg_with_debug_parameter(): expected_archive = 'archive-name' + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', '--debug', '--show-rc') + BORG_LIST_LATEST_ARGUMENTS, output_log_level=None, borg_local_path='borg', + extra_environment=None, ).and_return(expected_archive + '\n') insert_logging_mock(logging.DEBUG) @@ -57,10 +65,12 @@ def test_resolve_archive_name_with_log_debug_calls_borg_with_debug_parameter(): def test_resolve_archive_name_with_local_path_calls_borg_via_local_path(): expected_archive = 'archive-name' + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg1', 'list') + BORG_LIST_LATEST_ARGUMENTS, output_log_level=None, borg_local_path='borg1', + extra_environment=None, ).and_return(expected_archive + '\n') assert ( @@ -71,10 +81,12 @@ def test_resolve_archive_name_with_local_path_calls_borg_via_local_path(): def test_resolve_archive_name_with_remote_path_calls_borg_with_remote_path_parameters(): expected_archive = 'archive-name' + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', '--remote-path', 'borg1') + BORG_LIST_LATEST_ARGUMENTS, output_log_level=None, borg_local_path='borg', + extra_environment=None, ).and_return(expected_archive + '\n') assert ( @@ -84,8 +96,12 @@ def test_resolve_archive_name_with_remote_path_calls_borg_with_remote_path_param def test_resolve_archive_name_without_archives_raises(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, output_log_level=None, borg_local_path='borg' + ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, + output_log_level=None, + borg_local_path='borg', + extra_environment=None, ).and_return('') with pytest.raises(ValueError): @@ -95,10 +111,12 @@ def test_resolve_archive_name_without_archives_raises(): def test_resolve_archive_name_with_lock_wait_calls_borg_with_lock_wait_parameters(): expected_archive = 'archive-name' + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', '--lock-wait', 'okay') + BORG_LIST_LATEST_ARGUMENTS, output_log_level=None, borg_local_path='borg', + extra_environment=None, ).and_return(expected_archive + '\n') assert ( @@ -296,8 +314,12 @@ def test_list_archives_calls_borg_with_parameters(): remote_path=None, ).and_return(('borg', 'list', 'repo')) flexmock(module).should_receive('make_find_paths').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'list', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg' + ('borg', 'list', 'repo'), + output_log_level=logging.WARNING, + borg_local_path='borg', + extra_environment=None, ).once() module.list_archives( @@ -316,8 +338,12 @@ def test_list_archives_with_json_suppresses_most_borg_output(): remote_path=None, ).and_return(('borg', 'list', 'repo')) flexmock(module).should_receive('make_find_paths').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'list', 'repo'), output_log_level=None, borg_local_path='borg' + ('borg', 'list', 'repo'), + output_log_level=None, + borg_local_path='borg', + extra_environment=None, ).once() module.list_archives( @@ -336,8 +362,12 @@ def test_list_archives_calls_borg_with_local_path(): remote_path=None, ).and_return(('borg2', 'list', 'repo')) flexmock(module).should_receive('make_find_paths').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg2', 'list', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg2' + ('borg2', 'list', 'repo'), + output_log_level=logging.WARNING, + borg_local_path='borg2', + extra_environment=None, ).once() module.list_archives( @@ -355,20 +385,27 @@ def test_list_archives_calls_borg_multiple_times_with_find_paths(): ('borg', 'list', 'repo') ).and_return(('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'), output_log_level=None, borg_local_path='borg' + ('borg', 'list', 'repo'), + output_log_level=None, + borg_local_path='borg', + extra_environment=None, ).and_return( 'archive1 Sun, 2022-05-29 15:27:04 [abc]\narchive2 Mon, 2022-05-30 19:47:15 [xyz]' ).once() + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', 'repo::archive1') + glob_paths, output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ).once() flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', 'repo::archive2') + glob_paths, output_log_level=logging.WARNING, borg_local_path='borg', + extra_environment=None, ).once() module.list_archives( @@ -387,8 +424,12 @@ def test_list_archives_calls_borg_with_archive(): remote_path=None, ).and_return(('borg', 'list', 'repo::archive')) flexmock(module).should_receive('make_find_paths').and_return(()) + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'list', 'repo::archive'), output_log_level=logging.WARNING, borg_local_path='borg' + ('borg', 'list', 'repo::archive'), + output_log_level=logging.WARNING, + borg_local_path='borg', + extra_environment=None, ).once() module.list_archives( diff --git a/tests/unit/borg/test_mount.py b/tests/unit/borg/test_mount.py index 0de1147..c5638ca 100644 --- a/tests/unit/borg/test_mount.py +++ b/tests/unit/borg/test_mount.py @@ -8,8 +8,9 @@ from ..test_verbosity import insert_logging_mock def insert_execute_command_mock(command): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - command, borg_local_path='borg' + command, borg_local_path='borg', extra_environment=None, ).once() @@ -117,10 +118,12 @@ def test_mount_archive_with_log_debug_calls_borg_with_debug_parameters(): def test_mount_archive_calls_borg_with_foreground_parameter(): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'mount', '--foreground', 'repo::archive', '/mnt'), output_file=module.DO_NOT_CAPTURE, borg_local_path='borg', + extra_environment=None, ).once() module.mount_archive( diff --git a/tests/unit/borg/test_prune.py b/tests/unit/borg/test_prune.py index 5e20b07..f4f34ed 100644 --- a/tests/unit/borg/test_prune.py +++ b/tests/unit/borg/test_prune.py @@ -9,8 +9,12 @@ from ..test_verbosity import insert_logging_mock def insert_execute_command_mock(prune_command, output_log_level): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - prune_command, output_log_level=output_log_level, borg_local_path=prune_command[0] + prune_command, + output_log_level=output_log_level, + borg_local_path=prune_command[0], + extra_environment=None, ).once() diff --git a/tests/unit/borg/test_version.py b/tests/unit/borg/test_version.py index db4d218..6931e26 100644 --- a/tests/unit/borg/test_version.py +++ b/tests/unit/borg/test_version.py @@ -11,39 +11,45 @@ VERSION = '1.2.3' def insert_execute_command_mock(command, borg_local_path='borg', version_output=f'borg {VERSION}'): + flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - command, output_log_level=None, borg_local_path=borg_local_path + command, output_log_level=None, borg_local_path=borg_local_path, extra_environment=None, ).once().and_return(version_output) def test_local_borg_version_calls_borg_with_required_parameters(): insert_execute_command_mock(('borg', '--version')) + flexmock(module.environment).should_receive('make_environment') - assert module.local_borg_version() == VERSION + assert module.local_borg_version({}) == VERSION def test_local_borg_version_with_log_info_calls_borg_with_info_parameter(): insert_execute_command_mock(('borg', '--version', '--info')) insert_logging_mock(logging.INFO) + flexmock(module.environment).should_receive('make_environment') - assert module.local_borg_version() == VERSION + assert module.local_borg_version({}) == VERSION def test_local_borg_version_with_log_debug_calls_borg_with_debug_parameters(): insert_execute_command_mock(('borg', '--version', '--debug', '--show-rc')) insert_logging_mock(logging.DEBUG) + flexmock(module.environment).should_receive('make_environment') - assert module.local_borg_version() == VERSION + assert module.local_borg_version({}) == VERSION def test_local_borg_version_with_local_borg_path_calls_borg_with_it(): insert_execute_command_mock(('borg1', '--version'), borg_local_path='borg1') + flexmock(module.environment).should_receive('make_environment') - assert module.local_borg_version('borg1') == VERSION + assert module.local_borg_version({}, 'borg1') == VERSION def test_local_borg_version_with_invalid_version_raises(): insert_execute_command_mock(('borg', '--version'), version_output='wtf') + flexmock(module.environment).should_receive('make_environment') with pytest.raises(ValueError): - module.local_borg_version() + module.local_borg_version({}) diff --git a/tests/unit/commands/test_borgmatic.py b/tests/unit/commands/test_borgmatic.py index 6918d4e..bc62d7a 100644 --- a/tests/unit/commands/test_borgmatic.py +++ b/tests/unit/commands/test_borgmatic.py @@ -9,7 +9,6 @@ from borgmatic.commands import borgmatic as module def test_run_configuration_runs_actions_for_each_repository(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) expected_results = [flexmock(), flexmock()] flexmock(module).should_receive('run_actions').and_return(expected_results[:1]).and_return( @@ -24,7 +23,6 @@ def test_run_configuration_runs_actions_for_each_repository(): def test_run_configuration_with_invalid_borg_version_errors(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_raise(ValueError) flexmock(module.command).should_receive('execute_hook').never() flexmock(module.dispatch).should_receive('call_hooks').never() @@ -36,7 +34,6 @@ def test_run_configuration_with_invalid_borg_version_errors(): def test_run_configuration_logs_monitor_start_error(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.dispatch).should_receive('call_hooks').and_raise(OSError).and_return( None @@ -53,7 +50,6 @@ def test_run_configuration_logs_monitor_start_error(): def test_run_configuration_bails_for_monitor_start_soft_failure(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) error = subprocess.CalledProcessError(borgmatic.hooks.command.SOFT_FAIL_EXIT_CODE, 'try again') flexmock(module.dispatch).should_receive('call_hooks').and_raise(error) @@ -68,7 +64,6 @@ def test_run_configuration_bails_for_monitor_start_soft_failure(): def test_run_configuration_logs_actions_error(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.command).should_receive('execute_hook') flexmock(module.dispatch).should_receive('call_hooks') @@ -84,7 +79,6 @@ def test_run_configuration_logs_actions_error(): def test_run_configuration_bails_for_actions_soft_failure(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.dispatch).should_receive('call_hooks') error = subprocess.CalledProcessError(borgmatic.hooks.command.SOFT_FAIL_EXIT_CODE, 'try again') @@ -100,7 +94,6 @@ def test_run_configuration_bails_for_actions_soft_failure(): def test_run_configuration_logs_monitor_finish_error(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.dispatch).should_receive('call_hooks').and_return(None).and_return( None @@ -117,7 +110,6 @@ def test_run_configuration_logs_monitor_finish_error(): def test_run_configuration_bails_for_monitor_finish_soft_failure(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) error = subprocess.CalledProcessError(borgmatic.hooks.command.SOFT_FAIL_EXIT_CODE, 'try again') flexmock(module.dispatch).should_receive('call_hooks').and_return(None).and_return( @@ -135,7 +127,6 @@ def test_run_configuration_bails_for_monitor_finish_soft_failure(): def test_run_configuration_logs_on_error_hook_error(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.command).should_receive('execute_hook').and_raise(OSError) expected_results = [flexmock(), flexmock()] @@ -152,7 +143,6 @@ def test_run_configuration_logs_on_error_hook_error(): def test_run_configuration_bails_for_on_error_hook_soft_failure(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) error = subprocess.CalledProcessError(borgmatic.hooks.command.SOFT_FAIL_EXIT_CODE, 'try again') flexmock(module.command).should_receive('execute_hook').and_raise(error) @@ -169,7 +159,6 @@ def test_run_configuration_bails_for_on_error_hook_soft_failure(): def test_run_configuration_retries_soft_error(): # Run action first fails, second passes - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.command).should_receive('execute_hook') flexmock(module).should_receive('run_actions').and_raise(OSError).and_return([]) @@ -182,7 +171,6 @@ def test_run_configuration_retries_soft_error(): def test_run_configuration_retries_hard_error(): # Run action fails twice - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.command).should_receive('execute_hook') flexmock(module).should_receive('run_actions').and_raise(OSError).times(2) @@ -203,7 +191,6 @@ def test_run_configuration_retries_hard_error(): def test_run_repos_ordered(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.command).should_receive('execute_hook') flexmock(module).should_receive('run_actions').and_raise(OSError).times(2) @@ -221,7 +208,6 @@ def test_run_repos_ordered(): def test_run_configuration_retries_round_robbin(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.command).should_receive('execute_hook') flexmock(module).should_receive('run_actions').and_raise(OSError).times(4) @@ -252,7 +238,6 @@ def test_run_configuration_retries_round_robbin(): def test_run_configuration_retries_one_passes(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.command).should_receive('execute_hook') flexmock(module).should_receive('run_actions').and_raise(OSError).and_raise(OSError).and_return( @@ -281,7 +266,6 @@ def test_run_configuration_retries_one_passes(): def test_run_configuration_retry_wait(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.command).should_receive('execute_hook') flexmock(module).should_receive('run_actions').and_raise(OSError).times(4) @@ -320,7 +304,6 @@ def test_run_configuration_retry_wait(): def test_run_configuration_retries_timeout_multiple_repos(): - flexmock(module.borg_environment).should_receive('initialize') flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock()) flexmock(module.command).should_receive('execute_hook') flexmock(module).should_receive('run_actions').and_raise(OSError).and_raise(OSError).and_return(